| Index: src/trusted/gdb_rsp/target.cc
|
| diff --git a/src/trusted/gdb_rsp/target.cc b/src/trusted/gdb_rsp/target.cc
|
| index 2aa5d5ef018882dcbb0bbe7a3a5d615a5c05f08b..a6e702f85d3f83bb6f1faca6a1bf08ba4a70fc61 100644
|
| --- a/src/trusted/gdb_rsp/target.cc
|
| +++ b/src/trusted/gdb_rsp/target.cc
|
| @@ -41,6 +41,7 @@ Target::Target(const Abi* abi)
|
| sig_done_(NULL),
|
| session_(NULL),
|
| ctx_(NULL),
|
| + stepping_over_breakpoint_(false),
|
| cur_signal_(-1),
|
| sig_thread_(0),
|
| run_thread_(-1),
|
| @@ -182,20 +183,9 @@ void Target::Signal(uint32_t id, int8_t sig, bool wait) {
|
| // Wait for this signal's turn in the signal Q.
|
| sig_start_->Wait();
|
| {
|
| - // Now lock the target, sleeping all active threads
|
| + // Now lock the target
|
| MutexLock lock(mutex_);
|
|
|
| - // Suspend all threads except this one
|
| - uint32_t curId;
|
| - bool more = GetFirstThreadId(&curId);
|
| - while (more) {
|
| - if (curId != id) {
|
| - IThread *thread = threads_[curId];
|
| - thread->Suspend();
|
| - }
|
| - more = GetNextThreadId(&curId);
|
| - }
|
| -
|
| // Signal the stub (Run thread) that we are ready to process
|
| // a trap, by updating the signal information and releasing
|
| // the lock.
|
| @@ -234,22 +224,21 @@ void Target::Run(Session *ses) {
|
| sig_thread_ = 0;
|
|
|
| // put all the threads to sleep.
|
| - uint32_t curId;
|
| - bool more = GetFirstThreadId(&curId);
|
| - while (more) {
|
| - if (curId != id) {
|
| - IThread *thread = threads_[curId];
|
| - thread->Suspend();
|
| - }
|
| - more = GetNextThreadId(&curId);
|
| - }
|
| + IThread::SuspendAll(0);
|
| } else {
|
| // otherwise, nothing to do so try again.
|
| continue;
|
| }
|
| } else {
|
| // otherwise there really is an exception so get the id of the thread
|
| - id = GetRegThreadId();
|
| + id = sig_thread_;
|
| +
|
| + // Suspend all threads, unless we just did a step over breakpoint without
|
| + // resuming threads.
|
| + if (!stepping_over_breakpoint_) {
|
| + IThread::SuspendAll(id);
|
| + }
|
| + stepping_over_breakpoint_ = false;
|
|
|
| // Reset single stepping.
|
| IThread *thread = threads_[id];
|
| @@ -289,30 +278,10 @@ void Target::Run(Session *ses) {
|
| }
|
| } while (ses->Connected());
|
|
|
| -
|
| - // Now that we are done, we want to continue in the "correct order".
|
| - // This means letting the active thread go first, in case we are single
|
| - // stepping and want to catch it again. This is a desired behavior but
|
| - // it is not guaranteed since another thread may already be in an
|
| - // exception state and next in line to notify the target.
|
| -
|
| - // If the run thread is not the exception thread, wake it up now.
|
| - uint32_t run_thread = GetRunThreadId();
|
| - if (run_thread != id
|
| - && run_thread != static_cast<uint32_t>(-1)) {
|
| - IThread* thread = threads_[run_thread];
|
| - thread->Resume();
|
| - }
|
| -
|
| - // Now wake up everyone else
|
| - uint32_t curId;
|
| - bool more = GetFirstThreadId(&curId);
|
| - while (more) {
|
| - if ((curId != id) && (curId != GetRunThreadId())) {
|
| - IThread *thread = threads_[curId];
|
| - thread->Resume();
|
| - }
|
| - more = GetNextThreadId(&curId);
|
| + // Resume all threads, unless we need to single step signaled thread over
|
| + // breakpoint.
|
| + if (!stepping_over_breakpoint_) {
|
| + IThread::ResumeAll(id);
|
| }
|
|
|
| // Reset the signal value
|
| @@ -663,6 +632,10 @@ bool Target::ProcessPacket(Packet* pktIn, Packet* pktOut) {
|
|
|
| it->second->SetStep(true);
|
| run_thread_ = thread_id;
|
| + // TODO: check thread_id is signaled thread id!
|
| + // This is the only case we allow one thread to single step while
|
| + // others remain stopped.
|
| + stepping_over_breakpoint_ = true;
|
| return true;
|
| }
|
|
|
|
|