[PATCH] allow strace to trace SIGTRAP signals
Heiko Carstens
heiko.carstens at de.ibm.com
Thu Jan 20 23:00:01 UTC 2005
Hi Roland,
the patch below is from Ulrich Weigand which incorporates some changes
by me. It allows strace to trace SIGTRAP signals by exploiting the
PTRACE_O_TRACESYSGOOD flag.
Tested on i386 (2.4 kernel) and s390x (2.6 kernel). Tracing SIGTRAP
won't work on most architectures with 2.4 kernels since
PTRACE_(OLD)SETOPTIONS isn't implemented there.
This patch might break some other architectures since the
TCB_WAITEXECVE flag is now mandatory for all architectures (on
LINUX).
Please apply, thanks,
Heiko
diff -urN strace-4.5.8/defs.h strace-4.5.8-trace/defs.h
--- strace-4.5.8/defs.h Thu Oct 7 00:27:43 2004
+++ strace-4.5.8-trace/defs.h Thu Jan 20 15:33:23 2005
@@ -293,6 +293,7 @@
long baddr; /* `Breakpoint' address */
long inst[2]; /* Instructions on above */
int pfd; /* proc file descriptor */
+ int tracesysgood; /* signal indicating a PTRACE_SYSCALL trap */
#ifdef SVR4
#ifdef HAVE_MP_PROCFS
int pfd_stat;
@@ -322,7 +323,7 @@
#define TCB_FOLLOWFORK 00400 /* Process should have forks followed */
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
#ifdef LINUX
-# if defined(ALPHA) || defined(SPARC) || defined(SPARC64) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SH64) || defined(S390) || defined(S390X) || defined(ARM)
+# if defined(ALPHA) || defined(SPARC) || defined(SPARC64) || defined(POWERPC) || defined(IA64) || defined(HPPA) || defined(SH) || defined(SH64) || defined(S390) || defined(S390X) || defined(ARM) || defined(I386)
# define TCB_WAITEXECVE 02000 /* ignore SIGTRAP after exceve */
# endif
# define TCB_CLONE_DETACHED 04000 /* CLONE_DETACHED set in creating syscall */
@@ -418,6 +419,9 @@
extern struct tcb *pid2tcb P((int));
extern void droptcb P((struct tcb *));
extern int expand_tcbtab P((void));
+#ifdef LINUX
+extern void ptrace_set_options P((struct tcb *, int));
+#endif
extern void set_sortby P((char *));
extern void set_overhead P((int));
diff -urN strace-4.5.8/process.c strace-4.5.8-trace/process.c
--- strace-4.5.8/process.c Wed Oct 20 01:33:47 2004
+++ strace-4.5.8-trace/process.c Thu Jan 20 15:15:37 2005
@@ -840,7 +840,10 @@
droptcb(tcpchild);
return 0;
}
-#endif
+#ifdef LINUX
+ ptrace_set_options(tcb, pid);
+#endif /* LINUX */
+#endif /* CLONE_PTRACE */
if (bpt)
clearbpt(tcp);
@@ -989,6 +992,7 @@
droptcb(tcpchild);
return 0;
}
+ ptrace_set_options(tcb, pid);
#endif /* LINUX */
#ifdef SUNOS4
#ifdef oldway
diff -urN strace-4.5.8/strace.c strace-4.5.8-trace/strace.c
--- strace-4.5.8/strace.c Wed Oct 20 04:04:15 2004
+++ strace-4.5.8-trace/strace.c Thu Jan 20 15:47:46 2005
@@ -744,6 +744,7 @@
tcp->stime.tv_sec = 0;
tcp->stime.tv_usec = 0;
tcp->pfd = -1;
+ tcp->tracesysgood = 0;
nprocs++;
return tcp;
}
@@ -751,6 +752,32 @@
return NULL;
}
+#ifdef LINUX
+void
+ptrace_set_options(tcp, pid)
+struct tcb *tcp;
+int pid;
+{
+#ifndef PTRACE_SETOPTIONS
+#define PTRACE_SETOPTIONS 0x4200
+#endif
+#ifndef PTRACE_OLDSETOPTIONS
+#define PTRACE_OLDSETOPTIONS 21
+#endif
+#ifndef PTRACE_O_TRACESYSGOOD
+#define PTRACE_O_TRACESYSGOOD 0x00000001
+#endif
+ if (tcp->tracesysgood & 0x80)
+ return;
+ if ((ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0) &&
+ (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD) < 0)) {
+ perror("ptrace_set_options: ptrace(PTRACE_SETOPTIONS, ...)");
+ return;
+ }
+ tcp->tracesysgood |= 0x80;
+}
+#endif
+
#ifdef USE_PROCFS
int
proc_open(tcp, attaching)
@@ -1272,7 +1299,7 @@
break;
}
if ((error = ptrace(PTRACE_CONT, tcp->pid, (char *) 1,
- WSTOPSIG(status) == SIGTRAP ?
+ WSTOPSIG(status) == (SIGTRAP | tcp->tracesysgood) ?
0 : WSTOPSIG(status))) < 0) {
if (errno != ESRCH)
perror("detach: ptrace(PTRACE_CONT, ...)");
@@ -2096,6 +2123,9 @@
exit(1);
}
}
+#ifdef LINUX
+ ptrace_set_options(tcp, pid);
+#endif /* LINUX */
/* set current output file */
outf = tcp->outf;
if (cflag) {
@@ -2208,7 +2238,8 @@
goto tracing;
}
- if (WSTOPSIG(status) != SIGTRAP) {
+ if ((WSTOPSIG(status) != (SIGTRAP | tcp->tracesysgood)) &&
+ ((WSTOPSIG(status) != SIGTRAP) || !(tcp->flags & TCB_WAITEXECVE))) {
if (WSTOPSIG(status) == SIGSTOP &&
(tcp->flags & TCB_SIGTRAPPED)) {
/*
diff -urN strace-4.5.8/syscall.c strace-4.5.8-trace/syscall.c
--- strace-4.5.8/syscall.c Sat Sep 4 06:20:43 2004
+++ strace-4.5.8-trace/syscall.c Thu Jan 20 15:40:51 2005
@@ -891,6 +891,13 @@
#elif defined (I386)
if (upeek(pid, 4*ORIG_EAX, &scno) < 0)
return -1;
+ if (!(tcp->flags & TCB_INSYSCALL)) {
+ /* Check if we return from execve. */
+ if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+ }
#elif defined (X86_64)
if (upeek(pid, 8*ORIG_RAX, &scno) < 0)
return -1;
More information about the Strace-devel
mailing list