https://github.com/jimingham created 
https://github.com/llvm/llvm-project/pull/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.

>From a26c5596ac599f1b51cffebd658f38233899998e Mon Sep 17 00:00:00 2001
From: Jim Ingham <jing...@apple.com>
Date: Fri, 28 Feb 2025 11:45:51 -0800
Subject: [PATCH] Control the "step out through thunk" logic explicitly when
 pushing thread plans.

That allow the thread plan that is trying to step through a thunk to its target
to step out of a function it has stepped into without also stepping out past
the thunk we were trying to step through.
---
 .../lldb/Target/ThreadPlanShouldStopHere.h        |  3 ++-
 lldb/source/Target/ThreadPlanShouldStopHere.cpp   | 15 +++++++++++----
 lldb/source/Target/ThreadPlanStepInRange.cpp      |  3 ++-
 3 files changed, 15 insertions(+), 6 deletions(-)

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..be6bd981c72bc 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,11 @@ 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 +136,11 @@ 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..3affeae1ee388 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

Reply via email to