Skip to content

Commit 8559a35

Browse files
committed
The Function calling thread plan was replacing the stored stop info too soon, causing recursive entry into the
breakpoint StopInfo's PerformAction, which is bad. Reworked this so that it is now correct. <rdar://problem/12501259> llvm-svn: 168634
1 parent 110b73e commit 8559a35

File tree

6 files changed

+49
-9
lines changed

6 files changed

+49
-9
lines changed

lldb/include/lldb/Target/Thread.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,9 @@ friend class ThreadEventData;
731731
virtual bool
732732
CheckpointThreadState (ThreadStateCheckpoint &saved_state);
733733

734+
virtual bool
735+
RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
736+
734737
virtual bool
735738
RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state);
736739

lldb/include/lldb/Target/ThreadPlan.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,17 @@ class ThreadPlan :
494494
return lldb::ValueObjectSP();
495495
}
496496

497+
// If a thread plan stores the state before it was run, then you might
498+
// want to restore the state when it is done. This will do that job.
499+
// This is mostly useful for artificial plans like CallFunction plans.
500+
501+
virtual bool
502+
RestoreThreadState()
503+
{
504+
// Nothing to do in general.
505+
return true;
506+
}
507+
497508
protected:
498509
//------------------------------------------------------------------
499510
// Classes that inherit from ThreadPlan can see and modify these

lldb/include/lldb/Target/ThreadPlanCallFunction.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ class ThreadPlanCallFunction : public ThreadPlan
127127
return m_stop_address;
128128
}
129129

130+
virtual bool
131+
RestoreThreadState();
132+
130133
protected:
131134
void ReportRegisterState (const char *message);
132135
private:
@@ -154,8 +157,6 @@ class ThreadPlanCallFunction : public ThreadPlan
154157
Address m_function_addr;
155158
Address m_start_addr;
156159
lldb::addr_t m_function_sp;
157-
// Process &m_process;
158-
// Thread &m_thread;
159160
Thread::RegisterCheckpoint m_register_backup;
160161
lldb::ThreadPlanSP m_subplan_sp;
161162
LanguageRuntime *m_cxx_language_runtime;

lldb/source/Target/Process.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4377,6 +4377,9 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
43774377
const uint64_t default_one_thread_timeout_usec = 250000;
43784378
uint64_t computed_timeout = 0;
43794379

4380+
// This while loop must exit out the bottom, there's cleanup that we need to do when we are done.
4381+
// So don't call return anywhere within it.
4382+
43804383
while (1)
43814384
{
43824385
// We usually want to resume the process if we get to the top of the loop.
@@ -4784,6 +4787,12 @@ Process::RunThreadPlan (ExecutionContext &exe_ctx,
47844787

47854788
}
47864789

4790+
// Restore the thread state if we are going to discard the plan execution.
4791+
4792+
if (return_value == eExecutionCompleted || discard_on_error)
4793+
{
4794+
thread_plan_sp->RestoreThreadState();
4795+
}
47874796

47884797
// Now do some processing on the results of the run:
47894798
if (return_value == eExecutionInterrupted)

lldb/source/Target/Thread.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,15 @@ Thread::CheckpointThreadState (ThreadStateCheckpoint &saved_state)
396396
}
397397

398398
bool
399-
Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
399+
Thread::RestoreRegisterStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
400400
{
401401
RestoreSaveFrameZero(saved_state.register_backup);
402+
return true;
403+
}
404+
405+
bool
406+
Thread::RestoreThreadStateFromCheckpoint (ThreadStateCheckpoint &saved_state)
407+
{
402408
if (saved_state.stop_info_sp)
403409
saved_state.stop_info_sp->MakeStopInfoValid();
404410
SetStopInfo(saved_state.stop_info_sp);

lldb/source/Target/ThreadPlanCallFunction.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,6 @@ ThreadPlanCallFunction::ConstructorSetup (Thread &thread,
112112
log->Printf ("ThreadPlanCallFunction(%p): Setting up ThreadPlanCallFunction, failed to checkpoint thread state.", this);
113113
return false;
114114
}
115-
// Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
116-
thread.SetStopInfoToNothing();
117-
118115
function_load_addr = m_function_addr.GetLoadAddress (target_sp.get());
119116

120117
return true;
@@ -196,10 +193,11 @@ ThreadPlanCallFunction::ThreadPlanCallFunction (Thread &thread,
196193
m_valid (false),
197194
m_stop_other_threads (stop_other_threads),
198195
m_function_addr (function),
199-
m_function_sp(0),
196+
m_function_sp (0),
200197
m_return_type (return_type),
201198
m_takedown_done (false),
202-
m_stop_address (LLDB_INVALID_ADDRESS)
199+
m_stop_address (LLDB_INVALID_ADDRESS),
200+
m_discard_on_error (discard_on_error)
203201
{
204202
lldb::addr_t start_load_addr;
205203
ABI *abi;
@@ -289,7 +287,7 @@ ThreadPlanCallFunction::DoTakedown (bool success)
289287
m_takedown_done = true;
290288
m_stop_address = m_thread.GetStackFrameAtIndex(0)->GetRegisterContext()->GetPC();
291289
m_real_stop_info_sp = GetPrivateStopReason();
292-
m_thread.RestoreThreadStateFromCheckpoint(m_stored_thread_state);
290+
m_thread.RestoreRegisterStateFromCheckpoint(m_stored_thread_state);
293291
SetPlanComplete(success);
294292
ClearBreakpoints();
295293
if (log && log->GetVerbose())
@@ -460,6 +458,11 @@ ThreadPlanCallFunction::DidPush ()
460458
{
461459
//#define SINGLE_STEP_EXPRESSIONS
462460

461+
// Now set the thread state to "no reason" so we don't run with whatever signal was outstanding...
462+
// Wait till the plan is pushed so we aren't changing the stop info till we're about to run.
463+
464+
GetThread().SetStopInfoToNothing();
465+
463466
#ifndef SINGLE_STEP_EXPRESSIONS
464467
m_subplan_sp.reset(new ThreadPlanRunToAddress(m_thread, m_start_addr, m_stop_other_threads));
465468

@@ -533,3 +536,10 @@ ThreadPlanCallFunction::BreakpointsExplainStop()
533536

534537
return false;
535538
}
539+
540+
bool
541+
ThreadPlanCallFunction::RestoreThreadState()
542+
{
543+
return GetThread().RestoreThreadStateFromCheckpoint(m_stored_thread_state);
544+
}
545+

0 commit comments

Comments
 (0)