public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM] scox/dyninst: Add range step handling.
@ 2014-11-12 15:08 scox
0 siblings, 0 replies; only message in thread
From: scox @ 2014-11-12 15:08 UTC (permalink / raw)
To: archer-commits
The branch, scox/dyninst has been updated
via bc5aece835a317ef016557d57a6a32178091d821 (commit)
from c93a51b7e31702961ecb060b36740dd0390d0a51 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email.
- Log -----------------------------------------------------------------
commit bc5aece835a317ef016557d57a6a32178091d821
Author: Stan Cox <scox@redhat.com>
Date: Wed Nov 12 10:05:56 2014 -0500
Add range step handling.
* dyninst-low.cc (BreakpointSet, dyninst_bpset): New.
(dyninst_resume): Add range step handling.
(in_step_range): Check range step boundary.
(dyninst_wait_1): Add range step handling.
(dyninst_remove_point): Likewise.
(dyninst_supports_range_stepping): Likewise.
* dyninst-low.h: Likewise.
* dyninst-x86-low.cc: Likewise.
-----------------------------------------------------------------------
Summary of changes:
gdb/gdbserver/ChangeLog | 11 ++
gdb/gdbserver/dyninst-low.cc | 221 +++++++++++++++++++++++--------------
gdb/gdbserver/dyninst-low.h | 1 +
gdb/gdbserver/dyninst-x86-low.cc | 8 ++
4 files changed, 157 insertions(+), 84 deletions(-)
First 500 lines of diff:
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index e36db7f..f6113f8 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,14 @@
+2014-11-11 Stan Cox <scox@redhat.com>
+
+ * dyninst-low.cc (BreakpointSet, dyninst_bpset): New.
+ (dyninst_resume): Add range step handling.
+ (in_step_range): Check range step boundary.
+ (dyninst_wait_1): Add range step handling.
+ (dyninst_remove_point): Likewise.
+ (dyninst_supports_range_stepping): Likewise.
+ * dyninst-low.h: Likewise.
+ * dyninst-x86-low.cc: Likewise.
+
2014-10-31 Stan Cox <scox@redhat.com>
* dyninst-low.cc: New. Preliminary generic rsp packet handling for dyninst rsp server.
diff --git a/gdb/gdbserver/dyninst-low.cc b/gdb/gdbserver/dyninst-low.cc
index 8cf9478..018fa61 100644
--- a/gdb/gdbserver/dyninst-low.cc
+++ b/gdb/gdbserver/dyninst-low.cc
@@ -39,8 +39,8 @@ extern "C"
#include <string>
#include <vector>
#include "dyninst-low.h"
-#include <iostream> // std::cout
-#include <sstream> // std::ostringstream
+#include <iostream>
+#include <sstream>
#define DEBUG(func,cerrstr,args...) \
if (debug_threads) { \
@@ -55,6 +55,8 @@ using namespace Dyninst;
using namespace ProcControlAPI;
+typedef std::vector<Breakpoint::ptr> BreakpointSet;
+BreakpointSet dyninst_bpset;
ProcessSet::ptr dyninst_procset;
Thread::const_ptr NULL_Thread = Thread::const_ptr();
@@ -146,7 +148,7 @@ public:
bool is_stopped (Event::const_ptr event)
{
- if (event == NULL || event == NULL_Event)
+ if (event == NULL)
return false;
else
return event->getEventType().code() == EventType::Stop;
@@ -154,7 +156,7 @@ public:
bool is_exit (Event::const_ptr event)
{
- if (event != NULL && event != NULL_Event)
+ if (event != NULL)
return event->getEventType().code() == EventType::Exit;
else return false;
}
@@ -162,7 +164,7 @@ public:
bool is_breakpoint(Event::const_ptr event)
{
- if (event != NULL && event != NULL_Event)
+ if (event != NULL)
return event->getEventType().code() == EventType::Breakpoint;
else return false;
}
@@ -170,25 +172,32 @@ public:
bool is_singlestep(Event::const_ptr event)
{
- if (event != NULL && event != NULL_Event)
+ if (event != NULL)
return event->getEventType().code() == EventType::SingleStep;
else return false;
}
bool is_signal (Event::const_ptr event)
{
- if (event != NULL && event != NULL_Event)
+ if (event != NULL)
return event->getEventType().code() == EventType::Signal;
else return false;
}
bool is_threadcreate (Event::const_ptr event)
{
- if (event != NULL && event != NULL_Event)
+ if (event != NULL)
return event->getEventType().code() == EventType::ThreadCreate;
else return false;
}
+ bool is_threaddestroy(Event::const_ptr event)
+ {
+ if (event != NULL)
+ return event->getEventType().code() == EventType::ThreadDestroy;
+ else return false;
+ }
+
void dump ()
{
std::vector<Event::const_ptr>::iterator it;
@@ -196,7 +205,7 @@ public:
it != current_events.end(); ++it)
{
Event::const_ptr event = *it;
- if (event == NULL_Event)
+ if (event == NULL)
continue;
DEBUG("dump",event->name(), pid_to_string (event));
}
@@ -206,7 +215,7 @@ public:
void
-pid_to_string (long pid, long lwp, long tid)
+pid_to_string (Dyninst::PID pid, Dyninst::LWP lwp, Dyninst::THR_ID tid)
{
if (pid == -1)
cerr << "pid=NULL";
@@ -234,7 +243,7 @@ void
pid_to_string (Thread::const_ptr thr)
{
long tid;
- if (thr == NULL_Thread)
+ if (thr == NULL)
return;
if (thr->haveUserThreadInfo())
tid = thr->getTID();
@@ -247,7 +256,7 @@ pid_to_string (Thread::const_ptr thr)
void
pid_to_string (Event::const_ptr ev)
{
- if (ev == events.NULL_Event)
+ if (ev == NULL)
return;
pid_to_string (ev->getThread());
}
@@ -274,6 +283,8 @@ struct thread_info_private
{
Thread::const_ptr thread;
Event::const_ptr event;
+ CORE_ADDR step_range_start;
+ CORE_ADDR step_range_end;
};
@@ -296,8 +307,8 @@ dyninst_add_process (int pid, int attached, Process::ptr process)
void
dyninst_add_thread(int pid, Thread::const_ptr thread)
{
- int lwp;
- if (thread != NULL_Thread)
+ Dyninst::LWP lwp;
+ if (thread != NULL)
{
struct thread_info_private *tip = new struct thread_info_private;
tip->thread = thread;
@@ -467,8 +478,11 @@ dyninst_resume (struct thread_resume *resume_info, size_t n)
if (ptid_equal (ptid, minus_one_ptid))
ptid = thread_to_gdb_id (current_thread);
- unsigned long pid = ptid_get_pid (ptid);
+ 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;
DEBUG("dyninst_resume", "", pid_to_string (ptid));
@@ -490,10 +504,16 @@ dyninst_resume (struct thread_resume *resume_info, size_t n)
}
// 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);
+ th->setSingleStepMode(true);
}
else
th->setSingleStepMode(false);
@@ -522,12 +542,27 @@ dyninst_continue (ptid_t ptid)
dyninst_resume (&resume_info, 1);
}
+
+/* True if LWP is stopped in its stepping range. */
+
+bool
+in_step_range ()
+{
+ struct thread_info_private *tip = (struct thread_info_private*)(current_thread->target_data);
+ struct regcache *regcache = get_thread_regcache (current_thread, 1);
+ CORE_ADDR pc = (*the_low_target.get_pc) (regcache);
+ DEBUG("in_step_range", "range " << tip->step_range_start << "/" << tip->step_range_end << " pc=" << pc << " returning" << (pc >= tip->step_range_start && pc < tip->step_range_end));
+
+ return (pc >= tip->step_range_start && pc < tip->step_range_end);
+}
+
+
/* Wait for a thread PTID having a target STATUS */
static ptid_t
dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
{
- int pid = 0;
+ Dyninst::PID pid = 0;
ptid_t new_ptid;
@@ -551,24 +586,24 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
while (true) // wait events loop
{
- if ((event = events.get(new_ptid)))
+ if ((event = events.get(new_ptid)))
{
struct process_info *pi;
pi = find_process_pid(pid);
if (pi)
pi->piprivate->last_wait_event_ptid = new_ptid;
}
- if (event == NULL || event == events.NULL_Event)
- event = events.get(new_ptid);
-// continue;
+ if (event == NULL)
+ event = events.get(new_ptid);
- events.dump();
+ events.dump();
if (events.is_threadcreate(event))
{
Thread::const_ptr thr;
- if (event != events.NULL_Event)
+// if (event != events.NULL_Event)
+ if (event != NULL)
thr = event->getThread();
else
thr = NULL_Thread;
@@ -577,61 +612,59 @@ dyninst_wait_1 (ptid_t ptid, struct target_waitstatus *status, int options)
}
else if (events.is_exit(event))
{
- status->kind = TARGET_WAITKIND_EXITED;
EventExit::const_ptr exit_ev = event->getEventExit();
+ status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = exit_ev->getExitCode();
- DEBUG("dyninst_wait_1", "process exited with code: " << status->value.integer);
+ DEBUG("dyninst_wait_1", "process exited with status: " << status->value.integer);
}
- else if (events.is_stopped(event) || events.is_breakpoint(event) || events.is_singlestep(event))
+ else if (events.is_breakpoint(event) || events.is_singlestep(event))
{
+ EventBreakpoint::const_ptr breakpoint_ev = event->getEventBreakpoint();
+ if (breakpoint_ev)
+ {
+ 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("dyninst_wait_1", "breakpoint " << bp->getToAddress());
+ }
+ }
events.erase(event);
status->kind = TARGET_WAITKIND_STOPPED;
// EventStop doesn't have a signal member
- status->value.integer = gdb_signal_from_host (SIGSTOP);
- DEBUG("dyninst_wait_1", "process stopped with signal: " << status->value.integer);
+ status->value.integer = gdb_signal_from_host (SIGTRAP);
+ DEBUG("dyninst_wait_1", "process trapped: ");
}
else if (events.is_signal(event))
{
status->kind = TARGET_WAITKIND_SIGNALLED;
EventSignal::const_ptr signal_ev = event->getEventSignal();
+ DEBUG("dyninst_wait_1", signal_ev->name());
status->value.integer = signal_ev->getSignal();
- DEBUG("dyninst_wait_1", "process terminated with code: " << status->value.integer);
+ DEBUG("dyninst_wait_1", "process signalled with signal: " << status->value.integer);
+ }
+ else if (events.is_threadcreate(event))
+ {
+ dyninst_continue (new_ptid);
+ continue; // wait events loop
+ }
+ else if (events.is_threaddestroy(event))
+ {
+ remove_thread (find_thread_ptid (new_ptid));
+ dyninst_continue (new_ptid);
+ continue; // wait events loop
}
else
{
status->kind = TARGET_WAITKIND_STOPPED;
status->value.integer = gdb_signal_from_host (0);
- }
-
- /* SIGTRAP events are generated for situations other than single-step/
- breakpoint events (Eg. new-thread events). Handle those other types
- of events, and resume the execution if necessary. */
- if (status->kind == TARGET_WAITKIND_STOPPED
- && status->value.integer == GDB_SIGNAL_TRAP)
- {
- EventSignal::const_ptr signal_ev = event->getEventSignal();
-// int realsig = signal_ev->getSignal();
-
- switch (signal_ev->getEventType().code())
- {
- case EventType::ThreadCreate:
- /* We just added the new thread above. No need to do anything
- further. Just resume the execution again. */
- dyninst_continue (new_ptid);
- dyninst_process->continueProc();
- Process::handleEvents(true);
- continue; // wait events loop
-
- case EventType::ThreadDestroy:
- remove_thread (find_thread_ptid (new_ptid));
- dyninst_continue (new_ptid);
- dyninst_process->continueProc();
- Process::handleEvents(true);
- continue; // wait events loop
- }
+// DEBUG("dyninst_wait_1", "process received: " << (event != events.NULL_Event ? event->name() : ""));
+ DEBUG("dyninst_wait_1", "process received: " << (event != NULL ? event->name() : ""));
}
break;
- }
+ }
DEBUG("dyninst_wait_1 returning", "", pid_to_string (ptid));
return new_ptid;
@@ -655,10 +688,8 @@ dyninst_wait (ptid_t ptid, struct target_waitstatus *status, int options)
/* Kill a PID */
static int
-dyninst_kill (int pid)
+dyninst_kill (Dyninst::PID pid)
{
- // ptid_t ptid = ptid_build (pid, 0, 0);
- // struct target_waitstatus status;
struct process_info *process;
ProcessSet::iterator procset_it = dyninst_procset->find(pid);
Process::ptr dyninst_process = *procset_it;
@@ -677,7 +708,7 @@ dyninst_kill (int pid)
/* Detach a PID */
static int
-dyninst_detach (int pid)
+dyninst_detach (Dyninst::PID pid)
{
struct process_info *process;
ProcessSet::iterator procset_it = dyninst_procset->find(pid);
@@ -698,16 +729,14 @@ dyninst_detach (int pid)
static void
dyninst_mourn (struct process_info *proc)
{
- /* Free our private data. */
DEBUG("dyninst_mourn", "proc=" << proc);
- free (proc->piprivate);
proc->piprivate = NULL;
clear_inferiors ();
}
static void
-dyninst_join (int pid)
+dyninst_join (Dyninst::PID pid)
{
}
@@ -834,7 +863,7 @@ dyninst_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
static void
dyninst_request_interrupt (void)
{
- int pid = ptid_get_pid (thread_to_gdb_id (current_thread));
+ Dyninst::PID pid = ptid_get_pid (thread_to_gdb_id (current_thread));
ProcessSet::iterator procset_it = dyninst_procset->find(pid);
Process::ptr dyninst_process = *procset_it;
@@ -871,7 +900,9 @@ dyninst_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
DEBUG("dyninst_insert_point", " addr=" << addr, pid_to_string(th));
Breakpoint::ptr brp = Breakpoint::newBreakpoint();
+ brp->setData(bp);
bool result = dyninst_process->addBreakpoint(addr, brp);
+ dyninst_bpset.push_back(brp);
return result == false;
}
@@ -879,17 +910,39 @@ dyninst_insert_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
static int
dyninst_remove_point (enum raw_bkpt_type type, CORE_ADDR addr, int len,
- struct raw_breakpoint *bp)
+ struct raw_breakpoint *rbp)
{
Thread::const_ptr th = dyninst_get_inferior_thread();
DEBUG("dyninst_remove_point", " addr=" << addr, pid_to_string (th) );
Process::const_ptr dyninst_process = th->getProcess();
- Breakpoint::ptr brp = Breakpoint::newBreakpoint();
- bool result = dyninst_process->addBreakpoint(addr, brp);
+ std::vector<Breakpoint::ptr>::iterator it;
+ bool result;
+ for (it = dyninst_bpset.begin(); it != dyninst_bpset.end(); it++)
+ {
+ Breakpoint::ptr bp = *it;
+ if ((struct raw_breakpoint*)bp->getData() == rbp)
+ {
+ result = dyninst_process->rmBreakpoint(addr, bp);
+ break;
+ }
+ }
+ dyninst_bpset.erase(it);
+
return result == false;
}
+
+static int
+dyninst_supports_range_stepping (void)
+{
+ if (*the_low_target.supports_range_stepping == NULL)
+ return 0;
+
+ return (*the_low_target.supports_range_stepping) ();
+}
+
+
/* The Dyninst target_ops vector. */
static struct target_ops dyninst_target_ops = {
@@ -914,20 +967,20 @@ static struct target_ops dyninst_target_ops = {
dyninst_supports_z_point_type,
dyninst_insert_point, /* insert_point */
dyninst_remove_point, /* remove_point */
- NULL, /* stopped_by_watchpoint */
- NULL, /* stopped_data_address */
- NULL, /* read_offsets */
- NULL, /* get_tls_address */
- NULL, /* qxfer_spu */
- NULL, /* hostio_last_error */
- NULL, /* qxfer_osdata */
- NULL, /* qxfer_siginfo */
- NULL, /* supports_non_stop */
- NULL, /* async */
- NULL, /* start_non_stop */
- NULL, /* supports_multi_process */
- NULL, /* handle_monitor_command */
- NULL, /* common_core_of_thread */
+ NULL, // stopped_by_watchpoint
+ NULL, // stopped_data_address
+ NULL, // read_offsets
+ NULL, // get_tls_address
+ NULL, // qxfer_spu
+ NULL, // hostio_last_error
+ NULL, // qxfer_osdata
+ NULL, // qxfer_siginfo
+ NULL, // supports_non_stop
+ NULL, // async
+ NULL, // start_non_stop
+ NULL, // supports_multi_process
+ NULL, // handle_monitor_command
+ NULL, // common_core_of_thread
NULL, // read_loadmap
NULL, // process_qsupported
NULL, // supports_tracepoints
@@ -949,7 +1002,7 @@ static struct target_ops dyninst_target_ops = {
NULL,
NULL,
NULL,
- NULL // supports_range_stepping
+ dyninst_supports_range_stepping
};
void
diff --git a/gdb/gdbserver/dyninst-low.h b/gdb/gdbserver/dyninst-low.h
index f07beee..aab96f2 100644
--- a/gdb/gdbserver/dyninst-low.h
+++ b/gdb/gdbserver/dyninst-low.h
@@ -57,6 +57,7 @@ struct dyninst_target_ops
void (*arch_setup) (void);
CORE_ADDR (*get_pc) (struct regcache *regcache);
hooks/post-receive
--
Repository for Project Archer.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2014-11-12 15:08 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-12 15:08 [SCM] scox/dyninst: Add range step handling 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).