public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  scox/dyninst: Categorize client packets for handling multiplexed client connections.
@ 2015-05-04 21:00 scox
  0 siblings, 0 replies; only message in thread
From: scox @ 2015-05-04 21:00 UTC (permalink / raw)
  To: archer-commits

The branch, scox/dyninst has been updated
       via  21f64f60c407b97df755cc686c89b5d148450bdd (commit)
      from  182451b3fd3afbf1b88867a90c222d4e7c91d3c3 (commit)

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

- Log -----------------------------------------------------------------
commit 21f64f60c407b97df755cc686c89b5d148450bdd
Author: Stan Cox <scox@redhat.com>
Date:   Mon May 4 16:58:54 2015 -0400

    Categorize client packets for handling multiplexed client connections.
    
    * dyninst-low.cc (DYNERRMSG): New for error reporting.
      (EventSet): Convert current_events from a map to a vector.
      (insert, erase, get):  Likewise.
      (is_threadcreate, is_threaddestroy):  Handle all types of thread events.
      (pid_to_string):  Display pc if possible.
      (lwpdestroy_handler): New.
      (dyninst_store_registers, dyninst_fetch_registers)
      (dyninst_insert_point, dyninst_remove_point): Add howto_continue;
    
    * dyninst-x86-low.cc (x86_get_pc): New.
    
    * server.c (set_client_state) Simplify to only set or add a client_state.
       Change all callers.
      (set_lock): Remove.
      (normalize_packet): Given multiple requests for the same process,
       determine which should be allowed to proceed.
      (handle_monitor_command):  Add 'client status'
      (process_serial_event):  Handle multiple requests to the same process.
    
    * server.h (server_state): Move own_buf to client_state.
      (client_state):  Add in_buf to record the incoming packet when
       own_buf is overwritten.  Add normalized_packet and pending.
      (struct client_states):  Points to the current state.

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

Summary of changes:
 gdb/gdbserver/dyninst-low.cc     |  519 +++++++++++++++++++++++++----------
 gdb/gdbserver/dyninst-low.h      |    3 +-
 gdb/gdbserver/dyninst-x86-low.cc |   32 ++-
 gdb/gdbserver/event-loop.c       |   21 +-
 gdb/gdbserver/server.c           |  568 ++++++++++++++++++++++----------------
 gdb/gdbserver/server.h           |   20 +-
 6 files changed, 754 insertions(+), 409 deletions(-)

First 500 lines of diff:
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 4e3ac2c..199d7a1 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -54,8 +54,13 @@ extern "C"
   }
 
 
