Bug Summary

File:tools/lldb/source/API/SBThread.cpp
Warning:line 783, column 7
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name SBThread.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-eagerly-assume -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-7/lib/clang/7.0.0 -D HAVE_ROUND -D LLDB_CONFIGURATION_RELEASE -D LLDB_USE_BUILTIN_DEMANGLER -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/source/API -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/API -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/include -I /build/llvm-toolchain-snapshot-7~svn329677/include -I /usr/include/python2.7 -I /build/llvm-toolchain-snapshot-7~svn329677/tools/clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/. -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/x86_64-linux-gnu/c++/7.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.3.0/../../../../include/c++/7.3.0/backward -internal-isystem /usr/include/clang/7.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-7/lib/clang/7.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-deprecated-register -Wno-vla-extension -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-7~svn329677/build-llvm/tools/lldb/source/API -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-04-11-031539-24776-1 -x c++ /build/llvm-toolchain-snapshot-7~svn329677/tools/lldb/source/API/SBThread.cpp
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/State.h"
18#include "lldb/Core/StreamFile.h"
19#include "lldb/Core/ValueObject.h"
20#include "lldb/Interpreter/CommandInterpreter.h"
21#include "lldb/Symbol/CompileUnit.h"
22#include "lldb/Symbol/SymbolContext.h"
23#include "lldb/Target/Process.h"
24#include "lldb/Target/Queue.h"
25#include "lldb/Target/StopInfo.h"
26#include "lldb/Target/SystemRuntime.h"
27#include "lldb/Target/Target.h"
28#include "lldb/Target/Thread.h"
29#include "lldb/Target/ThreadPlan.h"
30#include "lldb/Target/ThreadPlanStepInRange.h"
31#include "lldb/Target/ThreadPlanStepInstruction.h"
32#include "lldb/Target/ThreadPlanStepOut.h"
33#include "lldb/Target/ThreadPlanStepRange.h"
34#include "lldb/Target/UnixSignals.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
48using namespace lldb;
49using namespace lldb_private;
50
51const char *SBThread::GetBroadcasterClassName() {
52 return Thread::GetStaticBroadcasterClass().AsCString();
53}
54
55//----------------------------------------------------------------------
56// Constructors
57//----------------------------------------------------------------------
58SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
59
60SBThread::SBThread(const ThreadSP &lldb_object_sp)
61 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
62
63SBThread::SBThread(const SBThread &rhs)
64 : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
65
66//----------------------------------------------------------------------
67// Assignment operator
68//----------------------------------------------------------------------
69
70const 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//----------------------------------------------------------------------
79SBThread::~SBThread() {}
80
81lldb::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(1u << 16)));
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
110bool 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__null;
120 }
121 // Without a valid target & process, this thread can't be valid.
122 return false;
123}
124
125void SBThread::Clear() { m_opaque_sp->Clear(); }
126
127StopReason SBThread::GetStopReason() {
128 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
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
154size_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(1u << 16)));
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
207uint64_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_ID0;
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(1u << 16)));
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
272bool 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
291SBThreadCollection
292SBThread::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
313size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
314 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
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__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(1u << 16)));
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
424SBValue SBThread::GetStopReturnValue() {
425 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
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
454void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
455 m_opaque_sp->SetThreadSP(lldb_object_sp);
456}
457
458lldb::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_ID0;
463}
464
465uint32_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(4294967295U);
470}
471
472const char *SBThread::GetName() const {
473 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
474 const char *name = NULL__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
497const char *SBThread::GetQueueName() const {
498 const char *name = NULL__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(1u << 16)));
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
522lldb::queue_id_t SBThread::GetQueueID() const {
523 queue_id_t id = LLDB_INVALID_QUEUE_ID0;
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(1u << 16)));
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"l" "x",
541 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
542
543 return id;
544}
545
546bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
547 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
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"l" "x", 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() == true)
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
601SBError 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
619 // then a "continue" will resume the plan.
620 if (new_plan != NULL__null) {
621 new_plan->SetIsMasterPlan(true);
622 new_plan->SetOkayToDiscard(false);
623 }
624
625 // Why do we need to set the current thread by ID here???
626 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
627
628 if (process->GetTarget().GetDebugger().GetAsyncExecution())
629 sb_error.ref() = process->Resume();
630 else
631 sb_error.ref() = process->ResumeSynchronous(NULL__null);
632
633 return sb_error;
634}
635
636void SBThread::StepOver(lldb::RunMode stop_other_threads) {
637 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
638
639 std::unique_lock<std::recursive_mutex> lock;
640 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
641
642 if (log)
643 log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
644 static_cast<void *>(exe_ctx.GetThreadPtr()),
645 Thread::RunModeAsCString(stop_other_threads));
646
647 if (exe_ctx.HasThreadScope()) {
648 Thread *thread = exe_ctx.GetThreadPtr();
649 bool abort_other_plans = false;
650 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
651
652 ThreadPlanSP new_plan_sp;
653 if (frame_sp) {
654 if (frame_sp->HasDebugInformation()) {
655 const LazyBool avoid_no_debug = eLazyBoolCalculate;
656 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
657 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
658 abort_other_plans, sc.line_entry, sc, stop_other_threads,
659 avoid_no_debug);
660 } else {
661 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
662 true, abort_other_plans, stop_other_threads);
663 }
664 }
665
666 // This returns an error, we should use it!
667 ResumeNewPlan(exe_ctx, new_plan_sp.get());
668 }
669}
670
671void SBThread::StepInto(lldb::RunMode stop_other_threads) {
672 StepInto(NULL__null, stop_other_threads);
673}
674
675void SBThread::StepInto(const char *target_name,
676 lldb::RunMode stop_other_threads) {
677 SBError error;
678 StepInto(target_name, LLDB_INVALID_LINE_NUMBER(4294967295U), error, stop_other_threads);
679}
680
681void SBThread::StepInto(const char *target_name, uint32_t end_line,
682 SBError &error, lldb::RunMode stop_other_threads) {
683 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
684
685 std::unique_lock<std::recursive_mutex> lock;
686 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
687
688 if (log)
689 log->Printf(
690 "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
691 static_cast<void *>(exe_ctx.GetThreadPtr()),
692 target_name ? target_name : "<NULL>",
693 Thread::RunModeAsCString(stop_other_threads));
694
695 if (exe_ctx.HasThreadScope()) {
696 bool abort_other_plans = false;
697
698 Thread *thread = exe_ctx.GetThreadPtr();
699 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
700 ThreadPlanSP new_plan_sp;
701
702 if (frame_sp && frame_sp->HasDebugInformation()) {
703 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
704 AddressRange range;
705 if (end_line == LLDB_INVALID_LINE_NUMBER(4294967295U))
706 range = sc.line_entry.range;
707 else {
708 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
709 return;
710 }
711
712 const LazyBool step_out_avoids_code_without_debug_info =
713 eLazyBoolCalculate;
714 const LazyBool step_in_avoids_code_without_debug_info =
715 eLazyBoolCalculate;
716 new_plan_sp = thread->QueueThreadPlanForStepInRange(
717 abort_other_plans, range, sc, target_name, stop_other_threads,
718 step_in_avoids_code_without_debug_info,
719 step_out_avoids_code_without_debug_info);
720 } else {
721 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
722 false, abort_other_plans, stop_other_threads);
723 }
724
725 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
726 }
727}
728
729void SBThread::StepOut() {
730 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
731
732 std::unique_lock<std::recursive_mutex> lock;
733 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
734
735 if (log)
736 log->Printf("SBThread(%p)::StepOut ()",
737 static_cast<void *>(exe_ctx.GetThreadPtr()));
738
739 if (exe_ctx.HasThreadScope()) {
740 bool abort_other_plans = false;
741 bool stop_other_threads = false;
742
743 Thread *thread = exe_ctx.GetThreadPtr();
744
745 const LazyBool avoid_no_debug = eLazyBoolCalculate;
746 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
747 abort_other_plans, NULL__null, false, stop_other_threads, eVoteYes,
748 eVoteNoOpinion, 0, avoid_no_debug));
749
750 // This returns an error, we should use it!
751 ResumeNewPlan(exe_ctx, new_plan_sp.get());
752 }
753}
754
755void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
756 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1
'log' initialized here
757
758 std::unique_lock<std::recursive_mutex> lock;
759 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
760
761 if (!sb_frame.IsValid()) {
2
Assuming the condition is false
3
Taking false branch
762 if (log)
763 log->Printf(
764 "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
765 static_cast<void *>(exe_ctx.GetThreadPtr()));
766 return;
767 }
768
769 StackFrameSP frame_sp(sb_frame.GetFrameSP());
770 if (log) {
4
Assuming 'log' is null
5
Taking false branch
771 SBStream frame_desc_strm;
772 sb_frame.GetDescription(frame_desc_strm);
773 log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
774 static_cast<void *>(exe_ctx.GetThreadPtr()),
775 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
776 }
777
778 if (exe_ctx.HasThreadScope()) {
6
Assuming the condition is true
7
Taking true branch
779 bool abort_other_plans = false;
780 bool stop_other_threads = false;
781 Thread *thread = exe_ctx.GetThreadPtr();
782 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
8
Assuming the condition is true
9
Taking true branch
783 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
10
Called C++ object pointer is null
784 "thread (0x%" PRIx64"l" "x" " vrs. 0x%" PRIx64"l" "x" ", returning.",
785 static_cast<void *>(exe_ctx.GetThreadPtr()),
786 sb_frame.GetThread().GetThreadID(), thread->GetID());
787 }
788
789 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
790 abort_other_plans, NULL__null, false, stop_other_threads, eVoteYes,
791 eVoteNoOpinion, frame_sp->GetFrameIndex()));
792
793 // This returns an error, we should use it!
794 ResumeNewPlan(exe_ctx, new_plan_sp.get());
795 }
796}
797
798void SBThread::StepInstruction(bool step_over) {
799 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
800
801 std::unique_lock<std::recursive_mutex> lock;
802 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
803
804 if (log)
805 log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
806 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
807
808 if (exe_ctx.HasThreadScope()) {
809 Thread *thread = exe_ctx.GetThreadPtr();
810 ThreadPlanSP new_plan_sp(
811 thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
812
813 // This returns an error, we should use it!
814 ResumeNewPlan(exe_ctx, new_plan_sp.get());
815 }
816}
817
818void SBThread::RunToAddress(lldb::addr_t addr) {
819 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
820
821 std::unique_lock<std::recursive_mutex> lock;
822 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
823
824 if (log)
825 log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64"l" "x" ")",
826 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
827
828 if (exe_ctx.HasThreadScope()) {
829 bool abort_other_plans = false;
830 bool stop_other_threads = true;
831
832 Address target_addr(addr);
833
834 Thread *thread = exe_ctx.GetThreadPtr();
835
836 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
837 abort_other_plans, target_addr, stop_other_threads));
838
839 // This returns an error, we should use it!
840 ResumeNewPlan(exe_ctx, new_plan_sp.get());
841 }
842}
843
844SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
845 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
846 SBError sb_error;
847 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
848 char path[PATH_MAX4096];
849
850 std::unique_lock<std::recursive_mutex> lock;
851 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
852
853 StackFrameSP frame_sp(sb_frame.GetFrameSP());
854
855 if (log) {
856 SBStream frame_desc_strm;
857 sb_frame.GetDescription(frame_desc_strm);
858 sb_file_spec->GetPath(path, sizeof(path));
859 log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
860 "file+line = %s:%u)",
861 static_cast<void *>(exe_ctx.GetThreadPtr()),
862 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
863 path, line);
864 }
865
866 if (exe_ctx.HasThreadScope()) {
867 Target *target = exe_ctx.GetTargetPtr();
868 Thread *thread = exe_ctx.GetThreadPtr();
869
870 if (line == 0) {
871 sb_error.SetErrorString("invalid line argument");
872 return sb_error;
873 }
874
875 if (!frame_sp) {
876 frame_sp = thread->GetSelectedFrame();
877 if (!frame_sp)
878 frame_sp = thread->GetStackFrameAtIndex(0);
879 }
880
881 SymbolContext frame_sc;
882 if (!frame_sp) {
883 sb_error.SetErrorString("no valid frames in thread to step");
884 return sb_error;
885 }
886
887 // If we have a frame, get its line
888 frame_sc = frame_sp->GetSymbolContext(
889 eSymbolContextCompUnit | eSymbolContextFunction |
890 eSymbolContextLineEntry | eSymbolContextSymbol);
891
892 if (frame_sc.comp_unit == NULL__null) {
893 sb_error.SetErrorStringWithFormat(
894 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
895 return sb_error;
896 }
897
898 FileSpec step_file_spec;
899 if (sb_file_spec.IsValid()) {
900 // The file spec passed in was valid, so use it
901 step_file_spec = sb_file_spec.ref();
902 } else {
903 if (frame_sc.line_entry.IsValid())
904 step_file_spec = frame_sc.line_entry.file;
905 else {
906 sb_error.SetErrorString("invalid file argument or no file for frame");
907 return sb_error;
908 }
909 }
910
911 // Grab the current function, then we will make sure the "until" address is
912 // within the function. We discard addresses that are out of the current
913 // function, and then if there are no addresses remaining, give an
914 // appropriate
915 // error message.
916
917 bool all_in_function = true;
918 AddressRange fun_range = frame_sc.function->GetAddressRange();
919
920 std::vector<addr_t> step_over_until_addrs;
921 const bool abort_other_plans = false;
922 const bool stop_other_threads = false;
923 const bool check_inlines = true;
924 const bool exact = false;
925
926 SymbolContextList sc_list;
927 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
928 step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
929 sc_list);
930 if (num_matches > 0) {
931 SymbolContext sc;
932 for (uint32_t i = 0; i < num_matches; ++i) {
933 if (sc_list.GetContextAtIndex(i, sc)) {
934 addr_t step_addr =
935 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
936 if (step_addr != LLDB_INVALID_ADDRESS(18446744073709551615UL)) {
937 if (fun_range.ContainsLoadAddress(step_addr, target))
938 step_over_until_addrs.push_back(step_addr);
939 else
940 all_in_function = false;
941 }
942 }
943 }
944 }
945
946 if (step_over_until_addrs.empty()) {
947 if (all_in_function) {
948 step_file_spec.GetPath(path, sizeof(path));
949 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
950 line);
951 } else
952 sb_error.SetErrorString("step until target not in current function");
953 } else {
954 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
955 abort_other_plans, &step_over_until_addrs[0],
956 step_over_until_addrs.size(), stop_other_threads,
957 frame_sp->GetFrameIndex()));
958
959 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
960 }
961 } else {
962 sb_error.SetErrorString("this SBThread object is invalid");
963 }
964 return sb_error;
965}
966
967SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
968 return StepUsingScriptedThreadPlan(script_class_name, true);
969}
970
971SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
972 bool resume_immediately) {
973 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
974 SBError sb_error;
975
976 std::unique_lock<std::recursive_mutex> lock;
977 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
978
979 if (log) {
980 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
981 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
982 }
983
984 if (!exe_ctx.HasThreadScope()) {
985 sb_error.SetErrorString("this SBThread object is invalid");
986 return sb_error;
987 }
988
989 Thread *thread = exe_ctx.GetThreadPtr();
990 ThreadPlanSP thread_plan_sp =
991 thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
992
993 if (!thread_plan_sp) {
994 sb_error.SetErrorStringWithFormat(
995 "Error queueing thread plan for class: %s", script_class_name);
996 return sb_error;
997 }
998
999 if (!resume_immediately) {
1000 return sb_error;
1001 }
1002
1003 if (thread_plan_sp)
1004 sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1005 else {
1006 sb_error.SetErrorStringWithFormat(
1007 "Error resuming thread plan for class: %s.", script_class_name);
1008 if (log)
1009 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing "
1010 "thread plan for class: %s",
1011 static_cast<void *>(exe_ctx.GetThreadPtr()),
1012 script_class_name);
1013 }
1014
1015 return sb_error;
1016}
1017
1018SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1019 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1020 SBError sb_error;
1021
1022 std::unique_lock<std::recursive_mutex> lock;
1023 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1024
1025 if (log)
1026 log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1027 static_cast<void *>(exe_ctx.GetThreadPtr()),
1028 file_spec->GetPath().c_str(), line);
1029
1030 if (!exe_ctx.HasThreadScope()) {
1031 sb_error.SetErrorString("this SBThread object is invalid");
1032 return sb_error;
1033 }
1034
1035 Thread *thread = exe_ctx.GetThreadPtr();
1036
1037 Status err = thread->JumpToLine(file_spec.get(), line, true);
1038 sb_error.SetError(err);
1039 return sb_error;
1040}
1041
1042SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1043 SBError sb_error;
1044
1045 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1046
1047 std::unique_lock<std::recursive_mutex> lock;
1048 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1049
1050 if (log)
1051 log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1052 static_cast<void *>(exe_ctx.GetThreadPtr()),
1053 frame.GetFrameID());
1054
1055 if (exe_ctx.HasThreadScope()) {
1056 Thread *thread = exe_ctx.GetThreadPtr();
1057 sb_error.SetError(
1058 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1059 }
1060
1061 return sb_error;
1062}
1063
1064SBError SBThread::UnwindInnermostExpression() {
1065 SBError sb_error;
1066
1067 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1068
1069 std::unique_lock<std::recursive_mutex> lock;
1070 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1071
1072 if (log)
1073 log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
1074 static_cast<void *>(exe_ctx.GetThreadPtr()));
1075
1076 if (exe_ctx.HasThreadScope()) {
1077 Thread *thread = exe_ctx.GetThreadPtr();
1078 sb_error.SetError(thread->UnwindInnermostExpression());
1079 if (sb_error.Success())
1080 thread->SetSelectedFrameByIndex(0, false);
1081 }
1082
1083 return sb_error;
1084}
1085
1086bool SBThread::Suspend() {
1087 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1088 std::unique_lock<std::recursive_mutex> lock;
1089 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1090
1091 bool result = false;
1092 if (exe_ctx.HasThreadScope()) {
1093 Process::StopLocker stop_locker;
1094 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1095 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1096 result = true;
1097 } else {
1098 if (log)
1099 log->Printf("SBThread(%p)::Suspend() => error: process is running",
1100 static_cast<void *>(exe_ctx.GetThreadPtr()));
1101 }
1102 }
1103 if (log)
1104 log->Printf("SBThread(%p)::Suspend() => %i",
1105 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1106 return result;
1107}
1108
1109bool SBThread::Resume() {
1110 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1111 std::unique_lock<std::recursive_mutex> lock;
1112 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1113
1114 bool result = false;
1115 if (exe_ctx.HasThreadScope()) {
1116 Process::StopLocker stop_locker;
1117 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1118 const bool override_suspend = true;
1119 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1120 result = true;
1121 } else {
1122 if (log)
1123 log->Printf("SBThread(%p)::Resume() => error: process is running",
1124 static_cast<void *>(exe_ctx.GetThreadPtr()));
1125 }
1126 }
1127 if (log)
1128 log->Printf("SBThread(%p)::Resume() => %i",
1129 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1130 return result;
1131}
1132
1133bool SBThread::IsSuspended() {
1134 std::unique_lock<std::recursive_mutex> lock;
1135 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1136
1137 if (exe_ctx.HasThreadScope())
1138 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1139 return false;
1140}
1141
1142bool SBThread::IsStopped() {
1143 std::unique_lock<std::recursive_mutex> lock;
1144 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1145
1146 if (exe_ctx.HasThreadScope())
1147 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1148 return false;
1149}
1150
1151SBProcess SBThread::GetProcess() {
1152 SBProcess sb_process;
1153 std::unique_lock<std::recursive_mutex> lock;
1154 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1155
1156 if (exe_ctx.HasThreadScope()) {
1157 // Have to go up to the target so we can get a shared pointer to our
1158 // process...
1159 sb_process.SetSP(exe_ctx.GetProcessSP());
1160 }
1161
1162 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1163 if (log) {
1164 SBStream frame_desc_strm;
1165 sb_process.GetDescription(frame_desc_strm);
1166 log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1167 static_cast<void *>(exe_ctx.GetThreadPtr()),
1168 static_cast<void *>(sb_process.GetSP().get()),
1169 frame_desc_strm.GetData());
1170 }
1171
1172 return sb_process;
1173}
1174
1175uint32_t SBThread::GetNumFrames() {
1176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1177
1178 uint32_t num_frames = 0;
1179 std::unique_lock<std::recursive_mutex> lock;
1180 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1181
1182 if (exe_ctx.HasThreadScope()) {
1183 Process::StopLocker stop_locker;
1184 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1185 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1186 } else {
1187 if (log)
1188 log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1189 static_cast<void *>(exe_ctx.GetThreadPtr()));
1190 }
1191 }
1192
1193 if (log)
1194 log->Printf("SBThread(%p)::GetNumFrames () => %u",
1195 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1196
1197 return num_frames;
1198}
1199
1200SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1201 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1202
1203 SBFrame sb_frame;
1204 StackFrameSP frame_sp;
1205 std::unique_lock<std::recursive_mutex> lock;
1206 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1207
1208 if (exe_ctx.HasThreadScope()) {
1209 Process::StopLocker stop_locker;
1210 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1211 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1212 sb_frame.SetFrameSP(frame_sp);
1213 } else {
1214 if (log)
1215 log->Printf(
1216 "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1217 static_cast<void *>(exe_ctx.GetThreadPtr()));
1218 }
1219 }
1220
1221 if (log) {
1222 SBStream frame_desc_strm;
1223 sb_frame.GetDescription(frame_desc_strm);
1224 log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1225 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1226 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1227 }
1228
1229 return sb_frame;
1230}
1231
1232lldb::SBFrame SBThread::GetSelectedFrame() {
1233 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1234
1235 SBFrame sb_frame;
1236 StackFrameSP frame_sp;
1237 std::unique_lock<std::recursive_mutex> lock;
1238 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1239
1240 if (exe_ctx.HasThreadScope()) {
1241 Process::StopLocker stop_locker;
1242 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1243 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1244 sb_frame.SetFrameSP(frame_sp);
1245 } else {
1246 if (log)
1247 log->Printf(
1248 "SBThread(%p)::GetSelectedFrame() => error: process is running",
1249 static_cast<void *>(exe_ctx.GetThreadPtr()));
1250 }
1251 }
1252
1253 if (log) {
1254 SBStream frame_desc_strm;
1255 sb_frame.GetDescription(frame_desc_strm);
1256 log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1257 static_cast<void *>(exe_ctx.GetThreadPtr()),
1258 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1259 }
1260
1261 return sb_frame;
1262}
1263
1264lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1265 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1266
1267 SBFrame sb_frame;
1268 StackFrameSP frame_sp;
1269 std::unique_lock<std::recursive_mutex> lock;
1270 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1271
1272 if (exe_ctx.HasThreadScope()) {
1273 Process::StopLocker stop_locker;
1274 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1275 Thread *thread = exe_ctx.GetThreadPtr();
1276 frame_sp = thread->GetStackFrameAtIndex(idx);
1277 if (frame_sp) {
1278 thread->SetSelectedFrame(frame_sp.get());
1279 sb_frame.SetFrameSP(frame_sp);
1280 }
1281 } else {
1282 if (log)
1283 log->Printf(
1284 "SBThread(%p)::SetSelectedFrame() => error: process is running",
1285 static_cast<void *>(exe_ctx.GetThreadPtr()));
1286 }
1287 }
1288
1289 if (log) {
1290 SBStream frame_desc_strm;
1291 sb_frame.GetDescription(frame_desc_strm);
1292 log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1293 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1294 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1295 }
1296 return sb_frame;
1297}
1298
1299bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1300 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL__null;
1301}
1302
1303SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1304 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1305}
1306
1307SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1308 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1309}
1310
1311bool SBThread::operator==(const SBThread &rhs) const {
1312 return m_opaque_sp->GetThreadSP().get() ==
1313 rhs.m_opaque_sp->GetThreadSP().get();
1314}
1315
1316bool SBThread::operator!=(const SBThread &rhs) const {
1317 return m_opaque_sp->GetThreadSP().get() !=
1318 rhs.m_opaque_sp->GetThreadSP().get();
1319}
1320
1321bool SBThread::GetStatus(SBStream &status) const {
1322 Stream &strm = status.ref();
1323
1324 std::unique_lock<std::recursive_mutex> lock;
1325 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1326
1327 if (exe_ctx.HasThreadScope()) {
1328 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
1329 } else
1330 strm.PutCString("No status");
1331
1332 return true;
1333}
1334
1335bool SBThread::GetDescription(SBStream &description) const {
1336 return GetDescription(description, false);
1337}
1338
1339bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
1340 Stream &strm = description.ref();
1341
1342 std::unique_lock<std::recursive_mutex> lock;
1343 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1344
1345 if (exe_ctx.HasThreadScope()) {
1346 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
1347 LLDB_INVALID_THREAD_ID0,
1348 stop_format);
1349 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1350 // exe_ctx.GetThreadPtr()->GetID());
1351 } else
1352 strm.PutCString("No value");
1353
1354 return true;
1355}
1356
1357SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1358 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API(1u << 16)));
1359 std::unique_lock<std::recursive_mutex> lock;
1360 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1361 SBThread sb_origin_thread;
1362
1363 if (exe_ctx.HasThreadScope()) {
1364 Process::StopLocker stop_locker;
1365 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1366 ThreadSP real_thread(exe_ctx.GetThreadSP());
1367 if (real_thread) {
1368 ConstString type_const(type);
1369 Process *process = exe_ctx.GetProcessPtr();
1370 if (process) {
1371 SystemRuntime *runtime = process->GetSystemRuntime();
1372 if (runtime) {
1373 ThreadSP new_thread_sp(
1374 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1375 if (new_thread_sp) {
1376 // Save this in the Process' ExtendedThreadList so a strong
1377 // pointer retains the
1378 // object.
1379 process->GetExtendedThreadList().AddThread(new_thread_sp);
1380 sb_origin_thread.SetThread(new_thread_sp);
1381 if (log) {
1382 const char *queue_name = new_thread_sp->GetQueueName();
1383 if (queue_name == NULL__null)
1384 queue_name = "";
1385 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1386 "extended Thread "
1387 "created (%p) with queue_id 0x%" PRIx64"l" "x"
1388 " queue name '%s'",
1389 static_cast<void *>(exe_ctx.GetThreadPtr()),
1390 static_cast<void *>(new_thread_sp.get()),
1391 new_thread_sp->GetQueueID(), queue_name);
1392 }
1393 }
1394 }
1395 }
1396 }
1397 } else {
1398 if (log)
1399 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1400 "process is running",
1401 static_cast<void *>(exe_ctx.GetThreadPtr()));
1402 }
1403 }
1404
1405 if (log && sb_origin_thread.IsValid() == false)
1406 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1407 "Valid thread",
1408 static_cast<void *>(exe_ctx.GetThreadPtr()));
1409 return sb_origin_thread;
1410}
1411
1412uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1413 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1414 if (thread_sp)
1415 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1416 return LLDB_INVALID_INDEX32(4294967295U);
1417}
1418
1419bool SBThread::SafeToCallFunctions() {
1420 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1421 if (thread_sp)
1422 return thread_sp->SafeToCallFunctions();
1423 return true;
1424}
1425
1426lldb_private::Thread *SBThread::operator->() {
1427 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1428 if (thread_sp)
1429 return thread_sp.get();
1430 else
1431 return NULL__null;
1432}
1433
1434lldb_private::Thread *SBThread::get() {
1435 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1436 if (thread_sp)
1437 return thread_sp.get();
1438 else
1439 return NULL__null;
1440}