PERFORCE change 56682 for review

David Xu davidxu at FreeBSD.org
Wed Jul 7 06:57:38 PDT 2004


http://perforce.freebsd.org/chv.cgi?CH=56682

Change 56682 by davidxu at 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);
 	/*


More information about the p4-projects mailing list