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>