Date: Mon, 13 Sep 2004 21:51:36 +1000 From: Sam Lawrance <boris@brooknet.com.au> To: current@freebsd.org Subject: truss -f "hangs" when traced process vfork()s Message-ID: <1095076295.77709.50.camel@dirk.no.domain>
next in thread | raw e-mail | index | archive | help
Hello, If I run "truss -f make clean" in a port directory, I wind up with a situation like the following. There are three processes concerned: truss, the initially traced process, and the newly forked child: root 77739 0.0 0.2 1304 764 v1 I+ 7:50PM 0:00.02 truss -f make clean root 77740 0.0 0.1 540 376 v1 DL+ 7:50PM 0:00.01 make clean root 77741 0.0 0.1 540 376 v1 DV+ 7:50PM 0:00.00 make clean Backtrace of truss. Truss is waiting for an event to be reported from procfs (everything past msleep omitted). msleep(c1c07f28,c1c07e6c,15c,c08052e3,0) at msleep+0x312 procfs_ioctl(c16ee960,c1c07e00,c173d480,40147004,ce674c60) at procfs_ioctl+0x139 pfs_ioctl(ce674b88) at pfs_ioctl+0xd9 vn_ioctl(c2f0ae14,40147004,ce674c60,c293bc00,c16ee960) at vn_ioctl+0x187 ioctl(c16ee960,ce674d14,3,1,292) at ioctl+0x551 syscall(2f,2f,2f,8057038,2) at syscall+0x283 Xint0x80_syscall() at Xint0x80_syscall+0x1f --- syscall (54, FreeBSD ELF32, ioctl), eip = 0x280d8123, esp = 0xbfbfeccc, ebp = 0xbfbfed50 --- Backtrace of the initially traced process. The process has vfork()ed and is awaiting return from fork1(). vfork() calls fork1() with the RFPPWAIT flag set, so the syscall won't return until the child process exits. msleep(c1c07e00,c1c0706c,5c,c080749a,0) at msleep+0x322 fork1(c1908c80,80000034,0,d33b9ce4,c1908c80) at fork1+0x14f9 vfork(c1908c80,d33b9d14,0,1,213) at vfork+0x1b syscall(2f,2f,2f,8080ba5,0) at syscall+0x283 Xint0x80_syscall() at Xint0x80_syscall+0x1f --- syscall (66, FreeBSD ELF32, vfork), eip = 0x805c0a0, esp = 0xbfbfd780, ebp = 0xbfbfdbb8 --- Backtrace of the child process. The process has been stopped because it has generated an event and has tracing flags set (like its parent). msleep(c1c0712c,c1c0706c,5c,c080b3bb,0,c1c07128) at msleep+0x322 stopevent(c1c07000,4,1) at stopevent+0x54 syscall(2f,2f,2f,0,0) at syscall+0x1f7 Xint0x80_syscall() at Xint0x80_syscall+0x1f --- syscall (6, FreeBSD ELF32, close), eip = 0x8064d03, esp = 0xbfbfd76c, ebp = 0xbfbfdbb8 --- Normally, truss will fork a copy of itself to trace the child process once it gets the PID. However, the initially traced process is still in vfork(). So: - truss is waiting (PIOCFWAIT) for the initially traced process to stop - the initially traced process is waiting for vfork() to return - the child process created by the vfork() has been created, stopped at the first event, and is waiting to be continued (PIOCCONT) - but since truss is still waiting for for the initial process to stop on return from vfork(), it doesn't have a PID for the child, and so has not forked another truss to trace the child. The child is stranded and won't return. I haven't thought much about a solution, but perhaps truss needs to fork at syscall entry rather than syscall exit, in cases where the traced process has executed a fork that RFPPWAITs. Is this right? Shall I file a PR? -- FreeBSD dirk.no.domain 5.3-BETA4 FreeBSD 5.3-BETA4 #5: Mon Sep 13 11:20:19 EST 2004 sam@dirk.no.domain:/usr/obj/usr/src/sys/GENERIC i386
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1095076295.77709.50.camel>