Author: jimingham Date: 2025-02-28T13:44:17-08:00 New Revision: ddbce2fd2380a4eafce9065ad991318f46a3292b
URL: https://github.com/llvm/llvm-project/commit/ddbce2fd2380a4eafce9065ad991318f46a3292b DIFF: https://github.com/llvm/llvm-project/commit/ddbce2fd2380a4eafce9065ad991318f46a3292b.diff LOG: 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. Added: Modified: lldb/include/lldb/Target/ThreadPlanShouldStopHere.h lldb/source/Target/ThreadPlanShouldStopHere.cpp lldb/source/Target/ThreadPlanStepInRange.cpp Removed: ################################################################################ diff --git a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h index 54b30291c3995..d0094c90b91a5 100644 --- a/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h +++ b/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -59,7 +59,8 @@ class ThreadPlanShouldStopHere { eNone = 0, eAvoidInlines = (1 << 0), eStepInAvoidNoDebug = (1 << 1), - eStepOutAvoidNoDebug = (1 << 2) + eStepOutAvoidNoDebug = (1 << 2), + eStepOutPastThunks = (1 << 3) }; // Constructors and Destructors diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/lldb/source/Target/ThreadPlanShouldStopHere.cpp index fa6bc08a9914d..d2cca49987f0f 100644 --- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -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; } diff --git a/lldb/source/Target/ThreadPlanStepInRange.cpp b/lldb/source/Target/ThreadPlanStepInRange.cpp index 109d1b6b3435b..8a2417e9da326 100644 --- a/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -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. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits