On 06/10/2013 04:55 PM, Dmitry V. Levin wrote:
> * strace.c (detach) [USE_SEIZE]: If PTRACE_SEIZE API is in use, stop
> the tracee using PTRACE_INTERRUPT instead of sending it a SIGSTOP.
> * tests/detach: New test.
> * tests/Makefile.am (TESTS): Add it.
>
> Reported-by: Raghavendra D Prabhu <[email protected]>
> ---
> Denys, please have a look whether this fix is correct.
>
> --- a/strace.c
> +++ b/strace.c
> @@ -769,7 +769,15 @@ detach(struct tcb *tcp)
> if (errno != ESRCH)
> perror_msg("detach: checking sanity");
> }
> - else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
> +#if USE_SEIZE
> + else if (!sigstop_expected && use_seize
> + && ptrace(PTRACE_INTERRUPT, tcp->pid, 0, 0) < 0) {
> + if (errno != ESRCH)
> + perror_msg("detach: ptrace(PTRACE_INTERRUPT,
> ...)");
> + }
> +#endif
> + else if (!sigstop_expected && !use_seize
> + && my_tkill(tcp->pid, SIGSTOP) < 0) {
> if (errno != ESRCH)
> perror_msg("detach: stopping child");
> }
The logic was:
else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
if (errno != ESRCH)
perror_msg("detach: stopping child");
}
else
sigstop_expected = 1;
which, if my_tkill succeeded, was setting sigstop_expected = 1.
Now if we send PTRACE_INTERRUPT, we also set sigstop_expected = 1.
But there will be no SIGSTOP (unless tracee is already stopped, then yes) -
PTRACE_INTERRUPT generates SIGTRAP-stop!
I propose the attached patch.
Sorry, Thunderbird mangles inline patches :(
diff --git a/defs.h b/defs.h
index 3f07c4f..fbbe48c 100644
--- a/defs.h
+++ b/defs.h
@@ -227,16 +227,14 @@ extern long ptrace(int, int, char *, long);
# define PTRACE_POKEUSER PTRACE_POKEUSR
#endif
-#if USE_SEIZE
-# undef PTRACE_SEIZE
-# define PTRACE_SEIZE 0x4206
-# undef PTRACE_INTERRUPT
-# define PTRACE_INTERRUPT 0x4207
-# undef PTRACE_LISTEN
-# define PTRACE_LISTEN 0x4208
-# undef PTRACE_EVENT_STOP
-# define PTRACE_EVENT_STOP 128
-#endif
+#undef PTRACE_SEIZE
+#define PTRACE_SEIZE 0x4206
+#undef PTRACE_INTERRUPT
+#define PTRACE_INTERRUPT 0x4207
+#undef PTRACE_LISTEN
+#define PTRACE_LISTEN 0x4208
+#undef PTRACE_EVENT_STOP
+#define PTRACE_EVENT_STOP 128
#ifdef ALPHA
# define REG_R0 0
diff --git a/strace.c b/strace.c
index 6eab600..8f67022 100644
--- a/strace.c
+++ b/strace.c
@@ -724,7 +724,7 @@ droptcb(struct tcb *tcp)
memset(tcp, 0, sizeof(*tcp));
}
-/* detach traced process; continue with sig
+/* Detach traced process.
* Never call DETACH twice on the same process as both unattached and
* attached-unstopped processes give the same ESRCH. For unattached process we
* would SIGSTOP it and wait for its SIGSTOP notification forever.
@@ -757,7 +757,7 @@ detach(struct tcb *tcp)
* would be left stopped (process state T).
*/
sigstop_expected = (tcp->flags & TCB_IGNORE_ONE_SIGSTOP);
- error = ptrace(PTRACE_DETACH, tcp->pid, (char *) 1, 0);
+ error = ptrace(PTRACE_DETACH, tcp->pid, 0, 0);
if (error == 0) {
/* On a clear day, you can see forever. */
}
@@ -769,12 +769,21 @@ detach(struct tcb *tcp)
if (errno != ESRCH)
perror_msg("detach: checking sanity");
}
- else if (!sigstop_expected && my_tkill(tcp->pid, SIGSTOP) < 0) {
- if (errno != ESRCH)
- perror_msg("detach: stopping child");
+ else if (!sigstop_expected) {
+ /* Process is running, need to stop it first */
+ if (use_seize)
+ error = ptrace(PTRACE_INTERRUPT, tcp->pid, 0, 0);
+ else
+ error = my_tkill(tcp->pid, SIGSTOP);
+ if (error && errno != ESRCH) {
+ if (use_seize)
+ perror_msg("detach: ptrace(PTRACE_INTERRUPT, ...)");
+ else
+ perror_msg("detach: stopping child");
+ } else {
+ sigstop_expected = 1;
+ }
}
- else
- sigstop_expected = 1;
}
if (sigstop_expected) {
@@ -810,7 +819,9 @@ detach(struct tcb *tcp)
/* Au revoir, mon ami. */
break;
}
- if (WSTOPSIG(status) == SIGSTOP) {
+ if (WSTOPSIG(status) == SIGSTOP
+ || WSTOPSIG(status) == SIGTRAP /* may be generated by PTRACE_INTERRUPT stop */
+ ) {
ptrace_restart(PTRACE_DETACH, tcp, 0);
break;
}
@@ -2252,7 +2263,6 @@ trace(void)
goto restart_tracee;
/* It's group-stop */
-#if USE_SEIZE
if (use_seize) {
/*
* This ends ptrace-stop, but does *not* end group-stop.
@@ -2266,7 +2276,6 @@ trace(void)
continue;
}
/* We don't have PTRACE_LISTEN support... */
-#endif
goto restart_tracee;
}
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel