Kamil Rytarowski wrote: >On 12.04.2016 14:14, Robert Swindells wrote: >> Patrick Welche wrote: >>> With a amd64 kernel built from Mar 28 16:05 GMT source, I just saw: >> [snip] > >I just reproduced it. > >>> (gdb) frame 5 >>> #5 0xffffffff8054547a in filt_sordetach (kn=0xfffffe804e698780) >>> at ../../../../kern/uipc_socket.c:2250 >>> 2250 SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, >>> kn_selnext); >>> (gdb) list >>> 2245 { >>> 2246 struct socket *so; >>> 2247 >>> 2248 so = ((file_t *)kn->kn_obj)->f_socket; >>> 2249 solock(so); >>> 2250 SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, >>> kn_selnext); >>> 2251 if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist)) >>> 2252 so->so_rcv.sb_flags &= ~SB_KNOTE; >>> 2253 sounlock(so); >>> 2254 } >> I have seen the same crash twice with sources from Apr 11, I have >> crash dumps but the kernel wasn't a debug build. >> >> Looking at the firefox sources the call to kevent(2) is presumably from: >> >> ipc/chromium/src/third_party/libevent/kqueue.c >> >> I guess it could be interesting to look at the fields of the socket >> struct.
If close(2) has already been called on the socket before the call to kevent(2) to delete the knote structure then f_socket would be NULL. It also looks to me as if sofree() would leak any knote structures that were attached. I have put a bit of debug code in my local tree to test the theory. Robert Swindells Index: uipc_socket.c =================================================================== RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v retrieving revision 1.247 diff -u -r1.247 uipc_socket.c --- uipc_socket.c 13 Oct 2015 21:28:35 -0000 1.247 +++ uipc_socket.c 16 May 2016 21:47:56 -0000 @@ -709,6 +709,12 @@ /* Remove acccept filter if one is present. */ if (so->so_accf != NULL) (void)accept_filt_clear(so); + if (so->so_rcv.sb_flags & SB_KNOTE) { + printf("sofree: rcv knote\n"); + } + if (so->so_snd.sb_flags & SB_KNOTE) { + printf("sofree: snd knote\n"); + } sounlock(so); if (refs == 0) /* XXX */ soput(so); @@ -2221,6 +2227,10 @@ struct socket *so; so = ((file_t *)kn->kn_obj)->f_socket; + if (so == NULL) { + printf("filt_sordetach: no socket\n"); + return; + } solock(so); SLIST_REMOVE(&so->so_rcv.sb_sel.sel_klist, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_rcv.sb_sel.sel_klist)) @@ -2260,6 +2270,10 @@ struct socket *so; so = ((file_t *)kn->kn_obj)->f_socket; + if (so == NULL) { + printf("filt_sowdetach: no socket\n"); + return; + } solock(so); SLIST_REMOVE(&so->so_snd.sb_sel.sel_klist, kn, knote, kn_selnext); if (SLIST_EMPTY(&so->so_snd.sb_sel.sel_klist))