public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  scox/dyninst: Improve adding and updating client state.
@ 2015-08-11 15:13 scox
  0 siblings, 0 replies; only message in thread
From: scox @ 2015-08-11 15:13 UTC (permalink / raw)
  To: archer-commits

The branch, scox/dyninst has been updated
       via  fabed36970d646da35ab5d0d1c4ab954356266b8 (commit)
      from  d7e297fed3bc38f07f5d0dbbf9658eade3c6a51e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit fabed36970d646da35ab5d0d1c4ab954356266b8
Author: Stan Cox <scox@redhat.com>
Date:   Tue Aug 11 11:11:28 2015 -0400

    Improve adding and updating client state.
    
    	* dyninst-low.cc (dump_processes):  Use for_each_client_state.
    	(delete_lwp_callback):  New.
    	(dyninst_request_interrupt): Insure we found the process.
    	(dyninst_insert_point):  Set break_info.
    	(dyninst_remove_point):  Remove break_info.
    	* event-loop.c (handle_file_event):  Set the client state.
    	* server.c (for_each_client_state):  New.
    	(set_client_state):  Reset current info for first case.
    	(count_client_state):  Insure we have a valid client.

-----------------------------------------------------------------------

Summary of changes:
 gdb/gdbserver/dyninst-low.cc     |  296 +++++++++++++++++++++-----------------
 gdb/gdbserver/dyninst-x86-low.cc |    3 +-
 gdb/gdbserver/event-loop.c       |   10 +-
 gdb/gdbserver/remote-utils.c     |    3 +-
 gdb/gdbserver/server.c           |  174 +++++++++++++----------
 gdb/gdbserver/server.h           |   10 +-
 6 files changed, 279 insertions(+), 217 deletions(-)

First 500 lines of diff:
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 23dc735..8f3273a 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -55,7 +55,7 @@ extern "C"
 
 
 #define DYNERRMSG(errstr,args...)						\