-#define DYNERR(errstr,args...)						\
+#define DYNERRMSG(errstr,args...)						\
   fprintf (stderr, "%s %s " errstr "\n", __FUNCTION__, dyninst_process->getLastErrorMsg(), ##args);
+#define DYNERR(errstr,args...)						\
+  fprintf (stderr, "%s " errstr "\n", __FUNCTION__, ##args);
+#define DEBUG_ENTER() if (debug_threads) debug_enter()
+#define DEBUG_EXIT()  if (debug_threads) debug_exit()
+
 
 using namespace std;
 using namespace __gnu_cxx;
@@ -71,6 +76,25 @@ LibrarySet dyninst_libset;
 Thread::const_ptr NULL_Thread = Thread::const_ptr();
 
 
+void
+dump_procset ()
+{
+  ProcessSet::iterator it;
+  ThreadPool::const_iterator thidx;
+  for (it = dyninst_procset->begin(); it != dyninst_procset->end(); it++)
+    {
+      Process::const_ptr proc = *it;
+      cout << __FUNCTION__ << ' ' << proc->getPid() << ' ' << hex;
+      for (thidx = proc->threads().begin();
+	  thidx != proc->threads().end(); thidx++)
+	{
+	  Thread::const_ptr thr = *thidx;
+	  cout << thr->getLWP() << ' ' << the_low_target.get_pc (thr) << ' ';
+	}
+      cout << '\n';
+    }
+}
+
 /* Are there pending callbacks for handleEvents */
 
 bool have_callbacks () __attribute__ ((unused));
@@ -125,69 +149,80 @@ class EventSet
 {
 private:
   /* The list of events that handleEvents has encountered */
-  std::map<ptid_t,Event::const_ptr> current_events;
+  std::vector<std::pair<ptid_t, Event::const_ptr> > current_events;
 public:
   EventSet() { NULL_Event = Event::const_ptr(); }
   Event::const_ptr NULL_Event;
-  void insert (Event::const_ptr ev) {
+  void insert (Event::const_ptr ev)
+  {
     ptid_t ptid = ptid_build (ev->getProcess()->getPid(), ev->getThread()->getLWP(), (ev->getThread()->haveUserThreadInfo() ? ev->getThread()->getTID() : -1));
-    current_events[ptid] = ev;
+    current_events.push_back(make_pair (ptid, ev));
     if (debug_threads)
+      {
 	dump("after insert ");
+	dump_procset ();
+      }
   }
   void erase (Event::const_ptr ev)
-    {
-      std::map<ptid_t,Event::const_ptr>::iterator it;
-      for (it = current_events.begin() ;
-	  it != current_events.end(); ++it)
-	{
-	  Event::const_ptr event = it->second;
-	  if (event == ev)
-	    {
-	      current_events.erase(it);
-	      break;
-	    }
-	}
-      if (debug_threads)
-	dump("after erase ");
-    }
+  {
+    if (ev != NULL_Event)
+      DEBUG(ev->name());
+    std::vector<std::pair<ptid_t,Event::const_ptr> >::iterator it;
+    for (it = current_events.begin() ;
+	it != current_events.end(); ++it)
+      {
+	Event::const_ptr event = it->second;
+	if (event == ev)
+	  {
+	    current_events.erase(it);
+	    break;
+	  }
+      }
+    if (debug_threads)
+      dump("after erase ");
+  }
 
   /* Get the event for a given PTID */
 
   Event::const_ptr get (ptid_t ptid)
   {
     Event::const_ptr event;
+    int attempt = 1;
 
-    if (! Process::handleEvents(true))
-      return NULL_Event;
-    DEBUG("after handleEvents",pid_to_string(ptid));
-
-    std::map<ptid_t,Event::const_ptr>::reverse_iterator rit;
-    for (rit = current_events.rbegin() ;
-	rit != current_events.rend(); ++rit)
+    do
       {
-	ptid_t ceptid = rit->first;
-	event = rit->second;
-	DEBUG(event->name() << " " << ptid.pid << " " << ceptid.pid << " " << ptid.lwp << " " << ceptid.lwp << " " << ptid.tid << " " <<  ceptid.tid);
-	if (ptid.pid == -1
-	    || (ceptid.pid == ptid.pid))
-//	    || (ceptid.pid == ptid.pid
-//		&& ceptid.lwp == ptid.lwp))
+	std::vector<std::pair<ptid_t,Event::const_ptr> >::iterator it;
+	for (it = current_events.begin() ;
+	    it != current_events.end(); ++it)
 	  {
-	    DEBUG("returning event " << event->name());
-	    return event;
+	    ptid_t ceptid = it->first;
+	    event = it->second;
+	    if (ptid.pid == -1
+		|| (ceptid.pid == ptid.pid))
+//	        || (ceptid.pid == ptid.pid
+//		    && ceptid.lwp == ptid.lwp))
+	      {
+		CORE_ADDR pc = (the_low_target.get_pc) (event->getThread());
+		DEBUG(event->name() << ' ' << ceptid.pid << '/' << ceptid.lwp << "pc=" << pc);
+		return event;
+	      }
 	  }
+	if (! Process::handleEvents(true))
+	  return NULL_Event;
+	DEBUG("after handleEvents",pid_to_string(ptid));
+	attempt += 1;
       }
+    while (attempt <= 2);
+
     DEBUG("returning null event");
     return NULL_Event;
   }
 
   bool is_stopped (Event::const_ptr event)
   {
-    if (event == NULL)
-      return false;
-    else
+    if (event != NULL)
       return event->getEventType().code() == EventType::Stop;
+    else return false;
    }
 
   bool is_exit (Event::const_ptr event)
@@ -197,7 +232,6 @@ public:
     else return false;
   }
 
-
   bool is_breakpoint(Event::const_ptr event)
   {
     if (event != NULL)
@@ -239,28 +273,59 @@ public:
 	      DEBUG(event->getEventType().code() << " UserThreadCreate");
 	    return newlwp_ev->getNewThread();
 	  }
+	else if (event->getEventType().code() == EventType::ThreadCreate)
+	  {
+	    EventNewUserThread::const_ptr newlwp_ev = event->getEventNewUserThread();
+	    if (event != NULL)
+	      DEBUG(event->getEventType().code() << " ThreadCreate");
+	    return newlwp_ev->getNewThread();
+	  }
       }
     return NULL_Thread;
   }
 
-  bool is_threaddestroy(Event::const_ptr event)
+  Thread::const_ptr is_threaddestroy (Event::const_ptr event)
   {
+    Thread::const_ptr thr;
     if (event != NULL)
-      return event->getEventType().code() == EventType::UserThreadDestroy;
-    else return false;
+      {
+	if (event->getEventType().code() == EventType::LWPDestroy)
+	  {
+	    EventLWPDestroy::const_ptr lwpd_ev = event->getEventLWPDestroy();
+	    if (event != NULL)
+	      DEBUG(event->getEventType().code() << " LWPDestroy");
+	    return lwpd_ev->getThread();
+	  }
+	else if (event->getEventType().code() == EventType::UserThreadDestroy)
+	  {
+	    EventUserThreadDestroy::const_ptr utd_ev = event->getEventUserThreadDestroy();
+	    if (event != NULL)
+	      DEBUG(event->getEventType().code() << " UserThreadDestroy");
+	    return utd_ev->getThread();
+	  }
+	else if (event->getEventType().code() == EventType::ThreadDestroy)
+	  {
+	    EventThreadDestroy::const_ptr td_ev = event->getEventThreadDestroy();
+	    if (event != NULL)
+	      DEBUG(event->getEventType().code() << " ThreadDestroy");
+	    return td_ev->getThread();
+	  }
+      }
+    return NULL_Thread;
   }
 
   void dump (string comment)
   {
-    std::map<ptid_t,Event::const_ptr>::iterator it;
+    int idx = 1;
+    std::vector<std::pair<ptid_t,Event::const_ptr> >::iterator it;
     for (it = current_events.begin() ;
 	it != current_events.end(); ++it)
       {
-	ptid_t ptid = it->first;
 	Event::const_ptr event = it->second;
 	if (event == NULL)
 	  continue;
-	DEBUG(comment << event->name() << " pid=" << ptid.pid << " lwp=" << ptid.lwp << " tid=" << ptid.tid);
+	DEBUG(dec << idx << hex << ' ' << comment << event->name(), pid_to_string (event));
+	idx += 1;
       }
 
   }
@@ -268,14 +333,12 @@ public:
 
 
 void
-pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid)
+pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid, CORE_ADDR pc)
 {
   if (pid == -1)
     cerr << "pid=*";
   else
     {
-      ptid_t ptid = ptid_build (pid, lwp, tid);
-      struct thread_info *ti = find_thread_ptid (ptid);
       cerr << "pid=" << pid;
       if (lwp < 0)
 	cerr << " lwp=*";
@@ -283,23 +346,40 @@ pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid)
 	cerr << " lwp=" << lwp;
       if (tid > 0)
 	cerr << " thr=" << tid;
-      if (ti != NULL)
+
+      string source = "";
+      if (pc == 0)
 	{
-	  struct regcache *regcache = get_thread_regcache (ti, 1);
-	  CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-	  cerr << " pc=" << pc;
+	  struct thread_info *ti = find_thread_ptid (ptid_build (pid, lwp, tid));
+	  if (ti == NULL)
+	    ti = find_thread_ptid (ptid_build (pid, lwp, 0));
+	  if (ti != NULL)
+	    {
+	      struct regcache *regcache = get_thread_regcache (ti, 0);
+	      pc = (*the_low_target.read_pc) (regcache);
+	      source = " cached";
+	    }
 	}
+      cerr << source << " pc=" << pc;
     }
   cerr << ' ';
 }
 
 
