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