On 05/07/16(Tue) 19:01, Dimitris Papastamos wrote:
> On Tue, Jul 05, 2016 at 02:14:57PM +0200, Martin Pieuchot wrote:
> > Without more information it's hard to find what could be the reason
> > for this crash. Being able to reproduce the crash easily is the key
> > to debugging. Can you do that?
>
> while :; do (chrome &); sleep 8; pkill chrome; done
>
> It takes up to a minute to trigger it.
That's good because I cannot reproduce it here on my test machine.
> I just noticed (sorry about this) that I am running with your scheduler
> hack from some months ago.
> [...]
This should not be necessary but...
> Without this diff, I cannot trigger it in any reasonable time.
...then keep it! Hopefully it's just a side effect.
> > My bet is that unp_discard() is called twice for a set of fps, because as
> > you can see the set of fps is cleared after being enqueued.
> >
> > If you can reproduce the crash, could you run with the diff below and
> > see if you can trigger the panic?
>
> I manually copied the panic output:
>
> panic: tell me what you really really want
Thanks! So could you try the second step? After applying the diff below
set splassert to 4 before starting your loop (sysctl kern.splassert=4).
The machine should no longer panic but dump multiple traces until a NULL
pointer is found.
Please report your dmesg as soon as you see "unp_discard: NULL fp..."
Index: kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.97
diff -u -p -r1.97 uipc_usrreq.c
--- kern/uipc_usrreq.c 25 Apr 2016 20:18:31 -0000 1.97
+++ kern/uipc_usrreq.c 6 Jul 2016 13:09:04 -0000
@@ -1053,10 +1053,33 @@ unp_mark(struct file **rp, int nfds)
}
}
+#include <ddb/db_output.h>
+
void
unp_discard(struct file **rp, int nfds)
{
struct unp_deferral *defer;
+#ifdef DIAGNOSTIC
+ struct file *fp;
+ int i;
+
+#ifdef DDB
+ extern int splassert_ctl;
+ if (splassert_ctl == 4) {
+ db_printf("==> p=%p rp=%p nfs=%d\n", curproc, rp, nfds);
+ db_stack_dump();
+ }
+#endif /* DDB */
+
+ for (i = 0; i < nfds; i++) {
+ memcpy(&fp, &((struct file **)(rp))[i], sizeof(fp));
+ if (fp == NULL) {
+ printf("%s: NULL fp, stop dumping\n", __func__);
+ splassert_ctl = 1;
+ return;
+ }
+ }
+#endif /* DIAGNOSTIC */
/* copy the file pointers to a deferral structure */
defer = malloc(sizeof(*defer) + sizeof(*rp) * nfds, M_TEMP, M_WAITOK);