+static Thread::const_ptr dyninst_get_thread(ptid_t ptid);
+
 /* Pretty print a pid/lwp/tid tuple */
 
 void
 pid_to_string (ptid_t ptid)
 {
-  pid_to_string (ptid.pid, ptid.lwp, ptid.tid);
+  CORE_ADDR pc;
+  Thread::const_ptr thr = dyninst_get_thread(ptid);
+  if (thr != NULL_Thread)
+    pc = (the_low_target.get_pc) (thr);
+  else
+    pc = 0;
+  pid_to_string (ptid.pid, ptid.lwp, ptid.tid, pc);
 }
 
 void
@@ -313,7 +393,9 @@ pid_to_string (Thread::const_ptr thr)
   else
     tid = -1;
 
-  pid_to_string (thr->getProcess()->getPid(), thr->getLWP(), tid);
+  CORE_ADDR pc = (the_low_target.get_pc) (thr);
+
+  pid_to_string (thr->getProcess()->getPid(), thr->getLWP(), tid, pc);
 }
 
 void
@@ -351,6 +433,17 @@ struct thread_info_private
 };
 
 
+static Thread::const_ptr
+dyninst_get_thread(ptid_t ptid)
+{
+  struct thread_info *ti = find_thread_ptid (ptid);
+  if (ti != NULL)
+    return ((struct thread_info_private*)ti->target_data)->thread;
+  else
+    return NULL_Thread;
+}
+
+
 /* Add a PROCESS PID, that is possibly being ATTACHED */
 
 static struct process_info *
