1 //===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "lldb/API/SBThread.h"
11
12 #include "lldb/API/SBFileSpec.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBSymbolContext.h"
15 #include "lldb/Breakpoint/BreakpointLocation.h"
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/StreamFile.h"
18 #include "lldb/Core/ValueObject.h"
19 #include "lldb/Interpreter/CommandInterpreter.h"
20 #include "lldb/Symbol/CompileUnit.h"
21 #include "lldb/Symbol/SymbolContext.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/Queue.h"
24 #include "lldb/Target/StopInfo.h"
25 #include "lldb/Target/SystemRuntime.h"
26 #include "lldb/Target/Target.h"
27 #include "lldb/Target/Thread.h"
28 #include "lldb/Target/ThreadPlan.h"
29 #include "lldb/Target/ThreadPlanStepInRange.h"
30 #include "lldb/Target/ThreadPlanStepInstruction.h"
31 #include "lldb/Target/ThreadPlanStepOut.h"
32 #include "lldb/Target/ThreadPlanStepRange.h"
33 #include "lldb/Target/UnixSignals.h"
34 #include "lldb/Utility/State.h"
35 #include "lldb/Utility/Stream.h"
36 #include "lldb/Utility/StructuredData.h"
37
38 #include "lldb/API/SBAddress.h"
39 #include "lldb/API/SBDebugger.h"
40 #include "lldb/API/SBEvent.h"
41 #include "lldb/API/SBFrame.h"
42 #include "lldb/API/SBProcess.h"
43 #include "lldb/API/SBThreadCollection.h"
44 #include "lldb/API/SBThreadPlan.h"
45 #include "lldb/API/SBValue.h"
46 #include "lldb/lldb-enumerations.h"
47
48 using namespace lldb;
49 using namespace lldb_private;
50
GetBroadcasterClassName()51 const char *SBThread::GetBroadcasterClassName() {
52 return Thread::GetStaticBroadcasterClass().AsCString();
53 }
54
55 //----------------------------------------------------------------------
56 // Constructors
57 //----------------------------------------------------------------------
SBThread()58 SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
59
SBThread(const ThreadSP & lldb_object_sp)60 SBThread::SBThread(const ThreadSP &lldb_object_sp)
61 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
62
SBThread(const SBThread & rhs)63 SBThread::SBThread(const SBThread &rhs)
64 : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
65
66 //----------------------------------------------------------------------
67 // Assignment operator
68 //----------------------------------------------------------------------
69
operator =(const SBThread & rhs)70 const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
71 if (this != &rhs)
72 *m_opaque_sp = *rhs.m_opaque_sp;
73 return *this;
74 }
75
76 //----------------------------------------------------------------------
77 // Destructor
78 //----------------------------------------------------------------------
~SBThread()79 SBThread::~SBThread() {}
80
GetQueue() const81 lldb::SBQueue SBThread::GetQueue() const {
82 SBQueue sb_queue;
83 QueueSP queue_sp;
84 std::unique_lock<std::recursive_mutex> lock;
85 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
86
87 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
88 if (exe_ctx.HasThreadScope()) {
89 Process::StopLocker stop_locker;
90 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
91 queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
92 if (queue_sp) {
93 sb_queue.SetQueue(queue_sp);
94 }
95 } else {
96 if (log)
97 log->Printf("SBThread(%p)::GetQueue() => error: process is running",
98 static_cast<void *>(exe_ctx.GetThreadPtr()));
99 }
100 }
101
102 if (log)
103 log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
104 static_cast<void *>(exe_ctx.GetThreadPtr()),
105 static_cast<void *>(queue_sp.get()));
106
107 return sb_queue;
108 }
109
IsValid() const110 bool SBThread::IsValid() const {
111 std::unique_lock<std::recursive_mutex> lock;
112 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
113
114 Target *target = exe_ctx.GetTargetPtr();
115 Process *process = exe_ctx.GetProcessPtr();
116 if (target && process) {
117 Process::StopLocker stop_locker;
118 if (stop_locker.TryLock(&process->GetRunLock()))
119 return m_opaque_sp->GetThreadSP().get() != NULL;
120 }
121 // Without a valid target & process, this thread can't be valid.
122 return false;
123 }
124
Clear()125 void SBThread::Clear() { m_opaque_sp->Clear(); }
126
GetStopReason()127 StopReason SBThread::GetStopReason() {
128 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
129
130 StopReason reason = eStopReasonInvalid;
131 std::unique_lock<std::recursive_mutex> lock;
132 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
133
134 if (exe_ctx.HasThreadScope()) {
135 Process::StopLocker stop_locker;
136 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
137 return exe_ctx.GetThreadPtr()->GetStopReason();
138 } else {
139 if (log)
140 log->Printf(
141 "SBThread(%p)::GetStopReason() => error: process is running",
142 static_cast<void *>(exe_ctx.GetThreadPtr()));
143 }
144 }
145
146 if (log)
147 log->Printf("SBThread(%p)::GetStopReason () => %s",
148 static_cast<void *>(exe_ctx.GetThreadPtr()),
149 Thread::StopReasonAsCString(reason));
150
151 return reason;
152 }
153
GetStopReasonDataCount()154 size_t SBThread::GetStopReasonDataCount() {
155 std::unique_lock<std::recursive_mutex> lock;
156 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
157
158 if (exe_ctx.HasThreadScope()) {
159 Process::StopLocker stop_locker;
160 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
161 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
162 if (stop_info_sp) {
163 StopReason reason = stop_info_sp->GetStopReason();
164 switch (reason) {
165 case eStopReasonInvalid:
166 case eStopReasonNone:
167 case eStopReasonTrace:
168 case eStopReasonExec:
169 case eStopReasonPlanComplete:
170 case eStopReasonThreadExiting:
171 case eStopReasonInstrumentation:
172 // There is no data for these stop reasons.
173 return 0;
174
175 case eStopReasonBreakpoint: {
176 break_id_t site_id = stop_info_sp->GetValue();
177 lldb::BreakpointSiteSP bp_site_sp(
178 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
179 site_id));
180 if (bp_site_sp)
181 return bp_site_sp->GetNumberOfOwners() * 2;
182 else
183 return 0; // Breakpoint must have cleared itself...
184 } break;
185
186 case eStopReasonWatchpoint:
187 return 1;
188
189 case eStopReasonSignal:
190 return 1;
191
192 case eStopReasonException:
193 return 1;
194 }
195 }
196 } else {
197 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
198 if (log)
199 log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
200 "is running",
201 static_cast<void *>(exe_ctx.GetThreadPtr()));
202 }
203 }
204 return 0;
205 }
206
GetStopReasonDataAtIndex(uint32_t idx)207 uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
208 std::unique_lock<std::recursive_mutex> lock;
209 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
210
211 if (exe_ctx.HasThreadScope()) {
212 Process::StopLocker stop_locker;
213 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
214 Thread *thread = exe_ctx.GetThreadPtr();
215 StopInfoSP stop_info_sp = thread->GetStopInfo();
216 if (stop_info_sp) {
217 StopReason reason = stop_info_sp->GetStopReason();
218 switch (reason) {
219 case eStopReasonInvalid:
220 case eStopReasonNone:
221 case eStopReasonTrace:
222 case eStopReasonExec:
223 case eStopReasonPlanComplete:
224 case eStopReasonThreadExiting:
225 case eStopReasonInstrumentation:
226 // There is no data for these stop reasons.
227 return 0;
228
229 case eStopReasonBreakpoint: {
230 break_id_t site_id = stop_info_sp->GetValue();
231 lldb::BreakpointSiteSP bp_site_sp(
232 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
233 site_id));
234 if (bp_site_sp) {
235 uint32_t bp_index = idx / 2;
236 BreakpointLocationSP bp_loc_sp(
237 bp_site_sp->GetOwnerAtIndex(bp_index));
238 if (bp_loc_sp) {
239 if (idx & 1) {
240 // Odd idx, return the breakpoint location ID
241 return bp_loc_sp->GetID();
242 } else {
243 // Even idx, return the breakpoint ID
244 return bp_loc_sp->GetBreakpoint().GetID();
245 }
246 }
247 }
248 return LLDB_INVALID_BREAK_ID;
249 } break;
250
251 case eStopReasonWatchpoint:
252 return stop_info_sp->GetValue();
253
254 case eStopReasonSignal:
255 return stop_info_sp->GetValue();
256
257 case eStopReasonException:
258 return stop_info_sp->GetValue();
259 }
260 }
261 } else {
262 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
263 if (log)
264 log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
265 "process is running",
266 static_cast<void *>(exe_ctx.GetThreadPtr()));
267 }
268 }
269 return 0;
270 }
271
GetStopReasonExtendedInfoAsJSON(lldb::SBStream & stream)272 bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
273 Stream &strm = stream.ref();
274
275 std::unique_lock<std::recursive_mutex> lock;
276 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
277
278 if (!exe_ctx.HasThreadScope())
279 return false;
280
281 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
282 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
283 if (!info)
284 return false;
285
286 info->Dump(strm);
287
288 return true;
289 }
290
291 SBThreadCollection
GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type)292 SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
293 ThreadCollectionSP threads;
294 threads.reset(new ThreadCollection());
295
296 std::unique_lock<std::recursive_mutex> lock;
297 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
298
299 if (!exe_ctx.HasThreadScope())
300 return threads;
301
302 ProcessSP process_sp = exe_ctx.GetProcessSP();
303
304 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
305 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
306 if (!info)
307 return threads;
308
309 return process_sp->GetInstrumentationRuntime(type)
310 ->GetBacktracesFromExtendedStopInfo(info);
311 }
312
GetStopDescription(char * dst,size_t dst_len)313 size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
314 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
315
316 std::unique_lock<std::recursive_mutex> lock;
317 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
318
319 if (exe_ctx.HasThreadScope()) {
320 Process::StopLocker stop_locker;
321 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
322
323 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
324 if (stop_info_sp) {
325 const char *stop_desc = stop_info_sp->GetDescription();
326 if (stop_desc) {
327 if (log)
328 log->Printf(
329 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
330 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
331 if (dst)
332 return ::snprintf(dst, dst_len, "%s", stop_desc);
333 else {
334 // NULL dst passed in, return the length needed to contain the
335 // description
336 return ::strlen(stop_desc) + 1; // Include the NULL byte for size
337 }
338 } else {
339 size_t stop_desc_len = 0;
340 switch (stop_info_sp->GetStopReason()) {
341 case eStopReasonTrace:
342 case eStopReasonPlanComplete: {
343 static char trace_desc[] = "step";
344 stop_desc = trace_desc;
345 stop_desc_len =
346 sizeof(trace_desc); // Include the NULL byte for size
347 } break;
348
349 case eStopReasonBreakpoint: {
350 static char bp_desc[] = "breakpoint hit";
351 stop_desc = bp_desc;
352 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
353 } break;
354
355 case eStopReasonWatchpoint: {
356 static char wp_desc[] = "watchpoint hit";
357 stop_desc = wp_desc;
358 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
359 } break;
360
361 case eStopReasonSignal: {
362 stop_desc =
363 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
364 stop_info_sp->GetValue());
365 if (stop_desc == NULL || stop_desc[0] == '\0') {
366 static char signal_desc[] = "signal";
367 stop_desc = signal_desc;
368 stop_desc_len =
369 sizeof(signal_desc); // Include the NULL byte for size
370 }
371 } break;
372
373 case eStopReasonException: {
374 char exc_desc[] = "exception";
375 stop_desc = exc_desc;
376 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
377 } break;
378
379 case eStopReasonExec: {
380 char exc_desc[] = "exec";
381 stop_desc = exc_desc;
382 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
383 } break;
384
385 case eStopReasonThreadExiting: {
386 char limbo_desc[] = "thread exiting";
387 stop_desc = limbo_desc;
388 stop_desc_len = sizeof(limbo_desc);
389 } break;
390 default:
391 break;
392 }
393
394 if (stop_desc && stop_desc[0]) {
395 if (log)
396 log->Printf(
397 "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
398 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
399
400 if (dst)
401 return ::snprintf(dst, dst_len, "%s", stop_desc) +
402 1; // Include the NULL byte
403
404 if (stop_desc_len == 0)
405 stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
406
407 return stop_desc_len;
408 }
409 }
410 }
411 } else {
412 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
413 if (log)
414 log->Printf(
415 "SBThread(%p)::GetStopDescription() => error: process is running",
416 static_cast<void *>(exe_ctx.GetThreadPtr()));
417 }
418 }
419 if (dst)
420 *dst = 0;
421 return 0;
422 }
423
GetStopReturnValue()424 SBValue SBThread::GetStopReturnValue() {
425 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
426 ValueObjectSP return_valobj_sp;
427 std::unique_lock<std::recursive_mutex> lock;
428 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
429
430 if (exe_ctx.HasThreadScope()) {
431 Process::StopLocker stop_locker;
432 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
433 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
434 if (stop_info_sp) {
435 return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
436 }
437 } else {
438 if (log)
439 log->Printf(
440 "SBThread(%p)::GetStopReturnValue() => error: process is running",
441 static_cast<void *>(exe_ctx.GetThreadPtr()));
442 }
443 }
444
445 if (log)
446 log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
447 static_cast<void *>(exe_ctx.GetThreadPtr()),
448 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
449 : "<no return value>");
450
451 return SBValue(return_valobj_sp);
452 }
453
SetThread(const ThreadSP & lldb_object_sp)454 void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
455 m_opaque_sp->SetThreadSP(lldb_object_sp);
456 }
457
GetThreadID() const458 lldb::tid_t SBThread::GetThreadID() const {
459 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
460 if (thread_sp)
461 return thread_sp->GetID();
462 return LLDB_INVALID_THREAD_ID;
463 }
464
GetIndexID() const465 uint32_t SBThread::GetIndexID() const {
466 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
467 if (thread_sp)
468 return thread_sp->GetIndexID();
469 return LLDB_INVALID_INDEX32;
470 }
471
GetName() const472 const char *SBThread::GetName() const {
473 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
474 const char *name = NULL;
475 std::unique_lock<std::recursive_mutex> lock;
476 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
477
478 if (exe_ctx.HasThreadScope()) {
479 Process::StopLocker stop_locker;
480 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
481 name = exe_ctx.GetThreadPtr()->GetName();
482 } else {
483 if (log)
484 log->Printf("SBThread(%p)::GetName() => error: process is running",
485 static_cast<void *>(exe_ctx.GetThreadPtr()));
486 }
487 }
488
489 if (log)
490 log->Printf("SBThread(%p)::GetName () => %s",
491 static_cast<void *>(exe_ctx.GetThreadPtr()),
492 name ? name : "NULL");
493
494 return name;
495 }
496
GetQueueName() const497 const char *SBThread::GetQueueName() const {
498 const char *name = NULL;
499 std::unique_lock<std::recursive_mutex> lock;
500 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
501
502 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
503 if (exe_ctx.HasThreadScope()) {
504 Process::StopLocker stop_locker;
505 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
506 name = exe_ctx.GetThreadPtr()->GetQueueName();
507 } else {
508 if (log)
509 log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
510 static_cast<void *>(exe_ctx.GetThreadPtr()));
511 }
512 }
513
514 if (log)
515 log->Printf("SBThread(%p)::GetQueueName () => %s",
516 static_cast<void *>(exe_ctx.GetThreadPtr()),
517 name ? name : "NULL");
518
519 return name;
520 }
521
GetQueueID() const522 lldb::queue_id_t SBThread::GetQueueID() const {
523 queue_id_t id = LLDB_INVALID_QUEUE_ID;
524 std::unique_lock<std::recursive_mutex> lock;
525 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
526
527 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
528 if (exe_ctx.HasThreadScope()) {
529 Process::StopLocker stop_locker;
530 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
531 id = exe_ctx.GetThreadPtr()->GetQueueID();
532 } else {
533 if (log)
534 log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
535 static_cast<void *>(exe_ctx.GetThreadPtr()));
536 }
537 }
538
539 if (log)
540 log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
541 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
542
543 return id;
544 }
545
GetInfoItemByPathAsString(const char * path,SBStream & strm)546 bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
547 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
548 bool success = false;
549 std::unique_lock<std::recursive_mutex> lock;
550 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
551
552 if (exe_ctx.HasThreadScope()) {
553 Process::StopLocker stop_locker;
554 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
555 Thread *thread = exe_ctx.GetThreadPtr();
556 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
557 if (info_root_sp) {
558 StructuredData::ObjectSP node =
559 info_root_sp->GetObjectForDotSeparatedPath(path);
560 if (node) {
561 if (node->GetType() == eStructuredDataTypeString) {
562 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
563 success = true;
564 }
565 if (node->GetType() == eStructuredDataTypeInteger) {
566 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
567 success = true;
568 }
569 if (node->GetType() == eStructuredDataTypeFloat) {
570 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
571 success = true;
572 }
573 if (node->GetType() == eStructuredDataTypeBoolean) {
574 if (node->GetAsBoolean()->GetValue())
575 strm.Printf("true");
576 else
577 strm.Printf("false");
578 success = true;
579 }
580 if (node->GetType() == eStructuredDataTypeNull) {
581 strm.Printf("null");
582 success = true;
583 }
584 }
585 }
586 } else {
587 if (log)
588 log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
589 "process is running",
590 static_cast<void *>(exe_ctx.GetThreadPtr()));
591 }
592 }
593
594 if (log)
595 log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
596 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
597
598 return success;
599 }
600
ResumeNewPlan(ExecutionContext & exe_ctx,ThreadPlan * new_plan)601 SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
602 ThreadPlan *new_plan) {
603 SBError sb_error;
604
605 Process *process = exe_ctx.GetProcessPtr();
606 if (!process) {
607 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
608 return sb_error;
609 }
610
611 Thread *thread = exe_ctx.GetThreadPtr();
612 if (!thread) {
613 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
614 return sb_error;
615 }
616
617 // User level plans should be Master Plans so they can be interrupted, other
618 // plans executed, and then a "continue" will resume the plan.
619 if (new_plan != NULL) {
620 new_plan->SetIsMasterPlan(true);
621 new_plan->SetOkayToDiscard(false);
622 }
623
624 // Why do we need to set the current thread by ID here???
625 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
626
627 if (process->GetTarget().GetDebugger().GetAsyncExecution())
628 sb_error.ref() = process->Resume();
629 else
630 sb_error.ref() = process->ResumeSynchronous(NULL);
631
632 return sb_error;
633 }
634
StepOver(lldb::RunMode stop_other_threads)635 void SBThread::StepOver(lldb::RunMode stop_other_threads) {
636 SBError error; // Ignored
637 StepOver(stop_other_threads, error);
638 }
639
StepOver(lldb::RunMode stop_other_threads,SBError & error)640 void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
641 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
642
643 std::unique_lock<std::recursive_mutex> lock;
644 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
645
646 if (log)
647 log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
648 static_cast<void *>(exe_ctx.GetThreadPtr()),
649 Thread::RunModeAsCString(stop_other_threads));
650
651 if (!exe_ctx.HasThreadScope()) {
652 error.SetErrorString("this SBThread object is invalid");
653 return;
654 }
655
656 Thread *thread = exe_ctx.GetThreadPtr();
657 bool abort_other_plans = false;
658 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
659
660 Status new_plan_status;
661 ThreadPlanSP new_plan_sp;
662 if (frame_sp) {
663 if (frame_sp->HasDebugInformation()) {
664 const LazyBool avoid_no_debug = eLazyBoolCalculate;
665 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
666 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
667 abort_other_plans, sc.line_entry, sc, stop_other_threads,
668 new_plan_status, avoid_no_debug);
669 } else {
670 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
671 true, abort_other_plans, stop_other_threads, new_plan_status);
672 }
673 }
674 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
675 }
676
StepInto(lldb::RunMode stop_other_threads)677 void SBThread::StepInto(lldb::RunMode stop_other_threads) {
678 StepInto(NULL, stop_other_threads);
679 }
680
StepInto(const char * target_name,lldb::RunMode stop_other_threads)681 void SBThread::StepInto(const char *target_name,
682 lldb::RunMode stop_other_threads) {
683 SBError error; // Ignored
684 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
685 }
686
StepInto(const char * target_name,uint32_t end_line,SBError & error,lldb::RunMode stop_other_threads)687 void SBThread::StepInto(const char *target_name, uint32_t end_line,
688 SBError &error, lldb::RunMode stop_other_threads) {
689 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
690
691 std::unique_lock<std::recursive_mutex> lock;
692 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
693
694 if (log)
695 log->Printf(
696 "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
697 static_cast<void *>(exe_ctx.GetThreadPtr()),
698 target_name ? target_name : "<NULL>",
699 Thread::RunModeAsCString(stop_other_threads));
700
701 if (!exe_ctx.HasThreadScope()) {
702 error.SetErrorString("this SBThread object is invalid");
703 return;
704 }
705
706 bool abort_other_plans = false;
707
708 Thread *thread = exe_ctx.GetThreadPtr();
709 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
710 ThreadPlanSP new_plan_sp;
711 Status new_plan_status;
712
713 if (frame_sp && frame_sp->HasDebugInformation()) {
714 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
715 AddressRange range;
716 if (end_line == LLDB_INVALID_LINE_NUMBER)
717 range = sc.line_entry.range;
718 else {
719 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
720 return;
721 }
722
723 const LazyBool step_out_avoids_code_without_debug_info =
724 eLazyBoolCalculate;
725 const LazyBool step_in_avoids_code_without_debug_info =
726 eLazyBoolCalculate;
727 new_plan_sp = thread->QueueThreadPlanForStepInRange(
728 abort_other_plans, range, sc, target_name, stop_other_threads,
729 new_plan_status, step_in_avoids_code_without_debug_info,
730 step_out_avoids_code_without_debug_info);
731 } else {
732 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
733 false, abort_other_plans, stop_other_threads, new_plan_status);
734 }
735
736 if (new_plan_status.Success())
737 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
738 else
739 error.SetErrorString(new_plan_status.AsCString());
740 }
741
StepOut()742 void SBThread::StepOut() {
743 SBError error; // Ignored
744 StepOut(error);
745 }
746
StepOut(SBError & error)747 void SBThread::StepOut(SBError &error) {
748 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
749
750 std::unique_lock<std::recursive_mutex> lock;
751 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
752
753 if (log)
754 log->Printf("SBThread(%p)::StepOut ()",
755 static_cast<void *>(exe_ctx.GetThreadPtr()));
756
757 if (!exe_ctx.HasThreadScope()) {
758 error.SetErrorString("this SBThread object is invalid");
759 return;
760 }
761
762 bool abort_other_plans = false;
763 bool stop_other_threads = false;
764
765 Thread *thread = exe_ctx.GetThreadPtr();
766
767 const LazyBool avoid_no_debug = eLazyBoolCalculate;
768 Status new_plan_status;
769 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
770 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
771 eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
772
773 if (new_plan_status.Success())
774 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
775 else
776 error.SetErrorString(new_plan_status.AsCString());
777 }
778
StepOutOfFrame(SBFrame & sb_frame)779 void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
780 SBError error; // Ignored
781 StepOutOfFrame(sb_frame, error);
782 }
783
StepOutOfFrame(SBFrame & sb_frame,SBError & error)784 void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
785 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
786
787 std::unique_lock<std::recursive_mutex> lock;
788 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
789
790 if (!sb_frame.IsValid()) {
791 if (log)
792 log->Printf(
793 "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
794 static_cast<void *>(exe_ctx.GetThreadPtr()));
795 error.SetErrorString("passed invalid SBFrame object");
796 return;
797 }
798
799 StackFrameSP frame_sp(sb_frame.GetFrameSP());
800 if (log) {
801 SBStream frame_desc_strm;
802 sb_frame.GetDescription(frame_desc_strm);
803 log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
804 static_cast<void *>(exe_ctx.GetThreadPtr()),
805 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
806 }
807
808 if (!exe_ctx.HasThreadScope()) {
809 error.SetErrorString("this SBThread object is invalid");
810 return;
811 }
812
813 bool abort_other_plans = false;
814 bool stop_other_threads = false;
815 Thread *thread = exe_ctx.GetThreadPtr();
816 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
817 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
818 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
819 static_cast<void *>(exe_ctx.GetThreadPtr()),
820 sb_frame.GetThread().GetThreadID(), thread->GetID());
821 error.SetErrorString("passed a frame from another thread");
822 return;
823 }
824
825 Status new_plan_status;
826 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
827 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
828 eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
829
830 if (new_plan_status.Success())
831 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
832 else
833 error.SetErrorString(new_plan_status.AsCString());
834 }
835
StepInstruction(bool step_over)836 void SBThread::StepInstruction(bool step_over) {
837 SBError error; // Ignored
838 StepInstruction(step_over, error);
839 }
840
StepInstruction(bool step_over,SBError & error)841 void SBThread::StepInstruction(bool step_over, SBError &error) {
842 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
843
844 std::unique_lock<std::recursive_mutex> lock;
845 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
846
847 if (log)
848 log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
849 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
850
851 if (!exe_ctx.HasThreadScope()) {
852 error.SetErrorString("this SBThread object is invalid");
853 return;
854 }
855
856 Thread *thread = exe_ctx.GetThreadPtr();
857 Status new_plan_status;
858 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
859 step_over, true, true, new_plan_status));
860
861 if (new_plan_status.Success())
862 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
863 else
864 error.SetErrorString(new_plan_status.AsCString());
865 }
866
RunToAddress(lldb::addr_t addr)867 void SBThread::RunToAddress(lldb::addr_t addr) {
868 SBError error; // Ignored
869 RunToAddress(addr, error);
870 }
871
RunToAddress(lldb::addr_t addr,SBError & error)872 void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
873 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
874
875 std::unique_lock<std::recursive_mutex> lock;
876 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
877
878 if (log)
879 log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
880 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
881
882 if (!exe_ctx.HasThreadScope()) {
883 error.SetErrorString("this SBThread object is invalid");
884 return;
885 }
886
887 bool abort_other_plans = false;
888 bool stop_other_threads = true;
889
890 Address target_addr(addr);
891
892 Thread *thread = exe_ctx.GetThreadPtr();
893
894 Status new_plan_status;
895 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
896 abort_other_plans, target_addr, stop_other_threads, new_plan_status));
897
898 if (new_plan_status.Success())
899 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
900 else
901 error.SetErrorString(new_plan_status.AsCString());
902 }
903
StepOverUntil(lldb::SBFrame & sb_frame,lldb::SBFileSpec & sb_file_spec,uint32_t line)904 SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
905 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
906 SBError sb_error;
907 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
908 char path[PATH_MAX];
909
910 std::unique_lock<std::recursive_mutex> lock;
911 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
912
913 StackFrameSP frame_sp(sb_frame.GetFrameSP());
914
915 if (log) {
916 SBStream frame_desc_strm;
917 sb_frame.GetDescription(frame_desc_strm);
918 sb_file_spec->GetPath(path, sizeof(path));
919 log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
920 "file+line = %s:%u)",
921 static_cast<void *>(exe_ctx.GetThreadPtr()),
922 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
923 path, line);
924 }
925
926 if (exe_ctx.HasThreadScope()) {
927 Target *target = exe_ctx.GetTargetPtr();
928 Thread *thread = exe_ctx.GetThreadPtr();
929
930 if (line == 0) {
931 sb_error.SetErrorString("invalid line argument");
932 return sb_error;
933 }
934
935 if (!frame_sp) {
936 frame_sp = thread->GetSelectedFrame();
937 if (!frame_sp)
938 frame_sp = thread->GetStackFrameAtIndex(0);
939 }
940
941 SymbolContext frame_sc;
942 if (!frame_sp) {
943 sb_error.SetErrorString("no valid frames in thread to step");
944 return sb_error;
945 }
946
947 // If we have a frame, get its line
948 frame_sc = frame_sp->GetSymbolContext(
949 eSymbolContextCompUnit | eSymbolContextFunction |
950 eSymbolContextLineEntry | eSymbolContextSymbol);
951
952 if (frame_sc.comp_unit == NULL) {
953 sb_error.SetErrorStringWithFormat(
954 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
955 return sb_error;
956 }
957
958 FileSpec step_file_spec;
959 if (sb_file_spec.IsValid()) {
960 // The file spec passed in was valid, so use it
961 step_file_spec = sb_file_spec.ref();
962 } else {
963 if (frame_sc.line_entry.IsValid())
964 step_file_spec = frame_sc.line_entry.file;
965 else {
966 sb_error.SetErrorString("invalid file argument or no file for frame");
967 return sb_error;
968 }
969 }
970
971 // Grab the current function, then we will make sure the "until" address is
972 // within the function. We discard addresses that are out of the current
973 // function, and then if there are no addresses remaining, give an
974 // appropriate error message.
975
976 bool all_in_function = true;
977 AddressRange fun_range = frame_sc.function->GetAddressRange();
978
979 std::vector<addr_t> step_over_until_addrs;
980 const bool abort_other_plans = false;
981 const bool stop_other_threads = false;
982 const bool check_inlines = true;
983 const bool exact = false;
984
985 SymbolContextList sc_list;
986 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
987 step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
988 sc_list);
989 if (num_matches > 0) {
990 SymbolContext sc;
991 for (uint32_t i = 0; i < num_matches; ++i) {
992 if (sc_list.GetContextAtIndex(i, sc)) {
993 addr_t step_addr =
994 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
995 if (step_addr != LLDB_INVALID_ADDRESS) {
996 if (fun_range.ContainsLoadAddress(step_addr, target))
997 step_over_until_addrs.push_back(step_addr);
998 else
999 all_in_function = false;
1000 }
1001 }
1002 }
1003 }
1004
1005 if (step_over_until_addrs.empty()) {
1006 if (all_in_function) {
1007 step_file_spec.GetPath(path, sizeof(path));
1008 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
1009 line);
1010 } else
1011 sb_error.SetErrorString("step until target not in current function");
1012 } else {
1013 Status new_plan_status;
1014 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
1015 abort_other_plans, &step_over_until_addrs[0],
1016 step_over_until_addrs.size(), stop_other_threads,
1017 frame_sp->GetFrameIndex(), new_plan_status));
1018
1019 if (new_plan_status.Success())
1020 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1021 else
1022 sb_error.SetErrorString(new_plan_status.AsCString());
1023 }
1024 } else {
1025 sb_error.SetErrorString("this SBThread object is invalid");
1026 }
1027 return sb_error;
1028 }
1029
StepUsingScriptedThreadPlan(const char * script_class_name)1030 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1031 return StepUsingScriptedThreadPlan(script_class_name, true);
1032 }
1033
StepUsingScriptedThreadPlan(const char * script_class_name,bool resume_immediately)1034 SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1035 bool resume_immediately) {
1036 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1037 SBError error;
1038
1039 std::unique_lock<std::recursive_mutex> lock;
1040 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1041
1042 if (log) {
1043 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1044 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
1045 }
1046
1047 if (!exe_ctx.HasThreadScope()) {
1048 error.SetErrorString("this SBThread object is invalid");
1049 return error;
1050 }
1051
1052 Thread *thread = exe_ctx.GetThreadPtr();
1053 Status new_plan_status;
1054 ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1055 false, script_class_name, false, new_plan_status);
1056
1057 if (new_plan_status.Fail()) {
1058 error.SetErrorString(new_plan_status.AsCString());
1059 return error;
1060 }
1061
1062 if (!resume_immediately)
1063 return error;
1064
1065 if (new_plan_status.Success())
1066 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1067 else
1068 error.SetErrorString(new_plan_status.AsCString());
1069
1070 return error;
1071 }
1072
JumpToLine(lldb::SBFileSpec & file_spec,uint32_t line)1073 SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1074 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1075 SBError sb_error;
1076
1077 std::unique_lock<std::recursive_mutex> lock;
1078 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1079
1080 if (log)
1081 log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1082 static_cast<void *>(exe_ctx.GetThreadPtr()),
1083 file_spec->GetPath().c_str(), line);
1084
1085 if (!exe_ctx.HasThreadScope()) {
1086 sb_error.SetErrorString("this SBThread object is invalid");
1087 return sb_error;
1088 }
1089
1090 Thread *thread = exe_ctx.GetThreadPtr();
1091
1092 Status err = thread->JumpToLine(file_spec.get(), line, true);
1093 sb_error.SetError(err);
1094 return sb_error;
1095 }
1096
ReturnFromFrame(SBFrame & frame,SBValue & return_value)1097 SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1098 SBError sb_error;
1099
1100 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1101
1102 std::unique_lock<std::recursive_mutex> lock;
1103 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1104
1105 if (log)
1106 log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1107 static_cast<void *>(exe_ctx.GetThreadPtr()),
1108 frame.GetFrameID());
1109
1110 if (exe_ctx.HasThreadScope()) {
1111 Thread *thread = exe_ctx.GetThreadPtr();
1112 sb_error.SetError(
1113 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1114 }
1115
1116 return sb_error;
1117 }
1118
UnwindInnermostExpression()1119 SBError SBThread::UnwindInnermostExpression() {
1120 SBError sb_error;
1121
1122 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1123
1124 std::unique_lock<std::recursive_mutex> lock;
1125 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1126
1127 if (log)
1128 log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
1129 static_cast<void *>(exe_ctx.GetThreadPtr()));
1130
1131 if (exe_ctx.HasThreadScope()) {
1132 Thread *thread = exe_ctx.GetThreadPtr();
1133 sb_error.SetError(thread->UnwindInnermostExpression());
1134 if (sb_error.Success())
1135 thread->SetSelectedFrameByIndex(0, false);
1136 }
1137
1138 return sb_error;
1139 }
1140
Suspend()1141 bool SBThread::Suspend() {
1142 SBError error; // Ignored
1143 return Suspend(error);
1144 }
1145
Suspend(SBError & error)1146 bool SBThread::Suspend(SBError &error) {
1147 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1148 std::unique_lock<std::recursive_mutex> lock;
1149 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1150
1151 bool result = false;
1152 if (exe_ctx.HasThreadScope()) {
1153 Process::StopLocker stop_locker;
1154 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1155 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1156 result = true;
1157 } else {
1158 error.SetErrorString("process is running");
1159 if (log)
1160 log->Printf("SBThread(%p)::Suspend() => error: process is running",
1161 static_cast<void *>(exe_ctx.GetThreadPtr()));
1162 }
1163 } else
1164 error.SetErrorString("this SBThread object is invalid");
1165 if (log)
1166 log->Printf("SBThread(%p)::Suspend() => %i",
1167 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1168 return result;
1169 }
1170
Resume()1171 bool SBThread::Resume() {
1172 SBError error; // Ignored
1173 return Resume(error);
1174 }
1175
Resume(SBError & error)1176 bool SBThread::Resume(SBError &error) {
1177 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1178 std::unique_lock<std::recursive_mutex> lock;
1179 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1180
1181 bool result = false;
1182 if (exe_ctx.HasThreadScope()) {
1183 Process::StopLocker stop_locker;
1184 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1185 const bool override_suspend = true;
1186 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1187 result = true;
1188 } else {
1189 error.SetErrorString("process is running");
1190 if (log)
1191 log->Printf("SBThread(%p)::Resume() => error: process is running",
1192 static_cast<void *>(exe_ctx.GetThreadPtr()));
1193 }
1194 } else
1195 error.SetErrorString("this SBThread object is invalid");
1196 if (log)
1197 log->Printf("SBThread(%p)::Resume() => %i",
1198 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1199 return result;
1200 }
1201
IsSuspended()1202 bool SBThread::IsSuspended() {
1203 std::unique_lock<std::recursive_mutex> lock;
1204 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1205
1206 if (exe_ctx.HasThreadScope())
1207 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1208 return false;
1209 }
1210
IsStopped()1211 bool SBThread::IsStopped() {
1212 std::unique_lock<std::recursive_mutex> lock;
1213 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1214
1215 if (exe_ctx.HasThreadScope())
1216 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1217 return false;
1218 }
1219
GetProcess()1220 SBProcess SBThread::GetProcess() {
1221 SBProcess sb_process;
1222 std::unique_lock<std::recursive_mutex> lock;
1223 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1224
1225 if (exe_ctx.HasThreadScope()) {
1226 // Have to go up to the target so we can get a shared pointer to our
1227 // process...
1228 sb_process.SetSP(exe_ctx.GetProcessSP());
1229 }
1230
1231 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1232 if (log) {
1233 SBStream frame_desc_strm;
1234 sb_process.GetDescription(frame_desc_strm);
1235 log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1236 static_cast<void *>(exe_ctx.GetThreadPtr()),
1237 static_cast<void *>(sb_process.GetSP().get()),
1238 frame_desc_strm.GetData());
1239 }
1240
1241 return sb_process;
1242 }
1243
GetNumFrames()1244 uint32_t SBThread::GetNumFrames() {
1245 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1246
1247 uint32_t num_frames = 0;
1248 std::unique_lock<std::recursive_mutex> lock;
1249 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1250
1251 if (exe_ctx.HasThreadScope()) {
1252 Process::StopLocker stop_locker;
1253 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1254 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1255 } else {
1256 if (log)
1257 log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1258 static_cast<void *>(exe_ctx.GetThreadPtr()));
1259 }
1260 }
1261
1262 if (log)
1263 log->Printf("SBThread(%p)::GetNumFrames () => %u",
1264 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1265
1266 return num_frames;
1267 }
1268
GetFrameAtIndex(uint32_t idx)1269 SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1270 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1271
1272 SBFrame sb_frame;
1273 StackFrameSP frame_sp;
1274 std::unique_lock<std::recursive_mutex> lock;
1275 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1276
1277 if (exe_ctx.HasThreadScope()) {
1278 Process::StopLocker stop_locker;
1279 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1280 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1281 sb_frame.SetFrameSP(frame_sp);
1282 } else {
1283 if (log)
1284 log->Printf(
1285 "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1286 static_cast<void *>(exe_ctx.GetThreadPtr()));
1287 }
1288 }
1289
1290 if (log) {
1291 SBStream frame_desc_strm;
1292 sb_frame.GetDescription(frame_desc_strm);
1293 log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1294 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1295 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1296 }
1297
1298 return sb_frame;
1299 }
1300
GetSelectedFrame()1301 lldb::SBFrame SBThread::GetSelectedFrame() {
1302 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1303
1304 SBFrame sb_frame;
1305 StackFrameSP frame_sp;
1306 std::unique_lock<std::recursive_mutex> lock;
1307 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1308
1309 if (exe_ctx.HasThreadScope()) {
1310 Process::StopLocker stop_locker;
1311 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1312 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1313 sb_frame.SetFrameSP(frame_sp);
1314 } else {
1315 if (log)
1316 log->Printf(
1317 "SBThread(%p)::GetSelectedFrame() => error: process is running",
1318 static_cast<void *>(exe_ctx.GetThreadPtr()));
1319 }
1320 }
1321
1322 if (log) {
1323 SBStream frame_desc_strm;
1324 sb_frame.GetDescription(frame_desc_strm);
1325 log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1326 static_cast<void *>(exe_ctx.GetThreadPtr()),
1327 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1328 }
1329
1330 return sb_frame;
1331 }
1332
SetSelectedFrame(uint32_t idx)1333 lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1334 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1335
1336 SBFrame sb_frame;
1337 StackFrameSP frame_sp;
1338 std::unique_lock<std::recursive_mutex> lock;
1339 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1340
1341 if (exe_ctx.HasThreadScope()) {
1342 Process::StopLocker stop_locker;
1343 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1344 Thread *thread = exe_ctx.GetThreadPtr();
1345 frame_sp = thread->GetStackFrameAtIndex(idx);
1346 if (frame_sp) {
1347 thread->SetSelectedFrame(frame_sp.get());
1348 sb_frame.SetFrameSP(frame_sp);
1349 }
1350 } else {
1351 if (log)
1352 log->Printf(
1353 "SBThread(%p)::SetSelectedFrame() => error: process is running",
1354 static_cast<void *>(exe_ctx.GetThreadPtr()));
1355 }
1356 }
1357
1358 if (log) {
1359 SBStream frame_desc_strm;
1360 sb_frame.GetDescription(frame_desc_strm);
1361 log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1362 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1363 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1364 }
1365 return sb_frame;
1366 }
1367
EventIsThreadEvent(const SBEvent & event)1368 bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1369 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1370 }
1371
GetStackFrameFromEvent(const SBEvent & event)1372 SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1373 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1374 }
1375
GetThreadFromEvent(const SBEvent & event)1376 SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1377 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1378 }
1379
operator ==(const SBThread & rhs) const1380 bool SBThread::operator==(const SBThread &rhs) const {
1381 return m_opaque_sp->GetThreadSP().get() ==
1382 rhs.m_opaque_sp->GetThreadSP().get();
1383 }
1384
operator !=(const SBThread & rhs) const1385 bool SBThread::operator!=(const SBThread &rhs) const {
1386 return m_opaque_sp->GetThreadSP().get() !=
1387 rhs.m_opaque_sp->GetThreadSP().get();
1388 }
1389
GetStatus(SBStream & status) const1390 bool SBThread::GetStatus(SBStream &status) const {
1391 Stream &strm = status.ref();
1392
1393 std::unique_lock<std::recursive_mutex> lock;
1394 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1395
1396 if (exe_ctx.HasThreadScope()) {
1397 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1398 } else
1399 strm.PutCString("No status");
1400
1401 return true;
1402 }
1403
GetDescription(SBStream & description) const1404 bool SBThread::GetDescription(SBStream &description) const {
1405 return GetDescription(description, false);
1406 }
1407
GetDescription(SBStream & description,bool stop_format) const1408 bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1409 Stream &strm = description.ref();
1410
1411 std::unique_lock<std::recursive_mutex> lock;
1412 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1413
1414 if (exe_ctx.HasThreadScope()) {
1415 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
1416 LLDB_INVALID_THREAD_ID,
1417 stop_format);
1418 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1419 // exe_ctx.GetThreadPtr()->GetID());
1420 } else
1421 strm.PutCString("No value");
1422
1423 return true;
1424 }
1425
GetExtendedBacktraceThread(const char * type)1426 SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1427 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1428 std::unique_lock<std::recursive_mutex> lock;
1429 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1430 SBThread sb_origin_thread;
1431
1432 if (exe_ctx.HasThreadScope()) {
1433 Process::StopLocker stop_locker;
1434 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1435 ThreadSP real_thread(exe_ctx.GetThreadSP());
1436 if (real_thread) {
1437 ConstString type_const(type);
1438 Process *process = exe_ctx.GetProcessPtr();
1439 if (process) {
1440 SystemRuntime *runtime = process->GetSystemRuntime();
1441 if (runtime) {
1442 ThreadSP new_thread_sp(
1443 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1444 if (new_thread_sp) {
1445 // Save this in the Process' ExtendedThreadList so a strong
1446 // pointer retains the object.
1447 process->GetExtendedThreadList().AddThread(new_thread_sp);
1448 sb_origin_thread.SetThread(new_thread_sp);
1449 if (log) {
1450 const char *queue_name = new_thread_sp->GetQueueName();
1451 if (queue_name == NULL)
1452 queue_name = "";
1453 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1454 "extended Thread "
1455 "created (%p) with queue_id 0x%" PRIx64
1456 " queue name '%s'",
1457 static_cast<void *>(exe_ctx.GetThreadPtr()),
1458 static_cast<void *>(new_thread_sp.get()),
1459 new_thread_sp->GetQueueID(), queue_name);
1460 }
1461 }
1462 }
1463 }
1464 }
1465 } else {
1466 if (log)
1467 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1468 "process is running",
1469 static_cast<void *>(exe_ctx.GetThreadPtr()));
1470 }
1471 }
1472
1473 if (log && !sb_origin_thread.IsValid())
1474 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1475 "Valid thread",
1476 static_cast<void *>(exe_ctx.GetThreadPtr()));
1477 return sb_origin_thread;
1478 }
1479
GetExtendedBacktraceOriginatingIndexID()1480 uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1481 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1482 if (thread_sp)
1483 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1484 return LLDB_INVALID_INDEX32;
1485 }
1486
GetCurrentException()1487 SBValue SBThread::GetCurrentException() {
1488 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1489 if (!thread_sp) return SBValue();
1490
1491 return SBValue(thread_sp->GetCurrentException());
1492 }
1493
GetCurrentExceptionBacktrace()1494 SBThread SBThread::GetCurrentExceptionBacktrace() {
1495 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1496 if (!thread_sp) return SBThread();
1497
1498 return SBThread(thread_sp->GetCurrentExceptionBacktrace());
1499 }
1500
SafeToCallFunctions()1501 bool SBThread::SafeToCallFunctions() {
1502 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1503 if (thread_sp)
1504 return thread_sp->SafeToCallFunctions();
1505 return true;
1506 }
1507
operator ->()1508 lldb_private::Thread *SBThread::operator->() {
1509 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1510 if (thread_sp)
1511 return thread_sp.get();
1512 else
1513 return NULL;
1514 }
1515
get()1516 lldb_private::Thread *SBThread::get() {
1517 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1518 if (thread_sp)
1519 return thread_sp.get();
1520 else
1521 return NULL;
1522 }
1523