Date: Wed, 7 Jul 2004 13:57:37 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 56682 for review Message-ID: <200407071357.i67DvbpB067583@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=56682 Change 56682 by davidxu@davidxu_alona on 2004/07/07 13:56:53 Discard ps_lsetstep, let debugger to deal with single step machine flag for lwp, libthread_db only deal inactive thread's single step flag. Redo single step in fbsd_thread_resume. Make proc service routines to be data modal independent. Affected files ... .. //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#8 edit .. //depot/projects/davidxu_ksedbg/src/include/proc_service.h#4 edit .. //depot/projects/davidxu_ksedbg/src/lib/libthread_db/pthread/pthread_db.c#5 edit Differences ... ==== //depot/projects/davidxu_ksedbg/src/gnu/usr.bin/gdb/libgdb/fbsd-threads.c#8 (text+ko) ==== @@ -362,32 +362,6 @@ child_ops.to_detach (args, from_tty); } -static int -single_step (ptid_t ptid, int step) -{ - if (IS_LWP(ptid)) - { - int req = step ? PT_SETSTEP : PT_CLEARSTEP; - return ptrace (req, GET_LWP (ptid), 0, 0) == 0; - } - - /* - * 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. - */ - td_thrhandle_t th; - if (td_ta_map_id2thr_p (thread_agent, GET_THREAD(ptid), &th) == 0) - { - td_thr_sstep_p (&th, step); - return 1; - } - return 0; -} - static void fbsd_thread_resume (ptid_t ptid, int step, enum target_signal signo) { @@ -420,64 +394,68 @@ work_ptid = inferior_ptid; } - /* - * Whether it is going to resume one thread or not, - * we always set/unset single step state for the thread according to - * step parameter. - */ - if (!single_step(work_ptid, step)) - error ("single_step failed"); + /* only resume one thread */ + lwp = GET_LWP (work_ptid); + if (lwp == 0) + { + /* check user thread */ + ret = td_ta_map_id2thr_p (thread_agent, GET_THREAD(work_ptid), &th); + if (ret) + error (thread_db_err_str (ret)); + + /* + * 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, 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)); + 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 (); + } + } + } - lwp = 0; - if (!resume_all) + if (lwp) { - /* only resume one thread */ - lwp = GET_LWP (work_ptid); - if (lwp == 0) - { - /* check a user thread */ - ret = td_ta_map_id2thr_p (thread_agent, - GET_THREAD(work_ptid), &th); - if (ret) - error(thread_db_err_str (ret)); - ret = td_thr_get_info_p (&th, &ti); - if (ret) - error(thread_db_err_str (ret)); - 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. - */ - if (lwp == 0) - { - printf_filtered("resuming inactive thread\n"); - 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; - /* XXX - * We need to give UTS to a hint to prefer scheduling - * the thread. - */ - insert_breakpoints (); - } - } - } + int req = step ? PT_SETSTEP : PT_CLEARSTEP; + if (ptrace (req, (pid_t) lwp, (caddr_t) 1, target_signal_to_host(signo))) + perror_with_name ("PT_SETSTEP/PT_CLEARSTEP"); } + else + resume_all = 1; - if (lwp == 0) + if (resume_all) lwp = proc_handle.pid; - if (ptrace (PT_CONTINUE, lwp, (caddr_t)1, target_signal_to_host(signo))) + if (ptrace (PT_CONTINUE, (pid_t) lwp, (caddr_t)1, target_signal_to_host(signo))) perror_with_name ("PT_CONTINUE"); } @@ -487,7 +465,6 @@ ptid_t ret; lwpid_t lwp; CORE_ADDR stop_pc; - unsigned char buf; ret = child_ops.to_wait (ptid, ourstatus); if (GET_PID(ret) >= 0 && ourstatus->kind == TARGET_WAITKIND_STOPPED) @@ -497,7 +474,6 @@ ret = thread_from_lwp (BUILD_LWP (lwp, GET_PID (ret))); if (!in_thread_list (ret)) add_thread (ret); - printf_filtered("signal=%d\n", ourstatus->value.sig); /* * if we previously single stepping inactive threads, * the inactive threads now becomes active, @@ -507,9 +483,6 @@ if (ourstatus->value.sig == TARGET_SIGNAL_TRAP) { stop_pc = read_pc_pid (ret) - DECR_PC_AFTER_BREAK; - target_read_memory(stop_pc, &buf, 1); - printf_filtered("stop_pc=%x data:%x, breakpoint?:%d\n", - stop_pc, buf, breakpoint_here_p(stop_pc)); if (ptid_equal(ret, single_step_inactive_thread) && stop_pc == single_step_inactive_thread_pc) { @@ -527,8 +500,8 @@ fbsd_thread_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct mem_attrib *attrib, struct target_ops *target) { - return child_ops.to_xfer_memory (memaddr, myaddr, len, write, - attrib, target); + return base_ops.to_xfer_memory (memaddr, myaddr, len, write, + attrib, target); } static void @@ -538,14 +511,7 @@ fpregset_t fpregs; lwpid_t lwp; -#if 0 - /* FIXME, is it possible ? */ - if (!IS_LWP (inferior_ptid)) - { - child_ops.to_fetch_registers (regno); - return; - } -#endif + /* FIXME, use base_ops to fetch lwp registers! */ lwp = GET_LWP (inferior_ptid); if (ptrace (PT_GETREGS, lwp, (caddr_t) &gregs, 0) == -1) @@ -574,19 +540,19 @@ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) - error ("Cannot find thread %d: TID=%ld, %s", + error ("Cannot find thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); err = td_thr_getgregs_p (&th, gregset); if (err != TD_OK) - error ("Cannot fetch general-purpose registers for thread %d: TID=%ld, %s", + error ("Cannot fetch general-purpose registers for thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); err = td_thr_getfpregs_p (&th, &fpregset); if (err != TD_OK) - error ("Cannot get floating-point registers for thread %d: TID=%ld, %s", + error ("Cannot get floating-point registers for thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); @@ -644,7 +610,7 @@ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (inferior_ptid), &th); if (err != TD_OK) - error ("Cannot find thread %d: TID=%ld, %s", + error ("Cannot find thread %d: Thread ID=%ld, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); @@ -668,12 +634,12 @@ err = td_thr_setgregs_p (&th, gregset); if (err != TD_OK) - error ("Cannot store general-purpose registers for thread %d: TID=%d, %s", + error ("Cannot store general-purpose registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); err = td_thr_setfpregs_p (&th, &fpregset); if (err != TD_OK) - error ("Cannot store floating-point registers for thread %d: TID=%d, %s", + error ("Cannot store floating-point registers for thread %d: Thread ID=%d, %s", pid_to_thread_id (inferior_ptid), GET_THREAD (inferior_ptid), thread_db_err_str (err)); } @@ -816,22 +782,22 @@ err = td_ta_map_id2thr_p (thread_agent, GET_THREAD (ptid), &th); if (err != TD_OK) - error ("Cannot find thread, TID=%ld, %s", + error ("Cannot find thread, Thread ID=%ld, %s", GET_THREAD (ptid), thread_db_err_str (err)); err = td_thr_get_info_p (&th, &ti); if (err != TD_OK) - error ("Cannot get thread info, TID=%ld, %s", + error ("Cannot get thread info, Thread ID=%ld, %s", GET_THREAD (ptid), thread_db_err_str (err)); if (ti.ti_lid != 0) { - snprintf (buf, sizeof (buf), "TID %ld (LWP %d)", + snprintf (buf, sizeof (buf), "Thread %ld (LWP %d)", GET_THREAD (ptid), ti.ti_lid); } else { - snprintf (buf, sizeof (buf), "TID %ld (%s)", + snprintf (buf, sizeof (buf), "Thread %ld (%s)", GET_THREAD (ptid), thread_db_state_str (ti.ti_state)); } @@ -1046,25 +1012,39 @@ ps_err_e ps_lgetregs (struct ps_prochandle *ph, lwpid_t lwpid, prgregset_t gregset) { - /* should check data modal, .core or process ? */ - if (ptrace (PT_GETREGS, lwpid, (caddr_t) gregset, 0) == -1) - return PS_ERR; + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); + target_fetch_registers (-1); + fill_gregset (gregset, -1); + do_cleanups (old_chain); return PS_OK; } ps_err_e ps_lsetregs (struct ps_prochandle *ph, lwpid_t lwpid, const prgregset_t gregset) { - if (ptrace (PT_SETREGS, lwpid, (caddr_t) gregset, 0) == -1) - return PS_ERR; + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); + supply_gregset (gregset); + target_store_registers (-1); + do_cleanups (old_chain); return PS_OK; } ps_err_e ps_lgetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, prfpregset_t *fpregset) { - if (ptrace (PT_GETFPREGS, lwpid, (caddr_t) fpregset, 0) == -1) - return PS_ERR; + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); + target_fetch_registers (-1); + fill_fpregset (fpregset, -1); + do_cleanups (old_chain); return PS_OK; } @@ -1072,8 +1052,13 @@ ps_lsetfpregs (struct ps_prochandle *ph, lwpid_t lwpid, const prfpregset_t *fpregset) { - if (ptrace (PT_SETFPREGS, lwpid, (caddr_t) fpregset, 0) == -1) - return PS_ERR; + struct cleanup *old_chain; + + old_chain = save_inferior_ptid (); + inferior_ptid = BUILD_LWP (lwpid, PIDGET (inferior_ptid)); + supply_fpregset (fpregset); + target_store_registers (-1); + do_cleanups (old_chain); return PS_OK; } @@ -1083,11 +1068,3 @@ return ph->pid; } -ps_err_e -ps_lsetstep (struct ps_prochandle *ph, lwpid_t lwp, int step) -{ - if (ptrace ((step ? PT_SETSTEP : PT_CLEARSTEP), lwp, 0, 0)) - return PS_ERR; - return PS_OK; -} - ==== //depot/projects/davidxu_ksedbg/src/include/proc_service.h#4 (text+ko) ==== @@ -98,7 +98,6 @@ psaddr_t go_addr, psaddr_t stop_addr); #endif void ps_plog(const char *fmt, ...); -ps_err_e ps_lsetstep(struct ps_prochandle *ph, lwpid_t lwpid, int step); pid_t ps_getpid (struct ps_prochandle *ph); #endif ==== //depot/projects/davidxu_ksedbg/src/lib/libthread_db/pthread/pthread_db.c#5 (text+ko) ==== @@ -848,8 +848,8 @@ return (ret); if (ta->map[th->th_unique].type == PT_LWP) { - ret = ps_lsetstep(ta->ph, ta->map[th->th_unique].lwp, step); - return (P2T(ret)); + /* Let debugger deal with single step flag in in kernel */ + return (0); } ret = ps_pdread(ta->ph, ta->map[th->th_unique].thr + @@ -869,10 +869,8 @@ tcb_tmbx.tm_lwp), &lwp, sizeof(lwpid_t)); if (ret != 0) return (P2T(ret)); - if (lwp != 0) { - ret = ps_lsetstep(ta->ph, lwp, step); - return (P2T(ret)); - } + if (lwp != 0) /* Let debugger deal with single step flag in in kernel */ + return (0); tmbx_addr = tcb_addr + offsetof(struct tcb, tcb_tmbx); /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200407071357.i67DvbpB067583>