@@ -413,7 +506,7 @@ dyninst_get_inferior_thread()
 
   struct thread_info_private *tip = (struct thread_info_private*)(cs->ss->current_thread->target_data);
   if (!tip)
-    error ("No inferior thread");
+    DYNERR ("No inferior thread");
   return tip->thread;
 }
 
@@ -423,8 +516,21 @@ dyninst_get_inferior_thread()
 Process::cb_ret_t
 signal_handler(Event::const_ptr ev)
 {
-  events.insert(ev);
   DEBUG(ev->name());
+  if (ev->name() != "post-LWPDestroy")
+    events.insert(ev);
+  return Process::cbDefault;
+}
+
+
+/* Handle a dyninst Breakpoint event */
+
+Process::cb_ret_t
+breakpoint_handler(Event::const_ptr ev)
+{
+  EventBreakpoint::const_ptr bp_ev = ev->getEventBreakpoint();
+  DEBUG('@' << bp_ev->getAddress() << " lwp=" << bp_ev->getThread()->getLWP());
+  events.insert(ev);
   return Process::cbDefault;
 }
 
@@ -434,21 +540,34 @@ signal_handler(Event::const_ptr ev)
 Process::cb_ret_t
 singlestep_handler(Event::const_ptr ev)
 {
-  events.insert(ev);
   DEBUG(ev->name());
+  events.insert(ev);
   ev->getThread()->setSingleStepMode(false);
   return Process::cbThreadStop;
 }
 
 
+// Handle a dyninst LWPDestroy event
+
+Process::cb_ret_t
+lwpdestroy_handler(Event::const_ptr ev)
+{
+  Process::cb_ret_t cbret (Process::cbProcStop, Process::cbProcStop);
+  DEBUG(ev->name());
+  if (ev->name() != "post-LWPDestroy")
+    events.insert(ev);
+  return cbret;
+}
+
+
 /* Handle a dyninst Stop event */
 
 Process::cb_ret_t
 stop_handler(Event::const_ptr ev)
 {
+  DEBUG(ev->name() << " stopped="  << ev->getThread()->isStopped() << " running=" << ev->getThread()->isRunning(), pid_to_string (ev->getThread()));
   events.insert(ev);
-  DEBUG(ev->name());
-  return Process::cbThreadStop;
+  return Process::cbDefault;
 }
 
 
@@ -462,7 +581,7 @@ library_handler(Event::const_ptr ev)
   for (set<Library::ptr>::const_iterator i = lib_ev->libsAdded().begin(); i != lib_ev->libsAdded().end(); i++)
     {
       Library::ptr lib = *i;
-      DEBUG("added library " << lib->getAbsoluteName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
+      DEBUG("added library " << lib->getAbsoluteName() << ' ' << lib->getDynamicAddress() << ' ' << lib->getLoadAddress() << endl);
     }
 
   return Process::cbDefault;
@@ -495,17 +614,17 @@ dyninst_create_inferior (char *program, char **allargs)
 
   Process::ptr dyninst_process = Process::createProcess(exec, args);
   if (dyninst_process == Process::ptr())
-    error ("No such file: %s\n", exec.c_str());
+    DYNERRMSG ("No such file: %s\n", exec.c_str());
   dyninst_procset->insert(dyninst_process);
 
   myregisterCB(EventType::Bootstrap, signal_handler);
-  myregisterCB(EventType::Breakpoint, signal_handler);
+  myregisterCB(EventType::Breakpoint, breakpoint_handler);
   myregisterCB(EventType::Crash, signal_handler);
   myregisterCB(EventType::Exec, signal_handler);
   myregisterCB(EventType::Exit, signal_handler);
   myregisterCB(EventType::Fork, signal_handler);
   myregisterCB(EventType::LWPCreate, signal_handler);
-  myregisterCB(EventType::LWPDestroy, signal_handler);
+  myregisterCB(EventType::LWPDestroy, lwpdestroy_handler);
   myregisterCB(EventType::Library, library_handler);
   myregisterCB(EventType::RPC, signal_handler);
   myregisterCB(EventType::Signal, signal_handler);
@@ -539,7 +658,7 @@ dyninst_create_inferior (char *program, char **allargs)
     }
 
   if (! dyninst_process->stopProc())
