Skip to content

Commit d5a9c5f

Browse files
authored
Merge pull request #10412 from swiftlang/lldb/expr-exe-ctx
🍒 [lldb][Target] RunThreadPlan to save/restore the ExecutionContext's frame if one exists
2 parents 3af5568 + d834e7e commit d5a9c5f

File tree

4 files changed

+43
-1
lines changed

4 files changed

+43
-1
lines changed

Diff for: lldb/source/Target/Process.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -5186,7 +5186,13 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx,
51865186
return eExpressionSetupError;
51875187
}
51885188

5189-
StackID ctx_frame_id = selected_frame_sp->GetStackID();
5189+
// If the ExecutionContext has a frame, we want to make sure to save/restore
5190+
// that frame into exe_ctx. This can happen when we run expressions from a
5191+
// non-selected SBFrame, in which case we don't want some thread-plan
5192+
// to overwrite the ExecutionContext frame.
5193+
StackID ctx_frame_id = exe_ctx.HasFrameScope()
5194+
? exe_ctx.GetFrameRef().GetStackID()
5195+
: selected_frame_sp->GetStackID();
51905196

51915197
// N.B. Running the target may unset the currently selected thread and frame.
51925198
// 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)