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.
This commit is contained in:
jimingham
2025-02-28 13:44:17 -08:00
committed by GitHub
parent f909b2229a
commit ddbce2fd23
3 changed files with 17 additions and 6 deletions

View File

@@ -59,7 +59,8 @@ public:
eNone = 0,
eAvoidInlines = (1 << 0),
eStepInAvoidNoDebug = (1 << 1),
eStepOutAvoidNoDebug = (1 << 2)
eStepOutAvoidNoDebug = (1 << 2),
eStepOutPastThunks = (1 << 3)
};
// Constructors and Destructors

View File

@@ -8,6 +8,7 @@
#include "lldb/Target/ThreadPlanShouldStopHere.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/Thread.h"
@@ -83,7 +84,12 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback(
if (Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol) {
ProcessSP process_sp(current_plan->GetThread().GetProcess());
for (auto *runtime : process_sp->GetLanguageRuntimes()) {
if (runtime->IsSymbolARuntimeThunk(*symbol)) {
if (runtime->IsSymbolARuntimeThunk(*symbol) &&
flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
LLDB_LOGF(
log, "Stepping out past a language thunk %s for: %s",
frame->GetFunctionName(),
Language::GetNameForLanguageType(runtime->GetLanguageType()));
should_stop_here = false;
break;
}
@@ -131,9 +137,12 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
// because it's marked line 0.
bool is_thunk = false;
for (auto *runtime : process_sp->GetLanguageRuntimes()) {
if (runtime->IsSymbolARuntimeThunk(*sc.symbol)) {
LLDB_LOGF(log, "In runtime thunk %s - stepping out.",
sc.symbol->GetName().GetCString());
if (runtime->IsSymbolARuntimeThunk(*sc.symbol) &&
flags.Test(ThreadPlanShouldStopHere::eStepOutPastThunks)) {
LLDB_LOGF(
log, "Stepping out past a language thunk %s for: %s",
frame->GetFunctionName(),
Language::GetNameForLanguageType(runtime->GetLanguageType()));
is_thunk = true;
break;
}

View File

@@ -27,7 +27,8 @@ using namespace lldb;
using namespace lldb_private;
uint32_t ThreadPlanStepInRange::s_default_flag_values =
ThreadPlanShouldStopHere::eStepInAvoidNoDebug;
ThreadPlanShouldStopHere::eStepInAvoidNoDebug |
ThreadPlanShouldStopHere::eStepOutPastThunks;
// ThreadPlanStepInRange: Step through a stack range, either stepping over or
// into based on the value of \a type.