Date: Tue, 20 Sep 2011 00:27:22 +0300 From: Kostik Belousov <kostikbel@gmail.com> To: Anton Yuzhaninov <citrin@citrin.ru> Cc: freebsd-current@freebsd.org Subject: Re: truss Message-ID: <20110919212722.GQ1511@deviant.kiev.zoral.com.ua> In-Reply-To: <j57p4t$8u8$1@dough.gmane.org> References: <4E5E46A4.3060705@citrin.ru> <4E6A99A9.1000204@delphij.net> <j4pgu9$m94$1@dough.gmane.org> <864o0adkva.fsf@kopusha.home.net> <j57bm4$3lk$1@dough.gmane.org> <86mxe0r8o5.fsf@in138.ua3> <j57lef$a3d$1@dough.gmane.org> <j57p4t$8u8$1@dough.gmane.org>
next in thread | previous in thread | raw e-mail | index | archive | help
--OWK2L5TNMedLh6HD Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Sep 19, 2011 at 04:03:42PM +0000, Anton Yuzhaninov wrote: > On Mon, 19 Sep 2011 15:00:31 +0000 (UTC), Anton Yuzhaninov wrote: > AY> On Mon, 19 Sep 2011 15:58:02 +0300, Mikolaj Golub wrote: > AY>>> ktrace -i for truss sleep 5 > AY>>> http://dl.dropbox.com/u/8798217/tmp/truss_ktrace2.txt > MG>>=20 > MG>> Although ptrace(PT_TRACE_ME,0,0,0) returned 0 the process did not st= op after > MG>> execve() and wait4() in parent (which was actually waiting for this = stop) > MG>> returned only after the child exit. No I idea why so far :-). > MG>>=20 > AY>=20 > AY> As I understand SIGTRAP used to stop child process after execve(), but > AY> this signal ignored: > AY>=20 > AY> citrin:~> sleep 300 & > AY> citrin:~> procstat -i 1991 | fgrep TRAP > AY> 1991 sleep TRAP -I- > AY>=20 > AY> Under FreeBSD 8, where ptrace works for me, this signal is not ignore= d: > AY> x:~> sleep 300 & > AY> x:~> procstat -i 78716 | fgrep TRAP > AY> 78716 sleep TRAP --- >=20 > SIGTRAP is ignored by X window manager used by me, and this is inherited = across > forks/execs up to the truss. >=20 > IMHO truss should restore default signal handler for SIGTRAP. >=20 > With this patch truss works for me: >=20 > --- usr.bin/truss/main.c (revision 225504) > +++ usr.bin/truss/main.c (working copy) > @@ -255,6 +255,11 @@ main(int ac, char **av) >=20 > if (trussinfo->pid =3D=3D 0) { /* Start a command ourselves = */ > command =3D av; > + /* > + * SIGTRUP used to stop traced process after execve > + * un-ignore this signal (it can be ignored by parents) > + */ > + signal(SIGTRAP, SIG_DFL); > trussinfo->pid =3D setup_and_wait(command); > signal(SIGINT, SIG_IGN); > signal(SIGTERM, SIG_IGN); This is quite a hack. The proper fix should go in kernel, otherwise we cannot debug programs that decided to ignore SIGTRAP. The reason there is that tdsendsignal() does nothing for attempt to deliver ignored signal, and kern_execve() simply tries to send a signal to self. BTW, it seems we might also have similar issues for threads that masks SIGTRAP, now because issignal() does nothing in that case too. But lets handle it by small steps. Could you, please, test the change below ? For me, I still can truss(1) or debug with gdb after the change applied. Does truss work for you with only this change, without resetting SIGTRAP handler in truss process ? commit 2ae586c039a55399edc3b34cd40410e0d690a16c Author: Konstantin Belousov <kostik@pooma.home> Date: Tue Sep 20 00:25:07 2011 +0300 Do not deliver SIGTRAP on exec as the normal signal, use ptracestop() on syscall exit path. Otherwise, if SIGTRAP is ignored, that tdsendsign= al() do not want to deliver, and debugger never get a notification of exec. =20 Found by: Anton Yuzhaninov <citrin@citrin.ru> diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index fe01142..4545848 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -777,16 +777,6 @@ interpret: KNOTE_LOCKED(&p->p_klist, NOTE_EXEC); p->p_flag &=3D ~P_INEXEC; =20 - /* - * If tracing the process, trap to the debugger so that - * breakpoints can be set before the program executes. We - * have to use tdsignal() to deliver the signal to the current - * thread since any other threads in this process will exit if - * execve() succeeds. - */ - if (p->p_flag & P_TRACED) - tdsignal(td, SIGTRAP); - /* clear "fork but no exec" flag, as we _are_ execing */ p->p_acflag &=3D ~AFORK; =20 diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c index cb0d929..bba4479 100644 --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -204,9 +204,17 @@ syscallret(struct thread *td, int error, struct syscal= l_args *sa __unused) * is not the case, this code will need to be revisited. */ STOPEVENT(p, S_SCX, sa->code); - PTRACESTOP_SC(p, td, S_PT_SCX); if (traced || (td->td_dbgflags & (TDB_EXEC | TDB_FORK)) !=3D 0) { PROC_LOCK(p); + /* + * If tracing the execed process, trap to the debugger + * so that breakpoints can be set before the program + * executes. If debugger requested tracing of syscall + * returns, do it now too. + */ + if (traced && ((td->td_dbgflags & TDB_EXEC) !=3D 0 || + (p->p_stops & S_PT_SCX) !=3D 0)) + ptracestop(td, SIGTRAP); td->td_dbgflags &=3D ~(TDB_SCX | TDB_EXEC | TDB_FORK); PROC_UNLOCK(p); } --OWK2L5TNMedLh6HD Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (FreeBSD) iEYEARECAAYFAk53s7oACgkQC3+MBN1Mb4gVnQCeNaNaGJ66YRXh1LbdzO6b7EU7 JQYAn0IYN6P92oPCqHCKROzwIv5di0Xg =87+g -----END PGP SIGNATURE----- --OWK2L5TNMedLh6HD--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20110919212722.GQ1511>