PERFORCE change 57628 for review

David Xu davidxu at FreeBSD.org
Sun Jul 18 06:34:30 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=57628

Change 57628 by davidxu at davidxu_alona on 2004/07/18 13:34:11

	Rewrite fbsd_thread_resume. Use ptrace to control LWP, when single stepping
	a thread, we don't use td_thr_dbsuspend or td_thr_dbresume, I think those
	two functions are used by user on command line to suspend/resume thread,
	do not try to use them internally, it may involve too much thing not related
	to single stepping. because we now bind thread in kernel if the thread
	generates a SIGTRAP, we are safe to single step it without bothering UTS which
	may can not run when process stops. Current, I still use PT_SUSPEND PT_RESUME,
	I think we may need change ptrace code to let PT_CONTINUE/PT_STEP resume
	only one LWP, TBD...

Affected files ...

.. //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#14 edit

Differences ...

==== //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#14 (text+ko) ====

@@ -70,7 +70,7 @@
 static td_thragent_t *thread_agent;
 
 /* The last thread we are single stepping */
-static ptid_t last_single_step_thread;
+static lwpid_t last_single_step_lwp;
 
 /* Pointers to the libthread_db functions.  */
 
@@ -316,7 +316,6 @@
           gdb_assert (proc_handle.pid == 0);
           keep_thread_db = 1;
         }
-
       /* We can only poke around if there actually is a child process.
          If there is no child process alive, postpone the steps below
          until one has been created.  */
@@ -383,7 +382,7 @@
   td_thrinfo_t ti;
   ptid_t work_ptid;
   int resume_all, ret;
-  long lwp, thvalid = 0;
+  long lwp;
 
 #if 0
   printf_filtered("%s ptid=%ld.%ld.%ld step=%d\n", __func__,
@@ -399,7 +398,7 @@
       return;
     }
 
-  if (GET_PID(ptid) != -1 && step != 0)
+  if (GET_PID (ptid) != -1 && step != 0)
     {
       resume_all = 0;
       work_ptid = ptid;
@@ -432,49 +431,59 @@
       ret = td_thr_get_info_p (&th, &ti);
       if (ret)
         error (thread_db_err_str (ret));
-      thvalid = 1;
       lwp = ti.ti_lid;
     }
 
+  if (!resume_all && lwp == 0)
+    {
+      error ("sorry this version of FreeBSD can not resume inactivated thread");
+    }
+
   if (lwp)
     {
       int req = step ? PT_SETSTEP : PT_CLEARSTEP;
-      if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
+      if (ptrace (req, (pid_t) lwp, 0, 0))
         perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
     }
 
-  if (!ptid_equal (last_single_step_thread, null_ptid))
+  int nlwps = ptrace (PT_GETNUMLWPS, proc_handle.pid, 0, 0);
+  if (nlwps == -1)
+    perror_with_name ("PT_GETNUMLWPS");
+  lwpid_t *lwps = malloc (nlwps * sizeof(lwpid_t));
+  nlwps = ptrace (PT_GETLWPLIST, proc_handle.pid, (caddr_t)lwps, nlwps);
+  if (nlwps == -1)
     {
-       ret = td_ta_thr_iter_p (thread_agent, resume_thread_callback, NULL,
-          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
-          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
-      if (ret != TD_OK)
-        error ("resume error: %s", thread_db_err_str (ret));
+      perror_with_name ("PT_GETLWPLIST");
+      free (lwps);
     }
 
-  if (!resume_all)
+  int i;
+  if (last_single_step_lwp != 0)
     {
-      ret = td_ta_thr_iter_p (thread_agent, suspend_thread_callback, NULL,
-          TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY,
-          TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
-      if (ret != TD_OK)
-        error ("suspend error: %s", thread_db_err_str (ret));
-      last_single_step_thread = work_ptid;
+       /* resume all threads if ever suspend them */
+       for (i = 0; i < nlwps; ++i)
+         {
+           if (ptrace (PT_RESUME, lwps[i], 0, 0))
+             perror_with_name ("PT_SUSPEND");
+         }
     }
-  else
-    last_single_step_thread = null_ptid;
 
-  if (thvalid)
+  if (!resume_all)
     {
-      ret = td_thr_dbresume_p (&th);
-      if (ret != TD_OK)
-        error ("resume error: %s", thread_db_err_str (ret));
+       for (i = 0; i < nlwps; ++i)
+         {
+           if (lwps[i] == lwp)
+		continue;
+	   if (ptrace (PT_SUSPEND, lwps[i], 0, 0))
+             perror_with_name ("PT_SUSPEND");
+         }
+       last_single_step_lwp = lwp;
     }
   else
-    {
-      /* it is not necessary, put it here for completness */
-      ret = ptrace(PT_RESUME, lwp, 0, 0);
-    }
+    last_single_step_lwp = 0;
+
+  free (lwps);
+/*  ret = ptrace(PT_RESUME, lwp, 0, 0); */
 
   /* now continue the process, suspended thread wont run */
   if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
@@ -496,6 +505,17 @@
       ret = thread_from_lwp (BUILD_LWP (lwp, GET_PID (ret)));
       if (!in_thread_list (ret))
         add_thread (ret);
+      /* this is a hack, if an event won't cause gdb to stop, for example,
+         SIGARLM, gdb resumes the process immediatly without setting
+         inferior_ptid to the new thread returned here, this is a bug
+         because inferior_ptid may already not exist there, and passing
+         a none existing thread to fbsd_thread_resume causes error, this
+         should be treated as a bug of gdb. */
+      if (!fbsd_thread_alive (inferior_ptid))
+        {
+          delete_thread (inferior_ptid);
+          inferior_ptid = ret;
+	}
     }
 
   return (ret);


More information about the p4-projects mailing list