public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  scox/dyninst: Remove global state, an initial step to enable multiple targets.
@ 2015-01-20 15:19 scox
  0 siblings, 0 replies; only message in thread
From: scox @ 2015-01-20 15:19 UTC (permalink / raw)
  To: archer-commits

The branch, scox/dyninst has been updated
       via  aa94c518bc927f2214532a512d9c7399f9ec32d2 (commit)
      from  02afeed30a601bea111805ef89f3c6a27dd59ad9 (commit)

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

- Log -----------------------------------------------------------------
commit aa94c518bc927f2214532a512d9c7399f9ec32d2
Author: Stan Cox <scox@redhat.com>
Date:   Tue Jan 20 10:08:12 2015 -0500

    Remove global state, an initial step to enable multiple targets.
    
    * server.h (client_state): Data structure for per client info.
    Currently, global state has been moved here.
    
    * server.c: Move global state to client_state.
    (set_client_state, get_client_state, new_client_state): New.
    Currently, there is only one client_state.
    (start_inferior, handle_btrace_general_set)
    (parse_debug_format_options, handle_monitor_command)
    (handle_qxfer_btrace, handle_query, handle_v_cont, resume)
    (handle_v_attach, handle_v_run, handle_v_kill, handle_v_requests)
    (find_status_pending_thread_callback, handle_status)
    (captured_main, process_serial_event, handle_target_event): Use client_state.
    
    * target.c (set_desired_thread, mywait, target_stop_and_wait): Likewise.
    
    * remote-utils.c (handle_accept_event, remote_prepare)
    (remote_open,  prepare_resume_reply): Likewise.
    
    * linux-low.c (linux_create_inferior, linux_attach_lwp)
    (linux_attach, get_detach_signal, lp_status_maybe_breakpoint)
    (linux_wait_1, wait_for_sigstop, linux_resume)
    (linux_look_up_symbols, linux_request_interrupt)
    (linux_unpause_all, linux_prepare_to_access_memory): Likewise.
    
    * spu-low.c (spu_wiat): Likewise.
    * win32-low.c (handle_output_debug_string): Likewise
    
    * dyninst-low.cc (DYNERR):  New.
    (ptid_t operator< operator==): New.
    (EventSet):  Use a map <ptid_t, Event>, change callers.
    (is_threadcreate): Make LWPCreate, UserThreadCreate aware.
    (stop_handler):  New.
    (dyninst_resume): Improve thread handling.
    (dyninst_wait_1): Likewise.
    (dyninst_fetch_registers):  Stop thread if needed.
    (dyninst_read_memory, dyninst_write_memory): Improve error handling.

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

Summary of changes:
 gdb/gdbserver/dyninst-low.cc |  500 ++++++++++++++++++++++-------------
 gdb/gdbserver/linux-low.c    |   51 +++--
 gdb/gdbserver/remote-utils.c |   31 ++-
 gdb/gdbserver/remote-utils.h |    2 +-
 gdb/gdbserver/server.c       |  606 ++++++++++++++++++++++--------------------
 gdb/gdbserver/server.h       |   60 ++++-
 gdb/gdbserver/spu-low.c      |    5 +-
 gdb/gdbserver/target.c       |   17 +-
 gdb/gdbserver/win32-low.c    |    3 +-
 9 files changed, 745 insertions(+), 530 deletions(-)

First 500 lines of diff:
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 39747ac..fec8825 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009-2014 Free Software Foundation, Inc.
+/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -46,13 +46,16 @@ extern "C"
 #include <sstream>
 #include <typeinfo>
 
-#define DEBUG(func,cerrstr,args...) 			\
+#define DEBUG(cerrstr,args...) 			\
   if (debug_threads) {					\
-     cerr << "DEBUG(dyninst): " << func << ' ';		\
+     cerr << "DEBUG(dyninst): " << __FUNCTION__ << ' ';	\
      args;						\
      cerr << cerrstr << '\n';				\
   }
 