-    error ("Cannot stop process %ld: %s", (long int)pid, getLastErrorMsg());
+    DYNERRMSG ("Cannot stop process %ld", (long int)pid);
   return dyninst_process->getPid();
 }
 
@@ -551,16 +670,15 @@ dyninst_attach (unsigned long pid)
   ProcessSet::iterator procset_it = dyninst_procset->find(pid);
   if (procset_it != dyninst_procset->end())
     DEBUG("already attached to pid " << pid);
-  Process::ptr dyninst_proc = Process::attachProcess(pid);
-  if (dyninst_proc == Process::ptr())
-    error ("Cannot attach to process %ld: %s",
-	   pid, getLastErrorMsg());
+  Process::ptr dyninst_process = Process::attachProcess(pid);
+  if (dyninst_process == Process::ptr())
+    DYNERRMSG ("Cannot attach to process %ld", pid);
 
-  dyninst_procset->insert(dyninst_proc);
+  dyninst_procset->insert(dyninst_process);
 
   DEBUG("pid=" << pid);
   myregisterCB(EventType::Bootstrap, signal_handler);
-  myregisterCB(EventType::Breakpoint, signal_handler);
+  myregisterCB(EventType::Breakpoint, breakpoint_handler);
   myregisterCB(EventType::Crash, signal_handler);
   myregisterCB(EventType::Exec, signal_handler);
   myregisterCB(EventType::Exit, signal_handler);
@@ -577,14 +695,13 @@ dyninst_attach (unsigned long pid)
   // ThreadDestroy, UserThreadDestroy handled via LWPDestroy
 
 
-  if (dyninst_proc == Process::ptr())
-    error ("Cannot attach to process %lu: %s (%d)\n", pid,
-	   dyninst_proc->getLastErrorMsg(), dyninst_proc->getLastError());
+  if (dyninst_process == Process::ptr())
+    DYNERRMSG ("Cannot attach to process %lu", pid);
 
-  dyninst_add_process (pid, 1, dyninst_proc);
+  dyninst_add_process (pid, 1, dyninst_process);
   ThreadPool::iterator thidx;
-  for (thidx = dyninst_proc->threads().begin();
-      thidx != dyninst_proc->threads().end(); thidx++)
+  for (thidx = dyninst_process->threads().begin();
+      thidx != dyninst_process->threads().end(); thidx++)
     {
       bool reg_map_setup = false;
       RegisterPool regpool;
@@ -600,10 +717,10 @@ dyninst_attach (unsigned long pid)
     }
 
   LibraryPool::iterator libidx;
-  for (libidx = dyninst_proc->libraries().begin(); libidx != dyninst_proc->libraries().end(); libidx++)
+  for (libidx = dyninst_process->libraries().begin(); libidx != dyninst_process->libraries().end(); libidx++)
     {
       Library::ptr lib = *libidx;
-      DEBUG("added library " << lib->getName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
+      DEBUG("added library " << lib->getName() << ' ' << lib->getDynamicAddress() << ' ' << lib->getLoadAddress() << endl);
     }
 
   return 0;
@@ -617,36 +734,41 @@ dyninst_resume (struct thread_resume *resume_info, size_t n)
   client_state *cs = get_client_state ();
 
 
+  DEBUG_ENTER ();
+
   for (int i = 0; i < (int)n; i++)
     {


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


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

only message in thread, other threads:[~2015-05-04 21:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-04 21:00 [SCM] scox/dyninst: Categorize client packets for handling multiplexed client connections 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).