-  fprintf (stderr, "%s %s " errstr "\n", __FUNCTION__, dyninst_process->getLastErrorMsg(), ##args);
+      fprintf (stderr, "%s %s " errstr "\n", __FUNCTION__, getLastErrorMsg(), ##args);
 #define DYNERR(errstr,args...)						\
   fprintf (stderr, "%s " errstr "\n", __FUNCTION__, ##args);
 #define DEBUG_ENTER() if (debug_threads) debug_enter()
@@ -213,6 +213,7 @@ public:
 
     do
       {
+	cerr << "";
 	std::vector<std::pair<ptid_t,Event::const_ptr> >::iterator it;
 	for (it = current_events.begin() ;
 	    it != current_events.end(); ++it)
@@ -385,11 +386,34 @@ dump_events (void)
 }
 
 
+static void dump_one_client (client_state*) __attribute__ ((unused));
 static void dump_processes (void) __attribute__ ((unused));
+
+static void
+dump_one_client (client_state *cs)
+{
+  struct inferior_list_entry *inf;
+  cerr << "client " << cs->ss->general_thread.pid << cs->ss->general_thread.lwp << " all processes ";
+  for (inf = cs->ss->all_processes.head; inf != NULL; inf = inf->next)
+    {
+      struct process_info *pi = (process_info*)inf;
+      cerr << pi->entry.id.pid << '/' << pi->entry.id.lwp << '/' << pi->entry.id.tid << ' ';
+    }
+  cerr << '\n';
+  cerr << "all threads ";
+  for (inf = cs->ss->all_threads.head; inf != NULL; inf = inf->next)
+    {
+      struct thread_info *ti = (thread_info*)inf;
+      cerr << ti->entry.id.pid << '/' << ti->entry.id.lwp << '/' << ti->entry.id.tid << ' ';
+    }
+  cerr << '\n';
+}
+
 static void
 dump_processes (void)
 {
   ProcessSet::iterator it;
+
   int idx = 1;
   for (it = dyninst_procset->begin();
       it != dyninst_procset->end(); ++it)
@@ -421,22 +445,7 @@ dump_processes (void)
       idx += 1;
     }
 
-  client_state *cs = get_client_state ();
-  struct inferior_list_entry *inf;
-  cerr << "all processes ";
-  for (inf = cs->ss->all_processes.head; inf != NULL; inf = inf->next)
-    {
-      struct process_info *pi = (process_info*)inf;
-      cerr << pi->entry.id.pid << '/' << pi->entry.id.lwp << '/' << pi->entry.id.tid << ' ';
-    }
-  cerr << '\n';
-  cerr << "all threads ";
-  for (inf = cs->ss->all_threads.head; inf != NULL; inf = inf->next)
-    {
-      struct thread_info *ti = (thread_info*)inf;
-      cerr << ti->entry.id.pid << '/' << ti->entry.id.lwp << '/' << ti->entry.id.tid << ' ';
-    }
-  cerr << '\n';
+  for_each_client_state (dump_one_client);
 }
 
 void
@@ -528,6 +537,12 @@ extern "C"
 
 /* Per-process private data.  */
 
+struct break_info
+{
+  Dyninst::PID pid;
+  CORE_ADDR addr;
+};
+
 struct process_info_private
 {
   Process::ptr process;
@@ -594,11 +609,12 @@ dyninst_add_lwp (int pid, Thread::const_ptr thread)
 
 
 void
-dyninst_remove_thread(Thread::const_ptr thread)
+dyninst_remove_lwp (Thread::const_ptr thread)
 {
   if (thread != NULL)
     {
       ptid_t ptid = ptid_build (thread->getProcess()->getPid(), thread->getLWP(), 0);
+      DEBUG(ptid.pid);
       struct thread_info *ti = find_thread_ptid (ptid);
       if (ti != NULL)
 	{
@@ -644,6 +660,8 @@ breakpoint_handler(Event::const_ptr ev)
   EventBreakpoint::const_ptr bp_ev = ev->getEventBreakpoint();
   DEBUG(ev->name() << bp_ev->getAddress(), pid_to_string (ev->getThread()));
   events.insert(ev);
+  if (debug_threads)
+      dump_events();
   return Process::cbDefault;
 }
 
@@ -813,17 +831,9 @@ dyninst_attach (unsigned long pid)
   for (thidx = dyninst_process->threads().begin();
       thidx != dyninst_process->threads().end(); thidx++)
     {
-      bool reg_map_setup = false;
-      RegisterPool regpool;
       DEBUG("created thread " << dec << (*thidx)->getTID() << ' ' << (*thidx)->getLWP() << hex);
       Thread::const_ptr th = *thidx;
       dyninst_add_lwp  (pid, th);
-      if (! reg_map_setup)
-	{
-	  th->getAllRegisters (regpool);
-	  (*the_low_target.reg_map_setup)(regpool);
-	  reg_map_setup = true;
-	}
     }
 
   LibraryPool::iterator libidx;
@@ -846,87 +856,84 @@ dyninst_resume (struct thread_resume *resume_info, size_t n)
 
   DEBUG_ENTER ();
 
-  // see linux-low.c::linux_set_resume_request for the proper way to handle multiple resumes
-  // for (int i = 0; i < (int)n; i++)
+  // TODO see linux-low.c::linux_set_resume_request for the proper way to handle multiple resumes
   int i = 0;
-    {
-      ptid_t ptid = resume_info[i].thread;
+  ptid_t ptid = resume_info[i].thread;
 
-      if (ptid_equal(ptid, minus_one_ptid))
-	ptid = thread_to_gdb_id (cs->ss->current_thread);
+  if (ptid_equal(ptid, minus_one_ptid))
+    ptid = thread_to_gdb_id (cs->ss->current_thread);
 
-      Dyninst::PID pid = ptid_get_pid (ptid);
-//      ProcessSet::iterator procset_it = dyninst_procset->find(pid);
-      ProcessSet::iterator it;
-      Process::ptr dyninst_process;
-      for (it = dyninst_procset->begin();
-	  it != dyninst_procset->end(); ++it)
+  Dyninst::PID pid = ptid_get_pid (ptid);
+  ProcessSet::iterator it;
+  Process::ptr dyninst_process;
+  for (it = dyninst_procset->begin();
+      it != dyninst_procset->end(); ++it)
+    {
+      Process::ptr proc = *it;
+      if (proc->getPid() == pid)
 	{
-	  Process::ptr proc = *it;
-	  if (proc->getPid() == pid)
-	    {
-	      dyninst_process = proc;
-	      break;
-	    }
+	  dyninst_process = proc;
+	  break;
 	}
-      if (it == dyninst_procset->end())
-	DYNERR ("Cannot resume process %lu\n", (long unsigned)pid);
+    }
+  if (it == dyninst_procset->end())
+    DYNERR ("Cannot resume process %lu\n", (long unsigned)pid);
 
-      ThreadPool::iterator thidx;
-      Thread::ptr th;
+  ThreadPool::iterator thidx;
+  Thread::ptr th;
 
-      if (dyninst_process->isTerminated())
-	{
-	  DEBUG_EXIT ();
-	  return;
-	}
+  if (dyninst_process->isTerminated())
+    {
+      DEBUG_EXIT ();
+      return;
+    }
 
-      regcache_invalidate ();
+  regcache_invalidate ();
 
-      if (resume_info[i].thread == minus_one_ptid
-	  || ptid_get_lwp (resume_info[i].thread) == -1
-	  || ptid_is_pid (resume_info[i].thread))
-	{
-	  DEBUG("before continue pid=" << pid);
-	  if (! dyninst_process->continueProc())
-	    DEBUG("Unable to continueProc " << dyninst_process->getLastErrorMsg());
-	  DEBUG_EXIT ();
-	  return;
-	}
+  if (resume_info[i].thread == minus_one_ptid
+      || ptid_get_lwp (resume_info[i].thread) == -1
+      || ptid_is_pid (resume_info[i].thread))
+    {
+      DEBUG("before continue pid=" << pid);
+      if (! dyninst_process->continueProc())
+	DEBUG("Unable to continueProc " << getLastErrorMsg());
+      DEBUG_EXIT ();
+      return;
+    }
 
-      for (thidx = dyninst_process->threads().begin();
-	   thidx != dyninst_process->threads().end(); thidx++)
+  for (thidx = dyninst_process->threads().begin();
+      thidx != dyninst_process->threads().end(); thidx++)
+    {
+      th = *thidx;
+      if (th->getLWP() == ptid.lwp)
 	{
-	  th = *thidx;
-	  if (th->getLWP() == ptid.lwp)
-	    {
-	      // resume_continue, resume_step, resume_stop
-	      struct thread_info *ti = find_thread_ptid (ptid);
-	      struct lwp_info *tip = (struct lwp_info*)(ti->target_data);
-	      tip->step_range_start = resume_info->step_range_start;
-	      tip->step_range_end = resume_info->step_range_end;
-	      struct regcache *regcache = get_thread_regcache (ti, 1);
-	      CORE_ADDR pc = (*the_low_target.read_pc) (regcache);
-	      DEBUG("range " << resume_info->step_range_start << "/" << resume_info->step_range_end << " pc=" << pc << " kind=" << resume_info[i].kind);
-
-	      switch (resume_info[i].kind)
-		{
-		case resume_step:
-		    MachRegisterVal result;
-		    th->getRegister(MachRegister(x86_64::rip), result);
-		    DEBUG("in step mode @" << result, pid_to_string (th));
-		    if (! th->setSingleStepMode(true))
-		      DYNERRMSG("Unable to setSingleStepMode");
-		case resume_continue:
-		    regcache_invalidate_thread (ti);
-		    if (! th->continueThread())
-		      DYNERRMSG("Unable to continueThread");
-		    break;
-		case resume_stop:
-		  if (! th->stopThread())
-		    DYNERRMSG("Unable to stopThread");
-		}
-	    }
+	  // resume_continue, resume_step, resume_stop
+	  struct thread_info *ti = find_thread_ptid (ptid);
+	  struct lwp_info *tip = (struct lwp_info*)(ti->target_data);
+	  tip->step_range_start = resume_info->step_range_start;
+	  tip->step_range_end = resume_info->step_range_end;
+	  struct regcache *regcache = get_thread_regcache (ti, 1);
+	  CORE_ADDR pc = (*the_low_target.read_pc) (regcache);
+	  DEBUG("range " << resume_info->step_range_start << "/" << resume_info->step_range_end << " pc=" << pc << " kind=" << resume_info[i].kind);
+
+	  switch (resume_info[i].kind)
+	  {
+	    case resume_step:
+	      MachRegisterVal result;
+	      th->getRegister(MachRegister(x86_64::rip), result);
+	      DEBUG("in step mode @" << result, pid_to_string (th));
+	      if (! th->setSingleStepMode(true))
+		DYNERRMSG("Unable to setSingleStepMode");
+	      // fall through
+	    case resume_continue:
+	      regcache_invalidate_thread (ti);
+	      if (! th->continueThread())
+		DYNERRMSG("Unable to continueThread");
+	      break;
+	    case resume_stop:
+	      if (! th->stopThread())
+		DYNERRMSG("Unable to stopThread");
+	  }
 	}
     }
   DEBUG_EXIT ();
@@ -990,7 +997,6 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
       if (event == NULL)
 	{
 	  event = events.get(new_ptid);
-//	  DEBUG("", pid_to_string (new_ptid));
 	}
       else
 	DEBUG("", pid_to_string (event));
@@ -998,6 +1004,15 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
 
       Thread::const_ptr new_thr;
       Process::const_ptr child;
+      if (debug_threads)
+	dump_events();
+//    if (event->getProcess()->isTerminated())
+//	{
+//	  status->kind = TARGET_WAITKIND_IGNORE;
+//	  status->value.integer = gdb_signal_from_host (0);
+//	  DEBUG_EXIT ();
+//	  return new_ptid;
+//	}
       if ((new_thr = events.is_threadcreate(event)) != NULL_Thread)
 	{
 	  DEBUG("threadcreate pid=" << pid << " New thread: " << event->getThread()->getLWP() << ' ' << ((new_thr != NULL_Thread) ? new_thr->getLWP() : 0), pid_to_string (new_ptid));
@@ -1014,7 +1029,7 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
 	  if (ti)
 	    remove_thread (ti);
 	  events.erase(event);
-	  continue;		// wait events loopNULL
+	  continue;		// wait events loop
 	}
       else if (events.is_exit(event))
 	{
@@ -1040,29 +1055,14 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
       else if (events.is_breakpoint(event))
 	{
 	  EventBreakpoint::const_ptr breakpoint_ev = event->getEventBreakpoint();
-	  // FIXME
-	  if (0 && breakpoint_ev)
+	  events.erase(event);
 	    {
-	      std::vector<Breakpoint::const_ptr> bps;
-	      breakpoint_ev->getBreakpoints(bps);
-	      std::vector<Breakpoint::const_ptr>::iterator it;
-	      for (it = bps.begin(); it != bps.end(); it++)
-		{
-		  Breakpoint::const_ptr bp = *it;
-		  DEBUG("breakpoint " << bp->getToAddress());
-		}
+	      status->kind = TARGET_WAITKIND_STOPPED;
+	      // EventStop doesn't have a signal member
+	      status->value.integer = gdb_signal_from_host (SIGTRAP);
+	      DEBUG_EXIT ();
+	      return ptid_build (event->getProcess()->getPid(), event->getThread()->getLWP(), 0);
 	    }
-	  events.erase(event);
-	  status->kind = TARGET_WAITKIND_STOPPED;
-	  // EventStop doesn't have a signal member
-	  status->value.integer = gdb_signal_from_host (SIGTRAP);
-	  DEBUG("returning ", pid_to_string (new_ptid));
-	  // TODO check this
-	  if (0 && ptid_get_pid (new_ptid) > 0)
-	    cs->ss->current_thread = find_thread_ptid (new_ptid);
-	  DEBUG("current_thread" << cs->ss->current_thread);
-	  DEBUG_EXIT ();
-	  return ptid_build (event->getProcess()->getPid(), event->getThread()->getLWP(), 0);
 	}
       else if (events.is_singlestep(event))
 	{
@@ -1191,6 +1191,8 @@ dyninst_detach (Dyninst::PID pid)
 {
   struct process_info *process;
   ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+  if (procset_it == dyninst_procset->end())
+    return 1;
   Process::ptr dyninst_process = *procset_it;
 
   process = find_process_pid (pid);
@@ -1204,14 +1206,30 @@ dyninst_detach (Dyninst::PID pid)
 
 /* Remove a PROC */
 
+/* Remove all LWPs that belong to process PROC from the lwp list.  */
+
+static int
+delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
+{
+  struct thread_info *thread = (struct thread_info *) entry;
+  struct lwp_info *lwp = (struct lwp_info*)(thread->target_data);
+  struct process_info *process = (struct process_info*)proc;
+
+  if (pid_of (thread) == pid_of (process))
+    dyninst_remove_lwp (lwp->thread);
+
+  return 0;
+}
+
 static void
 dyninst_mourn (struct process_info *proc)
 {
-  clear_inferiors ();
-// TODO
   ThreadPool::iterator thidx;
-
   Process::ptr dyninst_process;
+  client_state *cs = get_client_state ();
+
+  find_inferior (&cs->ss->all_threads, delete_lwp_callback, proc);
+
   if (proc->priv)
     {
       dyninst_process = ((struct process_info_private*)(proc->priv))->process;
@@ -1220,7 +1238,7 @@ dyninst_mourn (struct process_info *proc)
 	    thidx != dyninst_process->threads().end(); thidx++)
 	  {
 	    Thread::const_ptr th = *thidx;
-	    dyninst_remove_thread (th);
+	    dyninst_remove_lwp  (th);
 	  }
     }
 
@@ -1241,6 +1259,8 @@ dyninst_join (Dyninst::PID pid)
     {
       ptid_t new_ptid = ptid_build (pid, pid, 0);
       ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+      if (procset_it == dyninst_procset->end())
+	return;
       Process::ptr dyninst_process = *procset_it;
       if (! dyninst_process->hasRunningThread())
 	break;
@@ -1394,8 +1414,6 @@ dyninst_read_pc (struct regcache *regcache)
   if (the_low_target.read_pc == NULL)
     return 0;
 
-//  Thread::const_ptr thr_ = dyninst_get_inferior_thread();
-//  Thread::ptr thr = boost::const_pointer_cast<Thread>(thr_);
   CORE_ADDR pc = (*the_low_target.read_pc) (regcache);
   DEBUG("pc is " << pc);
   return pc;
@@ -1508,8 +1526,9 @@ dyninst_request_interrupt (void)
 
   Dyninst::PID pid = ptid_get_pid (thread_to_gdb_id (cs->ss->current_thread));
   ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+  if (procset_it == dyninst_procset->end())
+    return;
   Process::ptr dyninst_process = *procset_it;
-
   if (! dyninst_process->terminate())
     DYNERRMSG ("Unable to interrupt process %ld", (long)pid);
 }
@@ -1524,7 +1543,7 @@ dyninst_read_auxv (CORE_ADDR offset, unsigned char *myaddr, unsigned int len)
   char filename[PATH_MAX];
   int fd, n;
   client_state *cs = get_client_state ();
-  int pid = lwpid_of (cs->ss->current_thread);
+  Dyninst::PID pid = lwpid_of (cs->ss->current_thread);
 
   xsnprintf (filename, sizeof filename, "/proc/%d/auxv", pid);
 
@@ -1578,8 +1597,11 @@ dyninst_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
   if (dyninst_process->isTerminated())
     return true;
   Breakpoint::ptr brp = Breakpoint::newBreakpoint();
-  DEBUG(" addr=" << addr << ' ' << brp->getToAddress(), pid_to_string(th));
-  brp->setData(bp);
+  DEBUG(" addr=" << addr << " raw_break=" << bp, pid_to_string(th));
+  struct break_info *break_info = new struct break_info;
+  break_info->pid = dyninst_process->getPid();
+  break_info->addr = addr;
+  brp->setData((void*)break_info);
   insert_shadow_memory (bp);
 
   howto_continue = cont_none;
@@ -1622,6 +1644,7 @@ dyninst_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
   Thread::ptr th = boost::const_pointer_cast<Thread>(thr);
   Process::const_ptr dyninst_process = thr->getProcess();
   Process::ptr dyninst_proc = boost::const_pointer_cast<Process>(dyninst_process);
+  client_state *cs = get_client_state ();
 
   enum {cont_none, cont_thread, cont_proc} howto_continue;
 
@@ -1641,19 +1664,24 @@ dyninst_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
   std::vector<Breakpoint::ptr>::iterator it;
   bool result = false;
 
+  DEBUG("break_count=" << dyninst_bpset.size());
   for (it = dyninst_bpset.begin(); it != dyninst_bpset.end(); it++)
     {
       Breakpoint::ptr bp = *it;
-      if ((struct raw_breakpoint*)(bp->getData()) == rbp)
+      struct break_info *break_info = (struct break_info*)(bp->getData());
+      DEBUG(" addr=" << addr << " stored_pid=" << break_info->pid << " stored_break_addr=" << break_info->addr, pid_to_string(th));
+      if (break_info->addr == addr && break_info->pid == pid_of (cs->ss->current_thread))
 	{
-	  DEBUG(" addr=" << addr << ' ' << bp->getToAddress(), pid_to_string(th));
 	  if (! (result = dyninst_process->rmBreakpoint(addr, bp)))
-	    DYNERRMSG ("Unable remove breakpoint at %#lx", (long)addr);
+	    {
+	      DYNERRMSG ("Unable remove breakpoint at %#lx", (long)addr);
+	    }
+	  delete break_info;
+	  dyninst_bpset.erase(it);
 	  break;
 	}
     }
 
-  dyninst_bpset.erase(it);
 
   switch (howto_continue)
     {
@@ -1832,7 +1860,7 @@ static struct target_ops dyninst_target_ops = {


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2015-08-11 15:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-11 15:13 [SCM] scox/dyninst: Improve adding and updating client state scox

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).