Skip to content

Commit d734f30

Browse files
authored
Merge pull request #10413 from swiftlang/lldb/expr-exe-ctx-to-6.1
🍒 [lldb][Target] RunThreadPlan to save/restore the ExecutionContext's frame if one exists
2 parents af0d850 + c3f0a5d commit d734f30

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

lldb/source/Target/Process.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -5200,7 +5200,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
52005200
return eExpressionSetupError;
52015201
}
52025202

5203-
StackID ctx_frame_id = selected_frame_sp->GetStackID();
5203+
// If the ExecutionContext has a frame, we want to make sure to save/restore
5204+
// that frame into exe_ctx. This can happen when we run expressions from a
5205+
// non-selected SBFrame, in which case we don't want some thread-plan
5206+
// to overwrite the ExecutionContext frame.
5207+
StackID ctx_frame_id = exe_ctx.HasFrameScope()
5208+
? exe_ctx.GetFrameRef().GetStackID()
5209+
: selected_frame_sp->GetStackID();
52045210

52055211
// N.B. Running the target may unset the currently selected thread and frame.
52065212
// We don't want to do that either, so we should arrange to reset them as
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
C_SOURCES := main.c
2+
3+
include Makefile.rules
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class ExprFromNonZeroFrame(TestBase):
8+
NO_DEBUG_INFO_TESTCASE = True
9+
10+
def test(self):
11+
"""
12+
Tests that we can use SBFrame::EvaluateExpression on a frame
13+
that we're not stopped in, even if thread-plans run as part of
14+
parsing the expression (e.g., when running static initializers).
15+
"""
16+
self.build()
17+
18+
(_, _, thread, _) = lldbutil.run_to_source_breakpoint(
19+
self, "return 5", lldb.SBFileSpec("main.c")
20+
)
21+
frame = thread.GetFrameAtIndex(1)
22+
23+
# Using a function pointer inside the expression ensures we
24+
# emit a ptrauth static initializer on arm64e into the JITted
25+
# expression. The thread-plan that runs for this static
26+
# initializer should save/restore the current execution context
27+
# frame (which in this test is frame #1).
28+
result = frame.EvaluateExpression("int (*fptr)() = &func; fptr()")
29+
self.assertTrue(result.GetError().Success())
30+
self.assertEqual(result.GetValueAsSigned(), 5)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
int func(void) { return 5; }
2+
3+
int main(int argc, const char *argv[]) { return func(); }

0 commit comments

Comments
 (0)