PERFORCE change 59049 for review
David Xu
davidxu at FreeBSD.org
Fri Aug 6 20:56:33 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=59049
Change 59049 by davidxu at 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)
More information about the p4-projects
mailing list