Skip to content

Commit 0a9b91c

Browse files
committed
Revert "[lldb/DWARF] Use DW_AT_call_pc to determine artificial frame address"
This reverts commit 6905394. The changed test is failing on Debian/x86_64, possibly because lldb is subtracting an offset from the DW_AT_call_pc address used for the artificial frame: http://lab.llvm.org:8011/builders/lldb-x86_64-debian/builds/7171/steps/test/logs/stdio /home/worker/lldb-x86_64-debian/lldb-x86_64-debian/llvm-project/lldb/test/API/functionalities/tail_call_frames/unambiguous_sequence/main.cpp:6:17: error: CHECK-NEXT: expected string not found in input // CHECK-NEXT: frame #1: 0x{{[0-9a-f]+}} a.out`func3() at main.cpp:14:3 [opt] [artificial] ^ <stdin>:3:2: note: scanning from here frame #1: 0x0000000000401127 a.out`func3() at main.cpp:13:4 [opt] [artificial]
1 parent c84446f commit 0a9b91c

File tree

5 files changed

+41
-95
lines changed

5 files changed

+41
-95
lines changed

lldb/include/lldb/Symbol/Function.h

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -284,33 +284,19 @@ class CallEdge {
284284
/// Like \ref GetReturnPCAddress, but returns an unresolved file address.
285285
lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; }
286286

287-
/// Get the load PC address of the call instruction (or LLDB_INVALID_ADDRESS).
288-
lldb::addr_t GetCallInstPC(Function &caller, Target &target) const;
289-
290287
/// Get the call site parameters available at this call edge.
291288
llvm::ArrayRef<CallSiteParameter> GetCallSiteParameters() const {
292289
return parameters;
293290
}
294291

295292
protected:
296-
CallEdge(lldb::addr_t return_pc, lldb::addr_t call_inst_pc,
297-
CallSiteParameterArray &&parameters)
298-
: return_pc(return_pc), call_inst_pc(call_inst_pc),
299-
parameters(std::move(parameters)) {}
300-
301-
/// Helper that finds the load address of \p unresolved_pc, a file address
302-
/// which refers to an instruction within \p caller.
303-
static lldb::addr_t GetLoadAddress(lldb::addr_t unresolved_pc,
304-
Function &caller, Target &target);
293+
CallEdge(lldb::addr_t return_pc, CallSiteParameterArray &&parameters)
294+
: return_pc(return_pc), parameters(std::move(parameters)) {}
305295

306296
/// An invalid address if this is a tail call. Otherwise, the return PC for
307297
/// the call. Note that this is a file address which must be resolved.
308298
lldb::addr_t return_pc;
309299

310-
/// The address of the call instruction. Usually an invalid address, unless
311-
/// this is a tail call.
312-
lldb::addr_t call_inst_pc;
313-
314300
CallSiteParameterArray parameters;
315301
};
316302

