diff options
Diffstat (limited to 'lldb')
34 files changed, 281 insertions, 129 deletions
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 224efe3782c..dd8ccedade7 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -3348,13 +3348,15 @@ public: void RestoreProcessEvents (); -protected: +private: //------------------------------------------------------------------ /// This is the part of the event handling that for a process event. /// It decides what to do with the event and returns true if the /// event needs to be propagated to the user, and false otherwise. /// If the event is not propagated, this call will most likely set /// the target to executing again. + /// There is only one place where this call should be called, HandlePrivateEvent. + /// Don't call it from anywhere else... /// /// @param[in] event_ptr /// This is the event we are handling. @@ -3526,6 +3528,9 @@ protected: // new "NextEventAction" is added while one is already present, the // old action will be discarded (with HandleBeingUnshipped called // after it is discarded.) + // + // If you want to resume the process as a result of a resume action, + // call RequestResume, don't call Resume directly. //------------------------------------------------------------------ class NextEventAction { @@ -3551,6 +3556,10 @@ protected: virtual void HandleBeingUnshipped () {} virtual EventActionResult HandleBeingInterrupted () = 0; virtual const char *GetExitString() = 0; + void RequestResume() + { + m_process->m_resume_requested = true; + } protected: Process *m_process; }; @@ -3661,7 +3670,9 @@ protected: #if defined(__APPLE__) ReadWriteLock m_private_run_lock; #endif - Predicate<bool> m_currently_handling_event; + Predicate<bool> m_currently_handling_event; // This predicate is set in HandlePrivateEvent while all its business is being done. + bool m_currently_handling_do_on_removals; + bool m_resume_requested; // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check. bool m_finalize_called; lldb::StateType m_last_broadcast_state; /// This helps with the Public event coalescing in ShouldBroadcastEvent. bool m_destroy_in_process; @@ -3679,7 +3690,7 @@ protected: SynchronouslyNotifyStateChanged (lldb::StateType state); void - SetPublicState (lldb::StateType new_state); + SetPublicState (lldb::StateType new_state, bool restarted); void SetPrivateState (lldb::StateType state); diff --git a/lldb/include/lldb/Target/StopInfo.h b/lldb/include/lldb/Target/StopInfo.h index c4f243ea1ad..3435d392e2b 100644 --- a/lldb/include/lldb/Target/StopInfo.h +++ b/lldb/include/lldb/Target/StopInfo.h @@ -79,11 +79,20 @@ public: return true; } + void + OverrideShouldNotify (bool override_value) + { + m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo; + } + // If should stop returns false, check if we should notify of this event virtual bool ShouldNotify (Event *event_ptr) { - return false; + if (m_override_should_notify == eLazyBoolCalculate) + return DoShouldNotify (event_ptr); + else + return m_override_should_notify == eLazyBoolYes; } virtual void @@ -116,20 +125,19 @@ public: void OverrideShouldStop (bool override_value) { - m_override_set = true; - m_override_value = override_value; + m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo; } bool GetOverrideShouldStop() { - return m_override_set; + return m_override_should_stop != eLazyBoolCalculate; } bool GetOverriddenShouldStopValue () { - return m_override_value; + return m_override_should_stop == eLazyBoolYes; } static lldb::StopInfoSP @@ -169,6 +177,12 @@ protected: { } + virtual bool + DoShouldNotify (Event *event_ptr) + { + return false; + } + // Stop the thread by default. Subclasses can override this to allow // the thread to continue if desired. The ShouldStop method should not do anything // that might run code. If you need to run code when deciding whether to stop @@ -189,8 +203,8 @@ protected: uint32_t m_resume_id; // This is the resume ID when we made this stop ID. uint64_t m_value; // A generic value that can be used for things pertaining to this stop info std::string m_description; // A textual description describing this stop. - bool m_override_set; - bool m_override_value; + LazyBool m_override_should_notify; + LazyBool m_override_should_stop; // This determines whether the target has run since this stop info. // N.B. running to evaluate a user expression does not count. diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h index c1cd2a75d42..f1f8439e2a4 100644 --- a/lldb/include/lldb/Target/Thread.h +++ b/lldb/include/lldb/Target/Thread.h @@ -288,7 +288,7 @@ public: Vote ShouldReportStop (Event *event_ptr); - + Vote ShouldReportRun (Event *event_ptr); @@ -927,6 +927,9 @@ public: void SetStopInfo (const lldb::StopInfoSP &stop_info_sp); + void + SetShouldReportStop (Vote vote); + protected: friend class ThreadPlan; @@ -1015,7 +1018,7 @@ protected: bool m_destroy_called; // This is used internally to make sure derived Thread classes call DestroyThread. uint32_t m_thread_stop_reason_stop_id; // This is the stop id for which the StopInfo is valid. Can use this so you know that // the thread's m_actual_stop_info_sp is current and you don't have to fetch it again - + LazyBool m_override_should_notify; private: //------------------------------------------------------------------ // For Thread only diff --git a/lldb/include/lldb/Target/ThreadList.h b/lldb/include/lldb/Target/ThreadList.h index f1d699d8ffb..959091c81bf 100644 --- a/lldb/include/lldb/Target/ThreadList.h +++ b/lldb/include/lldb/Target/ThreadList.h @@ -137,6 +137,9 @@ public: protected: void + SetShouldReportStop (Vote vote); + + void NotifySelectedThreadChanged (lldb::tid_t tid); typedef std::vector<lldb::ThreadSP> collection; diff --git a/lldb/include/lldb/Target/ThreadPlan.h b/lldb/include/lldb/Target/ThreadPlan.h index 7a5fa101895..630fee3a9f2 100644 --- a/lldb/include/lldb/Target/ThreadPlan.h +++ b/lldb/include/lldb/Target/ThreadPlan.h @@ -92,7 +92,8 @@ namespace lldb_private { // When the target process is about to be restarted, the plan's WillResume method is called, // giving the plan a chance to prepare for the run. If WillResume returns false, then the // process is not restarted. Be sure to set an appropriate error value in the Process if -// you have to do this. +// you have to do this. Note, ThreadPlans actually implement DoWillResume, WillResume wraps that call. +// // Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan // returns "true" then only that thread gets to run. If more than one returns "true" the threads that want to run solo // get run one by one round robin fashion. Otherwise all are let to run. @@ -115,6 +116,8 @@ namespace lldb_private { // figure out what to do about the plans below it in the stack. If the stop is recoverable, then the plan that // understands it can just do what it needs to set up to restart, and then continue. // Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it. +// Note, plans actually implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so the DoPlanExplainsStop +// itself will only get called once per stop. // // Master plans: // @@ -331,9 +334,6 @@ public: virtual bool ValidatePlan (Stream *error) = 0; - virtual bool - PlanExplainsStop (Event *event_ptr) = 0; - bool TracerExplainsStop () { @@ -347,6 +347,9 @@ public: lldb::StateType RunState (); + bool + PlanExplainsStop (Event *event_ptr); + virtual bool ShouldStop (Event *event_ptr) = 0; @@ -371,9 +374,11 @@ public: virtual bool StopOthers (); - virtual bool + // This is the wrapper for DoWillResume that does generic ThreadPlan logic, then + // calls DoWillResume. + bool WillResume (lldb::StateType resume_state, bool current_plan); - + virtual bool WillStop () = 0; @@ -510,6 +515,12 @@ protected: // Classes that inherit from ThreadPlan can see and modify these //------------------------------------------------------------------ + virtual bool + DoWillResume (lldb::StateType resume_state, bool current_plan) { return true; }; + + virtual bool + DoPlanExplainsStop (Event *event_ptr) = 0; + // This gets the previous plan to the current plan (for forwarding requests). // This is mostly a formal requirement, it allows us to make the Thread's // GetPreviousPlan protected, but only friend ThreadPlan to thread. @@ -535,6 +546,18 @@ protected: m_thread.SetStopInfo (stop_reason_sp); } + void + CachePlanExplainsStop (bool does_explain) + { + m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo; + } + + LazyBool + GetCachedPlanExplainsStop () const + { + return m_cached_plan_explains_stop; + } + virtual lldb::StateType GetPlanRunState () = 0; @@ -551,6 +574,7 @@ private: ThreadPlanKind m_kind; std::string m_name; Mutex m_plan_complete_mutex; + LazyBool m_cached_plan_explains_stop; bool m_plan_complete; bool m_plan_private; bool m_okay_to_discard; diff --git a/lldb/include/lldb/Target/ThreadPlanBase.h b/lldb/include/lldb/Target/ThreadPlanBase.h index 73c92533a05..226caeab860 100644 --- a/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/lldb/include/lldb/Target/ThreadPlanBase.h @@ -35,13 +35,12 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); + virtual Vote ShouldReportStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); virtual bool WillStop (); virtual bool MischiefManaged (); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); virtual bool OkayToDiscard() { @@ -55,6 +54,8 @@ public: } protected: + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); + virtual bool DoPlanExplainsStop (Event *event_ptr); ThreadPlanBase (Thread &thread); private: diff --git a/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 4124596fa17..2c1d142a98b 100644 --- a/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -59,9 +59,6 @@ public: ValidatePlan (Stream *error); virtual bool - PlanExplainsStop (Event *event_ptr); - - virtual bool ShouldStop (Event *event_ptr); virtual Vote @@ -135,8 +132,12 @@ public: virtual bool RestoreThreadState(); -protected: +protected: void ReportRegisterState (const char *message); + + virtual bool + DoPlanExplainsStop (Event *event_ptr); + private: bool diff --git a/lldb/include/lldb/Target/ThreadPlanRunToAddress.h b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h index 7797456466c..d9482066801 100644 --- a/lldb/include/lldb/Target/ThreadPlanRunToAddress.h +++ b/lldb/include/lldb/Target/ThreadPlanRunToAddress.h @@ -47,9 +47,6 @@ public: ValidatePlan (Stream *error); virtual bool - PlanExplainsStop (Event *event_ptr); - - virtual bool ShouldStop (Event *event_ptr); virtual bool @@ -68,6 +65,9 @@ public: MischiefManaged (); protected: + virtual bool + DoPlanExplainsStop (Event *event_ptr); + void SetInitialBreakpoints(); bool AtOurAddress(); private: diff --git a/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/lldb/include/lldb/Target/ThreadPlanStepInRange.h index 1a60e4e094f..f9e64ce2ced 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -59,13 +59,12 @@ public: static void SetDefaultFlagValue (uint32_t new_value); - - virtual bool - PlanExplainsStop (Event *event_ptr); - - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); protected: + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); + + virtual bool + DoPlanExplainsStop (Event *event_ptr); virtual void SetFlagsToDefault (); diff --git a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index e4798ba961d..832508d8935 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -27,7 +27,6 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); @@ -35,6 +34,8 @@ public: virtual bool MischiefManaged (); protected: + virtual bool DoPlanExplainsStop (Event *event_ptr); + ThreadPlanStepInstruction (Thread &thread, bool step_over, bool stop_others, diff --git a/lldb/include/lldb/Target/ThreadPlanStepOut.h b/lldb/include/lldb/Target/ThreadPlanStepOut.h index 9fc6004eda3..9097eff26e2 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -34,11 +34,9 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); virtual bool WillStop (); virtual bool MischiefManaged (); virtual void DidPush(); @@ -50,6 +48,8 @@ public: } protected: + virtual bool DoPlanExplainsStop (Event *event_ptr); + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); bool QueueInlinedStepPlan (bool queue_now); private: diff --git a/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h index 1ae113246c8..c1c2a41a4d6 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -27,17 +27,17 @@ public: ThreadPlanStepOverBreakpoint (Thread &thread); virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); virtual bool WillStop (); virtual bool MischiefManaged (); void SetAutoContinue (bool do_it); virtual bool ShouldAutoContinue(Event *event_ptr); protected: + virtual bool DoPlanExplainsStop (Event *event_ptr); + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); private: diff --git a/lldb/include/lldb/Target/ThreadPlanStepOverRange.h b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h index 762c11648a6..de9e66829dc 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepOverRange.h +++ b/lldb/include/lldb/Target/ThreadPlanStepOverRange.h @@ -34,10 +34,10 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ShouldStop (Event *event_ptr); - virtual bool PlanExplainsStop (Event *event_ptr); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); protected: + virtual bool DoPlanExplainsStop (Event *event_ptr); + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); private: diff --git a/lldb/include/lldb/Target/ThreadPlanStepThrough.h b/lldb/include/lldb/Target/ThreadPlanStepThrough.h index eacfc897610..08169d1ecf4 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepThrough.h +++ b/lldb/include/lldb/Target/ThreadPlanStepThrough.h @@ -26,16 +26,17 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); virtual bool WillStop (); virtual bool MischiefManaged (); virtual void DidPush(); protected: + virtual bool DoPlanExplainsStop (Event *event_ptr); + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); + ThreadPlanStepThrough (Thread &thread, StackID &return_stack_id, bool stop_others); diff --git a/lldb/include/lldb/Target/ThreadPlanStepUntil.h b/lldb/include/lldb/Target/ThreadPlanStepUntil.h index b8e6eda4e4f..e87d24f1b59 100644 --- a/lldb/include/lldb/Target/ThreadPlanStepUntil.h +++ b/lldb/include/lldb/Target/ThreadPlanStepUntil.h @@ -27,15 +27,16 @@ public: virtual void GetDescription (Stream *s, lldb::DescriptionLevel level); virtual bool ValidatePlan (Stream *error); - virtual bool PlanExplainsStop (Event *event_ptr); virtual bool ShouldStop (Event *event_ptr); virtual bool StopOthers (); virtual lldb::StateType GetPlanRunState (); - virtual bool WillResume (lldb::StateType resume_state, bool current_plan); virtual bool WillStop (); virtual bool MischiefManaged (); protected: + virtual bool DoWillResume (lldb::StateType resume_state, bool current_plan); + virtual bool DoPlanExplainsStop (Event *event_ptr); + ThreadPlanStepUntil (Thread &thread, lldb::addr_t *address_list, size_t num_addresses, diff --git a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme index 88be19c71b5..4bc97ecb822 100644 --- a/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme +++ b/lldb/lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme @@ -79,7 +79,11 @@ isEnabled = "YES"> </CommandLineArgument> <CommandLineArgument - argument = "python_api/hello_world" + argument = "-f" + isEnabled = "YES"> + </CommandLineArgument> + <CommandLineArgument + argument = "ConditionalBreakTestCase.test_with_dwarf_command" isEnabled = "YES"> </CommandLineArgument> </CommandLineArguments> diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index 1a2639cd7ca..16d6e2e7d66 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -126,7 +126,7 @@ AppleThreadPlanStepThroughObjCTrampoline::ValidatePlan (Stream *error) } bool -AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop (Event *event_ptr) +AppleThreadPlanStepThroughObjCTrampoline::DoPlanExplainsStop (Event *event_ptr) { // If we get asked to explain the stop it will be because something went // wrong (like the implementation for selector function crashed... We're going diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h index 32c47de0068..253190991ce 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h @@ -45,10 +45,6 @@ public: virtual bool ValidatePlan (Stream *error); - virtual bool - PlanExplainsStop (Event *event_ptr); - - virtual lldb::StateType GetPlanRunState (); @@ -81,6 +77,8 @@ protected: //------------------------------------------------------------------ // Classes that inherit from AppleThreadPlanStepThroughObjCTrampoline can see and modify these //------------------------------------------------------------------ + virtual bool + DoPlanExplainsStop (Event *event_ptr); private: bool diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index fda71060d47..e5a92c615ac 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1643,11 +1643,11 @@ Process::GetState() } void -Process::SetPublicState (StateType new_state) +Process::SetPublicState (StateType new_state, bool restarted) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STATE | LIBLLDB_LOG_PROCESS)); if (log) - log->Printf("Process::SetPublicState (%s)", StateAsCString(new_state)); + log->Printf("Process::SetPublicState (state = %s, restarted = %i)", StateAsCString(new_state), restarted); const StateType old_state = m_public_state.GetValue(); m_public_state.SetValue (new_state); @@ -1666,9 +1666,9 @@ Process::SetPublicState (StateType new_state) { const bool old_state_is_stopped = StateIsStoppedState(old_state, false); const bool new_state_is_stopped = StateIsStoppedState(new_state, false); - if (old_state_is_stopped != new_state_is_stopped) + if ((old_state_is_stopped != new_state_is_stopped)) { - if (new_state_is_stopped) + if (new_state_is_stopped && !restarted) { if (log) log->Printf("Process::SetPublicState (%s) -- unlocking run lock", StateAsCString(new_state)); @@ -2866,7 +2866,8 @@ Process::Launch (const ProcessLaunchInfo &launch_info) error = WillLaunch (exe_module); if (error.Success()) { - SetPublicState (eStateLaunching); + const bool restarted = false; + SetPublicState (eStateLaunching, restarted); m_should_detach = false; if (m_public_run_lock.WriteTryLock()) @@ -2993,11 +2994,13 @@ Process::AttachCompletionHandler::PerformAction (lldb::EventSP &event_sp) // During attach, prior to sending the eStateStopped event, // lldb_private::Process subclasses must set the new process ID. assert (m_process->GetID() != LLDB_INVALID_PROCESS_ID); + // We don't want these events to be reported, so go set the ShouldReportStop here: + m_process->GetThreadList().SetShouldReportStop (eVoteNo); + if (m_exec_count > 0) { --m_exec_count; - m_process->PrivateResume (); - Process::ProcessEventData::SetRestartedInEvent (event_sp.get(), true); + RequestResume(); return eEventActionRetry; } else @@ -3056,7 +3059,8 @@ Process::Attach (ProcessAttachInfo &attach_info) if (m_public_run_lock.WriteTryLock()) { m_should_detach = true; - SetPublicState (eStateAttaching); + const bool restarted = false; + SetPublicState (eStateAttaching, restarted); // Now attach using these arguments. error = DoAttachToProcessWithName (process_name, wait_for_launch, attach_info); } @@ -3134,7 +3138,8 @@ Process::Attach (ProcessAttachInfo &attach_info) { // Now attach using these arguments. m_should_detach = true; - SetPublicState (eStateAttaching); + const bool restarted = false; + SetPublicState (eStateAttaching, restarted); error = DoAttachToProcessWithID (attach_pid, attach_info); } else @@ -3287,7 +3292,7 @@ Process::PrivateResume () // that they are supposed to have when the process is resumed // (suspended/running/stepping). Threads should also check // their resume signal in lldb::Thread::GetResumeSignal() - // to see if they are suppoed to start back up with a signal. + // to see if they are supposed to start back up with a signal. if (m_thread_list.WillResume()) { // Last thing, do the PreResumeActions. @@ -3677,6 +3682,7 @@ Process::ShouldBroadcastEvent (Event *event_ptr) // If we are going to stop, then we always broadcast the event. // If we aren't going to stop, let the thread plans decide if we're going to report this event. // If no thread has an opinion, we don't report it. + RefreshStateAfterStop (); if (ProcessEventData::GetInterruptedFromEvent (event_ptr)) { @@ -3688,15 +3694,17 @@ Process::ShouldBroadcastEvent (Event *event_ptr) } else { + bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr); + bool should_resume = false; + // It makes no sense to ask "ShouldStop" if we've already been restarted... // Asking the thread list is also not likely to go well, since we are running again. // So in that case just report the event. - bool was_restarted = ProcessEventData::GetRestartedFromEvent (event_ptr); - bool should_resume = false; if (!was_restarted) should_resume = m_thread_list.ShouldStop (event_ptr) == false; - if (was_restarted || should_resume) + + if (was_restarted || should_resume || m_resume_requested) { Vote stop_vote = m_thread_list.ShouldReportStop (event_ptr); if (log) @@ -3883,6 +3891,8 @@ void Process::HandlePrivateEvent (EventSP &event_sp) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS)); + m_resume_requested = false; + m_currently_handling_event.SetValue(true, eBroadcastNever); const StateType new_state = Process::ProcessEventData::GetStateFromEvent(event_sp.get()); @@ -3911,6 +3921,7 @@ Process::HandlePrivateEvent (EventSP &event_sp) { // FIXME: should cons up an exited event, and discard this one. SetExitStatus(0, m_next_event_action_ap->GetExitString()); + m_currently_handling_event.SetValue(false, eBroadcastAlways); SetNextEventAction(NULL); return; } @@ -4095,12 +4106,11 @@ Process::ProcessEventData::DoOnRemoval (Event *event_ptr) // the public event queue, then other times when we're pretending that this is where we stopped at the // end of expression evaluation. m_update_state is used to distinguish these // three cases; it is 0 when we're just pulling it off for private handling, - // and > 1 for expression evaluation, and we don't want to do the breakpoint command handling then. - + // and > 1 for expression evaluation, and we don't want to do the breakpoint command handling then. if (m_update_state != 1) return; - m_process_sp->SetPublicState (m_state); + m_process_sp->SetPublicState (m_state, Process::ProcessEventData::GetRestartedFromEvent(event_ptr)); // If we're stopped and haven't restarted, then do the breakpoint commands here: if (m_state == eStateStopped && ! m_restarted) diff --git a/lldb/source/Target/StopInfo.cpp b/lldb/source/Target/StopInfo.cpp index e4bcb95f274..3be1f9301d8 100644 --- a/lldb/source/Target/StopInfo.cpp +++ b/lldb/source/Target/StopInfo.cpp @@ -39,8 +39,8 @@ StopInfo::StopInfo (Thread &thread, uint64_t value) : m_stop_id (thread.GetProcess()->GetStopID()), m_resume_id (thread.GetProcess()->GetResumeID()), m_value (value), - m_override_set(false), - m_override_value(true) + m_override_should_notify (eLazyBoolCalculate), + m_override_should_stop (eLazyBoolCalculate) { } @@ -201,7 +201,7 @@ public: } virtual bool - ShouldNotify (Event *event_ptr) + DoShouldNotify (Event *event_ptr) { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) @@ -849,7 +849,7 @@ public: // If should stop returns false, check if we should notify of this event virtual bool - ShouldNotify (Event *event_ptr) + DoShouldNotify (Event *event_ptr) { ThreadSP thread_sp (m_thread_wp.lock()); if (thread_sp) diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp index 5096a91cf1f..23c75e3e9ac 100644 --- a/lldb/source/Target/Thread.cpp +++ b/lldb/source/Target/Thread.cpp @@ -259,7 +259,8 @@ Thread::Thread (Process &process, lldb::tid_t tid) : m_temporary_resume_state (eStateRunning), m_unwinder_ap (), m_destroy_called (false), - m_thread_stop_reason_stop_id (0) + m_thread_stop_reason_stop_id (0), + m_override_should_notify (eLazyBoolCalculate) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); if (log) @@ -394,7 +395,13 @@ Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp) { m_actual_stop_info_sp = stop_info_sp; if (m_actual_stop_info_sp) + { m_actual_stop_info_sp->MakeStopInfoValid(); + // If we are overriding the ShouldReportStop, do that here: + if (m_override_should_notify != eLazyBoolCalculate) + m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes); + } + ProcessSP process_sp (GetProcess()); if (process_sp) m_thread_stop_reason_stop_id = process_sp->GetStopID(); @@ -403,6 +410,19 @@ Thread::SetStopInfo (const lldb::StopInfoSP &stop_info_sp) } void +Thread::SetShouldReportStop (Vote vote) +{ + if (vote == eVoteNoOpinion) + return; + else + { + m_override_should_notify = (vote == eVoteYes ? eLazyBoolYes : eLazyBoolNo); + if (m_actual_stop_info_sp) + m_actual_stop_info_sp->OverrideShouldNotify (m_override_should_notify == eLazyBoolYes); + } +} + +void Thread::SetStopInfoToNothing() { // Note, we can't just NULL out the private reason, or the native thread implementation will try to @@ -530,6 +550,7 @@ Thread::ShouldResume (StateType resume_state) // At this point clear the completed plan stack. m_completed_plan_stack.clear(); m_discarded_plan_stack.clear(); + m_override_should_notify = eLazyBoolCalculate; m_temporary_resume_state = resume_state; diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp index 80df5957c3f..4971d6c963f 100644 --- a/lldb/source/Target/ThreadList.cpp +++ b/lldb/source/Target/ThreadList.cpp @@ -376,6 +376,19 @@ ThreadList::ShouldReportStop (Event *event_ptr) return result; } +void +ThreadList::SetShouldReportStop (Vote vote) +{ + Mutex::Locker locker(GetMutex()); + m_process->UpdateThreadListIfNeeded(); + collection::iterator pos, end = m_threads.end(); + for (pos = m_threads.begin(); pos != end; ++pos) + { + ThreadSP thread_sp(*pos); + thread_sp->SetShouldReportStop (vote); + } +} + Vote ThreadList::ShouldReportRun (Event *event_ptr) { diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp index d740879ae1d..bc0ce57f9fc 100644 --- a/lldb/source/Target/ThreadPlan.cpp +++ b/lldb/source/Target/ThreadPlan.cpp @@ -36,6 +36,7 @@ ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vo m_kind (kind), m_name (name), m_plan_complete_mutex (Mutex::eMutexTypeRecursive), + m_cached_plan_explains_stop (eLazyBoolCalculate), m_plan_complete (false), m_plan_private (false), m_okay_to_discard (true), @@ -53,6 +54,21 @@ ThreadPlan::~ThreadPlan() } bool +ThreadPlan::PlanExplainsStop (Event *event_ptr) +{ + if (m_cached_plan_explains_stop == eLazyBoolCalculate) + { + bool actual_value = DoPlanExplainsStop(event_ptr); + m_cached_plan_explains_stop = actual_value ? eLazyBoolYes : eLazyBoolNo; + return actual_value; + } + else + { + return m_cached_plan_explains_stop == eLazyBoolYes; + } +} + +bool ThreadPlan::IsPlanComplete () { Mutex::Locker locker(m_plan_complete_mutex); @@ -131,6 +147,8 @@ ThreadPlan::SetStopOthers (bool new_value) bool ThreadPlan::WillResume (StateType resume_state, bool current_plan) { + m_cached_plan_explains_stop = eLazyBoolCalculate; + if (current_plan) { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); @@ -154,7 +172,7 @@ ThreadPlan::WillResume (StateType resume_state, bool current_plan) StopOthers()); } } - return true; + return DoWillResume (resume_state, current_plan); } lldb::user_id_t diff --git a/lldb/source/Target/ThreadPlanBase.cpp b/lldb/source/Target/ThreadPlanBase.cpp index 817393924d1..998cc08f286 100644 --- a/lldb/source/Target/ThreadPlanBase.cpp +++ b/lldb/source/Target/ThreadPlanBase.cpp @@ -68,7 +68,7 @@ ThreadPlanBase::ValidatePlan (Stream *error) } bool -ThreadPlanBase::PlanExplainsStop (Event *event_ptr) +ThreadPlanBase::DoPlanExplainsStop (Event *event_ptr) { // The base plan should defer to its tracer, since by default it // always handles the stop. @@ -78,6 +78,22 @@ ThreadPlanBase::PlanExplainsStop (Event *event_ptr) return true; } +Vote +ThreadPlanBase::ShouldReportStop(Event *event_ptr) +{ + StopInfoSP stop_info_sp = m_thread.GetStopInfo (); + if (stop_info_sp) + { + bool should_notify = stop_info_sp->ShouldNotify(event_ptr); + if (should_notify) + return eVoteYes; + else + return eVoteNoOpinion; + } + else + return eVoteNoOpinion; +} + bool ThreadPlanBase::ShouldStop (Event *event_ptr) { @@ -201,7 +217,7 @@ ThreadPlanBase::WillStop () } bool -ThreadPlanBase::WillResume (lldb::StateType resume_state, bool current_plan) +ThreadPlanBase::DoWillResume (lldb::StateType resume_state, bool current_plan) { // Reset these to the default values so we don't set them wrong, then not get asked // for a while, then return the wrong answer. diff --git a/lldb/source/Target/ThreadPlanCallFunction.cpp b/lldb/source/Target/ThreadPlanCallFunction.cpp index 9f7bd8a0c24..0a77d0d1537 100644 --- a/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -362,7 +362,7 @@ ThreadPlanCallFunction::ShouldReportStop(Event *event_ptr) } bool -ThreadPlanCallFunction::PlanExplainsStop (Event *event_ptr) +ThreadPlanCallFunction::DoPlanExplainsStop (Event *event_ptr) { Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP|LIBLLDB_LOG_PROCESS)); m_real_stop_info_sp = GetPrivateStopReason(); @@ -475,9 +475,9 @@ ThreadPlanCallFunction::PlanExplainsStop (Event *event_ptr) bool ThreadPlanCallFunction::ShouldStop (Event *event_ptr) { - // We do some computation in PlanExplainsStop that may or may not set the plan as complete. + // We do some computation in DoPlanExplainsStop that may or may not set the plan as complete. // We need to do that here to make sure our state is correct. - PlanExplainsStop(event_ptr); + DoPlanExplainsStop(event_ptr); if (IsPlanComplete()) { diff --git a/lldb/source/Target/ThreadPlanRunToAddress.cpp b/lldb/source/Target/ThreadPlanRunToAddress.cpp index 56c16542967..86825d2eb26 100644 --- a/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -188,7 +188,7 @@ ThreadPlanRunToAddress::ValidatePlan (Stream *error) } bool -ThreadPlanRunToAddress::PlanExplainsStop (Event *event_ptr) +ThreadPlanRunToAddress::DoPlanExplainsStop (Event *event_ptr) { return AtOurAddress(); } diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index e6da7a037c0..d5a6b10858f 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -379,7 +379,7 @@ ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, } bool -ThreadPlanStepInRange::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepInRange::DoPlanExplainsStop (Event *event_ptr) { // We always explain a stop. Either we've just done a single step, in which // case we'll do our ordinary processing, or we stopped for some @@ -394,41 +394,54 @@ ThreadPlanStepInRange::PlanExplainsStop (Event *event_ptr) // // The only variation is that if we are doing "step by running to next branch" in which case // if we hit our branch breakpoint we don't set the plan to complete. + + bool return_value; if (m_virtual_step) - return true; - - StopInfoSP stop_info_sp = GetPrivateStopReason(); - if (stop_info_sp) { - StopReason reason = stop_info_sp->GetStopReason(); - - switch (reason) + return_value = true; + } + else + { + StopInfoSP stop_info_sp = GetPrivateStopReason(); + if (stop_info_sp) { - case eStopReasonBreakpoint: - if (NextRangeBreakpointExplainsStop(stop_info_sp)) - return true; - case eStopReasonWatchpoint: - case eStopReasonSignal: - case eStopReasonException: - case eStopReasonExec: - case eStopReasonThreadExiting: + StopReason reason = stop_info_sp->GetStopReason(); + + switch (reason) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); - if (log) - log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step."); + case eStopReasonBreakpoint: + if (NextRangeBreakpointExplainsStop(stop_info_sp)) + { + return_value = true; + break; + } + case eStopReasonWatchpoint: + case eStopReasonSignal: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonThreadExiting: + { + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + if (log) + log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step."); + } + return_value = false; + break; + default: + return_value = true; + break; } - return false; - break; - default: - break; } + else + return_value = true; } - return true; + + return return_value; } bool -ThreadPlanStepInRange::WillResume (lldb::StateType resume_state, bool current_plan) +ThreadPlanStepInRange::DoWillResume (lldb::StateType resume_state, bool current_plan) { if (resume_state == eStateStepping && current_plan) { @@ -438,7 +451,7 @@ ThreadPlanStepInRange::WillResume (lldb::StateType resume_state, bool current_pl { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (log) - log->Printf ("ThreadPlanStepInRange::WillResume: returning false, inline_depth: %d", + log->Printf ("ThreadPlanStepInRange::DoWillResume: returning false, inline_depth: %d", m_thread.GetCurrentInlinedDepth()); SetStopInfo(StopInfo::CreateStopReasonToTrace(m_thread)); @@ -448,7 +461,5 @@ ThreadPlanStepInRange::WillResume (lldb::StateType resume_state, bool current_pl } return !step_without_resume; } - else - return ThreadPlan::WillResume(resume_state, current_plan); - + return true; } diff --git a/lldb/source/Target/ThreadPlanStepInstruction.cpp b/lldb/source/Target/ThreadPlanStepInstruction.cpp index 32b9897bcec..fa45b2b8cf6 100644 --- a/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -81,7 +81,7 @@ ThreadPlanStepInstruction::ValidatePlan (Stream *error) } bool -ThreadPlanStepInstruction::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepInstruction::DoPlanExplainsStop (Event *event_ptr) { StopInfoSP stop_info_sp = GetPrivateStopReason(); if (stop_info_sp) diff --git a/lldb/source/Target/ThreadPlanStepOut.cpp b/lldb/source/Target/ThreadPlanStepOut.cpp index 46b011cdb40..86f99b250b2 100644 --- a/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/lldb/source/Target/ThreadPlanStepOut.cpp @@ -174,7 +174,7 @@ ThreadPlanStepOut::ValidatePlan (Stream *error) } bool -ThreadPlanStepOut::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepOut::DoPlanExplainsStop (Event *event_ptr) { // If one of our child plans just finished, then we do explain the stop. if (m_step_out_plan_sp) @@ -336,9 +336,8 @@ ThreadPlanStepOut::GetPlanRunState () } bool -ThreadPlanStepOut::WillResume (StateType resume_state, bool current_plan) +ThreadPlanStepOut::DoWillResume (StateType resume_state, bool current_plan) { - ThreadPlan::WillResume (resume_state, current_plan); if (m_step_out_plan_sp || m_step_through_inline_plan_sp) return true; diff --git a/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 9f3c4b04fa3..00a19804b2c 100644 --- a/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -58,7 +58,7 @@ ThreadPlanStepOverBreakpoint::ValidatePlan (Stream *error) } bool -ThreadPlanStepOverBreakpoint::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepOverBreakpoint::DoPlanExplainsStop (Event *event_ptr) { StopInfoSP stop_info_sp = GetPrivateStopReason(); if (stop_info_sp) @@ -91,10 +91,8 @@ ThreadPlanStepOverBreakpoint::GetPlanRunState () } bool -ThreadPlanStepOverBreakpoint::WillResume (StateType resume_state, bool current_plan) +ThreadPlanStepOverBreakpoint::DoWillResume (StateType resume_state, bool current_plan) { - ThreadPlan::WillResume (resume_state, current_plan); - if (current_plan) { BreakpointSiteSP bp_site_sp (m_thread.GetProcess()->GetBreakpointSiteList().FindByAddress (m_breakpoint_addr)); diff --git a/lldb/source/Target/ThreadPlanStepOverRange.cpp b/lldb/source/Target/ThreadPlanStepOverRange.cpp index 85642ad508e..33812925baf 100644 --- a/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -290,7 +290,7 @@ ThreadPlanStepOverRange::ShouldStop (Event *event_ptr) } bool -ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepOverRange::DoPlanExplainsStop (Event *event_ptr) { // For crashes, breakpoint hits, signals, etc, let the base plan (or some plan above us) // handle the stop. That way the user can see the stop, step around, and then when they @@ -301,6 +301,8 @@ ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr) Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); StopInfoSP stop_info_sp = GetPrivateStopReason(); + bool return_value; + if (stop_info_sp) { StopReason reason = stop_info_sp->GetStopReason(); @@ -308,13 +310,13 @@ ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr) switch (reason) { case eStopReasonTrace: - return true; + return_value = true; break; case eStopReasonBreakpoint: if (NextRangeBreakpointExplainsStop(stop_info_sp)) - return true; + return_value = true; else - return false; + return_value = false; break; case eStopReasonWatchpoint: case eStopReasonSignal: @@ -324,15 +326,18 @@ ThreadPlanStepOverRange::PlanExplainsStop (Event *event_ptr) default: if (log) log->PutCString ("ThreadPlanStepInRange got asked if it explains the stop for some reason other than step."); - return false; + return_value = false; break; } } - return true; + else + return_value = true; + + return return_value; } bool -ThreadPlanStepOverRange::WillResume (lldb::StateType resume_state, bool current_plan) +ThreadPlanStepOverRange::DoWillResume (lldb::StateType resume_state, bool current_plan) { if (resume_state != eStateSuspended && m_first_resume) { @@ -346,7 +351,7 @@ ThreadPlanStepOverRange::WillResume (lldb::StateType resume_state, bool current_ { Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (log) - log->Printf ("ThreadPlanStepInRange::WillResume: adjusting range to the frame at inlined depth %d.", + log->Printf ("ThreadPlanStepInRange::DoWillResume: adjusting range to the frame at inlined depth %d.", m_thread.GetCurrentInlinedDepth()); StackFrameSP stack_sp = m_thread.GetStackFrameAtIndex(0); if (stack_sp) @@ -379,5 +384,5 @@ ThreadPlanStepOverRange::WillResume (lldb::StateType resume_state, bool current_ } } - return ThreadPlan::WillResume(resume_state, current_plan); + return true; } diff --git a/lldb/source/Target/ThreadPlanStepThrough.cpp b/lldb/source/Target/ThreadPlanStepThrough.cpp index d6dab171037..92d1fcd850d 100644 --- a/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -139,7 +139,7 @@ ThreadPlanStepThrough::ValidatePlan (Stream *error) } bool -ThreadPlanStepThrough::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepThrough::DoPlanExplainsStop (Event *event_ptr) { // If we have a sub-plan, it will have been asked first if we explain the stop, and // we won't get asked. The only time we would be the one directly asked this question @@ -223,9 +223,8 @@ ThreadPlanStepThrough::GetPlanRunState () } bool -ThreadPlanStepThrough::WillResume (StateType resume_state, bool current_plan) +ThreadPlanStepThrough::DoWillResume (StateType resume_state, bool current_plan) { - ThreadPlan::WillResume(resume_state, current_plan); return true; } diff --git a/lldb/source/Target/ThreadPlanStepUntil.cpp b/lldb/source/Target/ThreadPlanStepUntil.cpp index f6e958a88a6..ca3d30d6f86 100644 --- a/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -305,7 +305,7 @@ ThreadPlanStepUntil::AnalyzeStop() } bool -ThreadPlanStepUntil::PlanExplainsStop (Event *event_ptr) +ThreadPlanStepUntil::DoPlanExplainsStop (Event *event_ptr) { // We don't explain signals or breakpoints (breakpoints that handle stepping in or // out will be handled by a child plan. @@ -341,9 +341,8 @@ ThreadPlanStepUntil::GetPlanRunState () } bool -ThreadPlanStepUntil::WillResume (StateType resume_state, bool current_plan) +ThreadPlanStepUntil::DoWillResume (StateType resume_state, bool current_plan) { - ThreadPlan::WillResume (resume_state, current_plan); if (current_plan) { TargetSP target_sp (m_thread.CalculateTarget()); diff --git a/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py b/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py index 2fb73fba6b6..045565a42d9 100644 --- a/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py +++ b/lldb/test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py @@ -129,6 +129,8 @@ class ObjCDynamicValueTestCase(TestBase): threads = lldbutil.get_stopped_threads (process, lldb.eStopReasonPlanComplete) self.assertTrue (len(threads) == 1) line_entry = threads[0].GetFrameAtIndex(0).GetLineEntry() + print "Line entry is: ", line_entry + self.assertTrue (line_entry.GetLine() == self.set_property_line) self.assertTrue (line_entry.GetFileSpec().GetFilename() == self.source_name) |