On Mon, 2011-08-22 at 12:21 +0200, Denys Vlasenko wrote:
> 5. Move post-execve SIGTRAP from get_scno_on_sysenter (multitude of
> places on many architectures) to a single location in
> trace_syscall_entering. This loosens the logic for some arches, since
> many of them had additional checks such as scno == 0. So maybe this last
> patch is not 100% safe. (However, on non-ancient Linux kernels we should
> never have post-execve SIGTRAP in the first place, by virtue of using
> PTRACE_O_TRACEEXEC.)
diff -d -urpN strace.4/syscall.c strace.5/syscall.c
--- strace.4/syscall.c 2011-08-22 04:01:28.851814943 +0200
+++ strace.5/syscall.c 2011-08-22 04:11:21.004866031 +0200
@@ -756,12 +756,6 @@ get_scno_on_sysenter(struct tcb *tcp)
#ifdef LINUX
# if defined(S390) || defined(S390X)
- if (tcp->flags & TCB_WAITEXECVE) {
- /* This is the post-execve SIGTRAP. */
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
return -1;
@@ -845,11 +839,6 @@ get_scno_on_sysenter(struct tcb *tcp)
# elif defined (POWERPC)
if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
return -1;
- /* Check if this is the post-execve SIGTRAP. */
- if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# ifdef POWERPC64
/* TODO: speed up strace by not doing this at every syscall.
* We only need to do it after execve.
@@ -874,19 +863,10 @@ get_scno_on_sysenter(struct tcb *tcp)
}
# endif
# elif defined(AVR32)
- /*
- * Read complete register set in one go.
- */
+ /* Read complete register set in one go. */
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
return -1;
-
scno = regs.r8;
-
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined(BFIN)
if (upeek(tcp, PT_ORIG_P0, &scno))
return -1;
@@ -971,15 +951,8 @@ get_scno_on_sysenter(struct tcb *tcp)
if (upeek(tcp, PT_R15, &scno) < 0)
return -1;
}
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined (ARM)
- /*
- * Read complete register set in one go.
- */
+ /* Read complete register set in one go. */
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
return -1;
@@ -987,12 +960,6 @@ get_scno_on_sysenter(struct tcb *tcp)
* We only need to grab the syscall number on syscall entry.
*/
if (regs.ARM_ip == 0) {
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
/*
* Note: we only deal with only 32-bit CPUs here.
*/
@@ -1010,14 +977,6 @@ get_scno_on_sysenter(struct tcb *tcp)
if (errno)
return -1;
- /* FIXME: bogus check? it is already done before,
- * so we never can see it here?
- */
- if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
/* Handle the EABI syscall convention. We do not
bother converting structures between the two
ABIs, but basic functionality should work even
@@ -1063,13 +1022,6 @@ get_scno_on_sysenter(struct tcb *tcp)
r2 = regs[REG_V0];
scno = r2;
-
- /* Check if this is the post-execve SIGTRAP. */
- if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
if (scno < 0 || scno > nsyscalls) {
if (a3 == 0 || a3 == -1) {
if (debug)
@@ -1083,12 +1035,6 @@ get_scno_on_sysenter(struct tcb *tcp)
if (upeek(tcp, REG_V0, &scno) < 0)
return -1;
- /* Check if this is the post-execve SIGTRAP. */
- if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
if (scno < 0 || scno > nsyscalls) {
if (a3 == 0 || a3 == -1) {
if (debug)
@@ -1099,16 +1045,9 @@ get_scno_on_sysenter(struct tcb *tcp)
# elif defined (ALPHA)
if (upeek(tcp, REG_A3, &a3) < 0)
return -1;
-
if (upeek(tcp, REG_R0, &scno) < 0)
return -1;
- /* Check if this is the post-execve SIGTRAP. */
- if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
-
/*
* Do some sanity checks to figure out if it's
* really a syscall entry
@@ -1164,11 +1103,6 @@ get_scno_on_sysenter(struct tcb *tcp)
set_personality(1);
break;
default:
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# if defined (SPARC64)
fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n",
trap, regs.tpc);
# else
@@ -1189,11 +1123,6 @@ get_scno_on_sysenter(struct tcb *tcp)
# elif defined(HPPA)
if (upeek(tcp, PT_GR20, &scno) < 0)
return -1;
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined(SH)
/*
* In the new syscall ABI, the system call number is in R3.
@@ -1214,34 +1143,16 @@ get_scno_on_sysenter(struct tcb *tcp)
correct_scno);
scno = correct_scno;
}
-
- /* Check if this is the post-execve SIGTRAP. */
- if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined(SH64)
if (upeek(tcp, REG_SYSCALL, &scno) < 0)
return -1;
scno &= 0xFFFF;
-
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined(CRISV10) || defined(CRISV32)
if (upeek(tcp, 4*PT_R9, &scno) < 0)
return -1;
# elif defined(TILE)
if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
return -1;
-
- /* Check if this is the post-execve SIGTRAP. */
- if (tcp->flags & TCB_WAITEXECVE) {
- tcp->flags &= ~TCB_WAITEXECVE;
- return 0;
- }
# elif defined(MICROBLAZE)
if (upeek(tcp, 0, &scno) < 0)
return -1;
@@ -1302,9 +1213,7 @@ get_scno_on_sysexit(struct tcb *tcp)
# if defined(S390) || defined(S390X)
# elif defined (POWERPC)
# elif defined(AVR32)
- /*
- * Read complete register set in one go.
- */
+ /* Read complete register set in one go. */
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
return -1;
# elif defined(BFIN)
@@ -1323,9 +1232,7 @@ get_scno_on_sysexit(struct tcb *tcp)
if (upeek(tcp, PT_R10, &r10) < 0)
return -1;
# elif defined (ARM)
- /*
- * Read complete register set in one go.
- */
+ /* Read complete register set in one go. */
if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
return -1;
# elif defined (M68K)
@@ -1513,6 +1420,7 @@ syscall_fixup(struct tcb *tcp)
== (TCB_INSYSCALL|TCB_WAITEXECVE))
&& (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
/*
+ * Return from execve.
* Fake a return value of zero. We leave the TCB_WAITEXECVE
* flag set for the post-execve SIGTRAP to see and reset.
*/
@@ -2422,6 +2330,14 @@ trace_syscall_entering(struct tcb *tcp)
{
int res, scno_good;
+#if defined TCB_WAITEXECVE
+ if (tcp->flags & TCB_WAITEXECVE) {
+ /* This is the post-execve SIGTRAP. */
+ tcp->flags &= ~TCB_WAITEXECVE;
+ return 0;
+ }
+#endif
+
scno_good = res = get_scno_on_sysenter(tcp);
if (res == 0)
return res;
@@ -2591,9 +2507,6 @@ trace_syscall_exiting(struct tcb *tcp)
if (dtime || cflag)
gettimeofday(&tv, NULL);
- /* BTW, why we don't just memorize syscall no. on entry
- * in tcp->something?
- */
scno_good = res = get_scno_on_sysexit(tcp);
if (res == 0)
return res;
------------------------------------------------------------------------------
uberSVN's rich system and user administration capabilities and model
configuration take the hassle out of deploying and managing Subversion and
the tools developers use with it. Learn more about uberSVN and get a free
download at: http://p.sf.net/sfu/wandisco-dev2dev
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel