Skip to content

Commit 26f4db4

Browse files
Merge pull request #11181 from felipepiovezan/felipe/cherry-pick-taskswitchprologuefix
🍒 [lldb] Skip prologue when stepping through swift_task_switch
2 parents cf66110 + 5418e44 commit 26f4db4

File tree

5 files changed

+58
-26
lines changed

5 files changed

+58
-26
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,31 +2924,15 @@ std::optional<lldb::addr_t> SwiftLanguageRuntime::TrySkipVirtualParentProlog(
29242924
addr_t pc_value = process.ReadPointerFromMemory(pc_location, error);
29252925
if (error.Fail())
29262926
return {};
2927-
// Clear any high order bits of this code address so that SetLoadAddress works
2928-
// properly.
2929-
pc_value = process.FixCodeAddress(pc_value);
29302927

2931-
Address pc;
2932-
Target &target = process.GetTarget();
2933-
pc.SetLoadAddress(pc_value, &target);
2934-
if (!pc.IsValid())
2935-
return {};
2936-
2937-
SymbolContext sc;
2938-
bool sc_ok = pc.CalculateSymbolContext(&sc, eSymbolContextFunction |
2939-
eSymbolContextSymbol);
2940-
if (!sc_ok || (!sc.symbol && !sc.function)) {
2941-
Log *log = GetLog(LLDBLog::Unwind);
2942-
LLDB_LOGF(log,
2943-
"SwiftLanguageRuntime::%s Failed to find a symbol context for "
2944-
"address 0x%" PRIx64,
2945-
__FUNCTION__, pc_value);
2946-
return {};
2947-
}
2928+
llvm::Expected<uint64_t> maybe_prologue_size =
2929+
FindPrologueSize(process, pc_value);
2930+
if (maybe_prologue_size)
2931+
return pc_value + *maybe_prologue_size;
29482932

2949-
auto prologue_size = sc.symbol ? sc.symbol->GetPrologueByteSize()
2950-
: sc.function->GetPrologueByteSize();
2951-
return pc_value + prologue_size;
2933+
LLDB_LOG_ERROR(GetLog(LLDBLog::Unwind), maybe_prologue_size.takeError(),
2934+
"{1}::{0}", __FUNCTION__);
2935+
return pc_value;
29522936
}
29532937

29542938
/// Attempts to read the memory location at `task_addr_location`, producing
@@ -3139,4 +3123,30 @@ llvm::Expected<std::optional<std::string>> GetTaskName(lldb::addr_t task_addr,
31393123
return status.takeError();
31403124
}
31413125

3126+
llvm::Expected<uint64_t> FindPrologueSize(Process &process,
3127+
uint64_t load_address) {
3128+
Address addr;
3129+
Target &target = process.GetTarget();
3130+
addr.SetLoadAddress(process.FixCodeAddress(load_address), &target);
3131+
if (!addr.IsValid())
3132+
return llvm::createStringError(
3133+
llvm::formatv("Invalid load address for {0:x}", load_address));
3134+
3135+
SymbolContext sc;
3136+
bool sc_ok = addr.CalculateSymbolContext(&sc, eSymbolContextFunction |
3137+
eSymbolContextSymbol);
3138+
if (!sc_ok || (!sc.symbol && !sc.function))
3139+
return llvm::createStringError(llvm::formatv(
3140+
"Failed to find a symbol context for address {1:x}", load_address));
3141+
3142+
uint64_t prologue_size = sc.symbol ? sc.symbol->GetPrologueByteSize()
3143+
: sc.function->GetPrologueByteSize();
3144+
3145+
if (prologue_size == 0)
3146+
return llvm::createStringError(llvm::formatv(
3147+
"Prologue size is 0 for function {0}",
3148+
sc.GetFunctionName(Mangled::NamePreference::ePreferMangled)));
3149+
3150+
return prologue_size;
3151+
}
31423152
} // namespace lldb_private

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,10 @@ class TaskInspector {
944944
llvm::Expected<std::optional<std::string>> GetTaskName(lldb::addr_t task,
945945
Process &process);
946946

947+
/// Finds the function for which `load_address` belongs, and returns its
948+
/// prologue size.
949+
llvm::Expected<uint64_t> FindPrologueSize(Process &process,
950+
uint64_t load_address);
947951
} // namespace lldb_private
948952

949953
#endif // liblldb_SwiftLanguageRuntime_h_

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,18 @@ CreateRunThroughTaskSwitchThreadPlan(Thread &thread,
394394
return {};
395395

396396
resume_fn_ptr = thread.GetProcess()->FixCodeAddress(resume_fn_ptr);
397-
return std::make_shared<ThreadPlanRunToAddress>(thread, resume_fn_ptr,
397+
398+
llvm::Expected<uint64_t> maybe_prologue_size =
399+
FindPrologueSize(*thread.GetProcess(), resume_fn_ptr);
400+
401+
uint64_t dest_address =
402+
resume_fn_ptr + (maybe_prologue_size ? *maybe_prologue_size : 0);
403+
404+
if (!maybe_prologue_size)
405+
LLDB_LOG_ERROR(GetLog(LLDBLog::Step), maybe_prologue_size.takeError(),
406+
"{1}::{0}", __FUNCTION__);
407+
408+
return std::make_shared<ThreadPlanRunToAddress>(thread, dest_address,
398409
/*stop_others*/ false);
399410
}
400411

lldb/test/API/lang/swift/async/stepping/step_over/TestSwiftAsyncStepOver.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
@skipIfAsan # rdar://138777205
88
class TestCase(lldbtest.TestBase):
99

10+
def check_x_is_available(self, frame):
11+
x_var = frame.FindVariable("x")
12+
self.assertTrue(x_var.IsValid(), f"Failed to find x in {frame}")
13+
self.assertEqual(x_var.GetValueAsUnsigned(), 30)
14+
1015
def check_is_in_line(self, thread, linenum):
1116
frame = thread.frames[0]
1217
line_entry = frame.GetLineEntry()
@@ -25,10 +30,11 @@ def test(self):
2530
bkpt.SetEnabled(False) # avoid hitting multiple locations in async breakpoints
2631

2732
expected_line_nums = [4] # print(x)
28-
expected_line_nums += [5, 6, 7, 5, 6, 7, 5] # two runs over the loop
29-
expected_line_nums += [8, 9] # if line + if block
33+
expected_line_nums += [5, 6, 7, 8, 5, 6, 7, 8, 5] # two runs over the loop
34+
expected_line_nums += [9, 10] # if line + if block
3035
for expected_line_num in expected_line_nums:
3136
thread.StepOver()
3237
stop_reason = thread.GetStopReason()
3338
self.assertStopReason(stop_reason, lldb.eStopReasonPlanComplete)
3439
self.check_is_in_line(thread, expected_line_num)
40+
self.check_x_is_available(thread.frames[0])

lldb/test/API/lang/swift/async/stepping/step_over/main.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
print(x)
55
for i in 1...2 {
66
await f()
7+
print("hello!")
78
}
89
if (await f() == 30) {
910
print("here!")

0 commit comments

Comments
 (0)