Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 7 Aug 2004 03:56:31 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 59049 for review
Message-ID:  <200408070356.i773uVrG042172@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=59049

Change 59049 by davidxu@davidxu_alona on 2004/08/07 03:55:54

	Revert to code in cvs tree.
	Add code to support tls debug.

Affected files ...

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

Differences ...

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

@@ -35,6 +35,7 @@
 #include "target.h"
 #include "regcache.h"
 #include "gdbcmd.h"
+#include "solib-svr4.h"
 
 #include <sys/ptrace.h>
 
@@ -70,10 +71,8 @@
 static td_thragent_t *thread_agent;
 
 /* The last thread we are single stepping */
-static lwpid_t last_single_step_lwp;
+static ptid_t last_single_step_thread;
 
-static ptid_t last_single_step_ptid;
-
 /* Pointers to the libthread_db functions.  */
 
 static td_err_e (*td_init_p) (void);
@@ -111,13 +110,14 @@
 
 static td_err_e (*td_ta_tsd_iter_p) (const td_thragent_t *ta,
 				 td_key_iter_f *func, void *data);
-
+static td_err_e (*td_thr_tls_get_addr_p) (const td_thrhandle_t *th,
+                                          void *map_address,
+                                          size_t offset, void **address);
 static td_err_e (*td_thr_dbsuspend_p) (const td_thrhandle_t *);
 static td_err_e (*td_thr_dbresume_p) (const td_thrhandle_t *);
 
 /* Prototypes for local functions.  */
 static void fbsd_thread_find_new_threads (void);
-static int fbsd_thread_alive (ptid_t ptid);
 
 /* Building process ids.  */
 
@@ -319,6 +319,7 @@
           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.  */
@@ -385,7 +386,7 @@
   td_thrinfo_t ti;
   ptid_t work_ptid;
   int resume_all, ret;
-  long lwp;
+  long lwp, thvalid = 0;
 
 #if 0
   printf_filtered("%s ptid=%ld.%ld.%ld step=%d\n", __func__,
@@ -401,7 +402,7 @@
       return;
     }
 
-  if (GET_PID (ptid) != -1 && step != 0)
+  if (GET_PID(ptid) != -1 && step != 0)
     {
       resume_all = 0;
       work_ptid = ptid;
@@ -412,26 +413,6 @@
       work_ptid = inferior_ptid;
     }
 
-  /*
-   * For KSE thread, if last time we were single stepping
-   * a thread, first we unbind thread because we had bound it,
-   * may rebind it in following code.
-   */
-  if (!ptid_equal(last_single_step_ptid, null_ptid))
-    {
-      ret = td_ta_map_id2thr_p (thread_agent,
-                                GET_THREAD(last_single_step_ptid), &th);
-      if (ret == TD_OK)
-        {
-          /* 
-           * keep stepping flag (may be cleared in following code),
-           * but unbind the thread
-           */
-          td_thr_sstep_p (&th, 1);
-        }
-      	last_single_step_ptid = null_ptid;
-    }
-
   lwp = GET_LWP (work_ptid);
   if (lwp == 0)
     {
@@ -441,84 +422,65 @@
         error (thread_db_err_str (ret));
 
       /*
-       * For KSE thread, we need to tell UTS to set/unset single step
+       * For M:N thread, we need to tell UTS to set/unset single step
        * flag at context switch time, the flag will be written into
        * thread mailbox. This becauses some architecture may not have
        * machine single step flag in ucontext, so we put the flag in mailbox,
        * when the thread switches back, kse_switchin restores the single step
        * state.
-       */
-      ret = td_thr_sstep_p (&th, resume_all ? step : 2);
+       */ 
+      ret = td_thr_sstep_p (&th, step);
       if (ret)
         error (thread_db_err_str (ret));
       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)
-      	last_single_step_ptid = work_ptid;
-    }
-
-  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, 0, 0))
+      if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo)))
         perror_with_name ("PT_SETSTEP/PT_CLEARSTEP");
     }
 
-  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)
+  if (!ptid_equal (last_single_step_thread, null_ptid))
     {
-      perror_with_name ("PT_GETLWPLIST");
-      free (lwps);
+       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));
     }
 
