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).