blob: d19758b0fbda933d2c71a72f3534c923a4bd975c [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- SBThread.cpp --------------------------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
Eli Friedman4c5de692010-06-09 07:44:37 +00009#include "lldb/API/SBThread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000010
Chris Lattner30fdc8d2010-06-08 16:52:24 +000011#include "lldb/API/SBFileSpec.h"
Caroline Ticedde9cff2010-09-20 05:20:02 +000012#include "lldb/API/SBStream.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000013#include "lldb/API/SBSymbolContext.h"
Greg Clayton4e78f602010-11-18 18:52:36 +000014#include "lldb/Breakpoint/BreakpointLocation.h"
Greg Clayton66111032010-06-23 01:19:29 +000015#include "lldb/Core/Debugger.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/StreamFile.h"
Zachary Turnera78bd7f2015-03-03 23:11:11 +000017#include "lldb/Core/ValueObject.h"
Greg Clayton66111032010-06-23 01:19:29 +000018#include "lldb/Interpreter/CommandInterpreter.h"
Zachary Turner93749ab2015-03-03 21:51:25 +000019#include "lldb/Symbol/CompileUnit.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000020#include "lldb/Symbol/SymbolContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000021#include "lldb/Target/Process.h"
Jason Molendab9ffa982014-04-25 00:01:15 +000022#include "lldb/Target/Queue.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000023#include "lldb/Target/StopInfo.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/Target/SystemRuntime.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Target/Target.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000026#include "lldb/Target/Thread.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000027#include "lldb/Target/ThreadPlan.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000028#include "lldb/Target/ThreadPlanStepInRange.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000029#include "lldb/Target/ThreadPlanStepInstruction.h"
30#include "lldb/Target/ThreadPlanStepOut.h"
31#include "lldb/Target/ThreadPlanStepRange.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000032#include "lldb/Target/UnixSignals.h"
Pavel Labathd821c992018-08-07 11:07:21 +000033#include "lldb/Utility/State.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000034#include "lldb/Utility/Stream.h"
Pavel Labathf2a8bcc2017-06-27 10:45:31 +000035#include "lldb/Utility/StructuredData.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036
Eli Friedman4c5de692010-06-09 07:44:37 +000037#include "lldb/API/SBAddress.h"
Eli Friedman4c5de692010-06-09 07:44:37 +000038#include "lldb/API/SBDebugger.h"
Jim Ingham4f465cf2012-10-10 18:32:14 +000039#include "lldb/API/SBEvent.h"
Jim Ingham73ca05a2011-12-17 01:35:57 +000040#include "lldb/API/SBFrame.h"
Eli Friedman4c5de692010-06-09 07:44:37 +000041#include "lldb/API/SBProcess.h"
Kuba Brecka6a831432016-03-23 15:36:22 +000042#include "lldb/API/SBThreadCollection.h"
Jim Ingham2bdbfd52014-09-29 23:17:18 +000043#include "lldb/API/SBThreadPlan.h"
Jim Ingham73ca05a2011-12-17 01:35:57 +000044#include "lldb/API/SBValue.h"
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +000045#include "lldb/lldb-enumerations.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000046
47using namespace lldb;
48using namespace lldb_private;
49
Kate Stoneb9c1b512016-09-06 20:57:50 +000050const char *SBThread::GetBroadcasterClassName() {
51 return Thread::GetStaticBroadcasterClass().AsCString();
Jim Ingham4f465cf2012-10-10 18:32:14 +000052}
53
Greg Claytoncfd1ace2010-10-31 03:01:06 +000054//----------------------------------------------------------------------
55// Constructors
56//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000057SBThread::SBThread() : m_opaque_sp(new ExecutionContextRef()) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059SBThread::SBThread(const ThreadSP &lldb_object_sp)
60 : m_opaque_sp(new ExecutionContextRef(lldb_object_sp)) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000061
Kate Stoneb9c1b512016-09-06 20:57:50 +000062SBThread::SBThread(const SBThread &rhs)
63 : m_opaque_sp(new ExecutionContextRef(*rhs.m_opaque_sp)) {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064
65//----------------------------------------------------------------------
Greg Claytoncfd1ace2010-10-31 03:01:06 +000066// Assignment operator
67//----------------------------------------------------------------------
68
Kate Stoneb9c1b512016-09-06 20:57:50 +000069const lldb::SBThread &SBThread::operator=(const SBThread &rhs) {
70 if (this != &rhs)
71 *m_opaque_sp = *rhs.m_opaque_sp;
72 return *this;
Greg Claytoncfd1ace2010-10-31 03:01:06 +000073}
74
75//----------------------------------------------------------------------
Chris Lattner30fdc8d2010-06-08 16:52:24 +000076// Destructor
77//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +000078SBThread::~SBThread() {}
79
80lldb::SBQueue SBThread::GetQueue() const {
81 SBQueue sb_queue;
82 QueueSP queue_sp;
83 std::unique_lock<std::recursive_mutex> lock;
84 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
85
86 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
87 if (exe_ctx.HasThreadScope()) {
88 Process::StopLocker stop_locker;
89 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
90 queue_sp = exe_ctx.GetThreadPtr()->GetQueue();
91 if (queue_sp) {
92 sb_queue.SetQueue(queue_sp);
93 }
94 } else {
95 if (log)
96 log->Printf("SBThread(%p)::GetQueue() => error: process is running",
97 static_cast<void *>(exe_ctx.GetThreadPtr()));
98 }
99 }
100
101 if (log)
102 log->Printf("SBThread(%p)::GetQueue () => SBQueue(%p)",
103 static_cast<void *>(exe_ctx.GetThreadPtr()),
104 static_cast<void *>(queue_sp.get()));
105
106 return sb_queue;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000107}
108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109bool SBThread::IsValid() const {
110 std::unique_lock<std::recursive_mutex> lock;
111 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molendab9ffa982014-04-25 00:01:15 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 Target *target = exe_ctx.GetTargetPtr();
114 Process *process = exe_ctx.GetProcessPtr();
115 if (target && process) {
116 Process::StopLocker stop_locker;
117 if (stop_locker.TryLock(&process->GetRunLock()))
118 return m_opaque_sp->GetThreadSP().get() != NULL;
119 }
120 // Without a valid target & process, this thread can't be valid.
121 return false;
122}
123
124void SBThread::Clear() { m_opaque_sp->Clear(); }
125
126StopReason SBThread::GetStopReason() {
127 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
128
129 StopReason reason = eStopReasonInvalid;
130 std::unique_lock<std::recursive_mutex> lock;
131 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
132
133 if (exe_ctx.HasThreadScope()) {
134 Process::StopLocker stop_locker;
135 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
136 return exe_ctx.GetThreadPtr()->GetStopReason();
137 } else {
138 if (log)
139 log->Printf(
140 "SBThread(%p)::GetStopReason() => error: process is running",
141 static_cast<void *>(exe_ctx.GetThreadPtr()));
142 }
143 }
144
145 if (log)
146 log->Printf("SBThread(%p)::GetStopReason () => %s",
147 static_cast<void *>(exe_ctx.GetThreadPtr()),
148 Thread::StopReasonAsCString(reason));
149
150 return reason;
151}
152
153size_t SBThread::GetStopReasonDataCount() {
154 std::unique_lock<std::recursive_mutex> lock;
155 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
156
157 if (exe_ctx.HasThreadScope()) {
158 Process::StopLocker stop_locker;
159 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
160 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
161 if (stop_info_sp) {
162 StopReason reason = stop_info_sp->GetStopReason();
163 switch (reason) {
164 case eStopReasonInvalid:
165 case eStopReasonNone:
166 case eStopReasonTrace:
167 case eStopReasonExec:
168 case eStopReasonPlanComplete:
169 case eStopReasonThreadExiting:
170 case eStopReasonInstrumentation:
171 // There is no data for these stop reasons.
172 return 0;
173
174 case eStopReasonBreakpoint: {
175 break_id_t site_id = stop_info_sp->GetValue();
176 lldb::BreakpointSiteSP bp_site_sp(
177 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
178 site_id));
179 if (bp_site_sp)
180 return bp_site_sp->GetNumberOfOwners() * 2;
181 else
182 return 0; // Breakpoint must have cleared itself...
183 } break;
184
185 case eStopReasonWatchpoint:
186 return 1;
187
188 case eStopReasonSignal:
189 return 1;
190
191 case eStopReasonException:
192 return 1;
193 }
194 }
195 } else {
196 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
197 if (log)
198 log->Printf("SBThread(%p)::GetStopReasonDataCount() => error: process "
199 "is running",
200 static_cast<void *>(exe_ctx.GetThreadPtr()));
201 }
202 }
203 return 0;
204}
205
206uint64_t SBThread::GetStopReasonDataAtIndex(uint32_t idx) {
207 std::unique_lock<std::recursive_mutex> lock;
208 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
209
210 if (exe_ctx.HasThreadScope()) {
211 Process::StopLocker stop_locker;
212 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
213 Thread *thread = exe_ctx.GetThreadPtr();
214 StopInfoSP stop_info_sp = thread->GetStopInfo();
215 if (stop_info_sp) {
216 StopReason reason = stop_info_sp->GetStopReason();
217 switch (reason) {
218 case eStopReasonInvalid:
219 case eStopReasonNone:
220 case eStopReasonTrace:
221 case eStopReasonExec:
222 case eStopReasonPlanComplete:
223 case eStopReasonThreadExiting:
224 case eStopReasonInstrumentation:
225 // There is no data for these stop reasons.
226 return 0;
227
228 case eStopReasonBreakpoint: {
229 break_id_t site_id = stop_info_sp->GetValue();
230 lldb::BreakpointSiteSP bp_site_sp(
231 exe_ctx.GetProcessPtr()->GetBreakpointSiteList().FindByID(
232 site_id));
233 if (bp_site_sp) {
234 uint32_t bp_index = idx / 2;
235 BreakpointLocationSP bp_loc_sp(
236 bp_site_sp->GetOwnerAtIndex(bp_index));
237 if (bp_loc_sp) {
238 if (idx & 1) {
239 // Odd idx, return the breakpoint location ID
240 return bp_loc_sp->GetID();
241 } else {
242 // Even idx, return the breakpoint ID
243 return bp_loc_sp->GetBreakpoint().GetID();
244 }
Jason Molendab9ffa982014-04-25 00:01:15 +0000245 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000246 }
247 return LLDB_INVALID_BREAK_ID;
248 } break;
249
250 case eStopReasonWatchpoint:
251 return stop_info_sp->GetValue();
252
253 case eStopReasonSignal:
254 return stop_info_sp->GetValue();
255
256 case eStopReasonException:
257 return stop_info_sp->GetValue();
Jason Molendab9ffa982014-04-25 00:01:15 +0000258 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000259 }
260 } else {
261 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
262 if (log)
263 log->Printf("SBThread(%p)::GetStopReasonDataAtIndex() => error: "
264 "process is running",
265 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molendab9ffa982014-04-25 00:01:15 +0000266 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000267 }
268 return 0;
Jason Molendab9ffa982014-04-25 00:01:15 +0000269}
270
Kate Stoneb9c1b512016-09-06 20:57:50 +0000271bool SBThread::GetStopReasonExtendedInfoAsJSON(lldb::SBStream &stream) {
272 Stream &strm = stream.ref();
Jason Molendab9ffa982014-04-25 00:01:15 +0000273
Kate Stoneb9c1b512016-09-06 20:57:50 +0000274 std::unique_lock<std::recursive_mutex> lock;
275 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham7fa7dc32016-05-07 00:54:56 +0000276
Kate Stoneb9c1b512016-09-06 20:57:50 +0000277 if (!exe_ctx.HasThreadScope())
Jim Ingham7fa7dc32016-05-07 00:54:56 +0000278 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000279
Kate Stoneb9c1b512016-09-06 20:57:50 +0000280 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
281 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
282 if (!info)
283 return false;
Greg Clayton48e42542010-07-30 20:12:55 +0000284
Kate Stoneb9c1b512016-09-06 20:57:50 +0000285 info->Dump(strm);
Greg Clayton48e42542010-07-30 20:12:55 +0000286
Kate Stoneb9c1b512016-09-06 20:57:50 +0000287 return true;
Kuba Breckaafdf8422014-10-10 23:43:03 +0000288}
289
Kuba Brecka6a831432016-03-23 15:36:22 +0000290SBThreadCollection
Kate Stoneb9c1b512016-09-06 20:57:50 +0000291SBThread::GetStopReasonExtendedBacktraces(InstrumentationRuntimeType type) {
292 ThreadCollectionSP threads;
293 threads.reset(new ThreadCollection());
Jim Inghamb2e7d282016-06-10 17:22:26 +0000294
Kate Stoneb9c1b512016-09-06 20:57:50 +0000295 std::unique_lock<std::recursive_mutex> lock;
296 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
297
298 if (!exe_ctx.HasThreadScope())
299 return threads;
300
301 ProcessSP process_sp = exe_ctx.GetProcessSP();
302
303 StopInfoSP stop_info = exe_ctx.GetThreadPtr()->GetStopInfo();
304 StructuredData::ObjectSP info = stop_info->GetExtendedInfo();
305 if (!info)
306 return threads;
307
308 return process_sp->GetInstrumentationRuntime(type)
309 ->GetBacktracesFromExtendedStopInfo(info);
Kuba Brecka6a831432016-03-23 15:36:22 +0000310}
311
Kate Stoneb9c1b512016-09-06 20:57:50 +0000312size_t SBThread::GetStopDescription(char *dst, size_t dst_len) {
313 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000314
Kate Stoneb9c1b512016-09-06 20:57:50 +0000315 std::unique_lock<std::recursive_mutex> lock;
316 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 if (exe_ctx.HasThreadScope()) {
319 Process::StopLocker stop_locker;
320 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
323 if (stop_info_sp) {
324 const char *stop_desc = stop_info_sp->GetDescription();
325 if (stop_desc) {
326 if (log)
327 log->Printf(
328 "SBThread(%p)::GetStopDescription (dst, dst_len) => \"%s\"",
329 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
330 if (dst)
331 return ::snprintf(dst, dst_len, "%s", stop_desc);
332 else {
333 // NULL dst passed in, return the length needed to contain the
334 // description
335 return ::strlen(stop_desc) + 1; // Include the NULL byte for size
336 }
337 } else {
338 size_t stop_desc_len = 0;
339 switch (stop_info_sp->GetStopReason()) {
340 case eStopReasonTrace:
341 case eStopReasonPlanComplete: {
342 static char trace_desc[] = "step";
343 stop_desc = trace_desc;
344 stop_desc_len =
345 sizeof(trace_desc); // Include the NULL byte for size
346 } break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000347
Kate Stoneb9c1b512016-09-06 20:57:50 +0000348 case eStopReasonBreakpoint: {
349 static char bp_desc[] = "breakpoint hit";
350 stop_desc = bp_desc;
351 stop_desc_len = sizeof(bp_desc); // Include the NULL byte for size
352 } break;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000353
Kate Stoneb9c1b512016-09-06 20:57:50 +0000354 case eStopReasonWatchpoint: {
355 static char wp_desc[] = "watchpoint hit";
356 stop_desc = wp_desc;
357 stop_desc_len = sizeof(wp_desc); // Include the NULL byte for size
358 } break;
Greg Clayton7fdf9ef2012-04-05 16:12:35 +0000359
Kate Stoneb9c1b512016-09-06 20:57:50 +0000360 case eStopReasonSignal: {
361 stop_desc =
362 exe_ctx.GetProcessPtr()->GetUnixSignals()->GetSignalAsCString(
363 stop_info_sp->GetValue());
364 if (stop_desc == NULL || stop_desc[0] == '\0') {
365 static char signal_desc[] = "signal";
366 stop_desc = signal_desc;
367 stop_desc_len =
368 sizeof(signal_desc); // Include the NULL byte for size
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000369 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370 } break;
371
372 case eStopReasonException: {
373 char exc_desc[] = "exception";
374 stop_desc = exc_desc;
375 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
376 } break;
377
378 case eStopReasonExec: {
379 char exc_desc[] = "exec";
380 stop_desc = exc_desc;
381 stop_desc_len = sizeof(exc_desc); // Include the NULL byte for size
382 } break;
383
384 case eStopReasonThreadExiting: {
385 char limbo_desc[] = "thread exiting";
386 stop_desc = limbo_desc;
387 stop_desc_len = sizeof(limbo_desc);
388 } break;
389 default:
390 break;
391 }
392
393 if (stop_desc && stop_desc[0]) {
Greg Claytonc9858e42012-04-06 02:17:47 +0000394 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000395 log->Printf(
396 "SBThread(%p)::GetStopDescription (dst, dst_len) => '%s'",
397 static_cast<void *>(exe_ctx.GetThreadPtr()), stop_desc);
398
399 if (dst)
400 return ::snprintf(dst, dst_len, "%s", stop_desc) +
401 1; // Include the NULL byte
402
403 if (stop_desc_len == 0)
404 stop_desc_len = ::strlen(stop_desc) + 1; // Include the NULL byte
405
406 return stop_desc_len;
407 }
Greg Claytonc9858e42012-04-06 02:17:47 +0000408 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000409 }
410 } else {
411 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
412 if (log)
413 log->Printf(
414 "SBThread(%p)::GetStopDescription() => error: process is running",
415 static_cast<void *>(exe_ctx.GetThreadPtr()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000416 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000417 }
418 if (dst)
419 *dst = 0;
420 return 0;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000421}
422
Kate Stoneb9c1b512016-09-06 20:57:50 +0000423SBValue SBThread::GetStopReturnValue() {
424 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
425 ValueObjectSP return_valobj_sp;
426 std::unique_lock<std::recursive_mutex> lock;
427 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000428
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 if (exe_ctx.HasThreadScope()) {
430 Process::StopLocker stop_locker;
431 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
432 StopInfoSP stop_info_sp = exe_ctx.GetThreadPtr()->GetStopInfo();
433 if (stop_info_sp) {
434 return_valobj_sp = StopInfo::GetReturnValueObject(stop_info_sp);
435 }
436 } else {
437 if (log)
438 log->Printf(
439 "SBThread(%p)::GetStopReturnValue() => error: process is running",
440 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jim Ingham73ca05a2011-12-17 01:35:57 +0000441 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000443
Kate Stoneb9c1b512016-09-06 20:57:50 +0000444 if (log)
445 log->Printf("SBThread(%p)::GetStopReturnValue () => %s",
446 static_cast<void *>(exe_ctx.GetThreadPtr()),
447 return_valobj_sp.get() ? return_valobj_sp->GetValueAsCString()
448 : "<no return value>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000449
Kate Stoneb9c1b512016-09-06 20:57:50 +0000450 return SBValue(return_valobj_sp);
Jim Ingham73ca05a2011-12-17 01:35:57 +0000451}
452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453void SBThread::SetThread(const ThreadSP &lldb_object_sp) {
454 m_opaque_sp->SetThreadSP(lldb_object_sp);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000455}
456
Kate Stoneb9c1b512016-09-06 20:57:50 +0000457lldb::tid_t SBThread::GetThreadID() const {
458 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
459 if (thread_sp)
460 return thread_sp->GetID();
461 return LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462}
463
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464uint32_t SBThread::GetIndexID() const {
465 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
466 if (thread_sp)
467 return thread_sp->GetIndexID();
468 return LLDB_INVALID_INDEX32;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000469}
Greg Clayton1ac04c32012-02-21 00:09:25 +0000470
Kate Stoneb9c1b512016-09-06 20:57:50 +0000471const char *SBThread::GetName() const {
472 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
473 const char *name = NULL;
474 std::unique_lock<std::recursive_mutex> lock;
475 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 if (exe_ctx.HasThreadScope()) {
478 Process::StopLocker stop_locker;
479 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
480 name = exe_ctx.GetThreadPtr()->GetName();
481 } else {
482 if (log)
483 log->Printf("SBThread(%p)::GetName() => error: process is running",
484 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000485 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000486 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000487
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 if (log)
489 log->Printf("SBThread(%p)::GetName () => %s",
490 static_cast<void *>(exe_ctx.GetThreadPtr()),
491 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000492
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000494}
495
Kate Stoneb9c1b512016-09-06 20:57:50 +0000496const char *SBThread::GetQueueName() const {
497 const char *name = NULL;
498 std::unique_lock<std::recursive_mutex> lock;
499 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Ingham4fc6cb92012-08-22 21:34:33 +0000500
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
502 if (exe_ctx.HasThreadScope()) {
503 Process::StopLocker stop_locker;
504 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
505 name = exe_ctx.GetThreadPtr()->GetQueueName();
506 } else {
507 if (log)
508 log->Printf("SBThread(%p)::GetQueueName() => error: process is running",
509 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +0000510 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000512
Kate Stoneb9c1b512016-09-06 20:57:50 +0000513 if (log)
514 log->Printf("SBThread(%p)::GetQueueName () => %s",
515 static_cast<void *>(exe_ctx.GetThreadPtr()),
516 name ? name : "NULL");
Caroline Ticeceb6b132010-10-26 03:11:13 +0000517
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518 return name;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000519}
520
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521lldb::queue_id_t SBThread::GetQueueID() const {
522 queue_id_t id = LLDB_INVALID_QUEUE_ID;
523 std::unique_lock<std::recursive_mutex> lock;
524 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000525
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
527 if (exe_ctx.HasThreadScope()) {
528 Process::StopLocker stop_locker;
529 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
530 id = exe_ctx.GetThreadPtr()->GetQueueID();
531 } else {
532 if (log)
533 log->Printf("SBThread(%p)::GetQueueID() => error: process is running",
534 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molenda4fdb5862013-10-21 23:52:54 +0000535 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000537
Kate Stoneb9c1b512016-09-06 20:57:50 +0000538 if (log)
539 log->Printf("SBThread(%p)::GetQueueID () => 0x%" PRIx64,
540 static_cast<void *>(exe_ctx.GetThreadPtr()), id);
Jason Molenda4fdb5862013-10-21 23:52:54 +0000541
Kate Stoneb9c1b512016-09-06 20:57:50 +0000542 return id;
Jason Molenda4fdb5862013-10-21 23:52:54 +0000543}
544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) {
546 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
547 bool success = false;
548 std::unique_lock<std::recursive_mutex> lock;
549 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jason Molenda705b1802014-06-13 02:37:02 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 if (exe_ctx.HasThreadScope()) {
552 Process::StopLocker stop_locker;
553 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
554 Thread *thread = exe_ctx.GetThreadPtr();
555 StructuredData::ObjectSP info_root_sp = thread->GetExtendedInfo();
556 if (info_root_sp) {
557 StructuredData::ObjectSP node =
558 info_root_sp->GetObjectForDotSeparatedPath(path);
559 if (node) {
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000560 if (node->GetType() == eStructuredDataTypeString) {
Zachary Turner28333212017-05-12 05:49:54 +0000561 strm.Printf("%s", node->GetAsString()->GetValue().str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 success = true;
563 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000564 if (node->GetType() == eStructuredDataTypeInteger) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000565 strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue());
566 success = true;
567 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000568 if (node->GetType() == eStructuredDataTypeFloat) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000569 strm.Printf("0x%f", node->GetAsFloat()->GetValue());
570 success = true;
571 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000572 if (node->GetType() == eStructuredDataTypeBoolean) {
Jonas Devliegherea6682a42018-12-15 00:15:33 +0000573 if (node->GetAsBoolean()->GetValue())
Kate Stoneb9c1b512016-09-06 20:57:50 +0000574 strm.Printf("true");
575 else
576 strm.Printf("false");
577 success = true;
578 }
Abhishek Aggarwal5bfee5f2017-05-29 08:25:46 +0000579 if (node->GetType() == eStructuredDataTypeNull) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 strm.Printf("null");
581 success = true;
582 }
Jason Molenda705b1802014-06-13 02:37:02 +0000583 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584 }
585 } else {
586 if (log)
587 log->Printf("SBThread(%p)::GetInfoItemByPathAsString() => error: "
588 "process is running",
589 static_cast<void *>(exe_ctx.GetThreadPtr()));
Jason Molenda705b1802014-06-13 02:37:02 +0000590 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000591 }
Jason Molenda705b1802014-06-13 02:37:02 +0000592
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 if (log)
Jason Molenda753e13c2017-02-02 03:02:51 +0000594 log->Printf("SBThread(%p)::GetInfoItemByPathAsString (\"%s\") => \"%s\"",
595 static_cast<void *>(exe_ctx.GetThreadPtr()), path, strm.GetData());
Jason Molenda705b1802014-06-13 02:37:02 +0000596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 return success;
Jason Molenda705b1802014-06-13 02:37:02 +0000598}
599
Kate Stoneb9c1b512016-09-06 20:57:50 +0000600SBError SBThread::ResumeNewPlan(ExecutionContext &exe_ctx,
601 ThreadPlan *new_plan) {
602 SBError sb_error;
Jason Molenda705b1802014-06-13 02:37:02 +0000603
Kate Stoneb9c1b512016-09-06 20:57:50 +0000604 Process *process = exe_ctx.GetProcessPtr();
605 if (!process) {
606 sb_error.SetErrorString("No process in SBThread::ResumeNewPlan");
Jim Ingham64e7ead2012-05-03 21:19:36 +0000607 return sb_error;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 }
609
610 Thread *thread = exe_ctx.GetThreadPtr();
611 if (!thread) {
612 sb_error.SetErrorString("No thread in SBThread::ResumeNewPlan");
613 return sb_error;
614 }
615
616 // User level plans should be Master Plans so they can be interrupted, other
Adrian Prantl05097242018-04-30 16:49:04 +0000617 // plans executed, and then a "continue" will resume the plan.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000618 if (new_plan != NULL) {
619 new_plan->SetIsMasterPlan(true);
620 new_plan->SetOkayToDiscard(false);
621 }
622
623 // Why do we need to set the current thread by ID here???
624 process->GetThreadList().SetSelectedThreadByID(thread->GetID());
625
626 if (process->GetTarget().GetDebugger().GetAsyncExecution())
627 sb_error.ref() = process->Resume();
628 else
629 sb_error.ref() = process->ResumeSynchronous(NULL);
630
631 return sb_error;
Jim Ingham64e7ead2012-05-03 21:19:36 +0000632}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000633
Kate Stoneb9c1b512016-09-06 20:57:50 +0000634void SBThread::StepOver(lldb::RunMode stop_other_threads) {
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000635 SBError error; // Ignored
636 StepOver(stop_other_threads, error);
637}
638
639void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642 std::unique_lock<std::recursive_mutex> lock;
643 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000644
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645 if (log)
646 log->Printf("SBThread(%p)::StepOver (stop_other_threads='%s')",
647 static_cast<void *>(exe_ctx.GetThreadPtr()),
648 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000649
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000650 if (!exe_ctx.HasThreadScope()) {
651 error.SetErrorString("this SBThread object is invalid");
652 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000653 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000654
655 Thread *thread = exe_ctx.GetThreadPtr();
656 bool abort_other_plans = false;
657 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
658
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000659 Status new_plan_status;
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000660 ThreadPlanSP new_plan_sp;
661 if (frame_sp) {
662 if (frame_sp->HasDebugInformation()) {
663 const LazyBool avoid_no_debug = eLazyBoolCalculate;
664 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
665 new_plan_sp = thread->QueueThreadPlanForStepOverRange(
666 abort_other_plans, sc.line_entry, sc, stop_other_threads,
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000667 new_plan_status, avoid_no_debug);
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000668 } else {
669 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000670 true, abort_other_plans, stop_other_threads, new_plan_status);
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000671 }
672 }
673 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
Greg Clayton481cef22011-01-21 06:11:58 +0000674}
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000675
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676void SBThread::StepInto(lldb::RunMode stop_other_threads) {
677 StepInto(NULL, 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,
681 lldb::RunMode stop_other_threads) {
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000682 SBError error; // Ignored
Kate Stoneb9c1b512016-09-06 20:57:50 +0000683 StepInto(target_name, LLDB_INVALID_LINE_NUMBER, error, stop_other_threads);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000684}
685
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686void SBThread::StepInto(const char *target_name, uint32_t end_line,
687 SBError &error, lldb::RunMode stop_other_threads) {
688 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Caroline Ticeceb6b132010-10-26 03:11:13 +0000689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 std::unique_lock<std::recursive_mutex> lock;
691 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +0000692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 if (log)
694 log->Printf(
695 "SBThread(%p)::StepInto (target_name='%s', stop_other_threads='%s')",
696 static_cast<void *>(exe_ctx.GetThreadPtr()),
697 target_name ? target_name : "<NULL>",
698 Thread::RunModeAsCString(stop_other_threads));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000699
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000700 if (!exe_ctx.HasThreadScope()) {
701 error.SetErrorString("this SBThread object is invalid");
702 return;
703 }
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000704
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000705 bool abort_other_plans = false;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000706
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000707 Thread *thread = exe_ctx.GetThreadPtr();
708 StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0));
709 ThreadPlanSP new_plan_sp;
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000710 Status new_plan_status;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000712 if (frame_sp && frame_sp->HasDebugInformation()) {
713 SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything));
714 AddressRange range;
715 if (end_line == LLDB_INVALID_LINE_NUMBER)
716 range = sc.line_entry.range;
717 else {
718 if (!sc.GetAddressRangeFromHereToEndLine(end_line, range, error.ref()))
719 return;
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000720 }
721
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000722 const LazyBool step_out_avoids_code_without_debug_info =
723 eLazyBoolCalculate;
724 const LazyBool step_in_avoids_code_without_debug_info =
725 eLazyBoolCalculate;
726 new_plan_sp = thread->QueueThreadPlanForStepInRange(
727 abort_other_plans, range, sc, target_name, stop_other_threads,
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000728 new_plan_status, step_in_avoids_code_without_debug_info,
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000729 step_out_avoids_code_without_debug_info);
730 } else {
731 new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction(
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000732 false, abort_other_plans, stop_other_threads, new_plan_status);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000733 }
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000734
735 if (new_plan_status.Success())
736 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
737 else
738 error.SetErrorString(new_plan_status.AsCString());
Jim Ingham2bdbfd52014-09-29 23:17:18 +0000739}
740
Kate Stoneb9c1b512016-09-06 20:57:50 +0000741void SBThread::StepOut() {
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000742 SBError error; // Ignored
743 StepOut(error);
744}
745
746void SBThread::StepOut(SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000747 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Richard Mittonf86248d2013-09-12 02:20:34 +0000748
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 std::unique_lock<std::recursive_mutex> lock;
750 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Richard Mittonf86248d2013-09-12 02:20:34 +0000751
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752 if (log)
753 log->Printf("SBThread(%p)::StepOut ()",
754 static_cast<void *>(exe_ctx.GetThreadPtr()));
Richard Mittonf86248d2013-09-12 02:20:34 +0000755
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000756 if (!exe_ctx.HasThreadScope()) {
757 error.SetErrorString("this SBThread object is invalid");
758 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000760
761 bool abort_other_plans = false;
762 bool stop_other_threads = false;
763
764 Thread *thread = exe_ctx.GetThreadPtr();
765
766 const LazyBool avoid_no_debug = eLazyBoolCalculate;
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000767 Status new_plan_status;
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000768 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
769 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000770 eVoteNoOpinion, 0, new_plan_status, avoid_no_debug));
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000771
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000772 if (new_plan_status.Success())
773 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
774 else
775 error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000776}
777
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000778void SBThread::StepOutOfFrame(SBFrame &sb_frame) {
779 SBError error; // Ignored
780 StepOutOfFrame(sb_frame, error);
781}
782
783void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000784 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
785
786 std::unique_lock<std::recursive_mutex> lock;
787 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
788
789 if (!sb_frame.IsValid()) {
790 if (log)
791 log->Printf(
792 "SBThread(%p)::StepOutOfFrame passed an invalid frame, returning.",
793 static_cast<void *>(exe_ctx.GetThreadPtr()));
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000794 error.SetErrorString("passed invalid SBFrame object");
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 return;
796 }
797
798 StackFrameSP frame_sp(sb_frame.GetFrameSP());
799 if (log) {
800 SBStream frame_desc_strm;
801 sb_frame.GetDescription(frame_desc_strm);
802 log->Printf("SBThread(%p)::StepOutOfFrame (frame = SBFrame(%p): %s)",
803 static_cast<void *>(exe_ctx.GetThreadPtr()),
804 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
805 }
806
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000807 if (!exe_ctx.HasThreadScope()) {
808 error.SetErrorString("this SBThread object is invalid");
809 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000811
812 bool abort_other_plans = false;
813 bool stop_other_threads = false;
814 Thread *thread = exe_ctx.GetThreadPtr();
815 if (sb_frame.GetThread().GetThreadID() != thread->GetID()) {
816 log->Printf("SBThread(%p)::StepOutOfFrame passed a frame from another "
817 "thread (0x%" PRIx64 " vrs. 0x%" PRIx64 ", returning.",
818 static_cast<void *>(exe_ctx.GetThreadPtr()),
819 sb_frame.GetThread().GetThreadID(), thread->GetID());
820 error.SetErrorString("passed a frame from another thread");
821 return;
822 }
823
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000824 Status new_plan_status;
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000825 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut(
826 abort_other_plans, NULL, false, stop_other_threads, eVoteYes,
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000827 eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status));
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000828
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000829 if (new_plan_status.Success())
830 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
831 else
832 error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000833}
834
835void SBThread::StepInstruction(bool step_over) {
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000836 SBError error; // Ignored
837 StepInstruction(step_over, error);
838}
839
840void SBThread::StepInstruction(bool step_over, SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
842
843 std::unique_lock<std::recursive_mutex> lock;
844 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
845
846 if (log)
847 log->Printf("SBThread(%p)::StepInstruction (step_over=%i)",
848 static_cast<void *>(exe_ctx.GetThreadPtr()), step_over);
849
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000850 if (!exe_ctx.HasThreadScope()) {
851 error.SetErrorString("this SBThread object is invalid");
852 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000853 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000854
855 Thread *thread = exe_ctx.GetThreadPtr();
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000856 Status new_plan_status;
857 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction(
858 step_over, true, true, new_plan_status));
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000859
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000860 if (new_plan_status.Success())
861 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
862 else
863 error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000864}
865
866void SBThread::RunToAddress(lldb::addr_t addr) {
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000867 SBError error; // Ignored
868 RunToAddress(addr, error);
869}
870
871void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
873
874 std::unique_lock<std::recursive_mutex> lock;
875 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
876
877 if (log)
878 log->Printf("SBThread(%p)::RunToAddress (addr=0x%" PRIx64 ")",
879 static_cast<void *>(exe_ctx.GetThreadPtr()), addr);
880
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000881 if (!exe_ctx.HasThreadScope()) {
882 error.SetErrorString("this SBThread object is invalid");
883 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000885
886 bool abort_other_plans = false;
887 bool stop_other_threads = true;
888
889 Address target_addr(addr);
890
891 Thread *thread = exe_ctx.GetThreadPtr();
892
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000893 Status new_plan_status;
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000894 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress(
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000895 abort_other_plans, target_addr, stop_other_threads, new_plan_status));
Alexander Polyakov859f54b2018-06-20 21:43:16 +0000896
Jonas Devliegheree103ae92018-11-15 01:18:15 +0000897 if (new_plan_status.Success())
898 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
899 else
900 error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901}
902
903SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame,
904 lldb::SBFileSpec &sb_file_spec, uint32_t line) {
905 SBError sb_error;
906 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
907 char path[PATH_MAX];
908
909 std::unique_lock<std::recursive_mutex> lock;
910 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
911
912 StackFrameSP frame_sp(sb_frame.GetFrameSP());
913
914 if (log) {
915 SBStream frame_desc_strm;
916 sb_frame.GetDescription(frame_desc_strm);
917 sb_file_spec->GetPath(path, sizeof(path));
918 log->Printf("SBThread(%p)::StepOverUntil (frame = SBFrame(%p): %s, "
919 "file+line = %s:%u)",
920 static_cast<void *>(exe_ctx.GetThreadPtr()),
921 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData(),
922 path, line);
923 }
924
925 if (exe_ctx.HasThreadScope()) {
926 Target *target = exe_ctx.GetTargetPtr();
927 Thread *thread = exe_ctx.GetThreadPtr();
928
929 if (line == 0) {
930 sb_error.SetErrorString("invalid line argument");
931 return sb_error;
932 }
933
934 if (!frame_sp) {
935 frame_sp = thread->GetSelectedFrame();
936 if (!frame_sp)
937 frame_sp = thread->GetStackFrameAtIndex(0);
938 }
939
940 SymbolContext frame_sc;
941 if (!frame_sp) {
942 sb_error.SetErrorString("no valid frames in thread to step");
943 return sb_error;
944 }
945
946 // If we have a frame, get its line
947 frame_sc = frame_sp->GetSymbolContext(
948 eSymbolContextCompUnit | eSymbolContextFunction |
949 eSymbolContextLineEntry | eSymbolContextSymbol);
950
951 if (frame_sc.comp_unit == NULL) {
952 sb_error.SetErrorStringWithFormat(
953 "frame %u doesn't have debug information", frame_sp->GetFrameIndex());
954 return sb_error;
955 }
956
957 FileSpec step_file_spec;
958 if (sb_file_spec.IsValid()) {
959 // The file spec passed in was valid, so use it
960 step_file_spec = sb_file_spec.ref();
961 } else {
962 if (frame_sc.line_entry.IsValid())
963 step_file_spec = frame_sc.line_entry.file;
964 else {
965 sb_error.SetErrorString("invalid file argument or no file for frame");
966 return sb_error;
967 }
968 }
969
970 // Grab the current function, then we will make sure the "until" address is
971 // within the function. We discard addresses that are out of the current
972 // function, and then if there are no addresses remaining, give an
Adrian Prantl05097242018-04-30 16:49:04 +0000973 // appropriate error message.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974
975 bool all_in_function = true;
976 AddressRange fun_range = frame_sc.function->GetAddressRange();
977
978 std::vector<addr_t> step_over_until_addrs;
979 const bool abort_other_plans = false;
980 const bool stop_other_threads = false;
981 const bool check_inlines = true;
982 const bool exact = false;
983
984 SymbolContextList sc_list;
985 const uint32_t num_matches = frame_sc.comp_unit->ResolveSymbolContext(
986 step_file_spec, line, check_inlines, exact, eSymbolContextLineEntry,
987 sc_list);
988 if (num_matches > 0) {
989 SymbolContext sc;
990 for (uint32_t i = 0; i < num_matches; ++i) {
991 if (sc_list.GetContextAtIndex(i, sc)) {
992 addr_t step_addr =
993 sc.line_entry.range.GetBaseAddress().GetLoadAddress(target);
994 if (step_addr != LLDB_INVALID_ADDRESS) {
995 if (fun_range.ContainsLoadAddress(step_addr, target))
996 step_over_until_addrs.push_back(step_addr);
997 else
998 all_in_function = false;
999 }
1000 }
1001 }
1002 }
1003
1004 if (step_over_until_addrs.empty()) {
1005 if (all_in_function) {
1006 step_file_spec.GetPath(path, sizeof(path));
1007 sb_error.SetErrorStringWithFormat("No line entries for %s:%u", path,
1008 line);
1009 } else
1010 sb_error.SetErrorString("step until target not in current function");
1011 } else {
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001012 Status new_plan_status;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013 ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil(
1014 abort_other_plans, &step_over_until_addrs[0],
1015 step_over_until_addrs.size(), stop_other_threads,
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001016 frame_sp->GetFrameIndex(), new_plan_status));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001018 if (new_plan_status.Success())
1019 sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1020 else
1021 sb_error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 }
1023 } else {
1024 sb_error.SetErrorString("this SBThread object is invalid");
1025 }
1026 return sb_error;
1027}
1028
1029SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) {
1030 return StepUsingScriptedThreadPlan(script_class_name, true);
1031}
1032
1033SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name,
1034 bool resume_immediately) {
1035 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001036 SBError error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001037
1038 std::unique_lock<std::recursive_mutex> lock;
1039 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1040
1041 if (log) {
1042 log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: class name: %s",
1043 static_cast<void *>(exe_ctx.GetThreadPtr()), script_class_name);
1044 }
1045
1046 if (!exe_ctx.HasThreadScope()) {
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001047 error.SetErrorString("this SBThread object is invalid");
1048 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001049 }
Richard Mittonf86248d2013-09-12 02:20:34 +00001050
Kate Stoneb9c1b512016-09-06 20:57:50 +00001051 Thread *thread = exe_ctx.GetThreadPtr();
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001052 Status new_plan_status;
1053 ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted(
1054 false, script_class_name, false, new_plan_status);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001055
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001056 if (new_plan_status.Fail()) {
1057 error.SetErrorString(new_plan_status.AsCString());
1058 return error;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001059 }
Jim Ingham44137582012-09-12 00:40:39 +00001060
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001061 if (!resume_immediately)
1062 return error;
Jim Ingham4ac8e932016-07-08 02:12:05 +00001063
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001064 if (new_plan_status.Success())
1065 error = ResumeNewPlan(exe_ctx, new_plan_sp.get());
1066 else
1067 error.SetErrorString(new_plan_status.AsCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068
Jonas Devliegheree103ae92018-11-15 01:18:15 +00001069 return error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001070}
1071
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) {
1073 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1074 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001075
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076 std::unique_lock<std::recursive_mutex> lock;
1077 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1078
1079 if (log)
1080 log->Printf("SBThread(%p)::JumpToLine (file+line = %s:%u)",
1081 static_cast<void *>(exe_ctx.GetThreadPtr()),
1082 file_spec->GetPath().c_str(), line);
1083
1084 if (!exe_ctx.HasThreadScope()) {
1085 sb_error.SetErrorString("this SBThread object is invalid");
1086 return sb_error;
1087 }
1088
1089 Thread *thread = exe_ctx.GetThreadPtr();
1090
Zachary Turner97206d52017-05-12 04:51:55 +00001091 Status err = thread->JumpToLine(file_spec.get(), line, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001092 sb_error.SetError(err);
1093 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001094}
1095
Kate Stoneb9c1b512016-09-06 20:57:50 +00001096SBError SBThread::ReturnFromFrame(SBFrame &frame, SBValue &return_value) {
1097 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001098
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1100
1101 std::unique_lock<std::recursive_mutex> lock;
1102 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1103
1104 if (log)
1105 log->Printf("SBThread(%p)::ReturnFromFrame (frame=%d)",
1106 static_cast<void *>(exe_ctx.GetThreadPtr()),
1107 frame.GetFrameID());
1108
1109 if (exe_ctx.HasThreadScope()) {
1110 Thread *thread = exe_ctx.GetThreadPtr();
1111 sb_error.SetError(
1112 thread->ReturnFromFrame(frame.GetFrameSP(), return_value.GetSP()));
1113 }
1114
1115 return sb_error;
Greg Clayton722a0cd2011-01-12 02:25:42 +00001116}
1117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118SBError SBThread::UnwindInnermostExpression() {
1119 SBError sb_error;
Jim Inghamb2e7d282016-06-10 17:22:26 +00001120
Kate Stoneb9c1b512016-09-06 20:57:50 +00001121 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1122
1123 std::unique_lock<std::recursive_mutex> lock;
1124 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1125
1126 if (log)
1127 log->Printf("SBThread(%p)::UnwindExpressionEvaluation",
1128 static_cast<void *>(exe_ctx.GetThreadPtr()));
1129
1130 if (exe_ctx.HasThreadScope()) {
1131 Thread *thread = exe_ctx.GetThreadPtr();
1132 sb_error.SetError(thread->UnwindInnermostExpression());
1133 if (sb_error.Success())
1134 thread->SetSelectedFrameByIndex(0, false);
1135 }
1136
1137 return sb_error;
Andrew Kaylora75418d2013-04-15 23:33:53 +00001138}
1139
Kate Stoneb9c1b512016-09-06 20:57:50 +00001140bool SBThread::Suspend() {
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001141 SBError error; // Ignored
1142 return Suspend(error);
1143}
1144
1145bool SBThread::Suspend(SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1147 std::unique_lock<std::recursive_mutex> lock;
1148 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Jim Inghamb2e7d282016-06-10 17:22:26 +00001149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150 bool result = false;
1151 if (exe_ctx.HasThreadScope()) {
1152 Process::StopLocker stop_locker;
1153 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1154 exe_ctx.GetThreadPtr()->SetResumeState(eStateSuspended);
1155 result = true;
1156 } else {
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001157 error.SetErrorString("process is running");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158 if (log)
1159 log->Printf("SBThread(%p)::Suspend() => error: process is running",
1160 static_cast<void *>(exe_ctx.GetThreadPtr()));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001162 } else
1163 error.SetErrorString("this SBThread object is invalid");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 if (log)
1165 log->Printf("SBThread(%p)::Suspend() => %i",
1166 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1167 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001168}
1169
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170bool SBThread::Resume() {
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001171 SBError error; // Ignored
1172 return Resume(error);
1173}
1174
1175bool SBThread::Resume(SBError &error) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001176 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1177 std::unique_lock<std::recursive_mutex> lock;
1178 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001179
Kate Stoneb9c1b512016-09-06 20:57:50 +00001180 bool result = false;
1181 if (exe_ctx.HasThreadScope()) {
1182 Process::StopLocker stop_locker;
1183 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1184 const bool override_suspend = true;
1185 exe_ctx.GetThreadPtr()->SetResumeState(eStateRunning, override_suspend);
1186 result = true;
1187 } else {
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001188 error.SetErrorString("process is running");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 if (log)
1190 log->Printf("SBThread(%p)::Resume() => error: process is running",
1191 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonaf67cec2010-12-20 20:49:23 +00001192 }
Alexander Polyakov859f54b2018-06-20 21:43:16 +00001193 } else
1194 error.SetErrorString("this SBThread object is invalid");
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195 if (log)
1196 log->Printf("SBThread(%p)::Resume() => %i",
1197 static_cast<void *>(exe_ctx.GetThreadPtr()), result);
1198 return result;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001199}
1200
Kate Stoneb9c1b512016-09-06 20:57:50 +00001201bool SBThread::IsSuspended() {
1202 std::unique_lock<std::recursive_mutex> lock;
1203 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Caroline Ticeceb6b132010-10-26 03:11:13 +00001204
Kate Stoneb9c1b512016-09-06 20:57:50 +00001205 if (exe_ctx.HasThreadScope())
1206 return exe_ctx.GetThreadPtr()->GetResumeState() == eStateSuspended;
1207 return false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208}
1209
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210bool SBThread::IsStopped() {
1211 std::unique_lock<std::recursive_mutex> lock;
1212 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001213
Kate Stoneb9c1b512016-09-06 20:57:50 +00001214 if (exe_ctx.HasThreadScope())
1215 return StateIsStoppedState(exe_ctx.GetThreadPtr()->GetState(), true);
1216 return false;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001217}
1218
Kate Stoneb9c1b512016-09-06 20:57:50 +00001219SBProcess SBThread::GetProcess() {
1220 SBProcess sb_process;
1221 std::unique_lock<std::recursive_mutex> lock;
1222 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
Greg Claytonf028a1f2010-12-17 02:26:24 +00001223
Kate Stoneb9c1b512016-09-06 20:57:50 +00001224 if (exe_ctx.HasThreadScope()) {
1225 // Have to go up to the target so we can get a shared pointer to our
1226 // process...
1227 sb_process.SetSP(exe_ctx.GetProcessSP());
1228 }
Jim Ingham4fc6cb92012-08-22 21:34:33 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1231 if (log) {
1232 SBStream frame_desc_strm;
1233 sb_process.GetDescription(frame_desc_strm);
1234 log->Printf("SBThread(%p)::GetProcess () => SBProcess(%p): %s",
1235 static_cast<void *>(exe_ctx.GetThreadPtr()),
1236 static_cast<void *>(sb_process.GetSP().get()),
1237 frame_desc_strm.GetData());
1238 }
1239
1240 return sb_process;
1241}
1242
1243uint32_t SBThread::GetNumFrames() {
1244 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1245
1246 uint32_t num_frames = 0;
1247 std::unique_lock<std::recursive_mutex> lock;
1248 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1249
1250 if (exe_ctx.HasThreadScope()) {
1251 Process::StopLocker stop_locker;
1252 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1253 num_frames = exe_ctx.GetThreadPtr()->GetStackFrameCount();
1254 } else {
1255 if (log)
1256 log->Printf("SBThread(%p)::GetNumFrames() => error: process is running",
1257 static_cast<void *>(exe_ctx.GetThreadPtr()));
1258 }
1259 }
1260
1261 if (log)
1262 log->Printf("SBThread(%p)::GetNumFrames () => %u",
1263 static_cast<void *>(exe_ctx.GetThreadPtr()), num_frames);
1264
1265 return num_frames;
1266}
1267
1268SBFrame SBThread::GetFrameAtIndex(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 frame_sp = exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(idx);
1280 sb_frame.SetFrameSP(frame_sp);
1281 } else {
1282 if (log)
1283 log->Printf(
1284 "SBThread(%p)::GetFrameAtIndex() => error: process is running",
1285 static_cast<void *>(exe_ctx.GetThreadPtr()));
1286 }
1287 }
1288
1289 if (log) {
1290 SBStream frame_desc_strm;
1291 sb_frame.GetDescription(frame_desc_strm);
1292 log->Printf("SBThread(%p)::GetFrameAtIndex (idx=%d) => SBFrame(%p): %s",
1293 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1294 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1295 }
1296
1297 return sb_frame;
1298}
1299
1300lldb::SBFrame SBThread::GetSelectedFrame() {
1301 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1302
1303 SBFrame sb_frame;
1304 StackFrameSP frame_sp;
1305 std::unique_lock<std::recursive_mutex> lock;
1306 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1307
1308 if (exe_ctx.HasThreadScope()) {
1309 Process::StopLocker stop_locker;
1310 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1311 frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame();
1312 sb_frame.SetFrameSP(frame_sp);
1313 } else {
1314 if (log)
1315 log->Printf(
1316 "SBThread(%p)::GetSelectedFrame() => error: process is running",
1317 static_cast<void *>(exe_ctx.GetThreadPtr()));
1318 }
1319 }
1320
1321 if (log) {
1322 SBStream frame_desc_strm;
1323 sb_frame.GetDescription(frame_desc_strm);
1324 log->Printf("SBThread(%p)::GetSelectedFrame () => SBFrame(%p): %s",
1325 static_cast<void *>(exe_ctx.GetThreadPtr()),
1326 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1327 }
1328
1329 return sb_frame;
1330}
1331
1332lldb::SBFrame SBThread::SetSelectedFrame(uint32_t idx) {
1333 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1334
1335 SBFrame sb_frame;
1336 StackFrameSP frame_sp;
1337 std::unique_lock<std::recursive_mutex> lock;
1338 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1339
1340 if (exe_ctx.HasThreadScope()) {
1341 Process::StopLocker stop_locker;
1342 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1343 Thread *thread = exe_ctx.GetThreadPtr();
1344 frame_sp = thread->GetStackFrameAtIndex(idx);
1345 if (frame_sp) {
1346 thread->SetSelectedFrame(frame_sp.get());
1347 sb_frame.SetFrameSP(frame_sp);
1348 }
1349 } else {
1350 if (log)
1351 log->Printf(
1352 "SBThread(%p)::SetSelectedFrame() => error: process is running",
1353 static_cast<void *>(exe_ctx.GetThreadPtr()));
1354 }
1355 }
1356
1357 if (log) {
1358 SBStream frame_desc_strm;
1359 sb_frame.GetDescription(frame_desc_strm);
1360 log->Printf("SBThread(%p)::SetSelectedFrame (idx=%u) => SBFrame(%p): %s",
1361 static_cast<void *>(exe_ctx.GetThreadPtr()), idx,
1362 static_cast<void *>(frame_sp.get()), frame_desc_strm.GetData());
1363 }
1364 return sb_frame;
1365}
1366
1367bool SBThread::EventIsThreadEvent(const SBEvent &event) {
1368 return Thread::ThreadEventData::GetEventDataFromEvent(event.get()) != NULL;
1369}
1370
1371SBFrame SBThread::GetStackFrameFromEvent(const SBEvent &event) {
1372 return Thread::ThreadEventData::GetStackFrameFromEvent(event.get());
1373}
1374
1375SBThread SBThread::GetThreadFromEvent(const SBEvent &event) {
1376 return Thread::ThreadEventData::GetThreadFromEvent(event.get());
1377}
1378
1379bool SBThread::operator==(const SBThread &rhs) const {
1380 return m_opaque_sp->GetThreadSP().get() ==
1381 rhs.m_opaque_sp->GetThreadSP().get();
1382}
1383
1384bool SBThread::operator!=(const SBThread &rhs) const {
1385 return m_opaque_sp->GetThreadSP().get() !=
1386 rhs.m_opaque_sp->GetThreadSP().get();
1387}
1388
1389bool SBThread::GetStatus(SBStream &status) const {
1390 Stream &strm = status.ref();
1391
1392 std::unique_lock<std::recursive_mutex> lock;
1393 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1394
1395 if (exe_ctx.HasThreadScope()) {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001396 exe_ctx.GetThreadPtr()->GetStatus(strm, 0, 1, 1, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001397 } else
1398 strm.PutCString("No status");
1399
1400 return true;
1401}
1402
1403bool SBThread::GetDescription(SBStream &description) const {
Jim Ingham6a9767c2016-11-08 20:36:40 +00001404 return GetDescription(description, false);
1405}
1406
1407bool SBThread::GetDescription(SBStream &description, bool stop_format) const {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 Stream &strm = description.ref();
1409
1410 std::unique_lock<std::recursive_mutex> lock;
1411 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1412
1413 if (exe_ctx.HasThreadScope()) {
1414 exe_ctx.GetThreadPtr()->DumpUsingSettingsFormat(strm,
Jim Ingham6a9767c2016-11-08 20:36:40 +00001415 LLDB_INVALID_THREAD_ID,
1416 stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001417 // strm.Printf("SBThread: tid = 0x%4.4" PRIx64,
1418 // exe_ctx.GetThreadPtr()->GetID());
1419 } else
1420 strm.PutCString("No value");
1421
1422 return true;
1423}
1424
1425SBThread SBThread::GetExtendedBacktraceThread(const char *type) {
1426 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1427 std::unique_lock<std::recursive_mutex> lock;
1428 ExecutionContext exe_ctx(m_opaque_sp.get(), lock);
1429 SBThread sb_origin_thread;
1430
1431 if (exe_ctx.HasThreadScope()) {
1432 Process::StopLocker stop_locker;
1433 if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) {
1434 ThreadSP real_thread(exe_ctx.GetThreadSP());
1435 if (real_thread) {
1436 ConstString type_const(type);
1437 Process *process = exe_ctx.GetProcessPtr();
1438 if (process) {
1439 SystemRuntime *runtime = process->GetSystemRuntime();
1440 if (runtime) {
1441 ThreadSP new_thread_sp(
1442 runtime->GetExtendedBacktraceThread(real_thread, type_const));
1443 if (new_thread_sp) {
1444 // Save this in the Process' ExtendedThreadList so a strong
Adrian Prantl05097242018-04-30 16:49:04 +00001445 // pointer retains the object.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001446 process->GetExtendedThreadList().AddThread(new_thread_sp);
1447 sb_origin_thread.SetThread(new_thread_sp);
1448 if (log) {
1449 const char *queue_name = new_thread_sp->GetQueueName();
1450 if (queue_name == NULL)
1451 queue_name = "";
1452 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => new "
1453 "extended Thread "
1454 "created (%p) with queue_id 0x%" PRIx64
1455 " queue name '%s'",
1456 static_cast<void *>(exe_ctx.GetThreadPtr()),
1457 static_cast<void *>(new_thread_sp.get()),
1458 new_thread_sp->GetQueueID(), queue_name);
1459 }
Greg Clayton7fdf9ef2012-04-05 16:12:35 +00001460 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001461 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001462 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001463 }
1464 } else {
1465 if (log)
1466 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() => error: "
1467 "process is running",
1468 static_cast<void *>(exe_ctx.GetThreadPtr()));
Greg Claytonf028a1f2010-12-17 02:26:24 +00001469 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001470 }
Greg Claytonf028a1f2010-12-17 02:26:24 +00001471
Jonas Devliegherea6682a42018-12-15 00:15:33 +00001472 if (log && !sb_origin_thread.IsValid())
Kate Stoneb9c1b512016-09-06 20:57:50 +00001473 log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a "
1474 "Valid thread",
1475 static_cast<void *>(exe_ctx.GetThreadPtr()));
1476 return sb_origin_thread;
Greg Claytonf028a1f2010-12-17 02:26:24 +00001477}
1478
Kate Stoneb9c1b512016-09-06 20:57:50 +00001479uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() {
1480 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1481 if (thread_sp)
1482 return thread_sp->GetExtendedBacktraceOriginatingIndexID();
1483 return LLDB_INVALID_INDEX32;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001484}
1485
Kuba Mraceke60bc532018-11-28 22:01:52 +00001486SBValue SBThread::GetCurrentException() {
1487 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1488 if (!thread_sp) return SBValue();
1489
1490 return SBValue(thread_sp->GetCurrentException());
1491}
1492
Kuba Mraceke60bc532018-11-28 22:01:52 +00001493SBThread SBThread::GetCurrentExceptionBacktrace() {
1494 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1495 if (!thread_sp) return SBThread();
1496
1497 return SBThread(thread_sp->GetCurrentExceptionBacktrace());
Kuba Mracekc9e11902018-12-20 02:01:59 +00001498}
Kuba Mraceke60bc532018-11-28 22:01:52 +00001499
Kate Stoneb9c1b512016-09-06 20:57:50 +00001500bool SBThread::SafeToCallFunctions() {
1501 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1502 if (thread_sp)
1503 return thread_sp->SafeToCallFunctions();
1504 return true;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001505}
1506
Kate Stoneb9c1b512016-09-06 20:57:50 +00001507lldb_private::Thread *SBThread::operator->() {
1508 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1509 if (thread_sp)
1510 return thread_sp.get();
1511 else
1512 return NULL;
Jim Ingham4f465cf2012-10-10 18:32:14 +00001513}
Greg Claytonf028a1f2010-12-17 02:26:24 +00001514
Kate Stoneb9c1b512016-09-06 20:57:50 +00001515lldb_private::Thread *SBThread::get() {
1516 ThreadSP thread_sp(m_opaque_sp->GetThreadSP());
1517 if (thread_sp)
1518 return thread_sp.get();
1519 else
1520 return NULL;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001521}