summaryrefslogtreecommitdiffstats
path: root/libdwfl/linux-pid-attach.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdwfl/linux-pid-attach.c')
-rw-r--r--libdwfl/linux-pid-attach.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index ae717028..076b2c3e 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -255,6 +255,11 @@ void
internal_function
__libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
{
+ // Older kernels (tested kernel-2.6.18-348.12.1.el5.x86_64) need special
+ // handling of the detachment to keep the process State: T (stopped).
+ if (tid_was_stopped)
+ syscall (__NR_tkill, tid, SIGSTOP);
+
/* This handling is needed only on older Linux kernels such as
2.6.32-358.23.2.el6.ppc64. Later kernels such as
3.11.7-200.fc19.x86_64 remember the T (stopped) state
@@ -262,6 +267,15 @@ __libdwfl_ptrace_detach (pid_t tid, bool tid_was_stopped)
PTRACE_DETACH. */
ptrace (PTRACE_DETACH, tid, NULL,
(void *) (intptr_t) (tid_was_stopped ? SIGSTOP : 0));
+
+ if (tid_was_stopped)
+ {
+ // Wait till the SIGSTOP settles down.
+ int i;
+ for (i = 0; i < 100000; i++)
+ if (linux_proc_pid_is_stopped (tid))
+ break;
+ }
}
static void