blob: 65ccb465c8da3dd1b0e763ab80ea19b6b19aafaa [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"
Jason Molenda705b1802014-06-13 02:37:02 +000019#include "lldb/Core/StructuredData.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000020#include "lldb/Core/ValueObject.h"
Greg Clayton66111032010-06-23 01:19:29 +000021#include "lldb/Interpreter/CommandInterpreter.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000022#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Symbol/SymbolContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Target/Process.h"
Jason Molendab9ffa982014-04-25 00:01:15 +000025#include "lldb/Target/Queue.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000026#include "lldb/Target/StopInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000027#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Target/Target.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Target/ThreadPlan.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000031#include "lldb/Target/ThreadPlanStepInRange.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000032#include "lldb/Target/ThreadPlanStepInstruction.h"
33#include "lldb/Target/ThreadPlanStepOut.h"
34#include "lldb/Target/ThreadPlanStepRange.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000035#include "lldb/Target/UnixSignals.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000036#include "lldb/Utility/Stream.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 // We currently only support ThreadSanitizer.
297 if (type != eInstrumentationRuntimeTypeThreadSanitizer)
298 return threads;
299
300 std::unique_lock<std::recursive_mutex> lock;
301 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
302
303 if (!exe_ctx.HasThreadScope())
304 return threads;
305
306 ProcessSP process_sp = exe_ctx.GetProcessSP();
307
308 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
309 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
310 if (!info)
311 return threads;
312
313 return process_sp->GetInstrumentationRuntime(type)
314 ->GetBacktracesFromExtendedStopInfo(info);
Kuba Brecka6a831432016-03-23 15:36:22 +0000315}
316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
318 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000319
Kate Stoneb9c1b512016-09-06 20:57:50 +0000320 std::unique_lock<std::recursive_mutex> lock;
321 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 if (exe_ctx.HasThreadScope()) {
324 Process::StopLocker stop_locker;
325 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000326
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
328 if (stop_info_sp) {
329 const char *stop_desc = stop_info_sp->GetDescription();
330 if (stop_desc) {
331 if (log)
332 log->Printf(
333 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
334 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
335 if (dst)
336 return ::snprintf(dst, dst_len, "%s", stop_desc);
337 else {
338 // NULL dst passed in, return the length needed to contain the
339 // description
340 return ::strlen(stop_desc) + 1; // Include the NULL byte for size
341 }
342 } else {
343 size_t stop_desc_len = 0;
344 switch (stop_info_sp->GetStopReason()) {
345 case eStopReasonTrace:
346 case eStopReasonPlanComplete: {
347 static char trace_desc[] = "step";
348 stop_desc = trace_desc;
349 stop_desc_len =
350 sizeof(trace_desc); // Include the NULL byte for size
351 } break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000352
Kate Stoneb9c1b512016-09-06 20:57:50 +0000353 case eStopReasonBreakpoint: {
354 static char bp_desc[] = "breakpoint hit";
355 stop_desc = bp_desc;
356 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
357 } break;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000358
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 case eStopReasonWatchpoint: {
360 static char wp_desc[] = "watchpoint hit";
361 stop_desc = wp_desc;
362 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
363 } break;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000364
Kate Stoneb9c1b512016-09-06 20:57:50 +0000365 case eStopReasonSignal: {
366 stop_desc =
367 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
368 stop_info_sp->GetValue());
369 if (stop_desc == NULL || stop_desc[0] == '\0') {
370 static char signal_desc[] = "signal";
371 stop_desc = signal_desc;
372 stop_desc_len =
373 sizeof(signal_desc); // Include the NULL byte for size
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000374 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000375 } break;
376
377 case eStopReasonException: {
378 char exc_desc[] = "exception";
379 stop_desc = exc_desc;
380 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
381 } break;
382
383 case eStopReasonExec: {
384 char exc_desc[] = "exec";
385 stop_desc = exc_desc;
386 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
387 } break;
388
389 case eStopReasonThreadExiting: {
390 char limbo_desc[] = "thread exiting";
391 stop_desc = limbo_desc;
392 stop_desc_len = sizeof(limbo_desc);
393 } break;
394 default:
395 break;
396 }
397
398 if (stop_desc && stop_desc[0]) {
Greg Claytonc9858e42012-04-06 02:17:47 +0000399 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000400 log->Printf(
401 "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
402 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
403
404 if (dst)
405 return ::snprintf(dst, dst_len, "%s", stop_desc) +
406 1; // Include the NULL byte
407
408 if (stop_desc_len == 0)
409 stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
410
411 return stop_desc_len;
412 }
Greg Claytonc9858e42012-04-06 02:17:47 +0000413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000414 }
415 } else {
416 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
417 if (log)
418 log->Printf(
419 "SBThread(%p)::GetStopDescription() => error: process is running",
420 static_cast<void *>(exe_ctx.GetThreadPtr()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000422 }
423 if (dst)
424 *dst = 0;
425 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000426}
427
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428SBValue SBThread::GetStopReturnValue() {
429 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
430 ValueObjectSP return_valobj_sp;
431 std::unique_lock<std::recursive_mutex> lock;
432 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 if (exe_ctx.HasThreadScope()) {
435 Process::StopLocker stop_locker;
436 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
437 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
438 if (stop_info_sp) {
439 return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
440 }
441 } else {
442 if (log)
443 log->Printf(
444 "SBThread(%p)::GetStopReturnValue() => error: process is running",
445 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jim Ingham73ca05a2011-12-17 01:35:57 +0000446 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000448
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449 if (log)
450 log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
451 static_cast<void *>(exe_ctx.GetThreadPtr()),
452 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
453 : "<no return value>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000454
Kate Stoneb9c1b512016-09-06 20:57:50 +0000455 return SBValue(return_valobj_sp);
Jim Ingham73ca05a2011-12-17 01:35:57 +0000456}
457
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
459 m_opaque_sp->SetThreadSP(lldb_object_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000460}
461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462lldb::tid_t SBThread::GetThreadID() const {
463 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
464 if (thread_sp)
465 return thread_sp->GetID();
466 return LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000467}
468
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469uint32_t SBThread::GetIndexID() const {
470 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
471 if (thread_sp)
472 return thread_sp->GetIndexID();
473 return LLDB_INVALID_INDEX32;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474}
Greg Clayton1ac04c32012-02-21 00:09:25 +0000475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476const char *SBThread::GetName() const {
477 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
478 const char *name = NULL;
479 std::unique_lock<std::recursive_mutex> lock;
480 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000481
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 if (exe_ctx.HasThreadScope()) {
483 Process::StopLocker stop_locker;
484 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
485 name = exe_ctx.GetThreadPtr()->GetName();
486 } else {
487 if (log)
488 log->Printf("SBThread(%p)::GetName() => error: process is running",
489 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000490 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000492
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493 if (log)
494 log->Printf("SBThread(%p)::GetName () => %s",
495 static_cast<void *>(exe_ctx.GetThreadPtr()),
496 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000497
Kate Stoneb9c1b512016-09-06 20:57:50 +0000498 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499}
500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501const char *SBThread::GetQueueName() const {
502 const char *name = NULL;
503 std::unique_lock<std::recursive_mutex> lock;
504 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000505
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
507 if (exe_ctx.HasThreadScope()) {
508 Process::StopLocker stop_locker;
509 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
510 name = exe_ctx.GetThreadPtr()->GetQueueName();
511 } else {
512 if (log)
513 log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
514 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000515 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000517
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518 if (log)
519 log->Printf("SBThread(%p)::GetQueueName () => %s",
520 static_cast<void *>(exe_ctx.GetThreadPtr()),
521 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000522
Kate Stoneb9c1b512016-09-06 20:57:50 +0000523 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000524}
525
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526lldb::queue_id_t SBThread::GetQueueID() const {
527 queue_id_t id = LLDB_INVALID_QUEUE_ID;
528 std::unique_lock<std::recursive_mutex> lock;
529 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000530
Kate Stoneb9c1b512016-09-06 20:57:50 +0000531 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
532 if (exe_ctx.HasThreadScope()) {
533 Process::StopLocker stop_locker;
534 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
535 id = exe_ctx.GetThreadPtr()->GetQueueID();
536 } else {
537 if (log)
538 log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
539 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molenda4fdb5862013-10-21 23:52:54 +0000540 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000541 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000542
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 if (log)
544 log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
545 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 return id;
Jason Molenda4fdb5862013-10-21 23:52:54 +0000548}
549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
551 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
552 bool success = false;
553 std::unique_lock<std::recursive_mutex> lock;
554 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molenda705b1802014-06-13 02:37:02 +0000555
Kate Stoneb9c1b512016-09-06 20:57:50 +0000556 if (exe_ctx.HasThreadScope()) {
557 Process::StopLocker stop_locker;
558 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
559 Thread *thread = exe_ctx.GetThreadPtr();
560 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
561 if (info_root_sp) {
562 StructuredData::ObjectSP node =
563 info_root_sp->GetObjectForDotSeparatedPath(path);
564 if (node) {
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000565 if (node->GetType() == eStructuredDataTypeString) {
Zachary Turner28333212017-05-12 05:49:54 +0000566 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000567 success = true;
568 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000569 if (node->GetType() == eStructuredDataTypeInteger) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
571 success = true;
572 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000573 if (node->GetType() == eStructuredDataTypeFloat) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
575 success = true;
576 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000577 if (node->GetType() == eStructuredDataTypeBoolean) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578 if (node->GetAsBoolean()->GetValue() == true)
579 strm.Printf("true");
580 else
581 strm.Printf("false");
582 success = true;
583 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000584 if (node->GetType() == eStructuredDataTypeNull) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000585 strm.Printf("null");
586 success = true;
587 }
Jason Molenda705b1802014-06-13 02:37:02 +0000588 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000589 }
590 } else {
591 if (log)
592 log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
593 "process is running",
594 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molenda705b1802014-06-13 02:37:02 +0000595 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 }
Jason Molenda705b1802014-06-13 02:37:02 +0000597
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 if (log)
Jason Molenda753e13c2017-02-02 03:02:51 +0000599 log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
600 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
Jason Molenda705b1802014-06-13 02:37:02 +0000601
Kate Stoneb9c1b512016-09-06 20:57:50 +0000602 return success;
Jason Molenda705b1802014-06-13 02:37:02 +0000603}
604
Kate Stoneb9c1b512016-09-06 20:57:50 +0000605SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
606 ThreadPlan *new_plan) {
607 SBError sb_error;
Jason Molenda705b1802014-06-13 02:37:02 +0000608
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609 Process *process = exe_ctx.GetProcessPtr();
610 if (!process) {
611 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
Jim Ingham64e7ead2012-05-03 21:19:36 +0000612 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 }
614
615 Thread *thread = exe_ctx.GetThreadPtr();
616 if (!thread) {
617 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
618 return sb_error;
619 }
620
621 // User level plans should be Master Plans so they can be interrupted, other
622 // plans executed, and
623 // then a "continue" will resume the plan.
624 if (new_plan != NULL) {
625 new_plan->SetIsMasterPlan(true);
626 new_plan->SetOkayToDiscard(false);
627 }
628
629 // Why do we need to set the current thread by ID here???
630 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
631
632 if (process->GetTarget().GetDebugger().GetAsyncExecution())
633 sb_error.ref() = process->Resume();
634 else
635 sb_error.ref() = process->ResumeSynchronous(NULL);
636
637 return sb_error;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000638}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000639
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640void SBThread::StepOver(lldb::RunMode stop_other_threads) {
641 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000642
Kate Stoneb9c1b512016-09-06 20:57:50 +0000643 std::unique_lock<std::recursive_mutex> lock;
644 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000645
Kate Stoneb9c1b512016-09-06 20:57:50 +0000646 if (log)
647 log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
648 static_cast<void *>(exe_ctx.GetThreadPtr()),
649 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000650
Kate Stoneb9c1b512016-09-06 20:57:50 +0000651 if (exe_ctx.HasThreadScope()) {
652 Thread *thread = exe_ctx.GetThreadPtr();
653 bool abort_other_plans = false;
654 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000655
Kate Stoneb9c1b512016-09-06 20:57:50 +0000656 ThreadPlanSP new_plan_sp;
657 if (frame_sp) {
658 if (frame_sp->HasDebugInformation()) {
Jim Ingham4b4b2472014-03-13 02:47:14 +0000659 const LazyBool avoid_no_debug = eLazyBoolCalculate;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
661 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
662 abort_other_plans, sc.line_entry, sc, stop_other_threads,
663 avoid_no_debug);
664 } else {
665 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
666 true, abort_other_plans, stop_other_threads);
667 }
Greg Clayton481cef22011-01-21 06:11:58 +0000668 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000669
670 // This returns an error, we should use it!
671 ResumeNewPlan(exe_ctx, new_plan_sp.get());
672 }
Greg Clayton481cef22011-01-21 06:11:58 +0000673}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000674
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675void SBThread::StepInto(lldb::RunMode stop_other_threads) {
676 StepInto(NULL, stop_other_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000677}
678
Kate Stoneb9c1b512016-09-06 20:57:50 +0000679void SBThread::StepInto(const char *target_name,
680 lldb::RunMode stop_other_threads) {
681 SBError error;
682 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683}
684
Kate Stoneb9c1b512016-09-06 20:57:50 +0000685void SBThread::StepInto(const char *target_name, uint32_t end_line,
686 SBError &error, lldb::RunMode stop_other_threads) {
687 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000688
Kate Stoneb9c1b512016-09-06 20:57:50 +0000689 std::unique_lock<std::recursive_mutex> lock;
690 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000691
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692 if (log)
693 log->Printf(
694 "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
695 static_cast<void *>(exe_ctx.GetThreadPtr()),
696 target_name ? target_name : "<NULL>",
697 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 if (exe_ctx.HasThreadScope()) {
700 bool abort_other_plans = false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000701
702 Thread *thread = exe_ctx.GetThreadPtr();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000703 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
704 ThreadPlanSP new_plan_sp;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000705
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 if (frame_sp && frame_sp->HasDebugInformation()) {
707 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
708 AddressRange range;
709 if (end_line == LLDB_INVALID_LINE_NUMBER)
710 range = sc.line_entry.range;
711 else {
712 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
713 return;
714 }
715
716 const LazyBool step_out_avoids_code_without_debug_info =
717 eLazyBoolCalculate;
718 const LazyBool step_in_avoids_code_without_debug_info =
719 eLazyBoolCalculate;
720 new_plan_sp = thread->QueueThreadPlanForStepInRange(
721 abort_other_plans, range, sc, target_name, stop_other_threads,
722 step_in_avoids_code_without_debug_info,
723 step_out_avoids_code_without_debug_info);
724 } else {
725 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
726 false, abort_other_plans, stop_other_threads);
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000727 }
728
Kate Stoneb9c1b512016-09-06 20:57:50 +0000729 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
730 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000731}
732
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733void SBThread::StepOut() {
734 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Richard Mittonf86248d2013-09-12 02:20:34 +0000735
Kate Stoneb9c1b512016-09-06 20:57:50 +0000736 std::unique_lock<std::recursive_mutex> lock;
737 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Richard Mittonf86248d2013-09-12 02:20:34 +0000738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 if (log)
740 log->Printf("SBThread(%p)::StepOut ()",
741 static_cast<void *>(exe_ctx.GetThreadPtr()));
Richard Mittonf86248d2013-09-12 02:20:34 +0000742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743 if (exe_ctx.HasThreadScope()) {
744 bool abort_other_plans = false;
745 bool stop_other_threads = false;
Richard Mittonf86248d2013-09-12 02:20:34 +0000746
747 Thread *thread = exe_ctx.GetThreadPtr();
748
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 const LazyBool avoid_no_debug = eLazyBoolCalculate;
750 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
751 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
752 eVoteNoOpinion, 0, avoid_no_debug));
753
754 // This returns an error, we should use it!
755 ResumeNewPlan(exe_ctx, new_plan_sp.get());
756 }
757}
758
759void SBThread::StepOutOfFrame(lldb::SBFrame &sb_frame) {
760 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
761
762 std::unique_lock<std::recursive_mutex> lock;
763 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
764
765 if (!sb_frame.IsValid()) {
766 if (log)
767 log->Printf(
768 "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
769 static_cast<void *>(exe_ctx.GetThreadPtr()));
770 return;
771 }
772
773 StackFrameSP frame_sp(sb_frame.GetFrameSP());
774 if (log) {
775 SBStream frame_desc_strm;
776 sb_frame.GetDescription(frame_desc_strm);
777 log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
778 static_cast<void *>(exe_ctx.GetThreadPtr()),
779 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
780 }
781
782 if (exe_ctx.HasThreadScope()) {
783 bool abort_other_plans = false;
784 bool stop_other_threads = false;
785 Thread *thread = exe_ctx.GetThreadPtr();
786 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
787 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
788 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
789 static_cast<void *>(exe_ctx.GetThreadPtr()),
790 sb_frame.GetThread().GetThreadID(), thread->GetID());
791 }
792
793 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
794 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
795 eVoteNoOpinion, frame_sp->GetFrameIndex()));
796
797 // This returns an error, we should use it!
798 ResumeNewPlan(exe_ctx, new_plan_sp.get());
799 }
800}
801
802void SBThread::StepInstruction(bool step_over) {
803 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
804
805 std::unique_lock<std::recursive_mutex> lock;
806 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
807
808 if (log)
809 log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
810 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
811
812 if (exe_ctx.HasThreadScope()) {
813 Thread *thread = exe_ctx.GetThreadPtr();
814 ThreadPlanSP new_plan_sp(
815 thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true));
816
817 // This returns an error, we should use it!
818 ResumeNewPlan(exe_ctx, new_plan_sp.get());
819 }
820}
821
822void SBThread::RunToAddress(lldb::addr_t addr) {
823 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
824
825 std::unique_lock<std::recursive_mutex> lock;
826 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
827
828 if (log)
829 log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
830 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
831
832 if (exe_ctx.HasThreadScope()) {
833 bool abort_other_plans = false;
834 bool stop_other_threads = true;
835
836 Address target_addr(addr);
837
838 Thread *thread = exe_ctx.GetThreadPtr();
839
840 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
841 abort_other_plans, target_addr, stop_other_threads));
842
843 // This returns an error, we should use it!
844 ResumeNewPlan(exe_ctx, new_plan_sp.get());
845 }
846}
847
848SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
849 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
850 SBError sb_error;
851 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
852 char path[PATH_MAX];
853
854 std::unique_lock<std::recursive_mutex> lock;
855 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
856
857 StackFrameSP frame_sp(sb_frame.GetFrameSP());
858
859 if (log) {
860 SBStream frame_desc_strm;
861 sb_frame.GetDescription(frame_desc_strm);
862 sb_file_spec->GetPath(path, sizeof(path));
863 log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
864 "file+line = %s:%u)",
865 static_cast<void *>(exe_ctx.GetThreadPtr()),
866 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
867 path, line);
868 }
869
870 if (exe_ctx.HasThreadScope()) {
871 Target *target = exe_ctx.GetTargetPtr();
872 Thread *thread = exe_ctx.GetThreadPtr();
873
874 if (line == 0) {
875 sb_error.SetErrorString("invalid line argument");
876 return sb_error;
877 }
878
879 if (!frame_sp) {
880 frame_sp = thread->GetSelectedFrame();
881 if (!frame_sp)
882 frame_sp = thread->GetStackFrameAtIndex(0);
883 }
884
885 SymbolContext frame_sc;
886 if (!frame_sp) {
887 sb_error.SetErrorString("no valid frames in thread to step");
888 return sb_error;
889 }
890
891 // If we have a frame, get its line
892 frame_sc = frame_sp->GetSymbolContext(
893 eSymbolContextCompUnit | eSymbolContextFunction |
894 eSymbolContextLineEntry | eSymbolContextSymbol);
895
896 if (frame_sc.comp_unit == NULL) {
897 sb_error.SetErrorStringWithFormat(
898 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
899 return sb_error;
900 }
901
902 FileSpec step_file_spec;
903 if (sb_file_spec.IsValid()) {
904 // The file spec passed in was valid, so use it
905 step_file_spec = sb_file_spec.ref();
906 } else {
907 if (frame_sc.line_entry.IsValid())
908 step_file_spec = frame_sc.line_entry.file;
909 else {
910 sb_error.SetErrorString("invalid file argument or no file for frame");
911 return sb_error;
912 }
913 }
914
915 // Grab the current function, then we will make sure the "until" address is
916 // within the function. We discard addresses that are out of the current
917 // function, and then if there are no addresses remaining, give an
918 // appropriate
919 // error message.
920
921 bool all_in_function = true;
922 AddressRange fun_range = frame_sc.function->GetAddressRange();
923
924 std::vector<addr_t> step_over_until_addrs;
925 const bool abort_other_plans = false;
926 const bool stop_other_threads = false;
927 const bool check_inlines = true;
928 const bool exact = false;
929
930 SymbolContextList sc_list;
931 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
932 step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
933 sc_list);
934 if (num_matches > 0) {
935 SymbolContext sc;
936 for (uint32_t i = 0; i < num_matches; ++i) {
937 if (sc_list.GetContextAtIndex(i, sc)) {
938 addr_t step_addr =
939 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
940 if (step_addr != LLDB_INVALID_ADDRESS) {
941 if (fun_range.ContainsLoadAddress(step_addr, target))
942 step_over_until_addrs.push_back(step_addr);
943 else
944 all_in_function = false;
945 }
946 }
947 }
948 }
949
950 if (step_over_until_addrs.empty()) {
951 if (all_in_function) {
952 step_file_spec.GetPath(path, sizeof(path));
953 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
954 line);
955 } else
956 sb_error.SetErrorString("step until target not in current function");
957 } else {
958 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
959 abort_other_plans, &step_over_until_addrs[0],
960 step_over_until_addrs.size(), stop_other_threads,
961 frame_sp->GetFrameIndex()));
962
963 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
964 }
965 } else {
966 sb_error.SetErrorString("this SBThread object is invalid");
967 }
968 return sb_error;
969}
970
971SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
972 return StepUsingScriptedThreadPlan(script_class_name, true);
973}
974
975SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
976 bool resume_immediately) {
977 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
978 SBError sb_error;
979
980 std::unique_lock<std::recursive_mutex> lock;
981 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
982
983 if (log) {
984 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
985 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
986 }
987
988 if (!exe_ctx.HasThreadScope()) {
989 sb_error.SetErrorString("this SBThread object is invalid");
Richard Mittonf86248d2013-09-12 02:20:34 +0000990 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 }
Richard Mittonf86248d2013-09-12 02:20:34 +0000992
Kate Stoneb9c1b512016-09-06 20:57:50 +0000993 Thread *thread = exe_ctx.GetThreadPtr();
994 ThreadPlanSP thread_plan_sp =
995 thread->QueueThreadPlanForStepScripted(false, script_class_name, false);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000996
Kate Stoneb9c1b512016-09-06 20:57:50 +0000997 if (!thread_plan_sp) {
998 sb_error.SetErrorStringWithFormat(
999 "Error queueing thread plan for class: %s", script_class_name);
Jim Ingham44137582012-09-12 00:40:39 +00001000 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 }
Jim Ingham44137582012-09-12 00:40:39 +00001002
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 if (!resume_immediately) {
Jim Ingham4ac8e932016-07-08 02:12:05 +00001004 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 }
Jim Ingham4ac8e932016-07-08 02:12:05 +00001006
Kate Stoneb9c1b512016-09-06 20:57:50 +00001007 if (thread_plan_sp)
1008 sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get());
1009 else {
1010 sb_error.SetErrorStringWithFormat(
1011 "Error resuming thread plan for class: %s.", script_class_name);
Greg Claytonc9858e42012-04-06 02:17:47 +00001012 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing "
1014 "thread plan for class: %s",
1015 static_cast<void *>(exe_ctx.GetThreadPtr()),
1016 script_class_name);
1017 }
1018
1019 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001020}
1021
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1023 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1024 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001025
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026 std::unique_lock<std::recursive_mutex> lock;
1027 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1028
1029 if (log)
1030 log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1031 static_cast<void *>(exe_ctx.GetThreadPtr()),
1032 file_spec->GetPath().c_str(), line);
1033
1034 if (!exe_ctx.HasThreadScope()) {
1035 sb_error.SetErrorString("this SBThread object is invalid");
1036 return sb_error;
1037 }
1038
1039 Thread *thread = exe_ctx.GetThreadPtr();
1040
Zachary Turner97206d52017-05-12 04:51:55 +00001041 Status err = thread->JumpToLine(file_spec.get(), line, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042 sb_error.SetError(err);
1043 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001044}
1045
Kate Stoneb9c1b512016-09-06 20:57:50 +00001046SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1047 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001048
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1050
1051 std::unique_lock<std::recursive_mutex> lock;
1052 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1053
1054 if (log)
1055 log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1056 static_cast<void *>(exe_ctx.GetThreadPtr()),
1057 frame.GetFrameID());
1058
1059 if (exe_ctx.HasThreadScope()) {
1060 Thread *thread = exe_ctx.GetThreadPtr();
1061 sb_error.SetError(
1062 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1063 }
1064
1065 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001066}
1067
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068SBError SBThread::UnwindInnermostExpression() {
1069 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001070
Kate Stoneb9c1b512016-09-06 20:57:50 +00001071 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1072
1073 std::unique_lock<std::recursive_mutex> lock;
1074 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1075
1076 if (log)
1077 log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
1078 static_cast<void *>(exe_ctx.GetThreadPtr()));
1079
1080 if (exe_ctx.HasThreadScope()) {
1081 Thread *thread = exe_ctx.GetThreadPtr();
1082 sb_error.SetError(thread->UnwindInnermostExpression());
1083 if (sb_error.Success())
1084 thread->SetSelectedFrameByIndex(0, false);
1085 }
1086
1087 return sb_error;
Andrew Kaylora75418d2013-04-15 23:33:53 +00001088}
1089
Kate Stoneb9c1b512016-09-06 20:57:50 +00001090bool SBThread::Suspend() {
1091 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1092 std::unique_lock<std::recursive_mutex> lock;
1093 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Inghamb2e7d282016-06-10 17:22:26 +00001094
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 bool result = false;
1096 if (exe_ctx.HasThreadScope()) {
1097 Process::StopLocker stop_locker;
1098 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1099 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1100 result = true;
1101 } else {
1102 if (log)
1103 log->Printf("SBThread(%p)::Suspend() => error: process is running",
1104 static_cast<void *>(exe_ctx.GetThreadPtr()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001105 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001106 }
1107 if (log)
1108 log->Printf("SBThread(%p)::Suspend() => %i",
1109 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1110 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001111}
1112
Kate Stoneb9c1b512016-09-06 20:57:50 +00001113bool SBThread::Resume() {
1114 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1115 std::unique_lock<std::recursive_mutex> lock;
1116 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 bool result = false;
1119 if (exe_ctx.HasThreadScope()) {
1120 Process::StopLocker stop_locker;
1121 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1122 const bool override_suspend = true;
1123 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1124 result = true;
1125 } else {
1126 if (log)
1127 log->Printf("SBThread(%p)::Resume() => error: process is running",
1128 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +00001129 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001130 }
1131 if (log)
1132 log->Printf("SBThread(%p)::Resume() => %i",
1133 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1134 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001135}
1136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137bool SBThread::IsSuspended() {
1138 std::unique_lock<std::recursive_mutex> lock;
1139 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001140
Kate Stoneb9c1b512016-09-06 20:57:50 +00001141 if (exe_ctx.HasThreadScope())
1142 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1143 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144}
1145
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146bool SBThread::IsStopped() {
1147 std::unique_lock<std::recursive_mutex> lock;
1148 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150 if (exe_ctx.HasThreadScope())
1151 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1152 return false;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001153}
1154
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155SBProcess SBThread::GetProcess() {
1156 SBProcess sb_process;
1157 std::unique_lock<std::recursive_mutex> lock;
1158 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001159
Kate Stoneb9c1b512016-09-06 20:57:50 +00001160 if (exe_ctx.HasThreadScope()) {
1161 // Have to go up to the target so we can get a shared pointer to our
1162 // process...
1163 sb_process.SetSP(exe_ctx.GetProcessSP());
1164 }
Jim Ingham4fc6cb92012-08-22 21:34:33 +00001165
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1167 if (log) {
1168 SBStream frame_desc_strm;
1169 sb_process.GetDescription(frame_desc_strm);
1170 log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1171 static_cast<void *>(exe_ctx.GetThreadPtr()),
1172 static_cast<void *>(sb_process.GetSP().get()),
1173 frame_desc_strm.GetData());
1174 }
1175
1176 return sb_process;
1177}
1178
1179uint32_t SBThread::GetNumFrames() {
1180 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1181
1182 uint32_t num_frames = 0;
1183 std::unique_lock<std::recursive_mutex> lock;
1184 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1185
1186 if (exe_ctx.HasThreadScope()) {
1187 Process::StopLocker stop_locker;
1188 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1189 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1190 } else {
1191 if (log)
1192 log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1193 static_cast<void *>(exe_ctx.GetThreadPtr()));
1194 }
1195 }
1196
1197 if (log)
1198 log->Printf("SBThread(%p)::GetNumFrames () => %u",
1199 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1200
1201 return num_frames;
1202}
1203
1204SBFrame SBThread::GetFrameAtIndex(uint32_t idx) {
1205 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1206
1207 SBFrame sb_frame;
1208 StackFrameSP frame_sp;
1209 std::unique_lock<std::recursive_mutex> lock;
1210 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1211
1212 if (exe_ctx.HasThreadScope()) {
1213 Process::StopLocker stop_locker;
1214 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1215 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1216 sb_frame.SetFrameSP(frame_sp);
1217 } else {
1218 if (log)
1219 log->Printf(
1220 "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1221 static_cast<void *>(exe_ctx.GetThreadPtr()));
1222 }
1223 }
1224
1225 if (log) {
1226 SBStream frame_desc_strm;
1227 sb_frame.GetDescription(frame_desc_strm);
1228 log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1229 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1230 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1231 }
1232
1233 return sb_frame;
1234}
1235
1236lldb::SBFrame SBThread::GetSelectedFrame() {
1237 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1238
1239 SBFrame sb_frame;
1240 StackFrameSP frame_sp;
1241 std::unique_lock<std::recursive_mutex> lock;
1242 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1243
1244 if (exe_ctx.HasThreadScope()) {
1245 Process::StopLocker stop_locker;
1246 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1247 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1248 sb_frame.SetFrameSP(frame_sp);
1249 } else {
1250 if (log)
1251 log->Printf(
1252 "SBThread(%p)::GetSelectedFrame() => error: process is running",
1253 static_cast<void *>(exe_ctx.GetThreadPtr()));
1254 }
1255 }
1256
1257 if (log) {
1258 SBStream frame_desc_strm;
1259 sb_frame.GetDescription(frame_desc_strm);
1260 log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1261 static_cast<void *>(exe_ctx.GetThreadPtr()),
1262 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1263 }
1264
1265 return sb_frame;
1266}
1267
1268lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1269 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1270
1271 SBFrame sb_frame;
1272 StackFrameSP frame_sp;
1273 std::unique_lock<std::recursive_mutex> lock;
1274 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1275
1276 if (exe_ctx.HasThreadScope()) {
1277 Process::StopLocker stop_locker;
1278 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1279 Thread *thread = exe_ctx.GetThreadPtr();
1280 frame_sp = thread->GetStackFrameAtIndex(idx);
1281 if (frame_sp) {
1282 thread->SetSelectedFrame(frame_sp.get());
1283 sb_frame.SetFrameSP(frame_sp);
1284 }
1285 } else {
1286 if (log)
1287 log->Printf(
1288 "SBThread(%p)::SetSelectedFrame() => error: process is running",
1289 static_cast<void *>(exe_ctx.GetThreadPtr()));
1290 }
1291 }
1292
1293 if (log) {
1294 SBStream frame_desc_strm;
1295 sb_frame.GetDescription(frame_desc_strm);
1296 log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1297 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1298 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1299 }
1300 return sb_frame;
1301}
1302
1303bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1304 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1305}
1306
1307SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1308 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1309}
1310
1311SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1312 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1313}
1314
1315bool SBThread::operator==(const SBThread &rhs) const {
1316 return m_opaque_sp->GetThreadSP().get() ==
1317 rhs.m_opaque_sp->GetThreadSP().get();
1318}
1319
1320bool SBThread::operator!=(const SBThread &rhs) const {
1321 return m_opaque_sp->GetThreadSP().get() !=
1322 rhs.m_opaque_sp->GetThreadSP().get();
1323}
1324
1325bool SBThread::GetStatus(SBStream &status) const {
1326 Stream &strm = status.ref();
1327
1328 std::unique_lock<std::recursive_mutex> lock;
1329 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1330
1331 if (exe_ctx.HasThreadScope()) {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001332 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001333 } else
1334 strm.PutCString("No status");
1335
1336 return true;
1337}
1338
1339bool SBThread::GetDescription(SBStream &description) const {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001340 return GetDescription(description, false);
1341}
1342
1343bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001344 Stream &strm = description.ref();
1345
1346 std::unique_lock<std::recursive_mutex> lock;
1347 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1348
1349 if (exe_ctx.HasThreadScope()) {
1350 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
Jim Ingham6a9767c2016-11-08 20:36:40 +00001351 LLDB_INVALID_THREAD_ID,
1352 stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001353 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1354 // exe_ctx.GetThreadPtr()->GetID());
1355 } else
1356 strm.PutCString("No value");
1357
1358 return true;
1359}
1360
1361SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1362 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1363 std::unique_lock<std::recursive_mutex> lock;
1364 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1365 SBThread sb_origin_thread;
1366
1367 if (exe_ctx.HasThreadScope()) {
1368 Process::StopLocker stop_locker;
1369 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1370 ThreadSP real_thread(exe_ctx.GetThreadSP());
1371 if (real_thread) {
1372 ConstString type_const(type);
1373 Process *process = exe_ctx.GetProcessPtr();
1374 if (process) {
1375 SystemRuntime *runtime = process->GetSystemRuntime();
1376 if (runtime) {
1377 ThreadSP new_thread_sp(
1378 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1379 if (new_thread_sp) {
1380 // Save this in the Process' ExtendedThreadList so a strong
1381 // pointer retains the
1382 // object.
1383 process->GetExtendedThreadList().AddThread(new_thread_sp);
1384 sb_origin_thread.SetThread(new_thread_sp);
1385 if (log) {
1386 const char *queue_name = new_thread_sp->GetQueueName();
1387 if (queue_name == NULL)
1388 queue_name = "";
1389 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1390 "extended Thread "
1391 "created (%p) with queue_id 0x%" PRIx64
1392 " queue name '%s'",
1393 static_cast<void *>(exe_ctx.GetThreadPtr()),
1394 static_cast<void *>(new_thread_sp.get()),
1395 new_thread_sp->GetQueueID(), queue_name);
1396 }
Greg Clayton7fdf9ef2012-04-05 16:12:35 +00001397 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001398 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001399 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 }
1401 } else {
1402 if (log)
1403 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1404 "process is running",
1405 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonf028a1f2010-12-17 02:26:24 +00001406 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001408
Kate Stoneb9c1b512016-09-06 20:57:50 +00001409 if (log && sb_origin_thread.IsValid() == false)
1410 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1411 "Valid thread",
1412 static_cast<void *>(exe_ctx.GetThreadPtr()));
1413 return sb_origin_thread;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001414}
1415
Kate Stoneb9c1b512016-09-06 20:57:50 +00001416uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1417 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1418 if (thread_sp)
1419 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1420 return LLDB_INVALID_INDEX32;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001421}
1422
Kate Stoneb9c1b512016-09-06 20:57:50 +00001423bool SBThread::SafeToCallFunctions() {
1424 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1425 if (thread_sp)
1426 return thread_sp->SafeToCallFunctions();
1427 return true;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001428}
1429
Kate Stoneb9c1b512016-09-06 20:57:50 +00001430lldb_private::Thread *SBThread::operator->() {
1431 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1432 if (thread_sp)
1433 return thread_sp.get();
1434 else
1435 return NULL;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001436}
Greg Claytonf028a1f2010-12-17 02:26:24 +00001437
Kate Stoneb9c1b512016-09-06 20:57:50 +00001438lldb_private::Thread *SBThread::get() {
1439 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1440 if (thread_sp)
1441 return thread_sp.get();
1442 else
1443 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001444}