Date: Sun, 11 Jul 2004 03:54:59 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 57039 for review Message-ID: <200407110354.i6B3sxk0055759@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=57039 Change 57039 by davidxu@davidxu_alona on 2004/07/11 03:54:31 Implement ps_lstop/ps_lcontinue. Use td_thr_dbsuspend/td_thr_dbresume to suspend/resume thread, yeah! M:N thread debugging works now. Affected files ... .. //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#10 edit Differences ... ==== //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#10 (text+ko) ==== @@ -68,11 +68,9 @@ /* Connection to the libthread_db library. */ static td_thragent_t *thread_agent; -/* The inactive M:N thread gdb is trying to single step it */ -static ptid_t single_step_inactive_thread; +/* The last thread we are single stepping */ +static ptid_t last_single_step_thread; -static CORE_ADDR single_step_inactive_thread_pc; - /* Pointers to the libthread_db functions. */ static td_err_e (*td_init_p) (void); @@ -111,6 +109,9 @@ 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_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); @@ -362,6 +363,18 @@ child_ops.to_detach (args, from_tty); } +static int +suspend_thread_callback (const td_thrhandle_t *th_p, void *data) +{ + return td_thr_dbsuspend_p (th_p); +} + +static int +resume_thread_callback (const td_thrhandle_t *th_p, void *data) +{ + return td_thr_dbresume_p (th_p); +} + static void fbsd_thread_resume (ptid_t ptid, int step, enum target_signal signo) { @@ -369,17 +382,19 @@ 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__, GET_PID(ptid), GET_LWP(ptid), GET_THREAD(ptid), step); printf_filtered("%s inferior_ptid=%ld.%ld.%ld\n", __func__, - GET_PID(inferior_ptid), GET_LWP(inferior_ptid), GET_THREAD(inferior_ptid)); + GET_PID(inferior_ptid), GET_LWP(inferior_ptid), + GET_THREAD(inferior_ptid)); #endif + if (proc_handle.pid == 0) { - child_resume (ptid, step, signo); + base_ops.to_resume (ptid, step, signo); return; } @@ -416,30 +431,8 @@ ret = td_thr_get_info_p (&th, &ti); if (ret) error (thread_db_err_str (ret)); + thvalid = 1; lwp = ti.ti_lid; - /* - * if we are single stepping an inactive M:N thread, - * we insert all breakpoints, and resume all threads, - * the inactive thread may or may not be scheduled to - * run, but if it runs, it may hit a breakpoint and - * becomes the current event thread, after it hit a - * breakpoint, the thread will stay in kernel until - * debugger resumes it. In that case, gdb will single - * step it again, but because it was already an active - * thread, we can use ptrace to resume it just as 1:1 - * thread. XXX This may not be needed, because gdb - * seems not switch away from event thread when resuming. - */ - if (lwp == 0) - { - if (breakpoint_here_p (read_pc_pid (work_ptid)) != - no_breakpoint_here) - { - single_step_inactive_thread_pc = read_pc_pid (work_ptid); - single_step_inactive_thread = work_ptid; - insert_breakpoints (); - } - } } if (lwp) @@ -448,13 +441,43 @@ if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo))) perror_with_name ("PT_SETSTEP/PT_CLEARSTEP"); } + + if (!ptid_equal (last_single_step_thread, null_ptid)) + { + 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)); + } + + if (!resume_all) + { + 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 - resume_all = 1; + last_single_step_thread = null_ptid; - if (resume_all) - lwp = proc_handle.pid; + if (thvalid) + { + ret = td_thr_dbresume_p (&th); + if (ret != TD_OK) + error ("resume error: %s", thread_db_err_str (ret)); + } + else + { + /* it is not necessary, put it here for completness */ + ret = ptrace(PT_RESUME, lwp, 0, 0); + } - if (ptrace (PT_CONTINUE, (pid_t) lwp, (caddr_t)1, target_signal_to_host(signo))) + /* now continue the process, suspended thread wont run */ + if (ptrace (PT_CONTINUE, proc_handle.pid , (caddr_t)1, + target_signal_to_host(signo))) perror_with_name ("PT_CONTINUE"); } @@ -473,25 +496,8 @@ ret = thread_from_lwp (BUILD_LWP (lwp, GET_PID (ret))); if (!in_thread_list (ret)) add_thread (ret); - /* - * if we previously single stepping inactive threads, - * the inactive threads now becomes active, - * we should tell gdb to ignore the event and resume - * thread again. - */ - if (ourstatus->value.sig == TARGET_SIGNAL_TRAP) - { - stop_pc = read_pc_pid (ret) - DECR_PC_AFTER_BREAK; - if (ptid_equal(ret, single_step_inactive_thread) && - stop_pc == single_step_inactive_thread_pc) - { - ourstatus->kind = TARGET_WAITKIND_SPURIOUS; - } - } } - single_step_inactive_thread = minus_one_ptid; - single_step_inactive_thread_pc = 0; return (ret); } @@ -921,6 +927,14 @@ if (td_ta_tsd_iter_p == NULL) return 0; + td_thr_dbsuspend_p = dlsym (handle, "td_thr_dbsuspend"); + if (td_thr_dbsuspend_p == NULL) + return 0; + + td_thr_dbresume_p = dlsym (handle, "td_thr_dbresume"); + if (td_thr_dbresume_p == NULL) + return 0; + /* Initialize the library. */ err = td_init_p (); if (err != TD_OK) @@ -1061,6 +1075,18 @@ return PS_OK; } +ps_err_e +ps_lstop(struct ps_prochandle *ph, lwpid_t lwpid) +{ + return (ptrace (lwpid, PT_SUSPEND, 0, 0) == 0); +} + +ps_err_e +ps_lcontinue(struct ps_prochandle *ph, lwpid_t lwpid) +{ + return (ptrace (lwpid, PT_RESUME, 0, 0) == 0); +} + pid_t ps_getpid (struct ps_prochandle *ph) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407110354.i6B3sxk0055759>