@@ -322,8 +308,8 @@ class DirectCallEdge : public CallEdge {
322308
/// Construct a call edge using a symbol name to identify the callee, and a
323309
/// return PC within the calling function to identify a specific call site.
324310
DirectCallEdge(const char *symbol_name, lldb::addr_t return_pc,
325-
lldb::addr_t call_inst_pc, CallSiteParameterArray &&parameters)
326-
: CallEdge(return_pc, call_inst_pc, std::move(parameters)) {
311+
CallSiteParameterArray &&parameters)
312+
: CallEdge(return_pc, std::move(parameters)) {
327313
lazy_callee.symbol_name = symbol_name;
328314
}
329315

@@ -353,9 +339,8 @@ class IndirectCallEdge : public CallEdge {
353339
/// Construct a call edge using a DWARFExpression to identify the callee, and
354340
/// a return PC within the calling function to identify a specific call site.
355341
IndirectCallEdge(DWARFExpression call_target, lldb::addr_t return_pc,
356-
lldb::addr_t call_inst_pc,
357342
CallSiteParameterArray &&parameters)
358-
: CallEdge(return_pc, call_inst_pc, std::move(parameters)),
343+
: CallEdge(return_pc, std::move(parameters)),
359344
call_target(std::move(call_target)) {}
360345

361346
Function *GetCallee(ModuleList &images, ExecutionContext &exe_ctx) override;

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3737,7 +3737,6 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
37373737
llvm::Optional<DWARFDIE> call_origin;
37383738
llvm::Optional<DWARFExpression> call_target;
37393739
addr_t return_pc = LLDB_INVALID_ADDRESS;
3740-
addr_t call_inst_pc = LLDB_INVALID_ADDRESS;
37413740

37423741
DWARFAttributes attributes;
37433742
const size_t num_attributes = child.GetAttributes(attributes);
@@ -3766,12 +3765,6 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
37663765
if (attr == DW_AT_call_return_pc)
37673766
return_pc = form_value.Address();
37683767

3769-
// Extract DW_AT_call_pc (the PC at the call/branch instruction). It
3770-
// should only ever be unavailable for non-tail calls, in which case use
3771-
// LLDB_INVALID_ADDRESS.
3772-
if (attr == DW_AT_call_pc)
3773-
call_inst_pc = form_value.Address();
3774-
37753768
// Extract DW_AT_call_target (the location of the address of the indirect
37763769
// call).
37773770
if (attr == DW_AT_call_target) {
@@ -3794,25 +3787,21 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
37943787
continue;
37953788
}
37963789

3797-
// Adjust any PC forms. It needs to be fixed up if the main executable
3790+
// Adjust the return PC. It needs to be fixed up if the main executable
37983791
// contains a debug map (i.e. pointers to object files), because we need a
37993792
// file address relative to the executable's text section.
38003793
return_pc = FixupAddress(return_pc);
3801-
call_inst_pc = FixupAddress(call_inst_pc);
38023794

38033795
// Extract call site parameters.
38043796
CallSiteParameterArray parameters =
38053797
CollectCallSiteParameters(module, child);
38063798

38073799
std::unique_ptr<CallEdge> edge;
38083800
if (call_origin) {
3809-
LLDB_LOG(log,
3810-
"CollectCallEdges: Found call origin: {0} (retn-PC: {1:x}) "
3811-
"(call-PC: {2:x})",
3812-
call_origin->GetPubname(), return_pc, call_inst_pc);
3801+
LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})",
3802+
call_origin->GetPubname(), return_pc);
38133803
edge = std::make_unique<DirectCallEdge>(call_origin->GetMangledName(),
3814-
return_pc, call_inst_pc,
3815-
std::move(parameters));
3804+
return_pc, std::move(parameters));
38163805
} else {
38173806
if (log) {
38183807
StreamString call_target_desc;
@@ -3821,8 +3810,8 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) {
38213810
LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}",
38223811
call_target_desc.GetString());
38233812
}
3824-
edge = std::make_unique<IndirectCallEdge>(
3825-
*call_target, return_pc, call_inst_pc, std::move(parameters));
3813+
edge = std::make_unique<IndirectCallEdge>(*call_target, return_pc,
3814+
std::move(parameters));
38263815
}
38273816

38283817
if (log && parameters.size()) {

lldb/source/Symbol/Function.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -120,36 +120,27 @@ size_t InlineFunctionInfo::MemorySize() const {
120120
/// @name Call site related structures
121121
/// @{
122122

123-
lldb::addr_t CallEdge::GetLoadAddress(lldb::addr_t unresolved_pc,
124-
Function &caller, Target &target) {
123+
lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller,
124+
Target &target) const {
125125
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));
126126

127127
const Address &caller_start_addr = caller.GetAddressRange().GetBaseAddress();
128128

129129
ModuleSP caller_module_sp = caller_start_addr.GetModule();
130130
if (!caller_module_sp) {
131-
LLDB_LOG(log, "GetLoadAddress: cannot get Module for caller");
131+
LLDB_LOG(log, "GetReturnPCAddress: cannot get Module for caller");
132132
return LLDB_INVALID_ADDRESS;
133133
}
134134

135135
SectionList *section_list = caller_module_sp->GetSectionList();
136136
if (!section_list) {
137-
LLDB_LOG(log, "GetLoadAddress: cannot get SectionList for Module");
137+
LLDB_LOG(log, "GetReturnPCAddress: cannot get SectionList for Module");
138138
return LLDB_INVALID_ADDRESS;
139139
}
140140

141-
Address the_addr = Address(unresolved_pc, section_list);
142-
lldb::addr_t load_addr = the_addr.GetLoadAddress(&target);
143-
return load_addr;
144-
}
145-
146-
lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller,
147-
Target &target) const {
148-
return GetLoadAddress(return_pc, caller, target);
149-
}
150-
151-
lldb::addr_t CallEdge::GetCallInstPC(Function &caller, Target &target) const {
152-
return GetLoadAddress(call_inst_pc, caller, target);
141+
Address return_pc_addr = Address(return_pc, section_list);
142+
lldb::addr_t ret_addr = return_pc_addr.GetLoadAddress(&target);
143+
return ret_addr;
153144
}
154145

