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]

[partial commit] [unwinder-portable patch 1/3] Handle T-stopped detach for old kernels


On Wed, 06 Nov 2013 11:38:20 +0100, Mark Wielaard wrote:
> This looks good for the portable branch. Just one request. Please add
> the kernel version you tested the workaround against as a comment...

Done.

The tests/ part is sure not yet committed as it is not yet in master.


Thanks,
Jan

commit 154fab925e0d2f829b54c03b695015245ed000dd
Author: Jan Kratochvil <jan.kratochvil@redhat.com>
Date:   Sat Nov 9 19:39:21 2013 +0100

    Handle T-stopped detach for old kernels.
    
    Signed-off-by: Jan Kratochvil <jan.kratochvil@redhat.com>

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 7a9f3f9..be780d1 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,12 @@
+2013-11-09  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.
+
 2013-11-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 	    Mark Wielaard  <mjw@redhat.com>
 
diff --git a/libdwfl/linux-pid-attach.c b/libdwfl/linux-pid-attach.c
index 5ad58f6..efdeb9f 100644
--- a/libdwfl/linux-pid-attach.c
+++ b/libdwfl/linux-pid-attach.c
@@ -42,6 +42,8 @@ struct pid_arg
   DIR *dir;
   /* It is 0 if not used.  */
   pid_t tid_attached;
+  /* TRUE if the process (first of its threads) was State: T (stopped).  */
+  bool stopped;
 };
 
 static bool
@@ -69,7 +71,7 @@ linux_proc_pid_is_stopped (pid_t pid)
 }
 
 static bool
-ptrace_attach (pid_t tid)
+ptrace_attach (pid_t tid, bool *stoppedp)
 {
   if (ptrace (PTRACE_ATTACH, tid, NULL, NULL) != 0)
     {
@@ -84,6 +86,7 @@ ptrace_attach (pid_t tid)
 	 above.  Which would make the waitpid below wait forever.  So emulate
 	 it.  Since there can only be one SIGSTOP notification pending this is
 	 safe.  See also gdb/linux-nat.c linux_nat_post_attach_wait.  */
+      *stoppedp = true;
       syscall (__NR_tkill, tid, SIGSTOP);
       ptrace (PTRACE_CONT, tid, NULL, NULL);
     }
@@ -213,7 +216,7 @@ pid_set_initial_registers (Dwfl_Thread *thread, void *thread_arg)
   struct pid_arg *pid_arg = thread_arg;
   assert (pid_arg->tid_attached == 0);
   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
-  if (! ptrace_attach (tid))
+  if (! ptrace_attach (tid, &pid_arg->stopped))
     return false;
   pid_arg->tid_attached = tid;
   Dwfl_Process *process = thread->process;
@@ -237,7 +240,20 @@ pid_thread_detach (Dwfl_Thread *thread, void *thread_arg)
   pid_t tid = INTUSE(dwfl_thread_tid) (thread);
   assert (pid_arg->tid_attached == tid);
   pid_arg->tid_attached = 0;
-  ptrace (PTRACE_DETACH, tid, NULL, NULL);
+  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;
 }
 
 static const Dwfl_Thread_Callbacks pid_thread_callbacks =
@@ -271,6 +287,7 @@ __libdwfl_attach_state_for_pid (Dwfl *dwfl, pid_t pid)
     }
   pid_arg->dir = dir;
   pid_arg->tid_attached = 0;
+  pid_arg->stopped = false;
   if (! INTUSE(dwfl_attach_state) (dwfl, EM_NONE, pid, &pid_thread_callbacks,
 				   pid_arg))
     {

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