-  /*
-   * FIX ME! if we can let PT_CONTINUE continue a single lwp,
-   * we needn't to iterate through lwp list to suspend/resume them,
-   * we just let the lwp run, this frees PT_SUSPEND PT_RESUME to user,
-   * so td_thr_dbsuspend/resume can be used to suspend or resume
-   * thread by user on command line...
-   */
- 
-  int i;
-  if (last_single_step_lwp != 0)
+  if (!resume_all)
     {
-       /* 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");
-         }
+      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;
     }
+  else
+    last_single_step_thread = null_ptid;
 
-  if (!resume_all)
+  if (thvalid)
     {
-       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;
+      ret = td_thr_dbresume_p (&th);
+      if (ret != TD_OK)
+        error ("resume error: %s", thread_db_err_str (ret));
     }
   else
-    last_single_step_lwp = 0;
+    {
+      /* it is not necessary, put it here for completness */
+      ret = ptrace(PT_RESUME, lwp, 0, 0);
+    }
 
-  free (lwps);
-
   /* now continue the process, suspended thread wont run */
-  if (ptrace (PT_CONTINUE, proc_handle.pid, (caddr_t)1,
+  if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1,
 	      target_signal_to_host(signo)))
     perror_with_name ("PT_CONTINUE");
 }
@@ -537,17 +499,6 @@
       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);
@@ -868,6 +819,59 @@
   return normal_pid_to_str (ptid);
 }
 
+CORE_ADDR
+fbsd_thread_get_local_address(ptid_t ptid, struct objfile *objfile,
+                              CORE_ADDR offset)
+{
+  td_thrhandle_t th;
+  void *address;
+  CORE_ADDR lm;
+  int ret, is_library = (objfile->flags & OBJF_SHARED);
+
+  if (IS_THREAD (ptid))
+    {
+      if (!td_thr_tls_get_addr_p)
+        error ("Cannot find thread-local interface in thread_db library.");
+
+      /* Get the address of the link map for this objfile. */
+      lm = svr4_fetch_objfile_link_map (objfile);
+
+      /* Couldn't find link map. Bail out. */
+      if (!lm)
+        {
+          if (is_library)
+            error ("Cannot find shared library `%s' link_map in dynamic"
+                   " linker's module list", objfile->name);
+          else
+            error ("Cannot find executable file `%s' link_map in dynamic"
+                   " linker's module list", objfile->name);
+        }
+
+      ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th);
+
+      /* get the address of the variable. */
+      ret = td_thr_tls_get_addr_p (&th, (void *) lm, offset, &address);
+
+      if (ret != TD_OK)
+        {
+          if (is_library)
+            error ("Cannot find thread-local storage for thread %ld, "
+                   "shared library %s:\n%s",
+                   (long) GET_THREAD (ptid),
+                   objfile->name, thread_db_err_str (ret));
+          else
+            error ("Cannot find thread-local storage for thread %ld, "
+                   "executable file %s:\n%s",
+                   (long) GET_THREAD (ptid),
+                   objfile->name, thread_db_err_str (ret));
+        }
+
+      /* Cast assuming host == target. */
+      return (CORE_ADDR) address;
+    }
+  return (0);
+}
+
 static int
 tsd_cb (thread_key_t key, void (*destructor)(void *), void *ignore)
 {
@@ -914,6 +918,7 @@
   thread_db_ops.to_has_thread_control = tc_none;
   thread_db_ops.to_insert_breakpoint = memory_insert_breakpoint;
   thread_db_ops.to_remove_breakpoint = memory_remove_breakpoint;
+  thread_db_ops.to_get_thread_local_address = fbsd_thread_get_local_address;
   thread_db_ops.to_magic = OPS_MAGIC;
 }
 
@@ -987,6 +992,8 @@
   if (td_thr_dbresume_p == NULL)
     return 0;
 
+  td_thr_tls_get_addr_p = dlsym (handle, "td_thr_tls_get_addr");
+
   /* Initialize the library.  */
   err = td_init_p ();
   if (err != TD_OK)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408070356.i773uVrG042172>