155146
void DirectCallEdge::ParseSymbolFileAndResolve(ModuleList &images) {

lldb/source/Target/StackFrameList.cpp

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,13 @@ void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx,
236236
m_frames.resize(num_frames);
237237
}
238238

239-
/// A sequence of calls that comprise some portion of a backtrace. Each frame
240-
/// is represented as a pair of a callee (Function *) and an address within the
241-
/// callee.
242-
using CallSequence = std::vector<std::pair<Function *, addr_t>>;
243-
244239
/// Find the unique path through the call graph from \p begin (with return PC
245240
/// \p return_pc) to \p end. On success this path is stored into \p path, and
246241
/// on failure \p path is unchanged.
247242
static void FindInterveningFrames(Function &begin, Function &end,
248243
ExecutionContext &exe_ctx, Target &target,
249-
addr_t return_pc, CallSequence &path,
244+
addr_t return_pc,
245+
std::vector<Function *> &path,
250246
ModuleList &images, Log *log) {
251247
LLDB_LOG(log, "Finding frames between {0} and {1}, retn-pc={2:x}",
252248
begin.GetDisplayName(), end.GetDisplayName(), return_pc);
@@ -279,27 +275,24 @@ static void FindInterveningFrames(Function &begin, Function &end,
279275
// Fully explore the set of functions reachable from the first edge via tail
280276
// calls in order to detect ambiguous executions.
281277
struct DFS {
282-
CallSequence active_path = {};
283-
CallSequence solution_path = {};
278+
std::vector<Function *> active_path = {};
279+
std::vector<Function *> solution_path = {};
284280
llvm::SmallPtrSet<Function *, 2> visited_nodes = {};
285281
bool ambiguous = false;
286282
Function *end;
287283
ModuleList &images;
288-
Target &target;
289284
ExecutionContext &context;
290285

291-
DFS(Function *end, ModuleList &images, Target &target,
292-
ExecutionContext &context)
293-
: end(end), images(images), target(target), context(context) {}
286+
DFS(Function *end, ModuleList &images, ExecutionContext &context)
287+
: end(end), images(images), context(context) {}
294288

295-
void search(CallEdge &first_edge, Function &first_callee,
296-
CallSequence &path) {
297-
dfs(first_edge, first_callee);
289+
void search(Function &first_callee, std::vector<Function *> &path) {
290+
dfs(first_callee);
298291
if (!ambiguous)
299292
path = std::move(solution_path);
300293
}
301294

302-
void dfs(CallEdge &current_edge, Function &callee) {
295+
void dfs(Function &callee) {
303296
// Found a path to the target function.
304297
if (&callee == end) {
305298
if (solution_path.empty())
@@ -319,24 +312,21 @@ static void FindInterveningFrames(Function &begin, Function &end,
319312
}
320313

321314
// Search the calls made from this callee.
322-
active_path.emplace_back(&callee, LLDB_INVALID_ADDRESS);
315+
active_path.push_back(&callee);
323316
for (const auto &edge : callee.GetTailCallingEdges()) {
324317
Function *next_callee = edge->GetCallee(images, context);
325318
if (!next_callee)
326319
continue;
327320

328-
addr_t tail_call_pc = edge->GetCallInstPC(callee, target);
329-
active_path.back().second = tail_call_pc;
330-
331-
dfs(*edge, *next_callee);
321+
dfs(*next_callee);
332322
if (ambiguous)
333323
return;
334324
}
335325
active_path.pop_back();
336326
}
337327
};
338328

339-
DFS(&end, images, target, exe_ctx).search(*first_edge, *first_callee, path);
329+
DFS(&end, images, exe_ctx).search(*first_callee, path);
340330
}
341331

342332
/// Given that \p next_frame will be appended to the frame list, synthesize
@@ -389,7 +379,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) {
389379

390380
// Try to find the unique sequence of (tail) calls which led from next_frame
391381
// to prev_frame.
392-
CallSequence path;
382+
std::vector<Function *> path;
393383
addr_t return_pc = next_reg_ctx_sp->GetPC();
394384
Target &target = *target_sp.get();
395385
ModuleList &images = next_frame.CalculateTarget()->GetImages();
@@ -399,13 +389,13 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) {
399389
path, images, log);
400390

401391
// Push synthetic tail call frames.
402-
for (auto calleeInfo : llvm::reverse(path)) {
403-
Function *callee = calleeInfo.first;
392+
for (Function *callee : llvm::reverse(path)) {
404393
uint32_t frame_idx = m_frames.size();
405394
uint32_t concrete_frame_idx = next_frame.GetConcreteFrameIndex();
406395
addr_t cfa = LLDB_INVALID_ADDRESS;
407396
bool cfa_is_valid = false;
408-
addr_t pc = calleeInfo.second;
397+
addr_t pc =
398+
callee->GetAddressRange().GetBaseAddress().GetLoadAddress(&target);
409399
constexpr bool behaves_like_zeroth_frame = false;
410400
SymbolContext sc;
411401
callee->CalculateSymbolContext(&sc);
@@ -414,7 +404,7 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) {
414404
cfa_is_valid, pc, StackFrame::Kind::Artificial,
415405
behaves_like_zeroth_frame, &sc);
416406
m_frames.push_back(synth_frame);
417-
LLDB_LOG(log, "Pushed frame {0} at {1:x}", callee->GetDisplayName(), pc);
407+
LLDB_LOG(log, "Pushed frame {0}", callee->GetDisplayName());
418408
}
419409

420410
// If any frames were created, adjust next_frame's index.

lldb/test/API/functionalities/tail_call_frames/unambiguous_sequence/main.cpp

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,19 @@ volatile int x;
33
void __attribute__((noinline)) sink() {
44
x++; //% self.filecheck("bt", "main.cpp", "-implicit-check-not=artificial")
55
// CHECK: frame #0: 0x{{[0-9a-f]+}} a.out`sink() at main.cpp:[[@LINE-1]]:4 [opt]
6-
// CHECK-NEXT: frame #1: 0x{{[0-9a-f]+}} a.out`func3() at main.cpp:14:3 [opt] [artificial]
7-
// CHECK-NEXT: frame #2: 0x{{[0-9a-f]+}} a.out`func2() {{.*}} [opt]
8-
// CHECK-NEXT: frame #3: 0x{{[0-9a-f]+}} a.out`func1() at main.cpp:23:3 [opt] [artificial]
6+
// CHECK-NEXT: frame #1: 0x{{[0-9a-f]+}} a.out`func3{{.*}} [opt] [artificial]
7+
// CHECK-NEXT: frame #2: 0x{{[0-9a-f]+}} a.out`func2{{.*}} [opt]
8+
// CHECK-NEXT: frame #3: 0x{{[0-9a-f]+}} a.out`func1{{.*}} [opt] [artificial]
99
// CHECK-NEXT: frame #4: 0x{{[0-9a-f]+}} a.out`main{{.*}} [opt]
1010
}
1111

12-
void __attribute__((noinline)) func3() {
13-
x++;
14-
sink(); /* tail */
15-
}
12+
void __attribute__((noinline)) func3() { sink(); /* tail */ }
1613

17-
void __attribute__((disable_tail_calls, noinline)) func2() {
18-
func3(); /* regular */
19-
}
14+
void __attribute__((disable_tail_calls, noinline)) func2() { func3(); /* regular */ }
2015

21-
void __attribute__((noinline)) func1() {
22-
x++;
23-
func2(); /* tail */
24-
}
16+
void __attribute__((noinline)) func1() { func2(); /* tail */ }
2517

2618
int __attribute__((disable_tail_calls)) main() {
27-
// DEBUG: self.runCmd("log enable lldb step -f /tmp/lldbstep.log")
2819
func1(); /* regular */
2920
return 0;
3021
}

0 commit comments

Comments
 (0)