This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
Re: [unwinder-portable patch 1/3] Handle T-stopped detach for old kernels
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Wed, 06 Nov 2013 11:38:20 +0100
- Subject: Re: [unwinder-portable patch 1/3] Handle T-stopped detach for old kernels
Hi Jan,
On Fri, 2013-11-01 at 17:05 +0100, Jan Kratochvil wrote:
> this patch is for the branch 'portable' to be checked in wotj
> 'jankratochvil/unwindx86', that is for RHEL-5 systems.
wotj?
I do agree this is too invasive (especially the "settle down" part) to
have enabled normally. So putting it in portable is a good idea.
> RHEL-5 kernels were not enough with
> ptrace (PTRACE_DETACH, tid, NULL, SIGSTOP);
> and they need to explicitly
> syscall (__NR_tkill, tid, SIGSTOP);
> beforehand.
This wouldn't be that bad to do in general since we already have the
detection in place, and SIGSTOPs don't stack/nest, but...
> Moreover for a short time after such PTRACE_DETACH the TID's /proc/PID/status
> State may be R (running), so if one tries to PTRACE_ATTACH that time again the
> attacher will not notice the process in fact should be T (stopped). Therefore
> it detaches the process without __NR_tkill SIGSTOP and the process is no
> longer stopped, as it should have been.
this is nasty :{ What a pity this is necessary.
But good you found out.
> 2013-11-01 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Handle T-stopped detach for old kernels.
> * linux-pid-attach.c (struct pid_arg): New field stopped.
> (ptrace_attach): New parameter stoppedp. Set it appropriately.
> (pid_set_initial_registers): Pass the new field.
> (pid_thread_detach): Handle the case of STOPPED for old kernels.
> (__libdwfl_attach_state_for_pid): Initialize STOPPED.
>
> tests/
> 2013-11-01 Jan Kratochvil <jan.kratochvil@redhat.com>
>
> Handle T-stopped detach for old kernels.
> * backtrace.c: Include sys/syscall.h.
> (linux_proc_pid_is_stopped): New function.
> (ptrace_detach_stopped): Handle old kernels.
This looks good for the portable branch. Just one request. Please add
the kernel version you tested the workaround against as a comment...
// Here...
> + 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;
> }
// And here...
> + syscall (__NR_tkill, pid, SIGSTOP);
> errno = 0;
> long l = ptrace (PTRACE_DETACH, pid, NULL, (void *) (intptr_t) SIGSTOP);
> assert_perror (errno);
> assert (l == 0);
> + // Wait till the SIGSTOP settles down.
> + int i;
> + for (i = 0; i < 100000; i++)
> + if (linux_proc_pid_is_stopped (pid))
> + break;
Thanks,
Mark