File: | tools/lldb/source/Target/Thread.cpp |
Location: | line 1693, column 14 |
Description: | Value stored to 'stack_size' during its initialization is never read |
1 | //===-- Thread.cpp ----------------------------------------------*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
4 | // |
5 | // This file is distributed under the University of Illinois Open Source |
6 | // License. See LICENSE.TXT for details. |
7 | // |
8 | //===----------------------------------------------------------------------===// |
9 | |
10 | #include "lldb/lldb-python.h" |
11 | |
12 | #include "lldb/lldb-private-log.h" |
13 | #include "lldb/Breakpoint/BreakpointLocation.h" |
14 | #include "lldb/Core/Debugger.h" |
15 | #include "lldb/Core/Log.h" |
16 | #include "lldb/Core/State.h" |
17 | #include "lldb/Core/Stream.h" |
18 | #include "lldb/Core/StreamString.h" |
19 | #include "lldb/Core/RegularExpression.h" |
20 | #include "lldb/Host/Host.h" |
21 | #include "lldb/Interpreter/OptionValueFileSpecList.h" |
22 | #include "lldb/Symbol/Function.h" |
23 | #include "lldb/Target/DynamicLoader.h" |
24 | #include "lldb/Target/ExecutionContext.h" |
25 | #include "lldb/Target/ObjCLanguageRuntime.h" |
26 | #include "lldb/Target/Process.h" |
27 | #include "lldb/Target/RegisterContext.h" |
28 | #include "lldb/Target/StopInfo.h" |
29 | #include "lldb/Target/SystemRuntime.h" |
30 | #include "lldb/Target/Target.h" |
31 | #include "lldb/Target/Thread.h" |
32 | #include "lldb/Target/ThreadPlan.h" |
33 | #include "lldb/Target/ThreadPlanCallFunction.h" |
34 | #include "lldb/Target/ThreadPlanBase.h" |
35 | #include "lldb/Target/ThreadPlanPython.h" |
36 | #include "lldb/Target/ThreadPlanStepInstruction.h" |
37 | #include "lldb/Target/ThreadPlanStepOut.h" |
38 | #include "lldb/Target/ThreadPlanStepOverBreakpoint.h" |
39 | #include "lldb/Target/ThreadPlanStepThrough.h" |
40 | #include "lldb/Target/ThreadPlanStepInRange.h" |
41 | #include "lldb/Target/ThreadPlanStepOverRange.h" |
42 | #include "lldb/Target/ThreadPlanRunToAddress.h" |
43 | #include "lldb/Target/ThreadPlanStepUntil.h" |
44 | #include "lldb/Target/ThreadSpec.h" |
45 | #include "lldb/Target/Unwind.h" |
46 | #include "Plugins/Process/Utility/UnwindLLDB.h" |
47 | #include "Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h" |
48 | |
49 | |
50 | using namespace lldb; |
51 | using namespace lldb_private; |
52 | |
53 | |
54 | const ThreadPropertiesSP & |
55 | Thread::GetGlobalProperties() |
56 | { |
57 | static ThreadPropertiesSP g_settings_sp; |
58 | if (!g_settings_sp) |
59 | g_settings_sp.reset (new ThreadProperties (true)); |
60 | return g_settings_sp; |
61 | } |
62 | |
63 | static PropertyDefinition |
64 | g_properties[] = |
65 | { |
66 | { "step-in-avoid-nodebug", OptionValue::eTypeBoolean, true, true, NULL__null, NULL__null, "If true, step-in will not stop in functions with no debug information." }, |
67 | { "step-out-avoid-nodebug", OptionValue::eTypeBoolean, true, false, NULL__null, NULL__null, "If true, when step-in/step-out/step-over leave the current frame, they will continue to step out till they come to a function with " |
68 | "debug information. Passing a frame argument to step-out will override this option." }, |
69 | { "step-avoid-regexp", OptionValue::eTypeRegex , true , REG_EXTENDED1, "^std::", NULL__null, "A regular expression defining functions step-in won't stop in." }, |
70 | { "step-avoid-libraries", OptionValue::eTypeFileSpecList , true , REG_EXTENDED1, NULL__null, NULL__null, "A list of libraries that source stepping won't stop in." }, |
71 | { "trace-thread", OptionValue::eTypeBoolean, false, false, NULL__null, NULL__null, "If true, this thread will single-step and log execution." }, |
72 | { NULL__null , OptionValue::eTypeInvalid, false, 0 , NULL__null, NULL__null, NULL__null } |
73 | }; |
74 | |
75 | enum { |
76 | ePropertyStepInAvoidsNoDebug, |
77 | ePropertyStepOutAvoidsNoDebug, |
78 | ePropertyStepAvoidRegex, |
79 | ePropertyStepAvoidLibraries, |
80 | ePropertyEnableThreadTrace |
81 | }; |
82 | |
83 | |
84 | class ThreadOptionValueProperties : public OptionValueProperties |
85 | { |
86 | public: |
87 | ThreadOptionValueProperties (const ConstString &name) : |
88 | OptionValueProperties (name) |
89 | { |
90 | } |
91 | |
92 | // This constructor is used when creating ThreadOptionValueProperties when it |
93 | // is part of a new lldb_private::Thread instance. It will copy all current |
94 | // global property values as needed |
95 | ThreadOptionValueProperties (ThreadProperties *global_properties) : |
96 | OptionValueProperties(*global_properties->GetValueProperties()) |
97 | { |
98 | } |
99 | |
100 | virtual const Property * |
101 | GetPropertyAtIndex (const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const |
102 | { |
103 | // When getting the value for a key from the thread options, we will always |
104 | // try and grab the setting from the current thread if there is one. Else we just |
105 | // use the one from this instance. |
106 | if (exe_ctx) |
107 | { |
108 | Thread *thread = exe_ctx->GetThreadPtr(); |
109 | if (thread) |
110 | { |
111 | ThreadOptionValueProperties *instance_properties = static_cast<ThreadOptionValueProperties *>(thread->GetValueProperties().get()); |
112 | if (this != instance_properties) |
113 | return instance_properties->ProtectedGetPropertyAtIndex (idx); |
114 | } |
115 | } |
116 | return ProtectedGetPropertyAtIndex (idx); |
117 | } |
118 | }; |
119 | |
120 | |
121 | |
122 | ThreadProperties::ThreadProperties (bool is_global) : |
123 | Properties () |
124 | { |
125 | if (is_global) |
126 | { |
127 | m_collection_sp.reset (new ThreadOptionValueProperties(ConstString("thread"))); |
128 | m_collection_sp->Initialize(g_properties); |
129 | } |
130 | else |
131 | m_collection_sp.reset (new ThreadOptionValueProperties(Thread::GetGlobalProperties().get())); |
132 | } |
133 | |
134 | ThreadProperties::~ThreadProperties() |
135 | { |
136 | } |
137 | |
138 | const RegularExpression * |
139 | ThreadProperties::GetSymbolsToAvoidRegexp() |
140 | { |
141 | const uint32_t idx = ePropertyStepAvoidRegex; |
142 | return m_collection_sp->GetPropertyAtIndexAsOptionValueRegex (NULL__null, idx); |
143 | } |
144 | |
145 | FileSpecList & |
146 | ThreadProperties::GetLibrariesToAvoid() const |
147 | { |
148 | const uint32_t idx = ePropertyStepAvoidLibraries; |
149 | OptionValueFileSpecList *option_value = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList (NULL__null, false, idx); |
150 | assert(option_value)((option_value) ? static_cast<void> (0) : __assert_fail ("option_value", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Target/Thread.cpp" , 150, __PRETTY_FUNCTION__)); |
151 | return option_value->GetCurrentValue(); |
152 | } |
153 | |
154 | bool |
155 | ThreadProperties::GetTraceEnabledState() const |
156 | { |
157 | const uint32_t idx = ePropertyEnableThreadTrace; |
158 | return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL__null, idx, g_properties[idx].default_uint_value != 0); |
159 | } |
160 | |
161 | bool |
162 | ThreadProperties::GetStepInAvoidsNoDebug() const |
163 | { |
164 | const uint32_t idx = ePropertyStepInAvoidsNoDebug; |
165 | return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL__null, idx, g_properties[idx].default_uint_value != 0); |
166 | } |
167 | |
168 | bool |
169 | ThreadProperties::GetStepOutAvoidsNoDebug() const |
170 | { |
171 | const uint32_t idx = ePropertyStepOutAvoidsNoDebug; |
172 | return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL__null, idx, g_properties[idx].default_uint_value != 0); |
173 | } |
174 | |
175 | |
176 | //------------------------------------------------------------------ |
177 | // Thread Event Data |
178 | //------------------------------------------------------------------ |
179 | |
180 | |
181 | const ConstString & |
182 | Thread::ThreadEventData::GetFlavorString () |
183 | { |
184 | static ConstString g_flavor ("Thread::ThreadEventData"); |
185 | return g_flavor; |
186 | } |
187 | |
188 | Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp) : |
189 | m_thread_sp (thread_sp), |
190 | m_stack_id () |
191 | { |
192 | } |
193 | |
194 | Thread::ThreadEventData::ThreadEventData (const lldb::ThreadSP thread_sp, const StackID &stack_id) : |
195 | m_thread_sp (thread_sp), |
196 | m_stack_id (stack_id) |
197 | { |
198 | } |
199 | |
200 | Thread::ThreadEventData::ThreadEventData () : |
201 | m_thread_sp (), |
202 | m_stack_id () |
203 | { |
204 | } |
205 | |
206 | Thread::ThreadEventData::~ThreadEventData () |
207 | { |
208 | } |
209 | |
210 | void |
211 | Thread::ThreadEventData::Dump (Stream *s) const |
212 | { |
213 | |
214 | } |
215 | |
216 | const Thread::ThreadEventData * |
217 | Thread::ThreadEventData::GetEventDataFromEvent (const Event *event_ptr) |
218 | { |
219 | if (event_ptr) |
220 | { |
221 | const EventData *event_data = event_ptr->GetData(); |
222 | if (event_data && event_data->GetFlavor() == ThreadEventData::GetFlavorString()) |
223 | return static_cast <const ThreadEventData *> (event_ptr->GetData()); |
224 | } |
225 | return NULL__null; |
226 | } |
227 | |
228 | ThreadSP |
229 | Thread::ThreadEventData::GetThreadFromEvent (const Event *event_ptr) |
230 | { |
231 | ThreadSP thread_sp; |
232 | const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr); |
233 | if (event_data) |
234 | thread_sp = event_data->GetThread(); |
235 | return thread_sp; |
236 | } |
237 | |
238 | StackID |
239 | Thread::ThreadEventData::GetStackIDFromEvent (const Event *event_ptr) |
240 | { |
241 | StackID stack_id; |
242 | const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr); |
243 | if (event_data) |
244 | stack_id = event_data->GetStackID(); |
245 | return stack_id; |
246 | } |
247 | |
248 | StackFrameSP |
249 | Thread::ThreadEventData::GetStackFrameFromEvent (const Event *event_ptr) |
250 | { |
251 | const ThreadEventData *event_data = GetEventDataFromEvent (event_ptr); |
252 | StackFrameSP frame_sp; |
253 | if (event_data) |
254 | { |
255 | ThreadSP thread_sp = event_data->GetThread(); |
256 | if (thread_sp) |
257 | { |
258 | frame_sp = thread_sp->GetStackFrameList()->GetFrameWithStackID (event_data->GetStackID()); |
259 | } |
260 | } |
261 | return frame_sp; |
262 | } |
263 | |
264 | //------------------------------------------------------------------ |
265 | // Thread class |
266 | //------------------------------------------------------------------ |
267 | |
268 | ConstString & |
269 | Thread::GetStaticBroadcasterClass () |
270 | { |
271 | static ConstString class_name ("lldb.thread"); |
272 | return class_name; |
273 | } |
274 | |
275 | Thread::Thread (Process &process, lldb::tid_t tid, bool use_invalid_index_id) : |
276 | ThreadProperties (false), |
277 | UserID (tid), |
278 | Broadcaster(&process.GetTarget().GetDebugger(), Thread::GetStaticBroadcasterClass().AsCString()), |
279 | m_process_wp (process.shared_from_this()), |
280 | m_stop_info_sp (), |
281 | m_stop_info_stop_id (0), |
282 | m_index_id (use_invalid_index_id ? LLDB_INVALID_INDEX32(4294967295U) : process.GetNextThreadIndexID(tid)), |
283 | m_reg_context_sp (), |
284 | m_state (eStateUnloaded), |
285 | m_state_mutex (Mutex::eMutexTypeRecursive), |
286 | m_plan_stack (), |
287 | m_completed_plan_stack(), |
288 | m_frame_mutex (Mutex::eMutexTypeRecursive), |
289 | m_curr_frames_sp (), |
290 | m_prev_frames_sp (), |
291 | m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER(2147483647)), |
292 | m_resume_state (eStateRunning), |
293 | m_temporary_resume_state (eStateRunning), |
294 | m_unwinder_ap (), |
295 | m_destroy_called (false), |
296 | m_override_should_notify (eLazyBoolCalculate), |
297 | m_extended_info_fetched (false), |
298 | m_extended_info () |
299 | { |
300 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT(1u << 11))); |
301 | if (log) |
302 | log->Printf ("%p Thread::Thread(tid = 0x%4.4" PRIx64"l" "x" ")", |
303 | static_cast<void*>(this), GetID()); |
304 | |
305 | CheckInWithManager(); |
306 | QueueFundamentalPlan(true); |
307 | } |
308 | |
309 | |
310 | Thread::~Thread() |
311 | { |
312 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT(1u << 11))); |
313 | if (log) |
314 | log->Printf ("%p Thread::~Thread(tid = 0x%4.4" PRIx64"l" "x" ")", |
315 | static_cast<void*>(this), GetID()); |
316 | /// If you hit this assert, it means your derived class forgot to call DoDestroy in its destructor. |
317 | assert (m_destroy_called)((m_destroy_called) ? static_cast<void> (0) : __assert_fail ("m_destroy_called", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Target/Thread.cpp" , 317, __PRETTY_FUNCTION__)); |
318 | } |
319 | |
320 | void |
321 | Thread::DestroyThread () |
322 | { |
323 | // Tell any plans on the plan stacks that the thread is being destroyed since |
324 | // any plans that have a thread go away in the middle of might need |
325 | // to do cleanup, or in some cases NOT do cleanup... |
326 | for (auto plan : m_plan_stack) |
327 | plan->ThreadDestroyed(); |
328 | |
329 | for (auto plan : m_discarded_plan_stack) |
330 | plan->ThreadDestroyed(); |
331 | |
332 | for (auto plan : m_completed_plan_stack) |
333 | plan->ThreadDestroyed(); |
334 | |
335 | m_destroy_called = true; |
336 | m_plan_stack.clear(); |
337 | m_discarded_plan_stack.clear(); |
338 | m_completed_plan_stack.clear(); |
339 | |
340 | // Push a ThreadPlanNull on the plan stack. That way we can continue assuming that the |
341 | // plan stack is never empty, but if somebody errantly asks questions of a destroyed thread |
342 | // without checking first whether it is destroyed, they won't crash. |
343 | ThreadPlanSP null_plan_sp(new ThreadPlanNull (*this)); |
344 | m_plan_stack.push_back (null_plan_sp); |
345 | |
346 | m_stop_info_sp.reset(); |
347 | m_reg_context_sp.reset(); |
348 | m_unwinder_ap.reset(); |
349 | Mutex::Locker locker(m_frame_mutex); |
350 | m_curr_frames_sp.reset(); |
351 | m_prev_frames_sp.reset(); |
352 | } |
353 | |
354 | void |
355 | Thread::BroadcastSelectedFrameChange(StackID &new_frame_id) |
356 | { |
357 | if (EventTypeHasListeners(eBroadcastBitSelectedFrameChanged)) |
358 | BroadcastEvent(eBroadcastBitSelectedFrameChanged, new ThreadEventData (this->shared_from_this(), new_frame_id)); |
359 | } |
360 | |
361 | uint32_t |
362 | Thread::SetSelectedFrame (lldb_private::StackFrame *frame, bool broadcast) |
363 | { |
364 | uint32_t ret_value = GetStackFrameList()->SetSelectedFrame(frame); |
365 | if (broadcast) |
366 | BroadcastSelectedFrameChange(frame->GetStackID()); |
367 | return ret_value; |
368 | } |
369 | |
370 | bool |
371 | Thread::SetSelectedFrameByIndex (uint32_t frame_idx, bool broadcast) |
372 | { |
373 | StackFrameSP frame_sp(GetStackFrameList()->GetFrameAtIndex (frame_idx)); |
374 | if (frame_sp) |
375 | { |
376 | GetStackFrameList()->SetSelectedFrame(frame_sp.get()); |
377 | if (broadcast) |
378 | BroadcastSelectedFrameChange(frame_sp->GetStackID()); |
379 | return true; |
380 | } |
381 | else |
382 | return false; |
383 | } |
384 | |
385 | bool |
386 | Thread::SetSelectedFrameByIndexNoisily (uint32_t frame_idx, Stream &output_stream) |
387 | { |
388 | const bool broadcast = true; |
389 | bool success = SetSelectedFrameByIndex (frame_idx, broadcast); |
390 | if (success) |
391 | { |
392 | StackFrameSP frame_sp = GetSelectedFrame(); |
393 | if (frame_sp) |
394 | { |
395 | bool already_shown = false; |
396 | SymbolContext frame_sc(frame_sp->GetSymbolContext(eSymbolContextLineEntry)); |
397 | if (GetProcess()->GetTarget().GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0) |
398 | { |
399 | already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); |
400 | } |
401 | |
402 | bool show_frame_info = true; |
403 | bool show_source = !already_shown; |
404 | return frame_sp->GetStatus (output_stream, show_frame_info, show_source); |
405 | } |
406 | return false; |
407 | } |
408 | else |
409 | return false; |
410 | } |
411 | |
412 | |
413 | lldb::StopInfoSP |
414 | Thread::GetStopInfo () |
415 | { |
416 | if (m_destroy_called) |
417 | return m_stop_info_sp; |
418 | |
419 | ThreadPlanSP plan_sp (GetCompletedPlan()); |
420 | ProcessSP process_sp (GetProcess()); |
421 | const uint32_t stop_id = process_sp ? process_sp->GetStopID() : UINT32_MAX(4294967295U); |
422 | if (plan_sp && plan_sp->PlanSucceeded()) |
423 | { |
424 | return StopInfo::CreateStopReasonWithPlan (plan_sp, GetReturnValueObject(), GetExpressionVariable()); |
425 | } |
426 | else |
427 | { |
428 | if ((m_stop_info_stop_id == stop_id) || // Stop info is valid, just return what we have (even if empty) |
429 | (m_stop_info_sp && m_stop_info_sp->IsValid())) // Stop info is valid, just return what we have |
430 | { |
431 | return m_stop_info_sp; |
432 | } |
433 | else |
434 | { |
435 | GetPrivateStopInfo (); |
436 | return m_stop_info_sp; |
437 | } |
438 | } |
439 | } |
440 | |
441 | lldb::StopInfoSP |
442 | Thread::GetPrivateStopInfo () |
443 | { |
444 | if (m_destroy_called) |
445 | return m_stop_info_sp; |
446 | |
447 | ProcessSP process_sp (GetProcess()); |
448 | if (process_sp) |
449 | { |
450 | const uint32_t process_stop_id = process_sp->GetStopID(); |
451 | if (m_stop_info_stop_id != process_stop_id) |
452 | { |
453 | if (m_stop_info_sp) |
454 | { |
455 | if (m_stop_info_sp->IsValid() |
456 | || IsStillAtLastBreakpointHit() |
457 | || GetCurrentPlan()->IsVirtualStep()) |
458 | SetStopInfo (m_stop_info_sp); |
459 | else |
460 | m_stop_info_sp.reset(); |
461 | } |
462 | |
463 | if (!m_stop_info_sp) |
464 | { |
465 | if (CalculateStopInfo() == false) |
466 | SetStopInfo (StopInfoSP()); |
467 | } |
468 | } |
469 | } |
470 | return m_stop_info_sp; |
471 | } |
472 | |
473 | |
474 | lldb::StopReason |
475 | Thread::GetStopReason() |
476 | { |
477 | lldb::StopInfoSP stop_info_sp (GetStopInfo ()); |
478 | if (stop_info_sp) |
479 | return stop_info_sp->GetStopReason(); |
480 | return eStopReasonNone; |
481 | } |
482 | |
483 | |
484 | |
485 | void |
486 | Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp) |
487 | { |
488 | m_stop_info_sp = stop_info_sp; |
489 | if (m_stop_info_sp) |
490 | { |
491 | m_stop_info_sp->MakeStopInfoValid(); |
492 | // If we are overriding the ShouldReportStop, do that here: |
493 | if (m_override_should_notify != eLazyBoolCalculate) |
494 | m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes); |
495 | } |
496 | |
497 | ProcessSP process_sp (GetProcess()); |
498 | if (process_sp) |
499 | m_stop_info_stop_id = process_sp->GetStopID(); |
500 | else |
501 | m_stop_info_stop_id = UINT32_MAX(4294967295U); |
502 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD(1u << 2))); |
503 | if (log) |
504 | log->Printf("%p: tid = 0x%" PRIx64"l" "x" ": stop info = %s (stop_id = %u)", |
505 | static_cast<void*>(this), GetID(), |
506 | stop_info_sp ? stop_info_sp->GetDescription() : "<NULL>", |
507 | m_stop_info_stop_id); |
508 | } |
509 | |
510 | void |
511 | Thread::SetShouldReportStop (Vote vote) |
512 | { |
513 | if (vote == eVoteNoOpinion) |
514 | return; |
515 | else |
516 | { |
517 | m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo); |
518 | if (m_stop_info_sp) |
519 | m_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes); |
520 | } |
521 | } |
522 | |
523 | void |
524 | Thread::SetStopInfoToNothing() |
525 | { |
526 | // Note, we can't just NULL out the private reason, or the native thread implementation will try to |
527 | // go calculate it again. For now, just set it to a Unix Signal with an invalid signal number. |
528 | SetStopInfo (StopInfo::CreateStopReasonWithSignal (*this, LLDB_INVALID_SIGNAL_NUMBER(2147483647))); |
529 | } |
530 | |
531 | bool |
532 | Thread::ThreadStoppedForAReason (void) |
533 | { |
534 | return (bool) GetPrivateStopInfo (); |
535 | } |
536 | |
537 | bool |
538 | Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state) |
539 | { |
540 | saved_state.register_backup_sp.reset(); |
541 | lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); |
542 | if (frame_sp) |
543 | { |
544 | lldb::RegisterCheckpointSP reg_checkpoint_sp(new RegisterCheckpoint(RegisterCheckpoint::Reason::eExpression)); |
545 | if (reg_checkpoint_sp) |
546 | { |
547 | lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext()); |
548 | if (reg_ctx_sp && reg_ctx_sp->ReadAllRegisterValues (*reg_checkpoint_sp)) |
549 | saved_state.register_backup_sp = reg_checkpoint_sp; |
550 | } |
551 | } |
552 | if (!saved_state.register_backup_sp) |
553 | return false; |
554 | |
555 | saved_state.stop_info_sp = GetStopInfo(); |
556 | ProcessSP process_sp (GetProcess()); |
557 | if (process_sp) |
558 | saved_state.orig_stop_id = process_sp->GetStopID(); |
559 | saved_state.current_inlined_depth = GetCurrentInlinedDepth(); |
560 | |
561 | return true; |
562 | } |
563 | |
564 | bool |
565 | Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state) |
566 | { |
567 | if (saved_state.register_backup_sp) |
568 | { |
569 | lldb::StackFrameSP frame_sp(GetStackFrameAtIndex (0)); |
570 | if (frame_sp) |
571 | { |
572 | lldb::RegisterContextSP reg_ctx_sp (frame_sp->GetRegisterContext()); |
573 | if (reg_ctx_sp) |
574 | { |
575 | bool ret = reg_ctx_sp->WriteAllRegisterValues (*saved_state.register_backup_sp); |
576 | |
577 | // Clear out all stack frames as our world just changed. |
578 | ClearStackFrames(); |
579 | reg_ctx_sp->InvalidateIfNeeded(true); |
580 | if (m_unwinder_ap.get()) |
581 | m_unwinder_ap->Clear(); |
582 | return ret; |
583 | } |
584 | } |
585 | } |
586 | return false; |
587 | } |
588 | |
589 | bool |
590 | Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state) |
591 | { |
592 | if (saved_state.stop_info_sp) |
593 | saved_state.stop_info_sp->MakeStopInfoValid(); |
594 | SetStopInfo(saved_state.stop_info_sp); |
595 | GetStackFrameList()->SetCurrentInlinedDepth (saved_state.current_inlined_depth); |
596 | return true; |
597 | } |
598 | |
599 | StateType |
600 | Thread::GetState() const |
601 | { |
602 | // If any other threads access this we will need a mutex for it |
603 | Mutex::Locker locker(m_state_mutex); |
604 | return m_state; |
605 | } |
606 | |
607 | void |
608 | Thread::SetState(StateType state) |
609 | { |
610 | Mutex::Locker locker(m_state_mutex); |
611 | m_state = state; |
612 | } |
613 | |
614 | void |
615 | Thread::WillStop() |
616 | { |
617 | ThreadPlan *current_plan = GetCurrentPlan(); |
618 | |
619 | // FIXME: I may decide to disallow threads with no plans. In which |
620 | // case this should go to an assert. |
621 | |
622 | if (!current_plan) |
623 | return; |
624 | |
625 | current_plan->WillStop(); |
626 | } |
627 | |
628 | void |
629 | Thread::SetupForResume () |
630 | { |
631 | if (GetResumeState() != eStateSuspended) |
632 | { |
633 | |
634 | // If we're at a breakpoint push the step-over breakpoint plan. Do this before |
635 | // telling the current plan it will resume, since we might change what the current |
636 | // plan is. |
637 | |
638 | // StopReason stop_reason = lldb::eStopReasonInvalid; |
639 | // StopInfoSP stop_info_sp = GetStopInfo(); |
640 | // if (stop_info_sp.get()) |
641 | // stop_reason = stop_info_sp->GetStopReason(); |
642 | // if (stop_reason == lldb::eStopReasonBreakpoint) |
643 | lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext()); |
644 | if (reg_ctx_sp) |
645 | { |
646 | BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(reg_ctx_sp->GetPC()); |
647 | if (bp_site_sp) |
648 | { |
649 | // Note, don't assume there's a ThreadPlanStepOverBreakpoint, the target may not require anything |
650 | // special to step over a breakpoint. |
651 | |
652 | ThreadPlan *cur_plan = GetCurrentPlan(); |
653 | |
654 | if (cur_plan->GetKind() != ThreadPlan::eKindStepOverBreakpoint) |
655 | { |
656 | ThreadPlanSP step_bp_plan_sp (new ThreadPlanStepOverBreakpoint (*this)); |
657 | if (step_bp_plan_sp) |
658 | { |
659 | ; |
660 | step_bp_plan_sp->SetPrivate (true); |
661 | |
662 | if (GetCurrentPlan()->RunState() != eStateStepping) |
663 | { |
664 | ThreadPlanStepOverBreakpoint *step_bp_plan |
665 | = static_cast<ThreadPlanStepOverBreakpoint *>(step_bp_plan_sp.get()); |
666 | step_bp_plan->SetAutoContinue(true); |
667 | } |
668 | QueueThreadPlan (step_bp_plan_sp, false); |
669 | } |
670 | } |
671 | } |
672 | } |
673 | } |
674 | } |
675 | |
676 | bool |
677 | Thread::ShouldResume (StateType resume_state) |
678 | { |
679 | // At this point clear the completed plan stack. |
680 | m_completed_plan_stack.clear(); |
681 | m_discarded_plan_stack.clear(); |
682 | m_override_should_notify = eLazyBoolCalculate; |
683 | |
684 | m_temporary_resume_state = resume_state; |
685 | |
686 | lldb::ThreadSP backing_thread_sp (GetBackingThread ()); |
687 | if (backing_thread_sp) |
688 | backing_thread_sp->m_temporary_resume_state = resume_state; |
689 | |
690 | // Make sure m_stop_info_sp is valid |
691 | GetPrivateStopInfo(); |
692 | |
693 | // This is a little dubious, but we are trying to limit how often we actually fetch stop info from |
694 | // the target, 'cause that slows down single stepping. So assume that if we got to the point where |
695 | // we're about to resume, and we haven't yet had to fetch the stop reason, then it doesn't need to know |
696 | // about the fact that we are resuming... |
697 | const uint32_t process_stop_id = GetProcess()->GetStopID(); |
698 | if (m_stop_info_stop_id == process_stop_id && |
699 | (m_stop_info_sp && m_stop_info_sp->IsValid())) |
700 | { |
701 | StopInfo *stop_info = GetPrivateStopInfo().get(); |
702 | if (stop_info) |
703 | stop_info->WillResume (resume_state); |
704 | } |
705 | |
706 | // Tell all the plans that we are about to resume in case they need to clear any state. |
707 | // We distinguish between the plan on the top of the stack and the lower |
708 | // plans in case a plan needs to do any special business before it runs. |
709 | |
710 | bool need_to_resume = false; |
711 | ThreadPlan *plan_ptr = GetCurrentPlan(); |
712 | if (plan_ptr) |
713 | { |
714 | need_to_resume = plan_ptr->WillResume(resume_state, true); |
715 | |
716 | while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL__null) |
717 | { |
718 | plan_ptr->WillResume (resume_state, false); |
719 | } |
720 | |
721 | // If the WillResume for the plan says we are faking a resume, then it will have set an appropriate stop info. |
722 | // In that case, don't reset it here. |
723 | |
724 | if (need_to_resume && resume_state != eStateSuspended) |
725 | { |
726 | m_stop_info_sp.reset(); |
727 | } |
728 | } |
729 | |
730 | if (need_to_resume) |
731 | { |
732 | ClearStackFrames(); |
733 | // Let Thread subclasses do any special work they need to prior to resuming |
734 | WillResume (resume_state); |
735 | } |
736 | |
737 | return need_to_resume; |
738 | } |
739 | |
740 | void |
741 | Thread::DidResume () |
742 | { |
743 | SetResumeSignal (LLDB_INVALID_SIGNAL_NUMBER(2147483647)); |
744 | } |
745 | |
746 | void |
747 | Thread::DidStop () |
748 | { |
749 | SetState (eStateStopped); |
750 | } |
751 | |
752 | bool |
753 | Thread::ShouldStop (Event* event_ptr) |
754 | { |
755 | ThreadPlan *current_plan = GetCurrentPlan(); |
756 | |
757 | bool should_stop = true; |
758 | |
759 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
760 | |
761 | if (GetResumeState () == eStateSuspended) |
762 | { |
763 | if (log) |
764 | log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64"l" "x" " 0x%4.4" PRIx64"l" "x" ", should_stop = 0 (ignore since thread was suspended)", |
765 | __FUNCTION__, GetID (), GetProtocolID()); |
766 | return false; |
767 | } |
768 | |
769 | if (GetTemporaryResumeState () == eStateSuspended) |
770 | { |
771 | if (log) |
772 | log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64"l" "x" " 0x%4.4" PRIx64"l" "x" ", should_stop = 0 (ignore since thread was suspended)", |
773 | __FUNCTION__, GetID (), GetProtocolID()); |
774 | return false; |
775 | } |
776 | |
777 | // Based on the current thread plan and process stop info, check if this |
778 | // thread caused the process to stop. NOTE: this must take place before |
779 | // the plan is moved from the current plan stack to the completed plan |
780 | // stack. |
781 | if (ThreadStoppedForAReason() == false) |
782 | { |
783 | if (log) |
784 | log->Printf ("Thread::%s for tid = 0x%4.4" PRIx64"l" "x" " 0x%4.4" PRIx64"l" "x" ", pc = 0x%16.16" PRIx64"l" "x" ", should_stop = 0 (ignore since no stop reason)", |
785 | __FUNCTION__, GetID (), GetProtocolID(), |
786 | GetRegisterContext() ? GetRegisterContext()->GetPC() : LLDB_INVALID_ADDRESS(18446744073709551615UL)); |
787 | return false; |
788 | } |
789 | |
790 | if (log) |
791 | { |
792 | log->Printf ("Thread::%s(%p) for tid = 0x%4.4" PRIx64"l" "x" " 0x%4.4" PRIx64"l" "x" ", pc = 0x%16.16" PRIx64"l" "x", |
793 | __FUNCTION__, static_cast<void*>(this), GetID (), |
794 | GetProtocolID (), |
795 | GetRegisterContext() |
796 | ? GetRegisterContext()->GetPC() |
797 | : LLDB_INVALID_ADDRESS(18446744073709551615UL)); |
798 | log->Printf ("^^^^^^^^ Thread::ShouldStop Begin ^^^^^^^^"); |
799 | StreamString s; |
800 | s.IndentMore(); |
801 | DumpThreadPlans(&s); |
802 | log->Printf ("Plan stack initial state:\n%s", s.GetData()); |
803 | } |
804 | |
805 | // The top most plan always gets to do the trace log... |
806 | current_plan->DoTraceLog (); |
807 | |
808 | // First query the stop info's ShouldStopSynchronous. This handles "synchronous" stop reasons, for example the breakpoint |
809 | // command on internal breakpoints. If a synchronous stop reason says we should not stop, then we don't have to |
810 | // do any more work on this stop. |
811 | StopInfoSP private_stop_info (GetPrivateStopInfo()); |
812 | if (private_stop_info && private_stop_info->ShouldStopSynchronous(event_ptr) == false) |
813 | { |
814 | if (log) |
815 | log->Printf ("StopInfo::ShouldStop async callback says we should not stop, returning ShouldStop of false."); |
816 | return false; |
817 | } |
818 | |
819 | // If we've already been restarted, don't query the plans since the state they would examine is not current. |
820 | if (Process::ProcessEventData::GetRestartedFromEvent(event_ptr)) |
821 | return false; |
822 | |
823 | // Before the plans see the state of the world, calculate the current inlined depth. |
824 | GetStackFrameList()->CalculateCurrentInlinedDepth(); |
825 | |
826 | // If the base plan doesn't understand why we stopped, then we have to find a plan that does. |
827 | // If that plan is still working, then we don't need to do any more work. If the plan that explains |
828 | // the stop is done, then we should pop all the plans below it, and pop it, and then let the plans above it decide |
829 | // whether they still need to do more work. |
830 | |
831 | bool done_processing_current_plan = false; |
832 | |
833 | if (!current_plan->PlanExplainsStop(event_ptr)) |
834 | { |
835 | if (current_plan->TracerExplainsStop()) |
836 | { |
837 | done_processing_current_plan = true; |
838 | should_stop = false; |
839 | } |
840 | else |
841 | { |
842 | // If the current plan doesn't explain the stop, then find one that |
843 | // does and let it handle the situation. |
844 | ThreadPlan *plan_ptr = current_plan; |
845 | while ((plan_ptr = GetPreviousPlan(plan_ptr)) != NULL__null) |
846 | { |
847 | if (plan_ptr->PlanExplainsStop(event_ptr)) |
848 | { |
849 | should_stop = plan_ptr->ShouldStop (event_ptr); |
850 | |
851 | // plan_ptr explains the stop, next check whether plan_ptr is done, if so, then we should take it |
852 | // and all the plans below it off the stack. |
853 | |
854 | if (plan_ptr->MischiefManaged()) |
855 | { |
856 | // We're going to pop the plans up to and including the plan that explains the stop. |
857 | ThreadPlan *prev_plan_ptr = GetPreviousPlan (plan_ptr); |
858 | |
859 | do |
860 | { |
861 | if (should_stop) |
862 | current_plan->WillStop(); |
863 | PopPlan(); |
864 | } |
865 | while ((current_plan = GetCurrentPlan()) != prev_plan_ptr); |
866 | // Now, if the responsible plan was not "Okay to discard" then we're done, |
867 | // otherwise we forward this to the next plan in the stack below. |
868 | if (plan_ptr->IsMasterPlan() && !plan_ptr->OkayToDiscard()) |
869 | done_processing_current_plan = true; |
870 | else |
871 | done_processing_current_plan = false; |
872 | } |
873 | else |
874 | done_processing_current_plan = true; |
875 | |
876 | break; |
877 | } |
878 | |
879 | } |
880 | } |
881 | } |
882 | |
883 | if (!done_processing_current_plan) |
884 | { |
885 | bool over_ride_stop = current_plan->ShouldAutoContinue(event_ptr); |
886 | |
887 | if (log) |
888 | log->Printf("Plan %s explains stop, auto-continue %i.", |
889 | current_plan->GetName(), over_ride_stop); |
890 | |
891 | // We're starting from the base plan, so just let it decide; |
892 | if (PlanIsBasePlan(current_plan)) |
893 | { |
894 | should_stop = current_plan->ShouldStop (event_ptr); |
895 | if (log) |
896 | log->Printf("Base plan says should stop: %i.", should_stop); |
897 | } |
898 | else |
899 | { |
900 | // Otherwise, don't let the base plan override what the other plans say to do, since |
901 | // presumably if there were other plans they would know what to do... |
902 | while (1) |
903 | { |
904 | if (PlanIsBasePlan(current_plan)) |
905 | break; |
906 | |
907 | should_stop = current_plan->ShouldStop(event_ptr); |
908 | if (log) |
909 | log->Printf("Plan %s should stop: %d.", |
910 | current_plan->GetName(), should_stop); |
911 | if (current_plan->MischiefManaged()) |
912 | { |
913 | if (should_stop) |
914 | current_plan->WillStop(); |
915 | |
916 | // If a Master Plan wants to stop, and wants to stick on the stack, we let it. |
917 | // Otherwise, see if the plan's parent wants to stop. |
918 | |
919 | if (should_stop && current_plan->IsMasterPlan() && !current_plan->OkayToDiscard()) |
920 | { |
921 | PopPlan(); |
922 | break; |
923 | } |
924 | else |
925 | { |
926 | |
927 | PopPlan(); |
928 | |
929 | current_plan = GetCurrentPlan(); |
930 | if (current_plan == NULL__null) |
931 | { |
932 | break; |
933 | } |
934 | } |
935 | } |
936 | else |
937 | { |
938 | break; |
939 | } |
940 | } |
941 | } |
942 | |
943 | if (over_ride_stop) |
944 | should_stop = false; |
945 | |
946 | } |
947 | |
948 | // One other potential problem is that we set up a master plan, then stop in before it is complete - for instance |
949 | // by hitting a breakpoint during a step-over - then do some step/finish/etc operations that wind up |
950 | // past the end point condition of the initial plan. We don't want to strand the original plan on the stack, |
951 | // This code clears stale plans off the stack. |
952 | |
953 | if (should_stop) |
954 | { |
955 | ThreadPlan *plan_ptr = GetCurrentPlan(); |
956 | while (!PlanIsBasePlan(plan_ptr)) |
957 | { |
958 | bool stale = plan_ptr->IsPlanStale (); |
959 | ThreadPlan *examined_plan = plan_ptr; |
960 | plan_ptr = GetPreviousPlan (examined_plan); |
961 | |
962 | if (stale) |
963 | { |
964 | if (log) |
965 | log->Printf("Plan %s being discarded in cleanup, it says it is already done.", |
966 | examined_plan->GetName()); |
967 | DiscardThreadPlansUpToPlan(examined_plan); |
968 | } |
969 | } |
970 | } |
971 | |
972 | if (log) |
973 | { |
974 | StreamString s; |
975 | s.IndentMore(); |
976 | DumpThreadPlans(&s); |
977 | log->Printf ("Plan stack final state:\n%s", s.GetData()); |
978 | log->Printf ("vvvvvvvv Thread::ShouldStop End (returning %i) vvvvvvvv", should_stop); |
979 | } |
980 | return should_stop; |
981 | } |
982 | |
983 | Vote |
984 | Thread::ShouldReportStop (Event* event_ptr) |
985 | { |
986 | StateType thread_state = GetResumeState (); |
987 | StateType temp_thread_state = GetTemporaryResumeState(); |
988 | |
989 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
990 | |
991 | if (thread_state == eStateSuspended || thread_state == eStateInvalid) |
992 | { |
993 | if (log) |
994 | log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64"l" "x" ": returning vote %i (state was suspended or invalid)", GetID(), eVoteNoOpinion); |
995 | return eVoteNoOpinion; |
996 | } |
997 | |
998 | if (temp_thread_state == eStateSuspended || temp_thread_state == eStateInvalid) |
999 | { |
1000 | if (log) |
1001 | log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64"l" "x" ": returning vote %i (temporary state was suspended or invalid)", GetID(), eVoteNoOpinion); |
1002 | return eVoteNoOpinion; |
1003 | } |
1004 | |
1005 | if (!ThreadStoppedForAReason()) |
1006 | { |
1007 | if (log) |
1008 | log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64"l" "x" ": returning vote %i (thread didn't stop for a reason.)", GetID(), eVoteNoOpinion); |
1009 | return eVoteNoOpinion; |
1010 | } |
1011 | |
1012 | if (m_completed_plan_stack.size() > 0) |
1013 | { |
1014 | // Don't use GetCompletedPlan here, since that suppresses private plans. |
1015 | if (log) |
1016 | log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64"l" "x" ": returning vote for complete stack's back plan", GetID()); |
1017 | return m_completed_plan_stack.back()->ShouldReportStop (event_ptr); |
1018 | } |
1019 | else |
1020 | { |
1021 | Vote thread_vote = eVoteNoOpinion; |
1022 | ThreadPlan *plan_ptr = GetCurrentPlan(); |
1023 | while (1) |
1024 | { |
1025 | if (plan_ptr->PlanExplainsStop(event_ptr)) |
1026 | { |
1027 | thread_vote = plan_ptr->ShouldReportStop(event_ptr); |
1028 | break; |
1029 | } |
1030 | if (PlanIsBasePlan(plan_ptr)) |
1031 | break; |
1032 | else |
1033 | plan_ptr = GetPreviousPlan(plan_ptr); |
1034 | } |
1035 | if (log) |
1036 | log->Printf ("Thread::ShouldReportStop() tid = 0x%4.4" PRIx64"l" "x" ": returning vote %i for current plan", GetID(), thread_vote); |
1037 | |
1038 | return thread_vote; |
1039 | } |
1040 | } |
1041 | |
1042 | Vote |
1043 | Thread::ShouldReportRun (Event* event_ptr) |
1044 | { |
1045 | StateType thread_state = GetResumeState (); |
1046 | |
1047 | if (thread_state == eStateSuspended |
1048 | || thread_state == eStateInvalid) |
1049 | { |
1050 | return eVoteNoOpinion; |
1051 | } |
1052 | |
1053 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1054 | if (m_completed_plan_stack.size() > 0) |
1055 | { |
1056 | // Don't use GetCompletedPlan here, since that suppresses private plans. |
1057 | if (log) |
1058 | log->Printf ("Current Plan for thread %d(%p) (0x%4.4" PRIx64"l" "x" ", %s): %s being asked whether we should report run.", |
1059 | GetIndexID(), static_cast<void*>(this), GetID(), |
1060 | StateAsCString(GetTemporaryResumeState()), |
1061 | m_completed_plan_stack.back()->GetName()); |
1062 | |
1063 | return m_completed_plan_stack.back()->ShouldReportRun (event_ptr); |
1064 | } |
1065 | else |
1066 | { |
1067 | if (log) |
1068 | log->Printf ("Current Plan for thread %d(%p) (0x%4.4" PRIx64"l" "x" ", %s): %s being asked whether we should report run.", |
1069 | GetIndexID(), static_cast<void*>(this), GetID(), |
1070 | StateAsCString(GetTemporaryResumeState()), |
1071 | GetCurrentPlan()->GetName()); |
1072 | |
1073 | return GetCurrentPlan()->ShouldReportRun (event_ptr); |
1074 | } |
1075 | } |
1076 | |
1077 | bool |
1078 | Thread::MatchesSpec (const ThreadSpec *spec) |
1079 | { |
1080 | if (spec == NULL__null) |
1081 | return true; |
1082 | |
1083 | return spec->ThreadPassesBasicTests(*this); |
1084 | } |
1085 | |
1086 | void |
1087 | Thread::PushPlan (ThreadPlanSP &thread_plan_sp) |
1088 | { |
1089 | if (thread_plan_sp) |
1090 | { |
1091 | // If the thread plan doesn't already have a tracer, give it its parent's tracer: |
1092 | if (!thread_plan_sp->GetThreadPlanTracer()) |
1093 | thread_plan_sp->SetThreadPlanTracer(m_plan_stack.back()->GetThreadPlanTracer()); |
1094 | m_plan_stack.push_back (thread_plan_sp); |
1095 | |
1096 | thread_plan_sp->DidPush(); |
1097 | |
1098 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1099 | if (log) |
1100 | { |
1101 | StreamString s; |
1102 | thread_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); |
1103 | log->Printf("Thread::PushPlan(0x%p): \"%s\", tid = 0x%4.4" PRIx64"l" "x" ".", |
1104 | static_cast<void*>(this), s.GetData(), |
1105 | thread_plan_sp->GetThread().GetID()); |
1106 | } |
1107 | } |
1108 | } |
1109 | |
1110 | void |
1111 | Thread::PopPlan () |
1112 | { |
1113 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1114 | |
1115 | if (m_plan_stack.size() <= 1) |
1116 | return; |
1117 | else |
1118 | { |
1119 | ThreadPlanSP &plan = m_plan_stack.back(); |
1120 | if (log) |
1121 | { |
1122 | log->Printf("Popping plan: \"%s\", tid = 0x%4.4" PRIx64"l" "x" ".", plan->GetName(), plan->GetThread().GetID()); |
1123 | } |
1124 | m_completed_plan_stack.push_back (plan); |
1125 | plan->WillPop(); |
1126 | m_plan_stack.pop_back(); |
1127 | } |
1128 | } |
1129 | |
1130 | void |
1131 | Thread::DiscardPlan () |
1132 | { |
1133 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1134 | if (m_plan_stack.size() > 1) |
1135 | { |
1136 | ThreadPlanSP &plan = m_plan_stack.back(); |
1137 | if (log) |
1138 | log->Printf("Discarding plan: \"%s\", tid = 0x%4.4" PRIx64"l" "x" ".", plan->GetName(), plan->GetThread().GetID()); |
1139 | |
1140 | m_discarded_plan_stack.push_back (plan); |
1141 | plan->WillPop(); |
1142 | m_plan_stack.pop_back(); |
1143 | } |
1144 | } |
1145 | |
1146 | ThreadPlan * |
1147 | Thread::GetCurrentPlan () |
1148 | { |
1149 | // There will always be at least the base plan. If somebody is mucking with a |
1150 | // thread with an empty plan stack, we should assert right away. |
1151 | if (m_plan_stack.empty()) |
1152 | return NULL__null; |
1153 | return m_plan_stack.back().get(); |
1154 | } |
1155 | |
1156 | ThreadPlanSP |
1157 | Thread::GetCompletedPlan () |
1158 | { |
1159 | ThreadPlanSP empty_plan_sp; |
1160 | if (!m_completed_plan_stack.empty()) |
1161 | { |
1162 | for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) |
1163 | { |
1164 | ThreadPlanSP completed_plan_sp; |
1165 | completed_plan_sp = m_completed_plan_stack[i]; |
1166 | if (!completed_plan_sp->GetPrivate ()) |
1167 | return completed_plan_sp; |
1168 | } |
1169 | } |
1170 | return empty_plan_sp; |
1171 | } |
1172 | |
1173 | ValueObjectSP |
1174 | Thread::GetReturnValueObject () |
1175 | { |
1176 | if (!m_completed_plan_stack.empty()) |
1177 | { |
1178 | for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) |
1179 | { |
1180 | ValueObjectSP return_valobj_sp; |
1181 | return_valobj_sp = m_completed_plan_stack[i]->GetReturnValueObject(); |
1182 | if (return_valobj_sp) |
1183 | return return_valobj_sp; |
1184 | } |
1185 | } |
1186 | return ValueObjectSP(); |
1187 | } |
1188 | |
1189 | ClangExpressionVariableSP |
1190 | Thread::GetExpressionVariable () |
1191 | { |
1192 | if (!m_completed_plan_stack.empty()) |
1193 | { |
1194 | for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) |
1195 | { |
1196 | ClangExpressionVariableSP expression_variable_sp; |
1197 | expression_variable_sp = m_completed_plan_stack[i]->GetExpressionVariable(); |
1198 | if (expression_variable_sp) |
1199 | return expression_variable_sp; |
1200 | } |
1201 | } |
1202 | return ClangExpressionVariableSP(); |
1203 | } |
1204 | |
1205 | bool |
1206 | Thread::IsThreadPlanDone (ThreadPlan *plan) |
1207 | { |
1208 | if (!m_completed_plan_stack.empty()) |
1209 | { |
1210 | for (int i = m_completed_plan_stack.size() - 1; i >= 0; i--) |
1211 | { |
1212 | if (m_completed_plan_stack[i].get() == plan) |
1213 | return true; |
1214 | } |
1215 | } |
1216 | return false; |
1217 | } |
1218 | |
1219 | bool |
1220 | Thread::WasThreadPlanDiscarded (ThreadPlan *plan) |
1221 | { |
1222 | if (!m_discarded_plan_stack.empty()) |
1223 | { |
1224 | for (int i = m_discarded_plan_stack.size() - 1; i >= 0; i--) |
1225 | { |
1226 | if (m_discarded_plan_stack[i].get() == plan) |
1227 | return true; |
1228 | } |
1229 | } |
1230 | return false; |
1231 | } |
1232 | |
1233 | ThreadPlan * |
1234 | Thread::GetPreviousPlan (ThreadPlan *current_plan) |
1235 | { |
1236 | if (current_plan == NULL__null) |
1237 | return NULL__null; |
1238 | |
1239 | int stack_size = m_completed_plan_stack.size(); |
1240 | for (int i = stack_size - 1; i > 0; i--) |
1241 | { |
1242 | if (current_plan == m_completed_plan_stack[i].get()) |
1243 | return m_completed_plan_stack[i-1].get(); |
1244 | } |
1245 | |
1246 | if (stack_size > 0 && m_completed_plan_stack[0].get() == current_plan) |
1247 | { |
1248 | if (m_plan_stack.size() > 0) |
1249 | return m_plan_stack.back().get(); |
1250 | else |
1251 | return NULL__null; |
1252 | } |
1253 | |
1254 | stack_size = m_plan_stack.size(); |
1255 | for (int i = stack_size - 1; i > 0; i--) |
1256 | { |
1257 | if (current_plan == m_plan_stack[i].get()) |
1258 | return m_plan_stack[i-1].get(); |
1259 | } |
1260 | return NULL__null; |
1261 | } |
1262 | |
1263 | void |
1264 | Thread::QueueThreadPlan (ThreadPlanSP &thread_plan_sp, bool abort_other_plans) |
1265 | { |
1266 | if (abort_other_plans) |
1267 | DiscardThreadPlans(true); |
1268 | |
1269 | PushPlan (thread_plan_sp); |
1270 | } |
1271 | |
1272 | |
1273 | void |
1274 | Thread::EnableTracer (bool value, bool single_stepping) |
1275 | { |
1276 | int stack_size = m_plan_stack.size(); |
1277 | for (int i = 0; i < stack_size; i++) |
1278 | { |
1279 | if (m_plan_stack[i]->GetThreadPlanTracer()) |
1280 | { |
1281 | m_plan_stack[i]->GetThreadPlanTracer()->EnableTracing(value); |
1282 | m_plan_stack[i]->GetThreadPlanTracer()->EnableSingleStep(single_stepping); |
1283 | } |
1284 | } |
1285 | } |
1286 | |
1287 | void |
1288 | Thread::SetTracer (lldb::ThreadPlanTracerSP &tracer_sp) |
1289 | { |
1290 | int stack_size = m_plan_stack.size(); |
1291 | for (int i = 0; i < stack_size; i++) |
1292 | m_plan_stack[i]->SetThreadPlanTracer(tracer_sp); |
1293 | } |
1294 | |
1295 | bool |
1296 | Thread::DiscardUserThreadPlansUpToIndex (uint32_t thread_index) |
1297 | { |
1298 | // Count the user thread plans from the back end to get the number of the one we want |
1299 | // to discard: |
1300 | |
1301 | uint32_t idx = 0; |
1302 | ThreadPlan *up_to_plan_ptr = nullptr; |
1303 | |
1304 | for (ThreadPlanSP plan_sp : m_plan_stack) |
1305 | { |
1306 | if (plan_sp->GetPrivate()) |
1307 | continue; |
1308 | if (idx == thread_index) |
1309 | { |
1310 | up_to_plan_ptr = plan_sp.get(); |
1311 | break; |
1312 | } |
1313 | else |
1314 | idx++; |
1315 | } |
1316 | |
1317 | if (up_to_plan_ptr == nullptr) |
1318 | return false; |
1319 | |
1320 | DiscardThreadPlansUpToPlan(up_to_plan_ptr); |
1321 | return true; |
1322 | } |
1323 | |
1324 | |
1325 | void |
1326 | Thread::DiscardThreadPlansUpToPlan (lldb::ThreadPlanSP &up_to_plan_sp) |
1327 | { |
1328 | DiscardThreadPlansUpToPlan (up_to_plan_sp.get()); |
1329 | } |
1330 | |
1331 | void |
1332 | Thread::DiscardThreadPlansUpToPlan (ThreadPlan *up_to_plan_ptr) |
1333 | { |
1334 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1335 | if (log) |
1336 | log->Printf("Discarding thread plans for thread tid = 0x%4.4" PRIx64"l" "x" ", up to %p", |
1337 | GetID(), static_cast<void*>(up_to_plan_ptr)); |
1338 | |
1339 | int stack_size = m_plan_stack.size(); |
1340 | |
1341 | // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the |
1342 | // stack, and if so discard up to and including it. |
1343 | |
1344 | if (up_to_plan_ptr == NULL__null) |
1345 | { |
1346 | for (int i = stack_size - 1; i > 0; i--) |
1347 | DiscardPlan(); |
1348 | } |
1349 | else |
1350 | { |
1351 | bool found_it = false; |
1352 | for (int i = stack_size - 1; i > 0; i--) |
1353 | { |
1354 | if (m_plan_stack[i].get() == up_to_plan_ptr) |
1355 | found_it = true; |
1356 | } |
1357 | if (found_it) |
1358 | { |
1359 | bool last_one = false; |
1360 | for (int i = stack_size - 1; i > 0 && !last_one ; i--) |
1361 | { |
1362 | if (GetCurrentPlan() == up_to_plan_ptr) |
1363 | last_one = true; |
1364 | DiscardPlan(); |
1365 | } |
1366 | } |
1367 | } |
1368 | return; |
1369 | } |
1370 | |
1371 | void |
1372 | Thread::DiscardThreadPlans(bool force) |
1373 | { |
1374 | Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP(1u << 7))); |
1375 | if (log) |
1376 | { |
1377 | log->Printf("Discarding thread plans for thread (tid = 0x%4.4" PRIx64"l" "x" ", force %d)", GetID(), force); |
1378 | } |
1379 | |
1380 | if (force) |
1381 | { |
1382 | int stack_size = m_plan_stack.size(); |
1383 | for (int i = stack_size - 1; i > 0; i--) |
1384 | { |
1385 | DiscardPlan(); |
1386 | } |
1387 | return; |
1388 | } |
1389 | |
1390 | while (1) |
1391 | { |
1392 | |
1393 | int master_plan_idx; |
1394 | bool discard = true; |
1395 | |
1396 | // Find the first master plan, see if it wants discarding, and if yes discard up to it. |
1397 | for (master_plan_idx = m_plan_stack.size() - 1; master_plan_idx >= 0; master_plan_idx--) |
1398 | { |
1399 | if (m_plan_stack[master_plan_idx]->IsMasterPlan()) |
1400 | { |
1401 | discard = m_plan_stack[master_plan_idx]->OkayToDiscard(); |
1402 | break; |
1403 | } |
1404 | } |
1405 | |
1406 | if (discard) |
1407 | { |
1408 | // First pop all the dependent plans: |
1409 | for (int i = m_plan_stack.size() - 1; i > master_plan_idx; i--) |
1410 | { |
1411 | |
1412 | // FIXME: Do we need a finalize here, or is the rule that "PrepareForStop" |
1413 | // for the plan leaves it in a state that it is safe to pop the plan |
1414 | // with no more notice? |
1415 | DiscardPlan(); |
1416 | } |
1417 | |
1418 | // Now discard the master plan itself. |
1419 | // The bottom-most plan never gets discarded. "OkayToDiscard" for it means |
1420 | // discard it's dependent plans, but not it... |
1421 | if (master_plan_idx > 0) |
1422 | { |
1423 | DiscardPlan(); |
1424 | } |
1425 | } |
1426 | else |
1427 | { |
1428 | // If the master plan doesn't want to get discarded, then we're done. |
1429 | break; |
1430 | } |
1431 | |
1432 | } |
1433 | } |
1434 | |
1435 | bool |
1436 | Thread::PlanIsBasePlan (ThreadPlan *plan_ptr) |
1437 | { |
1438 | if (plan_ptr->IsBasePlan()) |
1439 | return true; |
1440 | else if (m_plan_stack.size() == 0) |
1441 | return false; |
1442 | else |
1443 | return m_plan_stack[0].get() == plan_ptr; |
1444 | } |
1445 | |
1446 | Error |
1447 | Thread::UnwindInnermostExpression() |
1448 | { |
1449 | Error error; |
1450 | int stack_size = m_plan_stack.size(); |
1451 | |
1452 | // If the input plan is NULL, discard all plans. Otherwise make sure this plan is in the |
1453 | // stack, and if so discard up to and including it. |
1454 | |
1455 | for (int i = stack_size - 1; i > 0; i--) |
1456 | { |
1457 | if (m_plan_stack[i]->GetKind() == ThreadPlan::eKindCallFunction) |
1458 | { |
1459 | DiscardThreadPlansUpToPlan(m_plan_stack[i].get()); |
1460 | return error; |
1461 | } |
1462 | } |
1463 | error.SetErrorString("No expressions currently active on this thread"); |
1464 | return error; |
1465 | } |
1466 | |
1467 | |
1468 | ThreadPlanSP |
1469 | Thread::QueueFundamentalPlan (bool abort_other_plans) |
1470 | { |
1471 | ThreadPlanSP thread_plan_sp (new ThreadPlanBase(*this)); |
1472 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1473 | return thread_plan_sp; |
1474 | } |
1475 | |
1476 | ThreadPlanSP |
1477 | Thread::QueueThreadPlanForStepSingleInstruction |
1478 | ( |
1479 | bool step_over, |
1480 | bool abort_other_plans, |
1481 | bool stop_other_threads |
1482 | ) |
1483 | { |
1484 | ThreadPlanSP thread_plan_sp (new ThreadPlanStepInstruction (*this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion)); |
1485 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1486 | return thread_plan_sp; |
1487 | } |
1488 | |
1489 | ThreadPlanSP |
1490 | Thread::QueueThreadPlanForStepOverRange |
1491 | ( |
1492 | bool abort_other_plans, |
1493 | const AddressRange &range, |
1494 | const SymbolContext &addr_context, |
1495 | lldb::RunMode stop_other_threads, |
1496 | LazyBool step_out_avoids_code_withoug_debug_info |
1497 | ) |
1498 | { |
1499 | ThreadPlanSP thread_plan_sp; |
1500 | thread_plan_sp.reset (new ThreadPlanStepOverRange (*this, range, addr_context, stop_other_threads, step_out_avoids_code_withoug_debug_info)); |
1501 | |
1502 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1503 | return thread_plan_sp; |
1504 | } |
1505 | |
1506 | ThreadPlanSP |
1507 | Thread::QueueThreadPlanForStepInRange |
1508 | ( |
1509 | bool abort_other_plans, |
1510 | const AddressRange &range, |
1511 | const SymbolContext &addr_context, |
1512 | const char *step_in_target, |
1513 | lldb::RunMode stop_other_threads, |
1514 | LazyBool step_in_avoids_code_without_debug_info, |
1515 | LazyBool step_out_avoids_code_without_debug_info |
1516 | ) |
1517 | { |
1518 | ThreadPlanSP thread_plan_sp (new ThreadPlanStepInRange (*this, |
1519 | range, |
1520 | addr_context, |
1521 | stop_other_threads, |
1522 | step_in_avoids_code_without_debug_info, |
1523 | step_out_avoids_code_without_debug_info)); |
1524 | ThreadPlanStepInRange *plan = static_cast<ThreadPlanStepInRange *>(thread_plan_sp.get()); |
1525 | |
1526 | if (step_in_target) |
1527 | plan->SetStepInTarget(step_in_target); |
1528 | |
1529 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1530 | return thread_plan_sp; |
1531 | } |
1532 | |
1533 | |
1534 | ThreadPlanSP |
1535 | Thread::QueueThreadPlanForStepOut |
1536 | ( |
1537 | bool abort_other_plans, |
1538 | SymbolContext *addr_context, |
1539 | bool first_insn, |
1540 | bool stop_other_threads, |
1541 | Vote stop_vote, |
1542 | Vote run_vote, |
1543 | uint32_t frame_idx, |
1544 | LazyBool step_out_avoids_code_withoug_debug_info |
1545 | ) |
1546 | { |
1547 | ThreadPlanSP thread_plan_sp (new ThreadPlanStepOut (*this, |
1548 | addr_context, |
1549 | first_insn, |
1550 | stop_other_threads, |
1551 | stop_vote, |
1552 | run_vote, |
1553 | frame_idx, |
1554 | step_out_avoids_code_withoug_debug_info)); |
1555 | |
1556 | if (thread_plan_sp->ValidatePlan(NULL__null)) |
1557 | { |
1558 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1559 | return thread_plan_sp; |
1560 | } |
1561 | else |
1562 | { |
1563 | return ThreadPlanSP(); |
1564 | } |
1565 | } |
1566 | |
1567 | ThreadPlanSP |
1568 | Thread::QueueThreadPlanForStepOutNoShouldStop |
1569 | ( |
1570 | bool abort_other_plans, |
1571 | SymbolContext *addr_context, |
1572 | bool first_insn, |
1573 | bool stop_other_threads, |
1574 | Vote stop_vote, |
1575 | Vote run_vote, |
1576 | uint32_t frame_idx |
1577 | ) |
1578 | { |
1579 | ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut (*this, |
1580 | addr_context, |
1581 | first_insn, |
1582 | stop_other_threads, |
1583 | stop_vote, |
1584 | run_vote, |
1585 | frame_idx, |
1586 | eLazyBoolNo)); |
1587 | |
1588 | ThreadPlanStepOut *new_plan = static_cast<ThreadPlanStepOut *>(thread_plan_sp.get()); |
1589 | new_plan->ClearShouldStopHereCallbacks(); |
1590 | |
1591 | if (thread_plan_sp->ValidatePlan(NULL__null)) |
1592 | { |
1593 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1594 | return thread_plan_sp; |
1595 | } |
1596 | else |
1597 | { |
1598 | return ThreadPlanSP(); |
1599 | } |
1600 | } |
1601 | |
1602 | ThreadPlanSP |
1603 | Thread::QueueThreadPlanForStepThrough (StackID &return_stack_id, bool abort_other_plans, bool stop_other_threads) |
1604 | { |
1605 | ThreadPlanSP thread_plan_sp(new ThreadPlanStepThrough (*this, return_stack_id, stop_other_threads)); |
1606 | if (!thread_plan_sp || !thread_plan_sp->ValidatePlan (NULL__null)) |
1607 | return ThreadPlanSP(); |
1608 | |
1609 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1610 | return thread_plan_sp; |
1611 | } |
1612 | |
1613 | ThreadPlanSP |
1614 | Thread::QueueThreadPlanForRunToAddress (bool abort_other_plans, |
1615 | Address &target_addr, |
1616 | bool stop_other_threads) |
1617 | { |
1618 | ThreadPlanSP thread_plan_sp (new ThreadPlanRunToAddress (*this, target_addr, stop_other_threads)); |
1619 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1620 | return thread_plan_sp; |
1621 | } |
1622 | |
1623 | ThreadPlanSP |
1624 | Thread::QueueThreadPlanForStepUntil (bool abort_other_plans, |
1625 | lldb::addr_t *address_list, |
1626 | size_t num_addresses, |
1627 | bool stop_other_threads, |
1628 | uint32_t frame_idx) |
1629 | { |
1630 | ThreadPlanSP thread_plan_sp (new ThreadPlanStepUntil (*this, address_list, num_addresses, stop_other_threads, frame_idx)); |
1631 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1632 | return thread_plan_sp; |
1633 | |
1634 | } |
1635 | |
1636 | lldb::ThreadPlanSP |
1637 | Thread::QueueThreadPlanForStepScripted (bool abort_other_plans, |
1638 | const char *class_name, |
1639 | bool stop_other_threads) |
1640 | { |
1641 | ThreadPlanSP thread_plan_sp (new ThreadPlanPython (*this, class_name)); |
1642 | QueueThreadPlan (thread_plan_sp, abort_other_plans); |
1643 | // This seems a little funny, but I don't want to have to split up the constructor and the |
1644 | // DidPush in the scripted plan, that seems annoying. |
1645 | // That means the constructor has to be in DidPush. |
1646 | // So I have to validate the plan AFTER pushing it, and then take it off again... |
1647 | if (!thread_plan_sp->ValidatePlan(nullptr)) |
1648 | { |
1649 | DiscardThreadPlansUpToPlan(thread_plan_sp); |
1650 | return ThreadPlanSP(); |
1651 | } |
1652 | else |
1653 | return thread_plan_sp; |
1654 | |
1655 | } |
1656 | |
1657 | uint32_t |
1658 | Thread::GetIndexID () const |
1659 | { |
1660 | return m_index_id; |
1661 | } |
1662 | |
1663 | static void |
1664 | PrintPlanElement (Stream *s, const ThreadPlanSP &plan, lldb::DescriptionLevel desc_level, int32_t elem_idx) |
1665 | { |
1666 | s->IndentMore(); |
1667 | s->Indent(); |
1668 | s->Printf ("Element %d: ", elem_idx); |
1669 | plan->GetDescription (s, desc_level); |
1670 | s->EOL(); |
1671 | s->IndentLess(); |
1672 | } |
1673 | |
1674 | static void |
1675 | PrintPlanStack (Stream *s, const std::vector<lldb::ThreadPlanSP> &plan_stack, lldb::DescriptionLevel desc_level, bool include_internal) |
1676 | { |
1677 | int32_t print_idx = 0; |
1678 | for (ThreadPlanSP plan_sp : plan_stack) |
1679 | { |
1680 | if (include_internal || !plan_sp->GetPrivate()) |
1681 | { |
1682 | PrintPlanElement (s, plan_sp, desc_level, print_idx++); |
1683 | } |
1684 | } |
1685 | } |
1686 | |
1687 | void |
1688 | Thread::DumpThreadPlans (Stream *s, |
1689 | lldb::DescriptionLevel desc_level, |
1690 | bool include_internal, |
1691 | bool ignore_boring_threads) const |
1692 | { |
1693 | uint32_t stack_size = m_plan_stack.size(); |
Value stored to 'stack_size' during its initialization is never read | |
1694 | |
1695 | if (ignore_boring_threads) |
1696 | { |
1697 | uint32_t stack_size = m_plan_stack.size(); |
1698 | uint32_t completed_stack_size = m_completed_plan_stack.size(); |
1699 | uint32_t discarded_stack_size = m_discarded_plan_stack.size(); |
1700 | if (stack_size == 1 && completed_stack_size == 0 && discarded_stack_size == 0) |
1701 | { |
1702 | s->Printf ("thread #%u: tid = 0x%4.4" PRIx64"l" "x" "\n", GetIndexID(), GetID()); |
1703 | s->IndentMore(); |
1704 | s->Indent(); |
1705 | s->Printf("No active thread plans\n"); |
1706 | s->IndentLess(); |
1707 | return; |
1708 | } |
1709 | } |
1710 | |
1711 | s->Indent(); |
1712 | s->Printf ("thread #%u: tid = 0x%4.4" PRIx64"l" "x" ":\n", GetIndexID(), GetID()); |
1713 | s->IndentMore(); |
1714 | s->Indent(); |
1715 | s->Printf ("Active plan stack:\n"); |
1716 | PrintPlanStack (s, m_plan_stack, desc_level, include_internal); |
1717 | |
1718 | stack_size = m_completed_plan_stack.size(); |
1719 | if (stack_size > 0) |
1720 | { |
1721 | s->Indent(); |
1722 | s->Printf ("Completed Plan Stack:\n"); |
1723 | PrintPlanStack (s, m_completed_plan_stack, desc_level, include_internal); |
1724 | } |
1725 | |
1726 | stack_size = m_discarded_plan_stack.size(); |
1727 | if (stack_size > 0) |
1728 | { |
1729 | s->Indent(); |
1730 | s->Printf ("Discarded Plan Stack:\n"); |
1731 | PrintPlanStack (s, m_discarded_plan_stack, desc_level, include_internal); |
1732 | } |
1733 | |
1734 | s->IndentLess(); |
1735 | } |
1736 | |
1737 | TargetSP |
1738 | Thread::CalculateTarget () |
1739 | { |
1740 | TargetSP target_sp; |
1741 | ProcessSP process_sp(GetProcess()); |
1742 | if (process_sp) |
1743 | target_sp = process_sp->CalculateTarget(); |
1744 | return target_sp; |
1745 | |
1746 | } |
1747 | |
1748 | ProcessSP |
1749 | Thread::CalculateProcess () |
1750 | { |
1751 | return GetProcess(); |
1752 | } |
1753 | |
1754 | ThreadSP |
1755 | Thread::CalculateThread () |
1756 | { |
1757 | return shared_from_this(); |
1758 | } |
1759 | |
1760 | StackFrameSP |
1761 | Thread::CalculateStackFrame () |
1762 | { |
1763 | return StackFrameSP(); |
1764 | } |
1765 | |
1766 | void |
1767 | Thread::CalculateExecutionContext (ExecutionContext &exe_ctx) |
1768 | { |
1769 | exe_ctx.SetContext (shared_from_this()); |
1770 | } |
1771 | |
1772 | |
1773 | StackFrameListSP |
1774 | Thread::GetStackFrameList () |
1775 | { |
1776 | StackFrameListSP frame_list_sp; |
1777 | Mutex::Locker locker(m_frame_mutex); |
1778 | if (m_curr_frames_sp) |
1779 | { |
1780 | frame_list_sp = m_curr_frames_sp; |
1781 | } |
1782 | else |
1783 | { |
1784 | frame_list_sp.reset(new StackFrameList (*this, m_prev_frames_sp, true)); |
1785 | m_curr_frames_sp = frame_list_sp; |
1786 | } |
1787 | return frame_list_sp; |
1788 | } |
1789 | |
1790 | void |
1791 | Thread::ClearStackFrames () |
1792 | { |
1793 | Mutex::Locker locker(m_frame_mutex); |
1794 | |
1795 | Unwind *unwinder = GetUnwinder (); |
1796 | if (unwinder) |
1797 | unwinder->Clear(); |
1798 | |
1799 | // Only store away the old "reference" StackFrameList if we got all its frames: |
1800 | // FIXME: At some point we can try to splice in the frames we have fetched into |
1801 | // the new frame as we make it, but let's not try that now. |
1802 | if (m_curr_frames_sp && m_curr_frames_sp->GetAllFramesFetched()) |
1803 | m_prev_frames_sp.swap (m_curr_frames_sp); |
1804 | m_curr_frames_sp.reset(); |
1805 | |
1806 | m_extended_info.reset(); |
1807 | m_extended_info_fetched = false; |
1808 | } |
1809 | |
1810 | lldb::StackFrameSP |
1811 | Thread::GetFrameWithConcreteFrameIndex (uint32_t unwind_idx) |
1812 | { |
1813 | return GetStackFrameList()->GetFrameWithConcreteFrameIndex (unwind_idx); |
1814 | } |
1815 | |
1816 | |
1817 | Error |
1818 | Thread::ReturnFromFrameWithIndex (uint32_t frame_idx, lldb::ValueObjectSP return_value_sp, bool broadcast) |
1819 | { |
1820 | StackFrameSP frame_sp = GetStackFrameAtIndex (frame_idx); |
1821 | Error return_error; |
1822 | |
1823 | if (!frame_sp) |
1824 | { |
1825 | return_error.SetErrorStringWithFormat("Could not find frame with index %d in thread 0x%" PRIx64"l" "x" ".", frame_idx, GetID()); |
1826 | } |
1827 | |
1828 | return ReturnFromFrame(frame_sp, return_value_sp, broadcast); |
1829 | } |
1830 | |
1831 | Error |
1832 | Thread::ReturnFromFrame (lldb::StackFrameSP frame_sp, lldb::ValueObjectSP return_value_sp, bool broadcast) |
1833 | { |
1834 | Error return_error; |
1835 | |
1836 | if (!frame_sp) |
1837 | { |
1838 | return_error.SetErrorString("Can't return to a null frame."); |
1839 | return return_error; |
1840 | } |
1841 | |
1842 | Thread *thread = frame_sp->GetThread().get(); |
1843 | uint32_t older_frame_idx = frame_sp->GetFrameIndex() + 1; |
1844 | StackFrameSP older_frame_sp = thread->GetStackFrameAtIndex(older_frame_idx); |
1845 | if (!older_frame_sp) |
1846 | { |
1847 | return_error.SetErrorString("No older frame to return to."); |
1848 | return return_error; |
1849 | } |
1850 | |
1851 | if (return_value_sp) |
1852 | { |
1853 | lldb::ABISP abi = thread->GetProcess()->GetABI(); |
1854 | if (!abi) |
1855 | { |
1856 | return_error.SetErrorString("Could not find ABI to set return value."); |
1857 | return return_error; |
1858 | } |
1859 | SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextFunction); |
1860 | |
1861 | // FIXME: ValueObject::Cast doesn't currently work correctly, at least not for scalars. |
1862 | // Turn that back on when that works. |
1863 | if (0 && sc.function != NULL__null) |
1864 | { |
1865 | Type *function_type = sc.function->GetType(); |
1866 | if (function_type) |
1867 | { |
1868 | ClangASTType return_type = sc.function->GetClangType().GetFunctionReturnType(); |
1869 | if (return_type) |
1870 | { |
1871 | StreamString s; |
1872 | return_type.DumpTypeDescription(&s); |
1873 | ValueObjectSP cast_value_sp = return_value_sp->Cast(return_type); |
1874 | if (cast_value_sp) |
1875 | { |
1876 | cast_value_sp->SetFormat(eFormatHex); |
1877 | return_value_sp = cast_value_sp; |
1878 | } |
1879 | } |
1880 | } |
1881 | } |
1882 | |
1883 | return_error = abi->SetReturnValueObject(older_frame_sp, return_value_sp); |
1884 | if (!return_error.Success()) |
1885 | return return_error; |
1886 | } |
1887 | |
1888 | // Now write the return registers for the chosen frame: |
1889 | // Note, we can't use ReadAllRegisterValues->WriteAllRegisterValues, since the read & write |
1890 | // cook their data |
1891 | |
1892 | StackFrameSP youngest_frame_sp = thread->GetStackFrameAtIndex(0); |
1893 | if (youngest_frame_sp) |
1894 | { |
1895 | lldb::RegisterContextSP reg_ctx_sp (youngest_frame_sp->GetRegisterContext()); |
1896 | if (reg_ctx_sp) |
1897 | { |
1898 | bool copy_success = reg_ctx_sp->CopyFromRegisterContext(older_frame_sp->GetRegisterContext()); |
1899 | if (copy_success) |
1900 | { |
1901 | thread->DiscardThreadPlans(true); |
1902 | thread->ClearStackFrames(); |
1903 | if (broadcast && EventTypeHasListeners(eBroadcastBitStackChanged)) |
1904 | BroadcastEvent(eBroadcastBitStackChanged, new ThreadEventData (this->shared_from_this())); |
1905 | } |
1906 | else |
1907 | { |
1908 | return_error.SetErrorString("Could not reset register values."); |
1909 | } |
1910 | } |
1911 | else |
1912 | { |
1913 | return_error.SetErrorString("Frame has no register context."); |
1914 | } |
1915 | } |
1916 | else |
1917 | { |
1918 | return_error.SetErrorString("Returned past top frame."); |
1919 | } |
1920 | return return_error; |
1921 | } |
1922 | |
1923 | static void DumpAddressList (Stream &s, const std::vector<Address> &list, ExecutionContextScope *exe_scope) |
1924 | { |
1925 | for (size_t n=0;n<list.size();n++) |
1926 | { |
1927 | s << "\t"; |
1928 | list[n].Dump (&s, exe_scope, Address::DumpStyleResolvedDescription, Address::DumpStyleSectionNameOffset); |
1929 | s << "\n"; |
1930 | } |
1931 | } |
1932 | |
1933 | Error |
1934 | Thread::JumpToLine (const FileSpec &file, uint32_t line, bool can_leave_function, std::string *warnings) |
1935 | { |
1936 | ExecutionContext exe_ctx (GetStackFrameAtIndex(0)); |
1937 | Target *target = exe_ctx.GetTargetPtr(); |
1938 | TargetSP target_sp = exe_ctx.GetTargetSP(); |
1939 | RegisterContext *reg_ctx = exe_ctx.GetRegisterContext(); |
1940 | StackFrame *frame = exe_ctx.GetFramePtr(); |
1941 | const SymbolContext &sc = frame->GetSymbolContext(eSymbolContextFunction); |
1942 | |
1943 | // Find candidate locations. |
1944 | std::vector<Address> candidates, within_function, outside_function; |
1945 | target->GetImages().FindAddressesForLine (target_sp, file, line, sc.function, within_function, outside_function); |
1946 | |
1947 | // If possible, we try and stay within the current function. |
1948 | // Within a function, we accept multiple locations (optimized code may do this, |
1949 | // there's no solution here so we do the best we can). |
1950 | // However if we're trying to leave the function, we don't know how to pick the |
1951 | // right location, so if there's more than one then we bail. |
1952 | if (!within_function.empty()) |
1953 | candidates = within_function; |
1954 | else if (outside_function.size() == 1 && can_leave_function) |
1955 | candidates = outside_function; |
1956 | |
1957 | // Check if we got anything. |
1958 | if (candidates.empty()) |
1959 | { |
1960 | if (outside_function.empty()) |
1961 | { |
1962 | return Error("Cannot locate an address for %s:%i.", |
1963 | file.GetFilename().AsCString(), line); |
1964 | } |
1965 | else if (outside_function.size() == 1) |
1966 | { |
1967 | return Error("%s:%i is outside the current function.", |
1968 | file.GetFilename().AsCString(), line); |
1969 | } |
1970 | else |
1971 | { |
1972 | StreamString sstr; |
1973 | DumpAddressList(sstr, outside_function, target); |
1974 | return Error("%s:%i has multiple candidate locations:\n%s", |
1975 | file.GetFilename().AsCString(), line, sstr.GetString().c_str()); |
1976 | } |
1977 | } |
1978 | |
1979 | // Accept the first location, warn about any others. |
1980 | Address dest = candidates[0]; |
1981 | if (warnings && candidates.size() > 1) |
1982 | { |
1983 | StreamString sstr; |
1984 | sstr.Printf("%s:%i appears multiple times in this function, selecting the first location:\n", |
1985 | file.GetFilename().AsCString(), line); |
1986 | DumpAddressList(sstr, candidates, target); |
1987 | *warnings = sstr.GetString(); |
1988 | } |
1989 | |
1990 | if (!reg_ctx->SetPC (dest)) |
1991 | return Error("Cannot change PC to target address."); |
1992 | |
1993 | return Error(); |
1994 | } |
1995 | |
1996 | void |
1997 | Thread::DumpUsingSettingsFormat (Stream &strm, uint32_t frame_idx) |
1998 | { |
1999 | ExecutionContext exe_ctx (shared_from_this()); |
2000 | Process *process = exe_ctx.GetProcessPtr(); |
2001 | if (process == NULL__null) |
2002 | return; |
2003 | |
2004 | StackFrameSP frame_sp; |
2005 | SymbolContext frame_sc; |
2006 | if (frame_idx != LLDB_INVALID_INDEX32(4294967295U)) |
2007 | { |
2008 | frame_sp = GetStackFrameAtIndex (frame_idx); |
2009 | if (frame_sp) |
2010 | { |
2011 | exe_ctx.SetFrameSP(frame_sp); |
2012 | frame_sc = frame_sp->GetSymbolContext(eSymbolContextEverything); |
2013 | } |
2014 | } |
2015 | |
2016 | const char *thread_format = exe_ctx.GetTargetRef().GetDebugger().GetThreadFormat(); |
2017 | assert (thread_format)((thread_format) ? static_cast<void> (0) : __assert_fail ("thread_format", "/tmp/buildd/llvm-toolchain-snapshot-3.6~svn219601/tools/lldb/source/Target/Thread.cpp" , 2017, __PRETTY_FUNCTION__)); |
2018 | Debugger::FormatPrompt (thread_format, |
2019 | frame_sp ? &frame_sc : NULL__null, |
2020 | &exe_ctx, |
2021 | NULL__null, |
2022 | strm); |
2023 | } |
2024 | |
2025 | void |
2026 | Thread::SettingsInitialize () |
2027 | { |
2028 | } |
2029 | |
2030 | void |
2031 | Thread::SettingsTerminate () |
2032 | { |
2033 | } |
2034 | |
2035 | lldb::addr_t |
2036 | Thread::GetThreadPointer () |
2037 | { |
2038 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); |
2039 | } |
2040 | |
2041 | addr_t |
2042 | Thread::GetThreadLocalData (const ModuleSP module) |
2043 | { |
2044 | // The default implementation is to ask the dynamic loader for it. |
2045 | // This can be overridden for specific platforms. |
2046 | DynamicLoader *loader = GetProcess()->GetDynamicLoader(); |
2047 | if (loader) |
2048 | return loader->GetThreadLocalData (module, shared_from_this()); |
2049 | else |
2050 | return LLDB_INVALID_ADDRESS(18446744073709551615UL); |
2051 | } |
2052 | |
2053 | bool |
2054 | Thread::SafeToCallFunctions () |
2055 | { |
2056 | Process *process = GetProcess().get(); |
2057 | if (process) |
2058 | { |
2059 | SystemRuntime *runtime = process->GetSystemRuntime (); |
2060 | if (runtime) |
2061 | { |
2062 | return runtime->SafeToCallFunctionsOnThisThread (shared_from_this()); |
2063 | } |
2064 | } |
2065 | return true; |
2066 | } |
2067 | |
2068 | lldb::StackFrameSP |
2069 | Thread::GetStackFrameSPForStackFramePtr (StackFrame *stack_frame_ptr) |
2070 | { |
2071 | return GetStackFrameList()->GetStackFrameSPForStackFramePtr (stack_frame_ptr); |
2072 | } |
2073 | |
2074 | const char * |
2075 | Thread::StopReasonAsCString (lldb::StopReason reason) |
2076 | { |
2077 | switch (reason) |
2078 | { |
2079 | case eStopReasonInvalid: return "invalid"; |
2080 | case eStopReasonNone: return "none"; |
2081 | case eStopReasonTrace: return "trace"; |
2082 | case eStopReasonBreakpoint: return "breakpoint"; |
2083 | case eStopReasonWatchpoint: return "watchpoint"; |
2084 | case eStopReasonSignal: return "signal"; |
2085 | case eStopReasonException: return "exception"; |
2086 | case eStopReasonExec: return "exec"; |
2087 | case eStopReasonPlanComplete: return "plan complete"; |
2088 | case eStopReasonThreadExiting: return "thread exiting"; |
2089 | case eStopReasonInstrumentation: return "instrumentation break"; |
2090 | } |
2091 | |
2092 | |
2093 | static char unknown_state_string[64]; |
2094 | snprintf(unknown_state_string, sizeof (unknown_state_string), "StopReason = %i", reason); |
2095 | return unknown_state_string; |
2096 | } |
2097 | |
2098 | const char * |
2099 | Thread::RunModeAsCString (lldb::RunMode mode) |
2100 | { |
2101 | switch (mode) |
2102 | { |
2103 | case eOnlyThisThread: return "only this thread"; |
2104 | case eAllThreads: return "all threads"; |
2105 | case eOnlyDuringStepping: return "only during stepping"; |
2106 | } |
2107 | |
2108 | static char unknown_state_string[64]; |
2109 | snprintf(unknown_state_string, sizeof (unknown_state_string), "RunMode = %i", mode); |
2110 | return unknown_state_string; |
2111 | } |
2112 | |
2113 | size_t |
2114 | Thread::GetStatus (Stream &strm, uint32_t start_frame, uint32_t num_frames, uint32_t num_frames_with_source) |
2115 | { |
2116 | ExecutionContext exe_ctx (shared_from_this()); |
2117 | Target *target = exe_ctx.GetTargetPtr(); |
2118 | Process *process = exe_ctx.GetProcessPtr(); |
2119 | size_t num_frames_shown = 0; |
2120 | strm.Indent(); |
2121 | bool is_selected = false; |
2122 | if (process) |
2123 | { |
2124 | if (process->GetThreadList().GetSelectedThread().get() == this) |
2125 | is_selected = true; |
2126 | } |
2127 | strm.Printf("%c ", is_selected ? '*' : ' '); |
2128 | if (target && target->GetDebugger().GetUseExternalEditor()) |
2129 | { |
2130 | StackFrameSP frame_sp = GetStackFrameAtIndex(start_frame); |
2131 | if (frame_sp) |
2132 | { |
2133 | SymbolContext frame_sc(frame_sp->GetSymbolContext (eSymbolContextLineEntry)); |
2134 | if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) |
2135 | { |
2136 | Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line); |
2137 | } |
2138 | } |
2139 | } |
2140 | |
2141 | DumpUsingSettingsFormat (strm, start_frame); |
2142 | |
2143 | if (num_frames > 0) |
2144 | { |
2145 | strm.IndentMore(); |
2146 | |
2147 | const bool show_frame_info = true; |
2148 | |
2149 | const char *selected_frame_marker = NULL__null; |
2150 | if (num_frames == 1 || (GetID() != GetProcess()->GetThreadList().GetSelectedThread()->GetID())) |
2151 | strm.IndentMore (); |
2152 | else |
2153 | selected_frame_marker = "* "; |
2154 | |
2155 | num_frames_shown = GetStackFrameList ()->GetStatus (strm, |
2156 | start_frame, |
2157 | num_frames, |
2158 | show_frame_info, |
2159 | num_frames_with_source, |
2160 | selected_frame_marker); |
2161 | if (num_frames == 1) |
2162 | strm.IndentLess(); |
2163 | strm.IndentLess(); |
2164 | } |
2165 | return num_frames_shown; |
2166 | } |
2167 | |
2168 | bool |
2169 | Thread::GetDescription (Stream &strm, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo) |
2170 | { |
2171 | DumpUsingSettingsFormat (strm, 0); |
2172 | strm.Printf("\n"); |
2173 | |
2174 | StructuredData::ObjectSP thread_info = GetExtendedInfo(); |
2175 | StructuredData::ObjectSP stop_info = m_stop_info_sp->GetExtendedInfo(); |
2176 | |
2177 | if (print_json_thread || print_json_stopinfo) |
2178 | { |
2179 | if (thread_info && print_json_thread) |
2180 | { |
2181 | thread_info->Dump (strm); |
2182 | strm.Printf("\n"); |
2183 | } |
2184 | |
2185 | if (stop_info && print_json_stopinfo) |
2186 | { |
2187 | stop_info->Dump (strm); |
2188 | strm.Printf("\n"); |
2189 | } |
2190 | |
2191 | return true; |
2192 | } |
2193 | |
2194 | if (thread_info) |
2195 | { |
2196 | StructuredData::ObjectSP activity = thread_info->GetObjectForDotSeparatedPath("activity"); |
2197 | StructuredData::ObjectSP breadcrumb = thread_info->GetObjectForDotSeparatedPath("breadcrumb"); |
2198 | StructuredData::ObjectSP messages = thread_info->GetObjectForDotSeparatedPath("trace_messages"); |
2199 | |
2200 | bool printed_activity = false; |
2201 | if (activity && activity->GetType() == StructuredData::Type::eTypeDictionary) |
2202 | { |
2203 | StructuredData::Dictionary *activity_dict = activity->GetAsDictionary(); |
2204 | StructuredData::ObjectSP id = activity_dict->GetValueForKey("id"); |
2205 | StructuredData::ObjectSP name = activity_dict->GetValueForKey("name"); |
2206 | if (name && name->GetType() == StructuredData::Type::eTypeString |
2207 | && id && id->GetType() == StructuredData::Type::eTypeInteger) |
2208 | { |
2209 | strm.Printf(" Activity '%s', 0x%" PRIx64"l" "x" "\n", name->GetAsString()->GetValue().c_str(), id->GetAsInteger()->GetValue()); |
2210 | } |
2211 | printed_activity = true; |
2212 | } |
2213 | bool printed_breadcrumb = false; |
2214 | if (breadcrumb && breadcrumb->GetType() == StructuredData::Type::eTypeDictionary) |
2215 | { |
2216 | if (printed_activity) |
2217 | strm.Printf ("\n"); |
2218 | StructuredData::Dictionary *breadcrumb_dict = breadcrumb->GetAsDictionary(); |
2219 | StructuredData::ObjectSP breadcrumb_text = breadcrumb_dict->GetValueForKey ("name"); |
2220 | if (breadcrumb_text && breadcrumb_text->GetType() == StructuredData::Type::eTypeString) |
2221 | { |
2222 | strm.Printf (" Current Breadcrumb: %s\n", breadcrumb_text->GetAsString()->GetValue().c_str()); |
2223 | } |
2224 | printed_breadcrumb = true; |
2225 | } |
2226 | if (messages && messages->GetType() == StructuredData::Type::eTypeArray) |
2227 | { |
2228 | if (printed_breadcrumb) |
2229 | strm.Printf("\n"); |
2230 | StructuredData::Array *messages_array = messages->GetAsArray(); |
2231 | const size_t msg_count = messages_array->GetSize(); |
2232 | if (msg_count > 0) |
2233 | { |
2234 | strm.Printf (" %zu trace messages:\n", msg_count); |
2235 | for (size_t i = 0; i < msg_count; i++) |
2236 | { |
2237 | StructuredData::ObjectSP message = messages_array->GetItemAtIndex(i); |
2238 | if (message && message->GetType() == StructuredData::Type::eTypeDictionary) |
2239 | { |
2240 | StructuredData::Dictionary *message_dict = message->GetAsDictionary(); |
2241 | StructuredData::ObjectSP message_text = message_dict->GetValueForKey ("message"); |
2242 | if (message_text && message_text->GetType() == StructuredData::Type::eTypeString) |
2243 | { |
2244 | strm.Printf (" %s\n", message_text->GetAsString()->GetValue().c_str()); |
2245 | } |
2246 | } |
2247 | } |
2248 | } |
2249 | } |
2250 | } |
2251 | |
2252 | return true; |
2253 | } |
2254 | |
2255 | size_t |
2256 | Thread::GetStackFrameStatus (Stream& strm, |
2257 | uint32_t first_frame, |
2258 | uint32_t num_frames, |
2259 | bool show_frame_info, |
2260 | uint32_t num_frames_with_source) |
2261 | { |
2262 | return GetStackFrameList()->GetStatus (strm, |
2263 | first_frame, |
2264 | num_frames, |
2265 | show_frame_info, |
2266 | num_frames_with_source); |
2267 | } |
2268 | |
2269 | Unwind * |
2270 | Thread::GetUnwinder () |
2271 | { |
2272 | if (m_unwinder_ap.get() == NULL__null) |
2273 | { |
2274 | const ArchSpec target_arch (CalculateTarget()->GetArchitecture ()); |
2275 | const llvm::Triple::ArchType machine = target_arch.GetMachine(); |
2276 | switch (machine) |
2277 | { |
2278 | case llvm::Triple::x86_64: |
2279 | case llvm::Triple::x86: |
2280 | case llvm::Triple::arm: |
2281 | case llvm::Triple::aarch64: |
2282 | case llvm::Triple::thumb: |
2283 | case llvm::Triple::mips64: |
2284 | case llvm::Triple::hexagon: |
2285 | m_unwinder_ap.reset (new UnwindLLDB (*this)); |
2286 | break; |
2287 | |
2288 | default: |
2289 | if (target_arch.GetTriple().getVendor() == llvm::Triple::Apple) |
2290 | m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); |
2291 | break; |
2292 | } |
2293 | } |
2294 | return m_unwinder_ap.get(); |
2295 | } |
2296 | |
2297 | |
2298 | void |
2299 | Thread::Flush () |
2300 | { |
2301 | ClearStackFrames (); |
2302 | m_reg_context_sp.reset(); |
2303 | } |
2304 | |
2305 | bool |
2306 | Thread::IsStillAtLastBreakpointHit () |
2307 | { |
2308 | // If we are currently stopped at a breakpoint, always return that stopinfo and don't reset it. |
2309 | // This allows threads to maintain their breakpoint stopinfo, such as when thread-stepping in |
2310 | // multithreaded programs. |
2311 | if (m_stop_info_sp) { |
2312 | StopReason stop_reason = m_stop_info_sp->GetStopReason(); |
2313 | if (stop_reason == lldb::eStopReasonBreakpoint) { |
2314 | uint64_t value = m_stop_info_sp->GetValue(); |
2315 | lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext()); |
2316 | if (reg_ctx_sp) |
2317 | { |
2318 | lldb::addr_t pc = reg_ctx_sp->GetPC(); |
2319 | BreakpointSiteSP bp_site_sp = GetProcess()->GetBreakpointSiteList().FindByAddress(pc); |
2320 | if (bp_site_sp && |
2321 | static_cast<break_id_t>(value) == bp_site_sp->GetID()) |
2322 | return true; |
2323 | } |
2324 | } |
2325 | } |
2326 | return false; |
2327 | } |
2328 | |
2329 | |
2330 | Error |
2331 | Thread::StepIn (bool source_step, |
2332 | LazyBool step_in_avoids_code_without_debug_info, |
2333 | LazyBool step_out_avoids_code_without_debug_info) |
2334 | |
2335 | { |
2336 | Error error; |
2337 | Process *process = GetProcess().get(); |
2338 | if (StateIsStoppedState (process->GetState(), true)) |
2339 | { |
2340 | StackFrameSP frame_sp = GetStackFrameAtIndex (0); |
2341 | ThreadPlanSP new_plan_sp; |
2342 | const lldb::RunMode run_mode = eOnlyThisThread; |
2343 | const bool abort_other_plans = false; |
2344 | |
2345 | if (source_step && frame_sp && frame_sp->HasDebugInformation ()) |
2346 | { |
2347 | SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); |
2348 | new_plan_sp = QueueThreadPlanForStepInRange (abort_other_plans, |
2349 | sc.line_entry.range, |
2350 | sc, |
2351 | NULL__null, |
2352 | run_mode, |
2353 | step_in_avoids_code_without_debug_info, |
2354 | step_out_avoids_code_without_debug_info); |
2355 | } |
2356 | else |
2357 | { |
2358 | new_plan_sp = QueueThreadPlanForStepSingleInstruction (false, |
2359 | abort_other_plans, |
2360 | run_mode); |
2361 | } |
2362 | |
2363 | new_plan_sp->SetIsMasterPlan(true); |
2364 | new_plan_sp->SetOkayToDiscard(false); |
2365 | |
2366 | // Why do we need to set the current thread by ID here??? |
2367 | process->GetThreadList().SetSelectedThreadByID (GetID()); |
2368 | error = process->Resume(); |
2369 | } |
2370 | else |
2371 | { |
2372 | error.SetErrorString("process not stopped"); |
2373 | } |
2374 | return error; |
2375 | } |
2376 | |
2377 | Error |
2378 | Thread::StepOver (bool source_step, |
2379 | LazyBool step_out_avoids_code_without_debug_info) |
2380 | { |
2381 | Error error; |
2382 | Process *process = GetProcess().get(); |
2383 | if (StateIsStoppedState (process->GetState(), true)) |
2384 | { |
2385 | StackFrameSP frame_sp = GetStackFrameAtIndex (0); |
2386 | ThreadPlanSP new_plan_sp; |
2387 | |
2388 | const lldb::RunMode run_mode = eOnlyThisThread; |
2389 | const bool abort_other_plans = false; |
2390 | |
2391 | if (source_step && frame_sp && frame_sp->HasDebugInformation ()) |
2392 | { |
2393 | SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); |
2394 | new_plan_sp = QueueThreadPlanForStepOverRange (abort_other_plans, |
2395 | sc.line_entry.range, |
2396 | sc, |
2397 | run_mode, |
2398 | step_out_avoids_code_without_debug_info); |
2399 | } |
2400 | else |
2401 | { |
2402 | new_plan_sp = QueueThreadPlanForStepSingleInstruction (true, |
2403 | abort_other_plans, |
2404 | run_mode); |
2405 | } |
2406 | |
2407 | new_plan_sp->SetIsMasterPlan(true); |
2408 | new_plan_sp->SetOkayToDiscard(false); |
2409 | |
2410 | // Why do we need to set the current thread by ID here??? |
2411 | process->GetThreadList().SetSelectedThreadByID (GetID()); |
2412 | error = process->Resume(); |
2413 | } |
2414 | else |
2415 | { |
2416 | error.SetErrorString("process not stopped"); |
2417 | } |
2418 | return error; |
2419 | } |
2420 | |
2421 | Error |
2422 | Thread::StepOut () |
2423 | { |
2424 | Error error; |
2425 | Process *process = GetProcess().get(); |
2426 | if (StateIsStoppedState (process->GetState(), true)) |
2427 | { |
2428 | const bool first_instruction = false; |
2429 | const bool stop_other_threads = false; |
2430 | const bool abort_other_plans = false; |
2431 | |
2432 | ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut (abort_other_plans, |
2433 | NULL__null, |
2434 | first_instruction, |
2435 | stop_other_threads, |
2436 | eVoteYes, |
2437 | eVoteNoOpinion, |
2438 | 0)); |
2439 | |
2440 | new_plan_sp->SetIsMasterPlan(true); |
2441 | new_plan_sp->SetOkayToDiscard(false); |
2442 | |
2443 | // Why do we need to set the current thread by ID here??? |
2444 | process->GetThreadList().SetSelectedThreadByID (GetID()); |
2445 | error = process->Resume(); |
2446 | } |
2447 | else |
2448 | { |
2449 | error.SetErrorString("process not stopped"); |
2450 | } |
2451 | return error; |
2452 | } |