From: Jan Kratochvil Date: Tue, 19 Nov 2013 14:04:14 +0000 (+0100) Subject: Merge branch 'master' into portable X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b1a19549175f467b909e20c047c8775294f59645;p=thirdparty%2Felfutils.git Merge branch 'master' into portable Conflicts: libdwfl/linux-pid-attach.c --- b1a19549175f467b909e20c047c8775294f59645 diff --cc libdwfl/linux-pid-attach.c index fd2925010,e4eb62121..32eceb205 --- a/libdwfl/linux-pid-attach.c +++ b/libdwfl/linux-pid-attach.c @@@ -238,20 -238,12 +238,24 @@@ pid_thread_detach (Dwfl_Thread *thread pid_t tid = INTUSE(dwfl_thread_tid) (thread); assert (pid_arg->tid_attached == tid); pid_arg->tid_attached = 0; - if (! pid_arg->stopped) - { - ptrace (PTRACE_DETACH, tid, NULL, NULL); - return; - } + // 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). - syscall (__NR_tkill, tid, SIGSTOP); - ptrace (PTRACE_DETACH, tid, NULL, (void *) (intptr_t) SIGSTOP); - // Wait till the SIGSTOP settles down. - int i; - for (i = 0; i < 100000; i++) - if (linux_proc_pid_is_stopped (tid)) - break; ++ if (pid_arg->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 themselves and no longer need to pass + SIGSTOP during PTRACE_DETACH. */ + ptrace (PTRACE_DETACH, tid, NULL, + (void *) (intptr_t) (pid_arg->tid_was_stopped ? SIGSTOP : 0)); ++ if (pid_arg->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 const Dwfl_Thread_Callbacks pid_thread_callbacks =