Skip to content

Commit ddbce2f

Browse files
authored
Control the "step out through thunk" logic explicitly when pushing thread plans (#129301)
Jonas recently added a trampoline handling strategy for simple language thunks that does: "step through language thunks stepping in one level deep and stopping if you hit user code". That was actually pulled over from the swift implementation. However, this strategy and the strategy we have to "step out past language thunks" when stepping out come into conflict if the thunk you are stepping through calls some other function before dispatching to the intended method. When you step out of the called function back into the thunk, should you keep stepping out past the thunk or not? In most cases, you want to step out past the thunk, but in this particular case you don't. This patch adds a way to inform the thread plan (or really it's ShouldStopHere behavior) of which behavior it should have, and passes the don't step through thunks to the step through plan it uses to step through thunks. I didn't add a test for this because I couldn't find a C++ thunk that calls another function before getting to the target function. I asked the clang folks here if they could think of a case where clang would do this, and they couldn't. If anyone can think of such a construct, it will be easy to write the step through test for it... This does happen in swift, however, so when I cherry-pick this to the swift fork I'll test it there.
1 parent f909b22 commit ddbce2f

File tree

3 files changed

+17
-6
lines changed

3 files changed

+17
-6
lines changed

lldb/include/lldb/Target/ThreadPlanShouldStopHere.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere {
5959
eNone = 0,
6060
eAvoidInlines = (1 << 0),
6161
eStepInAvoidNoDebug = (1 << 1),
62-
eStepOutAvoidNoDebug = (1 << 2)
62+
eStepOutAvoidNoDebug = (1 << 2),
63+
eStepOutPastThunks = (1 << 3)
6364
};
6465

6566
// Constructors and Destructors

lldb/source/Target/ThreadPlanShouldStopHere.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "lldb/Target/ThreadPlanShouldStopHere.h"
1010
#include "lldb/Symbol/Symbol.h"
11+
#include "lldb/Target/Language.h"
1112
#include "lldb/Target/LanguageRuntime.h"
1213
#include "lldb/Target/RegisterContext.h"
1314
#include "lldb/Target/Thread.h"
@@ -83,7 +84,12 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
8384
if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) {
8485
ProcessSP process_sp(current_plan->GetThread().GetProcess());
8586
for (auto *runtime : process_sp->GetLanguageRuntimes()) {
86-
if (runtime->IsSymbolARuntimeThunk(*symbol)) {
87+
if (runtime->IsSymbolARuntimeThunk(*symbol) &&
88+
flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
89+
LLDB_LOGF(
90+
log, "Stepping out past a language thunk %s for: %s",
91+
frame->GetFunctionName(),
92+
Language::GetNameForLanguageType(runtime->GetLanguageType()));
8793
should_stop_here = false;
8894
break;
8995
}
@@ -131,9 +137,12 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
131137
// because it's marked line 0.
132138
bool is_thunk = false;
133139
for (auto *runtime : process_sp->GetLanguageRuntimes()) {
134-
if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
135-
LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
136-
sc.symbol->GetName().GetCString());
140+
if (runtime->IsSymbolARuntimeThunk(*sc.symbol) &&
141+
flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
142+
LLDB_LOGF(
143+
log, "Stepping out past a language thunk %s for: %s",
144+
frame->GetFunctionName(),
145+
Language::GetNameForLanguageType(runtime->GetLanguageType()));
137146
is_thunk = true;
138147
break;
139148
}

lldb/source/Target/ThreadPlanStepInRange.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ using namespace lldb;
2727
using namespace lldb_private;
2828

2929
uint32_t ThreadPlanStepInRange::s_default_flag_values =
30-
ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
30+
ThreadPlanShouldStopHere::eStepInAvoidNoDebug |
31+
ThreadPlanShouldStopHere::eStepOutPastThunks;
3132

3233
// ThreadPlanStepInRange: Step through a stack range, either stepping over or
3334
// into based on the value of \a type.

0 commit comments

Comments
 (0)