This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]