summaryrefslogtreecommitdiffstats
path: root/lldb/source/Target/ThreadPlanStepRange.cpp
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2019-12-16 17:38:13 -0800
committerJim Ingham <jingham@apple.com>2019-12-16 17:45:21 -0800
commit434905b97d961531286d4b49c7ee1969f7cbea0e (patch)
treee56180fd34ddd0d7316f26a5fffd9b4d2005a9c5 /lldb/source/Target/ThreadPlanStepRange.cpp
parent53bcd1e1413c878d2d988df80142a430a9abf24a (diff)
downloadbcm5719-llvm-434905b97d961531286d4b49c7ee1969f7cbea0e.tar.gz
bcm5719-llvm-434905b97d961531286d4b49c7ee1969f7cbea0e.zip
Run all threads when extending a next range over a call.
If you don't do this you end up running arbitrary code with only one thread allowed to run, which can cause deadlocks. <rdar://problem/56422478> Differential Revision: https://reviews.llvm.org/D71440
Diffstat (limited to 'lldb/source/Target/ThreadPlanStepRange.cpp')
-rw-r--r--lldb/source/Target/ThreadPlanStepRange.cpp22
1 files changed, 19 insertions, 3 deletions
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 27513a34ead..a22337deaed 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -238,8 +238,18 @@ lldb::FrameComparison ThreadPlanStepRange::CompareCurrentFrameToStartFrame() {
}
bool ThreadPlanStepRange::StopOthers() {
- return (m_stop_others == lldb::eOnlyThisThread ||
- m_stop_others == lldb::eOnlyDuringStepping);
+ switch (m_stop_others) {
+ case lldb::eOnlyThisThread:
+ return true;
+ case lldb::eOnlyDuringStepping:
+ // If there is a call in the range of the next branch breakpoint,
+ // then we should always run all threads, since a call can execute
+ // arbitrary code which might for instance take a lock that's held
+ // by another thread.
+ return !m_found_calls;
+ case lldb::eAllThreads:
+ return false;
+ }
}
InstructionList *ThreadPlanStepRange::GetInstructionsForAddress(
@@ -292,6 +302,7 @@ void ThreadPlanStepRange::ClearNextBranchBreakpoint() {
GetTarget().RemoveBreakpointByID(m_next_branch_bp_sp->GetID());
m_next_branch_bp_sp.reset();
m_could_not_resolve_hw_bp = false;
+ m_found_calls = false;
}
}
@@ -305,6 +316,9 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
if (!m_use_fast_step)
return false;
+ // clear the m_found_calls, we'll rediscover it for this range.
+ m_found_calls = false;
+
lldb::addr_t cur_addr = GetThread().GetRegisterContext()->GetPC();
// Find the current address in our address ranges, and fetch the disassembly
// if we haven't already:
@@ -317,9 +331,11 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() {
else {
Target &target = GetThread().GetProcess()->GetTarget();
const bool ignore_calls = GetKind() == eKindStepOverRange;
+ bool found_calls;
uint32_t branch_index =
instructions->GetIndexOfNextBranchInstruction(pc_index, target,
- ignore_calls);
+ ignore_calls,
+ &m_found_calls);
Address run_to_address;
OpenPOWER on IntegriCloud