Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: src/trusted/gdb_rsp/target.cc

Issue 10441152: Debug stub: suspend/resume threads on Linux Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/trusted/gdb_rsp/target.h ('k') | src/trusted/gdb_rsp/test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 #include <string.h> 7 #include <string.h>
8 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <stdio.h> 9 #include <stdio.h>
10 10
(...skipping 23 matching lines...) Expand all
34 namespace gdb_rsp { 34 namespace gdb_rsp {
35 35
36 36
37 Target::Target(const Abi* abi) 37 Target::Target(const Abi* abi)
38 : abi_(abi), 38 : abi_(abi),
39 mutex_(NULL), 39 mutex_(NULL),
40 sig_start_(NULL), 40 sig_start_(NULL),
41 sig_done_(NULL), 41 sig_done_(NULL),
42 session_(NULL), 42 session_(NULL),
43 ctx_(NULL), 43 ctx_(NULL),
44 stepping_over_breakpoint_(false),
44 cur_signal_(-1), 45 cur_signal_(-1),
45 sig_thread_(0), 46 sig_thread_(0),
46 run_thread_(-1), 47 run_thread_(-1),
47 reg_thread_(-1), 48 reg_thread_(-1),
48 mem_base_(0) { 49 mem_base_(0) {
49 if (NULL == abi_) abi_ = Abi::Get(); 50 if (NULL == abi_) abi_ = Abi::Get();
50 } 51 }
51 52
52 Target::~Target() { 53 Target::~Target() {
53 Destroy(); 54 Destroy();
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 176
176 return true; 177 return true;
177 } 178 }
178 179
179 180
180 181
181 void Target::Signal(uint32_t id, int8_t sig, bool wait) { 182 void Target::Signal(uint32_t id, int8_t sig, bool wait) {
182 // Wait for this signal's turn in the signal Q. 183 // Wait for this signal's turn in the signal Q.
183 sig_start_->Wait(); 184 sig_start_->Wait();
184 { 185 {
185 // Now lock the target, sleeping all active threads 186 // Now lock the target
186 MutexLock lock(mutex_); 187 MutexLock lock(mutex_);
187 188
188 // Suspend all threads except this one
189 uint32_t curId;
190 bool more = GetFirstThreadId(&curId);
191 while (more) {
192 if (curId != id) {
193 IThread *thread = threads_[curId];
194 thread->Suspend();
195 }
196 more = GetNextThreadId(&curId);
197 }
198
199 // Signal the stub (Run thread) that we are ready to process 189 // Signal the stub (Run thread) that we are ready to process
200 // a trap, by updating the signal information and releasing 190 // a trap, by updating the signal information and releasing
201 // the lock. 191 // the lock.
202 cur_signal_ = sig; 192 cur_signal_ = sig;
203 sig_thread_ = id; 193 sig_thread_ = id;
204 reg_thread_ = id; 194 reg_thread_ = id;
205 run_thread_ = id; 195 run_thread_ = id;
206 } 196 }
207 197
208 // Wait for permission to continue 198 // Wait for permission to continue
(...skipping 18 matching lines...) Expand all
227 217
228 // If no signal is waiting for this iteration... 218 // If no signal is waiting for this iteration...
229 if (-1 == cur_signal_) { 219 if (-1 == cur_signal_) {
230 // but the debugger is talking to us then force a break 220 // but the debugger is talking to us then force a break
231 if (ses->DataAvailable()) { 221 if (ses->DataAvailable()) {
232 // set signal to 0 to signify paused 222 // set signal to 0 to signify paused
233 cur_signal_ = 0; 223 cur_signal_ = 0;
234 sig_thread_ = 0; 224 sig_thread_ = 0;
235 225
236 // put all the threads to sleep. 226 // put all the threads to sleep.
237 uint32_t curId; 227 IThread::SuspendAll(0);
238 bool more = GetFirstThreadId(&curId);
239 while (more) {
240 if (curId != id) {
241 IThread *thread = threads_[curId];
242 thread->Suspend();
243 }
244 more = GetNextThreadId(&curId);
245 }
246 } else { 228 } else {
247 // otherwise, nothing to do so try again. 229 // otherwise, nothing to do so try again.
248 continue; 230 continue;
249 } 231 }
250 } else { 232 } else {
251 // otherwise there really is an exception so get the id of the thread 233 // otherwise there really is an exception so get the id of the thread
252 id = GetRegThreadId(); 234 id = sig_thread_;
235
236 // Suspend all threads, unless we just did a step over breakpoint without
237 // resuming threads.
238 if (!stepping_over_breakpoint_) {
239 IThread::SuspendAll(id);
240 }
241 stepping_over_breakpoint_ = false;
253 242
254 // Reset single stepping. 243 // Reset single stepping.
255 IThread *thread = threads_[id]; 244 IThread *thread = threads_[id];
256 thread->SetStep(false); 245 thread->SetStep(false);
257 246
258 RemoveTemporaryBreakpoints(thread); 247 RemoveTemporaryBreakpoints(thread);
259 } 248 }
260 249
261 // Next update the current thread info 250 // Next update the current thread info
262 char tmp[16]; 251 char tmp[16];
(...skipping 19 matching lines...) Expand all
282 if (ProcessPacket(&recv, &reply)) { 271 if (ProcessPacket(&recv, &reply)) {
283 // If this is a continue command, break out of this loop 272 // If this is a continue command, break out of this loop
284 break; 273 break;
285 } else { 274 } else {
286 // Othwerise send the reponse 275 // Othwerise send the reponse
287 ses->SendPacket(&reply); 276 ses->SendPacket(&reply);
288 } 277 }
289 } 278 }
290 } while (ses->Connected()); 279 } while (ses->Connected());
291 280
292 281 // Resume all threads, unless we need to single step signaled thread over
293 // Now that we are done, we want to continue in the "correct order". 282 // breakpoint.
294 // This means letting the active thread go first, in case we are single 283 if (!stepping_over_breakpoint_) {
295 // stepping and want to catch it again. This is a desired behavior but 284 IThread::ResumeAll(id);
296 // it is not guaranteed since another thread may already be in an
297 // exception state and next in line to notify the target.
298
299 // If the run thread is not the exception thread, wake it up now.
300 uint32_t run_thread = GetRunThreadId();
301 if (run_thread != id
302 && run_thread != static_cast<uint32_t>(-1)) {
303 IThread* thread = threads_[run_thread];
304 thread->Resume();
305 }
306
307 // Now wake up everyone else
308 uint32_t curId;
309 bool more = GetFirstThreadId(&curId);
310 while (more) {
311 if ((curId != id) && (curId != GetRunThreadId())) {
312 IThread *thread = threads_[curId];
313 thread->Resume();
314 }
315 more = GetNextThreadId(&curId);
316 } 285 }
317 286
318 // Reset the signal value 287 // Reset the signal value
319 cur_signal_ = -1; 288 cur_signal_ = -1;
320 289
321 // If there is no signaled thread, then we were interrupted by GDB, and 290 // If there is no signaled thread, then we were interrupted by GDB, and
322 // there is no signal handler waiting. 291 // there is no signal handler waiting.
323 // If there was a signaled thread, let the signal handler resume. 292 // If there was a signaled thread, let the signal handler resume.
324 if (id != 0) { 293 if (id != 0) {
325 sig_done_->Signal(); 294 sig_done_->Signal();
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
656 } 625 }
657 626
658 ThreadMap_t::iterator it = threads_.find(thread_id); 627 ThreadMap_t::iterator it = threads_.find(thread_id);
659 if (it == threads_.end()) { 628 if (it == threads_.end()) {
660 err = BAD_ARGS; 629 err = BAD_ARGS;
661 break; 630 break;
662 } 631 }
663 632
664 it->second->SetStep(true); 633 it->second->SetStep(true);
665 run_thread_ = thread_id; 634 run_thread_ = thread_id;
635 // TODO: check thread_id is signaled thread id!
636 // This is the only case we allow one thread to single step while
637 // others remain stopped.
638 stepping_over_breakpoint_ = true;
666 return true; 639 return true;
667 } 640 }
668 641
669 // Unsupported form of vCont. 642 // Unsupported form of vCont.
670 err = BAD_FORMAT; 643 err = BAD_FORMAT;
671 break; 644 break;
672 } 645 }
673 646
674 NaClLog(LOG_ERROR, "Unknown command: %s\n", pktIn->GetPayload()); 647 NaClLog(LOG_ERROR, "Unknown command: %s\n", pktIn->GetPayload());
675 return false; 648 return false;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 731
759 return NULL; 732 return NULL;
760 } 733 }
761 734
762 735
763 } // namespace gdb_rsp 736 } // namespace gdb_rsp
764 737
765 738
766 739
767 740
OLDNEW
« no previous file with comments | « src/trusted/gdb_rsp/target.h ('k') | src/trusted/gdb_rsp/test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698