blob: def3b3a93fea7f25cdd5ad2311bd89003ca882e3 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Eli Friedman4c5de692010-06-09 07:44:37 +000010#include "lldb/API/SBThread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012#include "lldb/API/SBFileSpec.h"
Caroline Ticedde9cff2010-09-20 05:20:02 +000013#include "lldb/API/SBStream.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000014#include "lldb/API/SBSymbolContext.h"
Greg Clayton4e78f602010-11-18 18:52:36 +000015#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Clayton66111032010-06-23 01:19:29 +000016#include "lldb/Core/Debugger.h"
Andrew Kaylora75418d2013-04-15 23:33:53 +000017#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/StreamFile.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000019#include "lldb/Core/ValueObject.h"
Greg Clayton66111032010-06-23 01:19:29 +000020#include "lldb/Interpreter/CommandInterpreter.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000021#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000022#include "lldb/Symbol/SymbolContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000023#include "lldb/Target/Process.h"
Jason Molendab9ffa982014-04-25 00:01:15 +000024#include "lldb/Target/Queue.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000025#include "lldb/Target/StopInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Target/Target.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000028#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/ThreadPlan.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000030#include "lldb/Target/ThreadPlanStepInRange.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Target/ThreadPlanStepInstruction.h"
32#include "lldb/Target/ThreadPlanStepOut.h"
33#include "lldb/Target/ThreadPlanStepRange.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000034#include "lldb/Target/UnixSignals.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000035#include "lldb/Utility/Stream.h"
Pavel Labathf2a8bcc2017-06-27 10:45:31 +000036#include "lldb/Utility/StructuredData.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000037
Eli Friedman4c5de692010-06-09 07:44:37 +000038#include "lldb/API/SBAddress.h"
Eli Friedman4c5de692010-06-09 07:44:37 +000039#include "lldb/API/SBDebugger.h"
Jim Ingham4f465cf2012-10-10 18:32:14 +000040#include "lldb/API/SBEvent.h"
Jim Ingham73ca05a2011-12-17 01:35:57 +000041#include "lldb/API/SBFrame.h"
Eli Friedman4c5de692010-06-09 07:44:37 +000042#include "lldb/API/SBProcess.h"
Kuba Brecka6a831432016-03-23 15:36:22 +000043#include "lldb/API/SBThreadCollection.h"
Jim Ingham2bdbfd52014-09-29 23:17:18 +000044#include "lldb/API/SBThreadPlan.h"
Jim Ingham73ca05a2011-12-17 01:35:57 +000045#include "lldb/API/SBValue.h"
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +000046#include "lldb/lldb-enumerations.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047
48using namespace lldb;
49using namespace lldb_private;
50
Kate Stoneb9c1b512016-09-06 20:57:50 +000051const char *SBThread::GetBroadcasterClassName() {
52 return Thread::GetStaticBroadcasterClass().AsCString();
Jim Ingham4f465cf2012-10-10 18:32:14 +000053}
54
Greg Claytoncfd1ace2010-10-31 03:01:06 +000055//----------------------------------------------------------------------
56// Constructors
57//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000058SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059
Kate Stoneb9c1b512016-09-06 20:57:50 +000060SBThread::SBThread(const ThreadSP &lldb_object_sp)
61 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000062
Kate Stoneb9c1b512016-09-06 20:57:50 +000063SBThread::SBThread(const SBThread &rhs)
64 : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000065
66//----------------------------------------------------------------------
Greg Claytoncfd1ace2010-10-31 03:01:06 +000067// Assignment operator
68//----------------------------------------------------------------------
69
Kate Stoneb9c1b512016-09-06 20:57:50 +000070const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
71 if (this != &rhs)
72 *m_opaque_sp = *rhs.m_opaque_sp;
73 return *this;
Greg Claytoncfd1ace2010-10-31 03:01:06 +000074}
75
76//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000077// Destructor
78//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000079SBThread::~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));
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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000108}
109
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110bool SBThread::IsValid() const {
111 std::unique_lock<std::recursive_mutex> lock;
112 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molendab9ffa982014-04-25 00:01:15 +0000113
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 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
125void SBThread::Clear() { m_opaque_sp->Clear(); }
126
127StopReason 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
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));
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 }
Jason Molendab9ffa982014-04-25 00:01:15 +0000246 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000247 }
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();
Jason Molendab9ffa982014-04-25 00:01:15 +0000259 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000260 }
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()));
Jason Molendab9ffa982014-04-25 00:01:15 +0000267 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000268 }
269 return 0;
Jason Molendab9ffa982014-04-25 00:01:15 +0000270}
271
Kate Stoneb9c1b512016-09-06 20:57:50 +0000272bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
273 Stream &strm = stream.ref();
Jason Molendab9ffa982014-04-25 00:01:15 +0000274
Kate Stoneb9c1b512016-09-06 20:57:50 +0000275 std::unique_lock<std::recursive_mutex> lock;
276 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham7fa7dc32016-05-07 00:54:56 +0000277
Kate Stoneb9c1b512016-09-06 20:57:50 +0000278 if (!exe_ctx.HasThreadScope())
Jim Ingham7fa7dc32016-05-07 00:54:56 +0000279 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000280
Kate Stoneb9c1b512016-09-06 20:57:50 +0000281 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
282 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
283 if (!info)
284 return false;
Greg Clayton48e42542010-07-30 20:12:55 +0000285
Kate Stoneb9c1b512016-09-06 20:57:50 +0000286 info->Dump(strm);
Greg Clayton48e42542010-07-30 20:12:55 +0000287
Kate Stoneb9c1b512016-09-06 20:57:50 +0000288 return true;
Kuba Breckaafdf8422014-10-10 23:43:03 +0000289}
290
Kuba Brecka6a831432016-03-23 15:36:22 +0000291SBThreadCollection
Kate Stoneb9c1b512016-09-06 20:57:50 +0000292SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
293 ThreadCollectionSP threads;
294 threads.reset(new ThreadCollection());
Jim Inghamb2e7d282016-06-10 17:22:26 +0000295
Kate Stoneb9c1b512016-09-06 20:57:50 +0000296 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);
Kuba Brecka6a831432016-03-23 15:36:22 +0000311}
312
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
314 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000315
Kate Stoneb9c1b512016-09-06 20:57:50 +0000316 std::unique_lock<std::recursive_mutex> lock;
317 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000318
Kate Stoneb9c1b512016-09-06 20:57:50 +0000319 if (exe_ctx.HasThreadScope()) {
320 Process::StopLocker stop_locker;
321 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000348
Kate Stoneb9c1b512016-09-06 20:57:50 +0000349 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;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000354
Kate Stoneb9c1b512016-09-06 20:57:50 +0000355 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;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000360
Kate Stoneb9c1b512016-09-06 20:57:50 +0000361 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
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000370 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000371 } 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]) {
Greg Claytonc9858e42012-04-06 02:17:47 +0000395 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000396 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 }
Greg Claytonc9858e42012-04-06 02:17:47 +0000409 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 }
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()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000417 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000418 }
419 if (dst)
420 *dst = 0;
421 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000422}
423
Kate Stoneb9c1b512016-09-06 20:57:50 +0000424SBValue 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);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000429
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 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()));
Jim Ingham73ca05a2011-12-17 01:35:57 +0000442 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000444
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 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>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000450
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 return SBValue(return_valobj_sp);
Jim Ingham73ca05a2011-12-17 01:35:57 +0000452}
453
Kate Stoneb9c1b512016-09-06 20:57:50 +0000454void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
455 m_opaque_sp->SetThreadSP(lldb_object_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456}
457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458lldb::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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000463}
464
Kate Stoneb9c1b512016-09-06 20:57:50 +0000465uint32_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;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000470}
Greg Clayton1ac04c32012-02-21 00:09:25 +0000471
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472const 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);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000477
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 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()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000486 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000487 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000488
Kate Stoneb9c1b512016-09-06 20:57:50 +0000489 if (log)
490 log->Printf("SBThread(%p)::GetName () => %s",
491 static_cast<void *>(exe_ctx.GetThreadPtr()),
492 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000493
Kate Stoneb9c1b512016-09-06 20:57:50 +0000494 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000495}
496
Kate Stoneb9c1b512016-09-06 20:57:50 +0000497const 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);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000501
Kate Stoneb9c1b512016-09-06 20:57:50 +0000502 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()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000511 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000513
Kate Stoneb9c1b512016-09-06 20:57:50 +0000514 if (log)
515 log->Printf("SBThread(%p)::GetQueueName () => %s",
516 static_cast<void *>(exe_ctx.GetThreadPtr()),
517 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000518
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000520}
521
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522lldb::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);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 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()));
Jason Molenda4fdb5862013-10-21 23:52:54 +0000536 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000538
Kate Stoneb9c1b512016-09-06 20:57:50 +0000539 if (log)
540 log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
541 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 return id;
Jason Molenda4fdb5862013-10-21 23:52:54 +0000544}
545
Kate Stoneb9c1b512016-09-06 20:57:50 +0000546bool 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);
Jason Molenda705b1802014-06-13 02:37:02 +0000551
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 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) {
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000561 if (node->GetType() == eStructuredDataTypeString) {
Zachary Turner28333212017-05-12 05:49:54 +0000562 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563 success = true;
564 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000565 if (node->GetType() == eStructuredDataTypeInteger) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000566 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
567 success = true;
568 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000569 if (node->GetType() == eStructuredDataTypeFloat) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
571 success = true;
572 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000573 if (node->GetType() == eStructuredDataTypeBoolean) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 if (node->GetAsBoolean()->GetValue() == true)
575 strm.Printf("true");
576 else
577 strm.Printf("false");
578 success = true;
579 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000580 if (node->GetType() == eStructuredDataTypeNull) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 strm.Printf("null");
582 success = true;
583 }
Jason Molenda705b1802014-06-13 02:37:02 +0000584 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585 }
586 } else {
587 if (log)
588 log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
589 "process is running",
590 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molenda705b1802014-06-13 02:37:02 +0000591 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 }
Jason Molenda705b1802014-06-13 02:37:02 +0000593
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 if (log)
Jason Molenda753e13c2017-02-02 03:02:51 +0000595 log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
596 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
Jason Molenda705b1802014-06-13 02:37:02 +0000597
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 return success;
Jason Molenda705b1802014-06-13 02:37:02 +0000599}
600
Kate Stoneb9c1b512016-09-06 20:57:50 +0000601SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
602 ThreadPlan *new_plan) {
603 SBError sb_error;
Jason Molenda705b1802014-06-13 02:37:02 +0000604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605 Process *process = exe_ctx.GetProcessPtr();
606 if (!process) {
607 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
Jim Ingham64e7ead2012-05-03 21:19:36 +0000608 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609 }
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
Adrian Prantl05097242018-04-30 16:49:04 +0000618 // plans executed, and then a "continue" will resume the plan.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000619 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;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000633}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634
Kate Stoneb9c1b512016-09-06 20:57:50 +0000635void SBThread::StepOver(lldb::RunMode stop_other_threads) {
636 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000637
Kate Stoneb9c1b512016-09-06 20:57:50 +0000638 std::unique_lock<std::recursive_mutex> lock;
639 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000640
Kate Stoneb9c1b512016-09-06 20:57:50 +0000641 if (log)
642 log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
643 static_cast<void *>(exe_ctx.GetThreadPtr()),
644 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000645
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646 if (exe_ctx.HasThreadScope()) {
647 Thread *thread = exe_ctx.GetThreadPtr();
648 bool abort_other_plans = false;
649 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 ThreadPlanSP new_plan_sp;
652 if (frame_sp) {
653 if (frame_sp->HasDebugInformation()) {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000654 const LazyBool avoid_no_debug = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000655 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
656 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
657 abort_other_plans, sc.line_entry, sc, stop_other_threads,
658 avoid_no_debug);
659 } else {
660 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
661 true, abort_other_plans, stop_other_threads);
662 }
Greg Clayton481cef22011-01-21 06:11:58 +0000663 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664
665 // This returns an error, we should use it!
666 ResumeNewPlan(exe_ctx, new_plan_sp.get());
667 }
Greg Clayton481cef22011-01-21 06:11:58 +0000668}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000669
Kate Stoneb9c1b512016-09-06 20:57:50 +0000670void SBThread::StepInto(lldb::RunMode stop_other_threads) {
671 StepInto(NULL, stop_other_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000672}
673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674void SBThread::StepInto(const char *target_name,
675 lldb::RunMode stop_other_threads) {
676 SBError error;
677 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678}
679
Kate Stoneb9c1b512016-09-06 20:57:50 +0000680void SBThread::StepInto(const char *target_name, uint32_t end_line,
681 SBError &error, lldb::RunMode stop_other_threads) {
682 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000683
Kate Stoneb9c1b512016-09-06 20:57:50 +0000684 std::unique_lock<std::recursive_mutex> lock;
685 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000686
Kate Stoneb9c1b512016-09-06 20:57:50 +0000687 if (log)
688 log->Printf(
689 "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
690 static_cast<void *>(exe_ctx.GetThreadPtr()),
691 target_name ? target_name : "<NULL>",
692 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000693
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 if (exe_ctx.HasThreadScope()) {
695 bool abort_other_plans = false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000696
697 Thread *thread = exe_ctx.GetThreadPtr();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000698 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
699 ThreadPlanSP new_plan_sp;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000700
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 if (frame_sp && frame_sp->HasDebugInformation()) {
702 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
703 AddressRange range;
704 if (end_line == LLDB_INVALID_LINE_NUMBER)
705 range = sc.line_entry.range;
706 else {
707 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
708 return;
709 }
710
711 const LazyBool step_out_avoids_code_without_debug_info =
712 eLazyBoolCalculate;
713 const LazyBool step_in_avoids_code_without_debug_info =
714 eLazyBoolCalculate;
715 new_plan_sp = thread->QueueThreadPlanForStepInRange(
716 abort_other_plans, range, sc, target_name, stop_other_threads,
717 step_in_avoids_code_without_debug_info,
718 step_out_avoids_code_without_debug_info);
719 } else {
720 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
721 false, abort_other_plans, stop_other_threads);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000722 }
723
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
725 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000726}
727
Kate Stoneb9c1b512016-09-06 20:57:50 +0000728void SBThread::StepOut() {
729 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Richard Mittonf86248d2013-09-12 02:20:34 +0000730
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 std::unique_lock<std::recursive_mutex> lock;
732 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Richard Mittonf86248d2013-09-12 02:20:34 +0000733
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 if (log)
735 log->Printf("SBThread(%p)::StepOut ()",
736 static_cast<void *>(exe_ctx.GetThreadPtr()));
Richard Mittonf86248d2013-09-12 02:20:34 +0000737
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738 if (exe_ctx.HasThreadScope()) {
739 bool abort_other_plans = false;
740 bool stop_other_threads = false;
Richard Mittonf86248d2013-09-12 02:20:34 +0000741
742 Thread *thread = exe_ctx.GetThreadPtr();
743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744 const LazyBool avoid_no_debug = eLazyBoolCalculate;
745 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
746 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
747 eVoteNoOpinion, 0, avoid_no_debug));
748
749 // This returns an error, we should use it!
750 ResumeNewPlan(exe_ctx, new_plan_sp.get());
751 }
752}
753
754void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
755 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
756
757 std::unique_lock<std::recursive_mutex> lock;
758 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
759
760 if (!sb_frame.IsValid()) {
761 if (log)
762 log->Printf(
763 "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
764 static_cast<void *>(exe_ctx.GetThreadPtr()));
765 return;
766 }
767
768 StackFrameSP frame_sp(sb_frame.GetFrameSP());
769 if (log) {
770 SBStream frame_desc_strm;
771 sb_frame.GetDescription(frame_desc_strm);
772 log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
773 static_cast<void *>(exe_ctx.GetThreadPtr()),
774 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
775 }
776
777 if (exe_ctx.HasThreadScope()) {
778 bool abort_other_plans = false;
779 bool stop_other_threads = false;
780 Thread *thread = exe_ctx.GetThreadPtr();
781 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
782 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
783 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
784 static_cast<void *>(exe_ctx.GetThreadPtr()),
785 sb_frame.GetThread().GetThreadID(), thread->GetID());
786 }
787
788 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
789 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
790 eVoteNoOpinion, frame_sp->GetFrameIndex()));
791
792 // This returns an error, we should use it!
793 ResumeNewPlan(exe_ctx, new_plan_sp.get());
794 }
795}
796
797void SBThread::StepInstruction(bool step_over) {
798 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
799
800 std::unique_lock<std::recursive_mutex> lock;
801 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
802
803 if (log)
804 log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
805 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
806
807 if (exe_ctx.HasThreadScope()) {
808 Thread *thread = exe_ctx.GetThreadPtr();
809 ThreadPlanSP new_plan_sp(
810 thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
811
812 // This returns an error, we should use it!
813 ResumeNewPlan(exe_ctx, new_plan_sp.get());
814 }
815}
816
817void SBThread::RunToAddress(lldb::addr_t addr) {
818 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
819
820 std::unique_lock<std::recursive_mutex> lock;
821 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
822
823 if (log)
824 log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
825 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
826
827 if (exe_ctx.HasThreadScope()) {
828 bool abort_other_plans = false;
829 bool stop_other_threads = true;
830
831 Address target_addr(addr);
832
833 Thread *thread = exe_ctx.GetThreadPtr();
834
835 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
836 abort_other_plans, target_addr, stop_other_threads));
837
838 // This returns an error, we should use it!
839 ResumeNewPlan(exe_ctx, new_plan_sp.get());
840 }
841}
842
843SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
844 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
845 SBError sb_error;
846 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
847 char path[PATH_MAX];
848
849 std::unique_lock<std::recursive_mutex> lock;
850 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
851
852 StackFrameSP frame_sp(sb_frame.GetFrameSP());
853
854 if (log) {
855 SBStream frame_desc_strm;
856 sb_frame.GetDescription(frame_desc_strm);
857 sb_file_spec->GetPath(path, sizeof(path));
858 log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
859 "file+line = %s:%u)",
860 static_cast<void *>(exe_ctx.GetThreadPtr()),
861 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
862 path, line);
863 }
864
865 if (exe_ctx.HasThreadScope()) {
866 Target *target = exe_ctx.GetTargetPtr();
867 Thread *thread = exe_ctx.GetThreadPtr();
868
869 if (line == 0) {
870 sb_error.SetErrorString("invalid line argument");
871 return sb_error;
872 }
873
874 if (!frame_sp) {
875 frame_sp = thread->GetSelectedFrame();
876 if (!frame_sp)
877 frame_sp = thread->GetStackFrameAtIndex(0);
878 }
879
880 SymbolContext frame_sc;
881 if (!frame_sp) {
882 sb_error.SetErrorString("no valid frames in thread to step");
883 return sb_error;
884 }
885
886 // If we have a frame, get its line
887 frame_sc = frame_sp->GetSymbolContext(
888 eSymbolContextCompUnit | eSymbolContextFunction |
889 eSymbolContextLineEntry | eSymbolContextSymbol);
890
891 if (frame_sc.comp_unit == NULL) {
892 sb_error.SetErrorStringWithFormat(
893 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
894 return sb_error;
895 }
896
897 FileSpec step_file_spec;
898 if (sb_file_spec.IsValid()) {
899 // The file spec passed in was valid, so use it
900 step_file_spec = sb_file_spec.ref();
901 } else {
902 if (frame_sc.line_entry.IsValid())
903 step_file_spec = frame_sc.line_entry.file;
904 else {
905 sb_error.SetErrorString("invalid file argument or no file for frame");
906 return sb_error;
907 }
908 }
909
910 // Grab the current function, then we will make sure the "until" address is
911 // within the function. We discard addresses that are out of the current
912 // function, and then if there are no addresses remaining, give an
Adrian Prantl05097242018-04-30 16:49:04 +0000913 // appropriate error message.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000914
915 bool all_in_function = true;
916 AddressRange fun_range = frame_sc.function->GetAddressRange();
917
918 std::vector<addr_t> step_over_until_addrs;
919 const bool abort_other_plans = false;
920 const bool stop_other_threads = false;
921 const bool check_inlines = true;
922 const bool exact = false;
923
924 SymbolContextList sc_list;
925 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
926 step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
927 sc_list);
928 if (num_matches > 0) {
929 SymbolContext sc;
930 for (uint32_t i = 0; i < num_matches; ++i) {
931 if (sc_list.GetContextAtIndex(i, sc)) {
932 addr_t step_addr =
933 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
934 if (step_addr != LLDB_INVALID_ADDRESS) {
935 if (fun_range.ContainsLoadAddress(step_addr, target))
936 step_over_until_addrs.push_back(step_addr);
937 else
938 all_in_function = false;
939 }
940 }
941 }
942 }
943
944 if (step_over_until_addrs.empty()) {
945 if (all_in_function) {
946 step_file_spec.GetPath(path, sizeof(path));
947 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
948 line);
949 } else
950 sb_error.SetErrorString("step until target not in current function");
951 } else {
952 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
953 abort_other_plans, &step_over_until_addrs[0],
954 step_over_until_addrs.size(), stop_other_threads,
955 frame_sp->GetFrameIndex()));
956
957 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
958 }
959 } else {
960 sb_error.SetErrorString("this SBThread object is invalid");
961 }
962 return sb_error;
963}
964
965SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
966 return StepUsingScriptedThreadPlan(script_class_name, true);
967}
968
969SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
970 bool resume_immediately) {
971 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
972 SBError sb_error;
973
974 std::unique_lock<std::recursive_mutex> lock;
975 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
976
977 if (log) {
978 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
979 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
980 }
981
982 if (!exe_ctx.HasThreadScope()) {
983 sb_error.SetErrorString("this SBThread object is invalid");
Richard Mittonf86248d2013-09-12 02:20:34 +0000984 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985 }
Richard Mittonf86248d2013-09-12 02:20:34 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 Thread *thread = exe_ctx.GetThreadPtr();
988 ThreadPlanSP thread_plan_sp =
989 thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000990
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 if (!thread_plan_sp) {
992 sb_error.SetErrorStringWithFormat(
993 "Error queueing thread plan for class: %s", script_class_name);
Jim Ingham44137582012-09-12 00:40:39 +0000994 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 }
Jim Ingham44137582012-09-12 00:40:39 +0000996
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 if (!resume_immediately) {
Jim Ingham4ac8e932016-07-08 02:12:05 +0000998 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 }
Jim Ingham4ac8e932016-07-08 02:12:05 +00001000
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 if (thread_plan_sp)
1002 sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1003 else {
1004 sb_error.SetErrorStringWithFormat(
1005 "Error resuming thread plan for class: %s.", script_class_name);
Greg Claytonc9858e42012-04-06 02:17:47 +00001006 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001007 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing "
1008 "thread plan for class: %s",
1009 static_cast<void *>(exe_ctx.GetThreadPtr()),
1010 script_class_name);
1011 }
1012
1013 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001014}
1015
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1017 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1018 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020 std::unique_lock<std::recursive_mutex> lock;
1021 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1022
1023 if (log)
1024 log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1025 static_cast<void *>(exe_ctx.GetThreadPtr()),
1026 file_spec->GetPath().c_str(), line);
1027
1028 if (!exe_ctx.HasThreadScope()) {
1029 sb_error.SetErrorString("this SBThread object is invalid");
1030 return sb_error;
1031 }
1032
1033 Thread *thread = exe_ctx.GetThreadPtr();
1034
Zachary Turner97206d52017-05-12 04:51:55 +00001035 Status err = thread->JumpToLine(file_spec.get(), line, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001036 sb_error.SetError(err);
1037 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001038}
1039
Kate Stoneb9c1b512016-09-06 20:57:50 +00001040SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1041 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001042
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1044
1045 std::unique_lock<std::recursive_mutex> lock;
1046 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1047
1048 if (log)
1049 log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1050 static_cast<void *>(exe_ctx.GetThreadPtr()),
1051 frame.GetFrameID());
1052
1053 if (exe_ctx.HasThreadScope()) {
1054 Thread *thread = exe_ctx.GetThreadPtr();
1055 sb_error.SetError(
1056 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1057 }
1058
1059 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001060}
1061
Kate Stoneb9c1b512016-09-06 20:57:50 +00001062SBError SBThread::UnwindInnermostExpression() {
1063 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001064
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1066
1067 std::unique_lock<std::recursive_mutex> lock;
1068 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1069
1070 if (log)
1071 log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
1072 static_cast<void *>(exe_ctx.GetThreadPtr()));
1073
1074 if (exe_ctx.HasThreadScope()) {
1075 Thread *thread = exe_ctx.GetThreadPtr();
1076 sb_error.SetError(thread->UnwindInnermostExpression());
1077 if (sb_error.Success())
1078 thread->SetSelectedFrameByIndex(0, false);
1079 }
1080
1081 return sb_error;
Andrew Kaylora75418d2013-04-15 23:33:53 +00001082}
1083
Kate Stoneb9c1b512016-09-06 20:57:50 +00001084bool SBThread::Suspend() {
1085 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1086 std::unique_lock<std::recursive_mutex> lock;
1087 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Inghamb2e7d282016-06-10 17:22:26 +00001088
Kate Stoneb9c1b512016-09-06 20:57:50 +00001089 bool result = false;
1090 if (exe_ctx.HasThreadScope()) {
1091 Process::StopLocker stop_locker;
1092 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1093 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1094 result = true;
1095 } else {
1096 if (log)
1097 log->Printf("SBThread(%p)::Suspend() => error: process is running",
1098 static_cast<void *>(exe_ctx.GetThreadPtr()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001099 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001100 }
1101 if (log)
1102 log->Printf("SBThread(%p)::Suspend() => %i",
1103 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1104 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001105}
1106
Kate Stoneb9c1b512016-09-06 20:57:50 +00001107bool SBThread::Resume() {
1108 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1109 std::unique_lock<std::recursive_mutex> lock;
1110 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001111
Kate Stoneb9c1b512016-09-06 20:57:50 +00001112 bool result = false;
1113 if (exe_ctx.HasThreadScope()) {
1114 Process::StopLocker stop_locker;
1115 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1116 const bool override_suspend = true;
1117 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1118 result = true;
1119 } else {
1120 if (log)
1121 log->Printf("SBThread(%p)::Resume() => error: process is running",
1122 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +00001123 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 }
1125 if (log)
1126 log->Printf("SBThread(%p)::Resume() => %i",
1127 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1128 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001129}
1130
Kate Stoneb9c1b512016-09-06 20:57:50 +00001131bool SBThread::IsSuspended() {
1132 std::unique_lock<std::recursive_mutex> lock;
1133 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135 if (exe_ctx.HasThreadScope())
1136 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1137 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001138}
1139
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140bool SBThread::IsStopped() {
1141 std::unique_lock<std::recursive_mutex> lock;
1142 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 if (exe_ctx.HasThreadScope())
1145 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1146 return false;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001147}
1148
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149SBProcess SBThread::GetProcess() {
1150 SBProcess sb_process;
1151 std::unique_lock<std::recursive_mutex> lock;
1152 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 if (exe_ctx.HasThreadScope()) {
1155 // Have to go up to the target so we can get a shared pointer to our
1156 // process...
1157 sb_process.SetSP(exe_ctx.GetProcessSP());
1158 }
Jim Ingham4fc6cb92012-08-22 21:34:33 +00001159
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1161 if (log) {
1162 SBStream frame_desc_strm;
1163 sb_process.GetDescription(frame_desc_strm);
1164 log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1165 static_cast<void *>(exe_ctx.GetThreadPtr()),
1166 static_cast<void *>(sb_process.GetSP().get()),
1167 frame_desc_strm.GetData());
1168 }
1169
1170 return sb_process;
1171}
1172
1173uint32_t SBThread::GetNumFrames() {
1174 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1175
1176 uint32_t num_frames = 0;
1177 std::unique_lock<std::recursive_mutex> lock;
1178 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1179
1180 if (exe_ctx.HasThreadScope()) {
1181 Process::StopLocker stop_locker;
1182 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1183 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1184 } else {
1185 if (log)
1186 log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1187 static_cast<void *>(exe_ctx.GetThreadPtr()));
1188 }
1189 }
1190
1191 if (log)
1192 log->Printf("SBThread(%p)::GetNumFrames () => %u",
1193 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1194
1195 return num_frames;
1196}
1197
1198SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1199 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1200
1201 SBFrame sb_frame;
1202 StackFrameSP frame_sp;
1203 std::unique_lock<std::recursive_mutex> lock;
1204 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1205
1206 if (exe_ctx.HasThreadScope()) {
1207 Process::StopLocker stop_locker;
1208 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1209 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1210 sb_frame.SetFrameSP(frame_sp);
1211 } else {
1212 if (log)
1213 log->Printf(
1214 "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1215 static_cast<void *>(exe_ctx.GetThreadPtr()));
1216 }
1217 }
1218
1219 if (log) {
1220 SBStream frame_desc_strm;
1221 sb_frame.GetDescription(frame_desc_strm);
1222 log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1223 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1224 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1225 }
1226
1227 return sb_frame;
1228}
1229
1230lldb::SBFrame SBThread::GetSelectedFrame() {
1231 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1232
1233 SBFrame sb_frame;
1234 StackFrameSP frame_sp;
1235 std::unique_lock<std::recursive_mutex> lock;
1236 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1237
1238 if (exe_ctx.HasThreadScope()) {
1239 Process::StopLocker stop_locker;
1240 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1241 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1242 sb_frame.SetFrameSP(frame_sp);
1243 } else {
1244 if (log)
1245 log->Printf(
1246 "SBThread(%p)::GetSelectedFrame() => error: process is running",
1247 static_cast<void *>(exe_ctx.GetThreadPtr()));
1248 }
1249 }
1250
1251 if (log) {
1252 SBStream frame_desc_strm;
1253 sb_frame.GetDescription(frame_desc_strm);
1254 log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1255 static_cast<void *>(exe_ctx.GetThreadPtr()),
1256 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1257 }
1258
1259 return sb_frame;
1260}
1261
1262lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1263 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1264
1265 SBFrame sb_frame;
1266 StackFrameSP frame_sp;
1267 std::unique_lock<std::recursive_mutex> lock;
1268 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1269
1270 if (exe_ctx.HasThreadScope()) {
1271 Process::StopLocker stop_locker;
1272 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1273 Thread *thread = exe_ctx.GetThreadPtr();
1274 frame_sp = thread->GetStackFrameAtIndex(idx);
1275 if (frame_sp) {
1276 thread->SetSelectedFrame(frame_sp.get());
1277 sb_frame.SetFrameSP(frame_sp);
1278 }
1279 } else {
1280 if (log)
1281 log->Printf(
1282 "SBThread(%p)::SetSelectedFrame() => error: process is running",
1283 static_cast<void *>(exe_ctx.GetThreadPtr()));
1284 }
1285 }
1286
1287 if (log) {
1288 SBStream frame_desc_strm;
1289 sb_frame.GetDescription(frame_desc_strm);
1290 log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1291 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1292 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1293 }
1294 return sb_frame;
1295}
1296
1297bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1298 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1299}
1300
1301SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1302 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1303}
1304
1305SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1306 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1307}
1308
1309bool SBThread::operator==(const SBThread &rhs) const {
1310 return m_opaque_sp->GetThreadSP().get() ==
1311 rhs.m_opaque_sp->GetThreadSP().get();
1312}
1313
1314bool SBThread::operator!=(const SBThread &rhs) const {
1315 return m_opaque_sp->GetThreadSP().get() !=
1316 rhs.m_opaque_sp->GetThreadSP().get();
1317}
1318
1319bool SBThread::GetStatus(SBStream &status) const {
1320 Stream &strm = status.ref();
1321
1322 std::unique_lock<std::recursive_mutex> lock;
1323 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1324
1325 if (exe_ctx.HasThreadScope()) {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001326 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001327 } else
1328 strm.PutCString("No status");
1329
1330 return true;
1331}
1332
1333bool SBThread::GetDescription(SBStream &description) const {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001334 return GetDescription(description, false);
1335}
1336
1337bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 Stream &strm = description.ref();
1339
1340 std::unique_lock<std::recursive_mutex> lock;
1341 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1342
1343 if (exe_ctx.HasThreadScope()) {
1344 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
Jim Ingham6a9767c2016-11-08 20:36:40 +00001345 LLDB_INVALID_THREAD_ID,
1346 stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001347 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1348 // exe_ctx.GetThreadPtr()->GetID());
1349 } else
1350 strm.PutCString("No value");
1351
1352 return true;
1353}
1354
1355SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1356 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1357 std::unique_lock<std::recursive_mutex> lock;
1358 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1359 SBThread sb_origin_thread;
1360
1361 if (exe_ctx.HasThreadScope()) {
1362 Process::StopLocker stop_locker;
1363 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1364 ThreadSP real_thread(exe_ctx.GetThreadSP());
1365 if (real_thread) {
1366 ConstString type_const(type);
1367 Process *process = exe_ctx.GetProcessPtr();
1368 if (process) {
1369 SystemRuntime *runtime = process->GetSystemRuntime();
1370 if (runtime) {
1371 ThreadSP new_thread_sp(
1372 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1373 if (new_thread_sp) {
1374 // Save this in the Process' ExtendedThreadList so a strong
Adrian Prantl05097242018-04-30 16:49:04 +00001375 // pointer retains the object.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001376 process->GetExtendedThreadList().AddThread(new_thread_sp);
1377 sb_origin_thread.SetThread(new_thread_sp);
1378 if (log) {
1379 const char *queue_name = new_thread_sp->GetQueueName();
1380 if (queue_name == NULL)
1381 queue_name = "";
1382 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1383 "extended Thread "
1384 "created (%p) with queue_id 0x%" PRIx64
1385 " queue name '%s'",
1386 static_cast<void *>(exe_ctx.GetThreadPtr()),
1387 static_cast<void *>(new_thread_sp.get()),
1388 new_thread_sp->GetQueueID(), queue_name);
1389 }
Greg Clayton7fdf9ef2012-04-05 16:12:35 +00001390 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001391 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001392 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001393 }
1394 } else {
1395 if (log)
1396 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1397 "process is running",
1398 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonf028a1f2010-12-17 02:26:24 +00001399 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001401
Kate Stoneb9c1b512016-09-06 20:57:50 +00001402 if (log && sb_origin_thread.IsValid() == false)
1403 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1404 "Valid thread",
1405 static_cast<void *>(exe_ctx.GetThreadPtr()));
1406 return sb_origin_thread;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001407}
1408
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1410 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1411 if (thread_sp)
1412 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1413 return LLDB_INVALID_INDEX32;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001414}
1415
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416bool SBThread::SafeToCallFunctions() {
1417 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1418 if (thread_sp)
1419 return thread_sp->SafeToCallFunctions();
1420 return true;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001421}
1422
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423lldb_private::Thread *SBThread::operator->() {
1424 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1425 if (thread_sp)
1426 return thread_sp.get();
1427 else
1428 return NULL;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001429}
Greg Claytonf028a1f2010-12-17 02:26:24 +00001430
Kate Stoneb9c1b512016-09-06 20:57:50 +00001431lldb_private::Thread *SBThread::get() {
1432 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1433 if (thread_sp)
1434 return thread_sp.get();
1435 else
1436 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001437}