PT_ATTACH resumes suspended process

From: Ben Widawsky <widawsky_at_gmail.com>
Date: Fri, 7 May 2010 13:52:15 -0700
If a debugger attaches to a suspended process, the process will be
resumed, and backgrounded. This seems like the incorrect behavior to me
based what I read in the man page. "The tracing process will see the
newly-traced process stop and may then control it as if it had been
traced all along."

The behavior exhibited in FreeBSD is that the process is resumed, and we
will not reach ptracestop() until the next debugger command comes in.

The exact code in question I believe is a combination of kern_ptrace()
and issignal(). When a PT_ATTACH comes in, ptrace code will unsuspend the
process and set xsig=SIGSTOP of the thread picked to communicate with the
debugger (which by the way should be the same as the thread chosen to
deliver the SIGSTOP earlier, and I see no guarantee of this either but I
may be missing something). The thread will resume in issignal, and may
not have any signals pending, so issignal will return 0. The result here is
every thread gets unsuspended until the debugger explicitly suspends.

There is even a comment in kern_ptrace() for which I see no action:
/* deliver or queue signal */

I've created a quick hack to enable debugging to work how I think it
should. Essentially the change is as follows, there are a couple
other bits as well; line 2524 kern_sig.c, in issignal():
	if (traced && !sig) {
		/*
		 * see if we were given a signal by sendsig in kern_ptrace()
		 */
		sig = td->td_xsig;
	}

You can reproduce this with a simple app that spins forever doing
something. In one shell, run the app and from another shell send a
SIGSTOP and attach with gdb. I've only tried this on FreeBSD 8.0-RELEASE,
but judging by the code it seems like it would still happen in HEAD.

:::SHELL1:::
[bwidawsk_at_bwfbsd ~/workspace/C/debugg]$ ./a.out
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

[1]+  Stopped                 ./a.out
[bwidawsk_at_bwfbsd ~/workspace/C/debugg]$ 21
22


:::SHELL2:::
[bwidawsk_at_bwfbsd ~/workspace/C/debugg]$ kill -SIGSTOP 4134
[bwidawsk_at_bwfbsd ~/workspace/C/debugg]$ gdb a.out 4134
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
Attaching to program: /usr/home/bwidawsk/workspace/C/debugg/a.out, process 4134
Received on Fri May 07 2010 - 19:21:34 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:03 UTC