+#define DYNERR(errstr,args...)						\
+  error ("%s %s " errstr, __FUNCTION__, dyninst_process->getLastErrorMsg(), ##args);
+
 using namespace std;
 using namespace __gnu_cxx;
 using namespace Dyninst;
@@ -69,6 +72,8 @@ Thread::const_ptr NULL_Thread = Thread::const_ptr();
 
 /* Are there pending callbacks for handleEvents */
 
+bool have_callbacks () __attribute__ ((unused));
+
 bool
 have_callbacks ()
 {
@@ -81,8 +86,8 @@ have_callbacks ()
   FD_SET (evNotify()->getFD(), &set);
 
   /* Initialize the timeout data structure. */
-  timeout.tv_sec = 1;
-  timeout.tv_usec = 0;
+  timeout.tv_sec = 0;
+  timeout.tv_usec = 250;
 
   int result = TEMP_FAILURE_RETRY (select (FD_SETSIZE,
 				     &set, NULL, NULL,
@@ -94,27 +99,49 @@ have_callbacks ()
     return true;
 }
 
-
 void pid_to_string (Event::const_ptr ev);
 void pid_to_string (ptid_t ptid);
 
 
+bool operator<(const ptid_t & l, const ptid_t & r )
+{
+  if (l.pid < r.pid)
+    return true;
+  if (l.tid < r.tid)
+    return true;
+  if (l.lwp < r.lwp)
+    return true;
+  return false;
+}
+
+bool operator==(const ptid_t & l, const ptid_t & r )
+{
+  if (l.pid == r.pid && l.tid == r.tid && l.lwp == r.lwp)
+    return true;
+  return false;
+}
+
 class EventSet
 {
 private:
   /* The list of events that handleEvents has encountered */
-  std::vector<Event::const_ptr> current_events;
+  std::vector<Event::const_ptr> current_events_;
+  std::map<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) { current_events.push_back(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(ev);
+  }
   void erase (Event::const_ptr ev)
     {
-      std::vector<Event::const_ptr>::iterator it;
+      std::map<ptid_t,Event::const_ptr>::iterator it;
       for (it = current_events.begin() ;
 	  it != current_events.end(); ++it)
 	{
-	  Event::const_ptr event = *it;
+	  Event::const_ptr event = it->second;
 	  if (event == ev)
 	    {
 	      current_events.erase(it);
@@ -127,28 +154,29 @@ public:
 
   Event::const_ptr get (ptid_t ptid)
   {
-    DEBUG("events.get",(!have_callbacks() ? "(no callbacks)" : ""),pid_to_string (ptid));
     Event::const_ptr event;
-    bool result;
 
-    result = Process::handleEvents(true);
-    if (!result)
+    if (! Process::handleEvents(true))
       return NULL_Event;
-    DEBUG("events.get","after handleEvents");
+    DEBUG("after handleEvents",pid_to_string(ptid));
 
-    std::vector<Event::const_ptr>::reverse_iterator rit;
+    std::map<ptid_t,Event::const_ptr>::reverse_iterator rit;
     for (rit = current_events.rbegin() ;
 	rit != current_events.rend(); ++rit)
       {
-
-	event = *rit;
-	if (ptid.pid == -1 || event->getProcess()->getPid() == ptid.pid)
+	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))
 	  {
-	    DEBUG("events.get","returning event " << event->name());
+	    DEBUG("returning event " << event->name());
 	    return event;
 	  }
       }
-    DEBUG("events.get","returning null event");
+    DEBUG("returning null event");
     return NULL_Event;
   }
 
@@ -190,13 +218,25 @@ public:
       else return false;
   }
 
-  bool is_threadcreate (Event::const_ptr event)
+  Thread::const_ptr is_threadcreate (Event::const_ptr event)
   {
+    Thread::const_ptr thr;
     if (event != NULL)
-      DEBUG("is_threadcreate", event->getEventType().code() << EventType::LWPCreate);
+      DEBUG(event->getEventType().code() << " " << EventType::LWPCreate);
     if (event != NULL)
-      return event->getEventType().code() == EventType::LWPCreate;
-    else return false;
+      {
+	if (event->getEventType().code() == EventType::LWPCreate)
+	  {
+	    EventNewLWP::const_ptr newlwp_ev = event->getEventNewLWP();
+	    return newlwp_ev->getNewThread();
+	  }
+	else if (event->getEventType().code() == EventType::UserThreadCreate)
+	  {
+	    EventNewUserThread::const_ptr newlwp_ev = event->getEventNewUserThread();
+	    return newlwp_ev->getNewThread();
+	  }
+      }
+    return NULL_Thread;
   }
 
   bool is_threaddestroy(Event::const_ptr event)
@@ -208,14 +248,15 @@ public:
 
   void dump ()
   {
-    std::vector<Event::const_ptr>::iterator it;
+    std::map<ptid_t,Event::const_ptr>::iterator it;
     for (it = current_events.begin() ;
 	it != current_events.end(); ++it)
       {
-	Event::const_ptr event = *it;
+	ptid_t ptid = it->first;
+	Event::const_ptr event = it->second;
 	if (event == NULL)
 	  continue;
-	DEBUG("dump",event->name(), pid_to_string (event));
+	DEBUG(event->name() << " pid=" << ptid.pid << " lwp=" << ptid.lwp << " tid=" << ptid.tid);
       }
 
   }
@@ -226,11 +267,13 @@ void
 pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid)
 {
   if (pid == -1)
-    cerr << "pid=NULL";
+    cerr << "pid=*";
   else
     {
       cerr << "pid=" << pid;
-      if (pid != lwp && lwp > 0)
+      if (lwp < 0)
+	cerr << " lwp=*";
+      else
 	cerr << " lwp=" << lwp;
       if (tid > 0)
 	cerr << " thr=" << tid;
@@ -335,9 +378,9 @@ dyninst_add_thread(int pid, Thread::const_ptr thread)
 static Thread::const_ptr
 dyninst_get_inferior_thread()
 {
-  DEBUG("dyninst_get_inferior_thread", "current_thread=" << current_thread);
+  DEBUG("current_thread=" << current_thread);
   struct thread_info_private *tip = (struct thread_info_private*)(current_thread->target_data);
-  DEBUG("dyninst_get_inferior_thread", "", pid_to_string (current_thread->entry.id));
+  DEBUG("", pid_to_string (current_thread->entry.id));
   if (!tip)
     error ("No inferior thread");
   return tip->thread;
@@ -350,7 +393,7 @@ Process::cb_ret_t
 signal_handler(Event::const_ptr ev)
 {
   events.insert(ev);
-  DEBUG("signal_handler", ev->name());
+  DEBUG(ev->name());
   return Process::cbDefault;
 }
 
@@ -361,12 +404,23 @@ Process::cb_ret_t
 singlestep_handler(Event::const_ptr ev)
 {
   events.insert(ev);
-  DEBUG("singlestep_handler", ev->name());
+  DEBUG(ev->name());
   ev->getThread()->setSingleStepMode(false);
   return Process::cbThreadStop;
 }
 
 
+/* Handle a dyninst Stop event */
+
+Process::cb_ret_t
+stop_handler(Event::const_ptr ev)
+{
+  events.insert(ev);
+  DEBUG(ev->name());
+  return Process::cbThreadStop;
+}
+
+
 /* Handle a dyninst Library event */
 
 Process::cb_ret_t
@@ -377,8 +431,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("dyninst_attach", "added library " << lib->getAbsoluteName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
-//      loaded_dll (lib->getAbsoluteName().c_str(), lib->getDynamicAddress());
+      DEBUG("added library " << lib->getAbsoluteName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
     }
 
   return Process::cbDefault;
@@ -388,10 +441,8 @@ library_handler(Event::const_ptr ev)
 void
 myregisterCB(EventType et, Process::cb_func_t f)
 {
-  bool result = Process::registerEventCallback(et, f);
-  if (!result) {
+  if (! Process::registerEventCallback(et, f))
     cout << "Error registering thread callback " << et.name() << '\n';
-  }
 }
 
 
@@ -422,19 +473,19 @@ dyninst_create_inferior (char *program, char **allargs)
   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::Library, library_handler);
   myregisterCB(EventType::RPC, signal_handler);
   myregisterCB(EventType::Signal, signal_handler);
   myregisterCB(EventType::SingleStep, singlestep_handler);
-  myregisterCB(EventType::Stop, signal_handler);
+  myregisterCB(EventType::Stop, stop_handler);
   myregisterCB(EventType::Terminate, signal_handler);
-  myregisterCB(EventType::ThreadCreate, signal_handler);
-  myregisterCB(EventType::ThreadDestroy, signal_handler);
-  myregisterCB(EventType::UserThreadCreate, signal_handler);
-  myregisterCB(EventType::UserThreadDestroy, signal_handler);
+  // ThreadCreate, UserThreadCreate handled via LWPCreate
+  // ThreadDestroy, UserThreadDestroy handled via LWPDestroy
 
 
-  DEBUG("dyninst_create_inferior", "created process " << dyninst_process->getPid() << program);
+  DEBUG("created process " << dyninst_process->getPid() << program);
 
   pid_t pid = dyninst_process->getPid();
   dyninst_add_process (pid, 0, dyninst_process);
@@ -443,12 +494,13 @@ dyninst_create_inferior (char *program, char **allargs)
   for (thidx = dyninst_process->threads().begin();
       thidx != dyninst_process->threads().end(); thidx++)
     {
-      DEBUG("dyninst_create_inferior", "created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP());
+      DEBUG("created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP());
       Thread::ptr th = *thidx;
       dyninst_add_thread (pid, th);
     }
 
-  dyninst_process->stopProc();
+  if (! dyninst_process->stopProc())
+    error ("Cannot stop process %ld: %s", (long int)pid, getLastErrorMsg());
   return dyninst_process->getPid();
 }
 
@@ -457,24 +509,30 @@ dyninst_create_inferior (char *program, char **allargs)
 static int
 dyninst_attach (unsigned long pid)
 {
-  static Process::ptr dyninst_proc = Process::attachProcess(pid);
+  Process::ptr dyninst_proc = Process::attachProcess(pid);
+  if (dyninst_proc == Process::ptr())
+    error ("Cannot attach to process %ld: %s",
+	   pid, getLastErrorMsg());
+
+  dyninst_procset->insert(dyninst_proc);
 
-  DEBUG("dyninst_attach", "pid=" << pid);
+  DEBUG("pid=" << pid);
   myregisterCB(EventType::Bootstrap, signal_handler);
   myregisterCB(EventType::Breakpoint, signal_handler);
   myregisterCB(EventType::Crash, signal_handler);
   myregisterCB(EventType::Exec, signal_handler);
   myregisterCB(EventType::Exit, signal_handler);
   myregisterCB(EventType::Fork, signal_handler);
-  myregisterCB(EventType::Library, signal_handler);
+  myregisterCB(EventType::LWPCreate, signal_handler);
+  myregisterCB(EventType::LWPDestroy, signal_handler);
+  myregisterCB(EventType::Library, library_handler);
   myregisterCB(EventType::RPC, signal_handler);
   myregisterCB(EventType::Signal, signal_handler);
-  myregisterCB(EventType::SingleStep, signal_handler);
-  myregisterCB(EventType::Stop, signal_handler);
+  myregisterCB(EventType::SingleStep, singlestep_handler);
+  myregisterCB(EventType::Stop, stop_handler);
   myregisterCB(EventType::Terminate, signal_handler);
-  myregisterCB(EventType::ThreadCreate, signal_handler);
-  myregisterCB(EventType::ThreadDestroy, signal_handler);
-  myregisterCB(EventType::UserThreadCreate, signal_handler);
+  // ThreadCreate, UserThreadCreate handled via LWPCreate
+  // ThreadDestroy, UserThreadDestroy handled via LWPDestroy
 
 
   if (dyninst_proc == Process::ptr())
@@ -486,7 +544,7 @@ dyninst_attach (unsigned long pid)
   for (thidx = dyninst_proc->threads().begin();
       thidx != dyninst_proc->threads().end(); thidx++)
     {
-      DEBUG("dyninst_attach", "created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP());
+      DEBUG("created thread " << (*thidx)->getTID() << ' ' << (*thidx)->getLWP());
       Thread::const_ptr th = *thidx;
       dyninst_add_thread (pid, th);
     }
@@ -495,8 +553,7 @@ dyninst_attach (unsigned long pid)
   for (libidx = dyninst_proc->libraries().begin(); libidx != dyninst_proc->libraries().end(); libidx++)
     {
       Library::ptr lib = *libidx;
-      DEBUG("dyninst_attach", "added library " << lib->getName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
-//      loaded_dll (lib->getAbsoluteName().c_str(), lib->getDynamicAddress());
+      DEBUG("added library " << lib->getName() << " " << lib->getDynamicAddress() << " " << lib->getLoadAddress() << endl);
     }
 
   return 0;
@@ -507,68 +564,85 @@ dyninst_attach (unsigned long pid)
 static void
 dyninst_resume (struct thread_resume *resume_info, size_t n)
 {
-  /* FIXME: Assume for now that n == 1.  */
-  ptid_t ptid = resume_info[0].thread;
+  for (int i = 0; i < (int)n; i++)
+    {
+      DEBUG("",pid_to_string(resume_info[i].thread));
+      ptid_t ptid = resume_info[i].thread;
 
-  if (ptid_equal (ptid, minus_one_ptid))
-    ptid = thread_to_gdb_id (current_thread);
+      if (ptid_equal (ptid, minus_one_ptid))
+	ptid = thread_to_gdb_id (current_thread);
 
-  Dyninst::PID pid = ptid_get_pid (ptid);
-  ProcessSet::iterator procset_it = dyninst_procset->find(pid);
-  if (procset_it == dyninst_procset->end())
-    error ("Cannot resume process %lu\n", (long unsigned)pid);
+      Dyninst::PID pid = ptid_get_pid (ptid);
+      ProcessSet::iterator procset_it = dyninst_procset->find(pid);
+      if (procset_it == dyninst_procset->end())
+	error ("Cannot resume process %lu\n", (long unsigned)pid);
 
-  Process::ptr dyninst_process = *procset_it;
+      Process::ptr dyninst_process = *procset_it;
 
-  DEBUG("dyninst_resume", "", pid_to_string (ptid));
-  DEBUG("dyninst_resume", "found proc " << dyninst_process->getPid());
-  ThreadPool::iterator thidx;
-  Thread::ptr th;
+      DEBUG("", pid_to_string (ptid));
+      DEBUG("found proc " << dyninst_process->getPid());
+      ThreadPool::iterator thidx;
+      Thread::ptr th;
 
-  if (dyninst_process->isTerminated())
-    return;
-  for (thidx = dyninst_process->threads().begin();
-      thidx != dyninst_process->threads().end(); thidx++)
-    {
-      th = *thidx;
-      if (th->getTID() == ptid.tid)
+      if (dyninst_process->isTerminated())
+	return;
+
+      if (resume_info[i].thread == minus_one_ptid)
 	{
-	  th = *thidx;
-	  break;
+	  DEBUG("before regcache_invalidate");
+	  regcache_invalidate ();
+	  DEBUG("before continue pid=" << pid);
+	  if (! dyninst_process->continueProc())
+	    DEBUG("Unable to continueProc " << dyninst_process->getLastErrorMsg());
+	  return;
 	}
-    }
 
-  // resume_continue, resume_step, resume_stop
-  struct thread_info_private *tip = (struct thread_info_private*)(current_thread->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 (current_thread, 1);
-  CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
-  DEBUG("dyninst_resume", "range " << resume_info->step_range_start << "/" << resume_info->step_range_end << " pc=" << pc << "kind=" << resume_info[0].kind);
-  if (resume_info[0].kind == resume_step)
-    {
-      DEBUG("dyninst_resume", "in step mode", pid_to_string (th));
-      th->setSingleStepMode(true);
+      for (thidx = dyninst_process->threads().begin();
+	   thidx != dyninst_process->threads().end(); thidx++)
+	{
+	  th = *thidx;
+	  if (th->getLWP() == ptid.lwp)
+	    {
+	      // resume_continue, resume_step, resume_stop
+	      struct thread_info *ti = find_thread_ptid (ptid);
+	      struct thread_info_private *tip = (struct thread_info_private*)(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.get_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:
+		    DEBUG("in step mode", pid_to_string (th));
+		    if (! th->setSingleStepMode(true))
+		      DYNERR("Unable to setSingleStepMode");
+		case resume_continue:
+		    regcache_invalidate ();
+		    if (! th->continueThread())
+		      DYNERR("Unable to continueThread");
+		    break;
+		case resume_stop:
+		  if (! th->stopThread())
+		    DYNERR("Unable to stopThread");
+		}
+	    }
+	}
     }
-  else
-    th->setSingleStepMode(false);
-
-  regcache_invalidate ();
-
-  DEBUG("dyninst_resume","before continue");
-  bool result = dyninst_process->continueProc();
-  if (! result)
-    cout << "Cannot continueProc " << dyninst_process->getLastErrorMsg() << '\n';
 }
 
+
 /* Handle a vCont packet */
 
+static void dyninst_continue (ptid_t) __attribute__ ((unused));
+
 static void
 dyninst_continue (ptid_t ptid)


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


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

only message in thread, other threads:[~2015-01-20 15:19 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-20 15:19 [SCM] scox/dyninst: Remove global state, an initial step to enable multiple targets 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).