From: Peter Seiderer <seiderer123@ciselant.de>
To: linux-kernel@vger.kernel.org
Subject: Question about PTRACE_DETACH
Date: Fri, 9 Apr 2004 10:34:04 +0200 [thread overview]
Message-ID: <20040409083404.GA1461@zodiak> (raw)
[-- Attachment #1: Type: text/plain, Size: 2537 bytes --]
Hello,
shouldn't ptrace(PTRACE_DETACH, pid, NULL, SIGSTOP) stop the child?
The Valgrind [1] sequence call to stop a child, change the registers and
attach a debugger to the child is as following (or take a look at
[2] function start_debugger(), or the attached test program):
if ((pid = fork()) == 0) {
ptrace(PTRACE_TRACEME, ...);
kill(getpid(), SIGSTOP);
// should never be reached
} else {
waitpid(pid, ...);
ptrace(PTRACE_SETREGS, ...)
ptrace(PTRACE_DETACH, pid, NULL, SIGSTOP)
// attach gdb to child
}
But the child seems to resume execution after the PTRACE_DETACH call (in
contradiction to what the ptrace man page [3] tells).
Example programm gdb_attach.c attached to the e-mail.
gcc -Wall -g -o g db_attach gdb_attach.c
./gdb_attach
parent
child
parent: cmdl: gdb gdb_attach 1509
child: should never be reached
<gdb output snipped>
0x400d4411 in nanosleep () from /lib/libc.so.6
(gdb) bt
#0 0x400d4411 in nanosleep () from /lib/libc.so.6
#1 0x400d43a8 in sleep () from /lib/libc.so.6
#2 0x08048704 in start_debugger () at gdb_attach.c:20
#3 0x08048889 in main (argc=1, argv=0xbffff444) at gdb_attach.c:46
#4 0x400499ed in __libc_start_main () from /lib/libc.so.6
One 'workaround' is to send an additional SIGSTOP from the parent:
gcc -Wall -g -DADDITIONAL_SIGSTOP -o gdb_attach gdb_attach.c
./gdb_attach
parent
child
parent: cmdl: gdb gdb_attach 1519
<gdb output>
0x4005aab1 in kill () from /lib/libc.so.6
(gdb) bt
#0 0x4005aab1 in kill () from /lib/libc.so.6
#1 0x080486ec in start_debugger () at gdb_attach.c:17
#2 0x080488c5 in main (argc=1, argv=0xbffff444) at gdb_attach.c:46
#3 0x400499ed in __libc_start_main () from /lib/libc.so.6
(gdb)
It this a PTRACE_DETACH bug (kernel used 2.4.25)?
If not, is the additional SIGSTOP a valid 'workaround'?
If not, is there a better workaround/solution?
Thanks in advance for your help,
Peter Seiderer
[1] http://valgrind.kde.org/
[2] http://webcvs.kde.org/cgi-bin/cvsweb.cgi/~checkout~/valgrind/coregrind/vg_main.c?rev=1.147&content-type=text/plain
[3] http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi?coll=linux&db=man&fname=/usr/share/catman/man2/ptrace.2.html
PTRACE_DETACH: ... Restarts the stopped child as for PTRACE_CONT ...
PTRACE_CONT: ... Restarts the stopped child process. If data is
non-zero and not SIGSTOP, it is interpreted as a signal to be
delivered to the child ...
--
------------------------------------------------------------------------
Peter Seiderer E-Mail: seiderer123@ciselant.de
[-- Attachment #2: gdb_attach.c --]
[-- Type: text/plain, Size: 1100 bytes --]
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
void start_debugger() {
int pid;
if ((pid = fork()) == 0) {
printf("child\n");
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
kill(getpid(), SIGSTOP);
while(1){
printf("child: should never be reached\n");
sleep(1);
}
} else if (pid > 0) {
int status;
printf("parent\n");
assert(waitpid(pid, &status, 0) == pid);
assert(WIFSTOPPED(status));
assert(WSTOPSIG(status) == SIGSTOP);
#ifdef ADDITIONAL_SIGSTOP
// send additional SIGSTOP to work around possible PTRACE_DETACH bug
assert(kill(pid, SIGSTOP) == 0);
#endif
assert(ptrace(PTRACE_DETACH, pid, NULL, SIGSTOP) == 0);
char buf[1024];
snprintf(buf, 1024, "gdb gdb_attach %d", pid);
printf("parent: cmdl: %s\n", buf);
system(buf);
} else {
printf("parent: fork failed\n");
}
}
int main(int argc, char *argv[]) {
start_debugger();
return 0;
}
reply other threads:[~2004-04-09 8:35 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20040409083404.GA1461@zodiak \
--to=seiderer123@ciselant.de \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox