Skip to content

Commit 720e920

Browse files
author
git apple-llvm automerger
committed
Merge commit '6c3814b4b110' from swift/release/6.2 into stable/20240723
2 parents af731cf + 6c3814b commit 720e920

File tree

13 files changed

+81
-50
lines changed

13 files changed

+81
-50
lines changed

lldb/include/lldb/lldb-private-enumerations.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,22 @@ enum class IterationAction {
268268
Stop,
269269
};
270270

271+
/// Specifies the type of PCs when creating a `HistoryThread`.
272+
/// - `Returns` - Usually, when LLDB unwinds the stack or we retrieve a stack
273+
/// trace via `backtrace()` we are collecting return addresses (except for the
274+
/// topmost frame which is the actual PC). LLDB then maps these return
275+
/// addresses back to call addresses to give accurate source line annotations.
276+
/// - `ReturnsNoZerothFrame` - Some trace providers (e.g., libsanitizers traces)
277+
/// collect return addresses but prune the topmost frames, so we should skip
278+
/// the special treatment of frame 0.
279+
/// - `Calls` - Other trace providers (e.g., ASan compiler-rt runtime) already
280+
/// perform this mapping, so we need to prevent LLDB from doing it again.
281+
enum class HistoryPCType {
282+
Returns, ///< PCs are return addresses, except for topmost frame.
283+
ReturnsNoZerothFrame, ///< All PCs are return addresses.
284+
Calls ///< PCs are call addresses.
285+
};
286+
271287
inline std::string GetStatDescription(lldb_private::StatisticKind K) {
272288
switch (K) {
273289
case StatisticKind::ExpressionSuccessful:

lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,9 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo(
370370

371371
// We gather symbolication addresses above, so no need for HistoryThread to
372372
// try to infer the call addresses.
373-
bool pcs_are_call_addresses = true;
374-
ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
375-
*process_sp, tid, PCs, pcs_are_call_addresses);
373+
auto pc_type = HistoryPCType::Calls;
374+
ThreadSP new_thread_sp =
375+
std::make_shared<HistoryThread>(*process_sp, tid, PCs, pc_type);
376376

377377
// Save this in the Process' ExtendedThreadList so a strong pointer retains
378378
// the object

lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,9 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo(
324324

325325
// We gather symbolication addresses above, so no need for HistoryThread to
326326
// try to infer the call addresses.
327-
bool pcs_are_call_addresses = true;
328-
ThreadSP new_thread_sp = std::make_shared<HistoryThread>(
329-
*process_sp, tid, PCs, pcs_are_call_addresses);
327+
auto pc_type = HistoryPCType::Calls;
328+
ThreadSP new_thread_sp =
329+
std::make_shared<HistoryThread>(*process_sp, tid, PCs, pc_type);
330330
std::string stop_reason_description = GetStopReasonDescription(info);
331331
new_thread_sp->SetName(stop_reason_description.c_str());
332332

lldb/source/Plugins/InstrumentationRuntime/Utility/ReportRetriever.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ ReportRetriever::RetrieveReportData(const ProcessSP process_sp) {
8383
options.SetAutoApplyFixIts(false);
8484
options.SetLanguage(eLanguageTypeObjC_plus_plus);
8585

86-
if (auto m = GetPreferredAsanModule(process_sp->GetTarget())) {
86+
if (auto [m, _] = GetPreferredAsanModule(process_sp->GetTarget()); m) {
8787
SymbolContextList sc_list;
8888
sc_list.Append(SymbolContext(std::move(m)));
8989
options.SetPreferredSymbolContexts(std::move(sc_list));

lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,13 @@ namespace lldb_private {
1717
///< compiler-rt, and we should prefer it in favour of the system sanitizers.
1818
///< This helper searches the target for such a dylib. Returns nullptr if no
1919
///< such dylib was found.
20-
lldb::ModuleSP GetPreferredAsanModule(const Target &target) {
20+
std::tuple<lldb::ModuleSP, HistoryPCType>
21+
GetPreferredAsanModule(const Target &target) {
22+
// Currently only Darwin provides ASan runtime support as part of the OS
23+
// (libsanitizers).
24+
if (!target.GetArchitecture().GetTriple().isOSDarwin())
25+
return {nullptr, HistoryPCType::Calls};
26+
2127
lldb::ModuleSP module;
2228
llvm::Regex pattern(R"(libclang_rt\.asan_.*_dynamic\.dylib)");
2329
target.GetImages().ForEach([&](const lldb::ModuleSP &m) {
@@ -29,7 +35,16 @@ lldb::ModuleSP GetPreferredAsanModule(const Target &target) {
2935
return true;
3036
});
3137

32-
return module;
38+
// `Calls` - The ASan compiler-rt runtime already massages the return
39+
// addresses into call addresses, so we don't want LLDB's unwinder to try to
40+
// locate the previous instruction again as this might lead to us reporting
41+
// a different line.
42+
// `ReturnsNoZerothFrame` - Darwin, but not ASan compiler-rt implies
43+
// libsanitizers which collects return addresses. It also discards a few
44+
// non-user frames at the top of the stack.
45+
auto pc_type =
46+
(module ? HistoryPCType::Calls : HistoryPCType::ReturnsNoZerothFrame);
47+
return {module, pc_type};
3348
}
3449

3550
} // namespace lldb_private

lldb/source/Plugins/InstrumentationRuntime/Utility/Utility.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@
99
#ifndef LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_UTILITY_H
1010
#define LLDB_SOURCE_PLUGINS_INSTRUMENTATIONRUNTIME_UTILITY_UTILITY_H
1111

12+
#include <tuple>
13+
1214
#include "lldb/lldb-forward.h"
15+
#include "lldb/lldb-private-enumerations.h"
1316

1417
namespace lldb_private {
1518

16-
class Target;
17-
1819
///< On Darwin, if LLDB loaded libclang_rt, it's coming from a locally built
1920
///< compiler-rt, and we should prefer it in favour of the system sanitizers
2021
///< when running InstrumentationRuntime utility expressions that use symbols
2122
///< from the sanitizer libraries. This helper searches the target for such a
2223
///< dylib. Returns nullptr if no such dylib was found.
23-
lldb::ModuleSP GetPreferredAsanModule(const Target &target);
24+
std::tuple<lldb::ModuleSP, HistoryPCType>
25+
GetPreferredAsanModule(const Target &target);
2426

2527
} // namespace lldb_private
2628

lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,11 +91,9 @@ const char *memory_history_asan_command_format =
9191
t;
9292
)";
9393

94-
static void CreateHistoryThreadFromValueObject(ProcessSP process_sp,
95-
ValueObjectSP return_value_sp,
96-
const char *type,
97-
const char *thread_name,
98-
HistoryThreads &result) {
94+
static void CreateHistoryThreadFromValueObject(
95+
ProcessSP process_sp, ValueObjectSP return_value_sp, HistoryPCType pc_type,
96+
const char *type, const char *thread_name, HistoryThreads &result) {
9997
std::string count_path = "." + std::string(type) + "_count";
10098
std::string tid_path = "." + std::string(type) + "_tid";
10199
std::string trace_path = "." + std::string(type) + "_trace";
@@ -128,12 +126,8 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp,
128126
pcs.push_back(pc);
129127
}
130128

131-
// The ASAN runtime already massages the return addresses into call
132-
// addresses, we don't want LLDB's unwinder to try to locate the previous
133-
// instruction again as this might lead to us reporting a different line.
134-
bool pcs_are_call_addresses = true;
135129
HistoryThread *history_thread =
136-
new HistoryThread(*process_sp, tid, pcs, pcs_are_call_addresses);
130+
new HistoryThread(*process_sp, tid, pcs, pc_type);
137131
ThreadSP new_thread_sp(history_thread);
138132
std::ostringstream thread_name_with_number;
139133
thread_name_with_number << thread_name << " Thread " << tid;
@@ -176,7 +170,8 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) {
176170
options.SetAutoApplyFixIts(false);
177171
options.SetLanguage(eLanguageTypeObjC_plus_plus);
178172

179-
if (auto m = GetPreferredAsanModule(process_sp->GetTarget())) {
173+
auto [m, pc_type] = GetPreferredAsanModule(process_sp->GetTarget());
174+
if (m) {
180175
SymbolContextList sc_list;
181176
sc_list.Append(SymbolContext(std::move(m)));
182177
options.SetPreferredSymbolContexts(std::move(sc_list));
@@ -197,10 +192,10 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) {
197192
if (!return_value_sp)
198193
return result;
199194

200-
CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "free",
201-
"Memory deallocated by", result);
202-
CreateHistoryThreadFromValueObject(process_sp, return_value_sp, "alloc",
203-
"Memory allocated by", result);
195+
CreateHistoryThreadFromValueObject(process_sp, return_value_sp, pc_type,
196+
"free", "Memory deallocated by", result);
197+
CreateHistoryThreadFromValueObject(process_sp, return_value_sp, pc_type,
198+
"alloc", "Memory allocated by", result);
204199

205200
return result;
206201
}

lldb/source/Plugins/Process/Utility/HistoryThread.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ using namespace lldb_private;
2727

2828
HistoryThread::HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
2929
std::vector<lldb::addr_t> pcs,
30-
bool pcs_are_call_addresses)
30+
HistoryPCType pc_type)
3131
: Thread(process, tid, true), m_framelist_mutex(), m_framelist(),
3232
m_pcs(pcs), m_extended_unwind_token(LLDB_INVALID_ADDRESS), m_queue_name(),
3333
m_thread_name(), m_originating_unique_thread_id(tid),
3434
m_queue_id(LLDB_INVALID_QUEUE_ID) {
35-
m_unwinder_up =
36-
std::make_unique<HistoryUnwind>(*this, pcs, pcs_are_call_addresses);
35+
m_unwinder_up = std::make_unique<HistoryUnwind>(*this, pcs, pc_type);
3736
Log *log = GetLog(LLDBLog::Object);
3837
LLDB_LOGF(log, "%p HistoryThread::HistoryThread", static_cast<void *>(this));
3938
}

lldb/source/Plugins/Process/Utility/HistoryThread.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ namespace lldb_private {
2727
/// process execution
2828
///
2929
/// This subclass of Thread is used to provide a backtrace from earlier in
30-
/// process execution. It is given a backtrace list of pc addresses and it
31-
/// will create stack frames for them.
30+
/// process execution. It is given a backtrace list of pcs (return or call
31+
/// addresses) and it will create stack frames for them.
3232

3333
class HistoryThread : public lldb_private::Thread {
3434
public:
3535
HistoryThread(lldb_private::Process &process, lldb::tid_t tid,
3636
std::vector<lldb::addr_t> pcs,
37-
bool pcs_are_call_addresses = false);
37+
HistoryPCType pc_type = HistoryPCType::Returns);
3838

3939
~HistoryThread() override;
4040

lldb/source/Plugins/Process/Utility/HistoryUnwind.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ using namespace lldb_private;
2424
// Constructor
2525

2626
HistoryUnwind::HistoryUnwind(Thread &thread, std::vector<lldb::addr_t> pcs,
27-
bool pcs_are_call_addresses)
28-
: Unwind(thread), m_pcs(pcs),
29-
m_pcs_are_call_addresses(pcs_are_call_addresses) {}
27+
HistoryPCType pc_type)
28+
: Unwind(thread), m_pcs(pcs), m_pc_type(pc_type) {}
3029

3130
// Destructor
3231

@@ -52,6 +51,17 @@ HistoryUnwind::DoCreateRegisterContextForFrame(StackFrame *frame) {
5251
return rctx;
5352
}
5453

54+
static bool BehavesLikeZerothFrame(HistoryPCType pc_type, uint32_t frame_idx) {
55+
switch (pc_type) {
56+
case HistoryPCType::Returns:
57+
return (frame_idx == 0);
58+
case HistoryPCType::ReturnsNoZerothFrame:
59+
return false;
60+
case HistoryPCType::Calls:
61+
return true;
62+
}
63+
}
64+
5565
bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
5666
lldb::addr_t &pc,
5767
bool &behaves_like_zeroth_frame) {
@@ -61,10 +71,7 @@ bool HistoryUnwind::DoGetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa,
6171
if (frame_idx < m_pcs.size()) {
6272
cfa = frame_idx;
6373
pc = m_pcs[frame_idx];
64-
if (m_pcs_are_call_addresses)
65-
behaves_like_zeroth_frame = true;
66-
else
67-
behaves_like_zeroth_frame = (frame_idx == 0);
74+
behaves_like_zeroth_frame = BehavesLikeZerothFrame(m_pc_type, frame_idx);
6875
return true;
6976
}
7077
return false;

0 commit comments

Comments
 (0)