| line |
true |
false |
branch |
|
27
|
527 |
17 |
for (auto& so: so_map) { |
|
28
|
527 |
0 |
auto info = std::make_unique(so); |
|
29
|
527 |
0 |
string real_path(PANDA_PATH_MAX); |
|
33
|
527 |
0 |
file = fopen(so.name.c_str(), "rb"); |
|
|
527 |
0 |
file = fopen(so.name.c_str(), "rb"); |
|
34
|
527 |
0 |
DwarfInfo::file_guard_t file_guard (file, [](auto* f){ if (f) {fclose(f); }}); |
|
|
527 |
0 |
DwarfInfo::file_guard_t file_guard (file, [](auto* f){ if (f) {fclose(f); }}); |
|
35
|
527 |
0 |
int fd = file ? fileno(file) : 0; |
|
36
|
527 |
0 |
if (fd > 0) { |
|
37
|
527 |
0 |
auto err = dwarf_init_b(fd, DW_DLC_READ, DW_GROUPNUMBER_ANY, nullptr, &info->err_arg, &info->debug, &error); |
|
39
|
527 |
0 |
if (err == DW_DLV_OK) { |
|
49
|
527 |
0 |
result.emplace(so.name, std::move(info)); |
|
54
|
0 |
17 |
struct DwarfBackend: BacktraceBackend { |
|
67
|
3436 |
0 |
for(auto& it: info_map) { |
|
69
|
267 |
3169 |
if (it.second->resolve(ip_addr, frames)) return true; |
|
86
|
527 |
0 |
if (debug) { |
|
90
|
0 |
527 |
if (res != DW_DLV_OK) { |
|
108
|
527 |
0 |
if (res != DW_DLV_OK) { break; } |
|
113
|
0 |
0 |
if (res != DW_DLV_OK) { break; } |
|
115
|
0 |
527 |
dwarf::DieHolder cu_die_holder(cu_die, debug, nullptr); |
|
124
|
499 |
2937 |
if (ip < so_info.begin || ip >= so_info.end) { return false; } |
|
|
232 |
267 |
if (ip < so_info.begin || ip >= so_info.end) { return false; } |
|
129
|
0 |
267 |
for(auto it = CUs.begin(); it != CUs.end(); ++it){ |
|
133
|
0 |
0 |
if (r.is_complete()) { return r.get_frames(ip, so_info, frames); } |
|
|
0 |
0 |
if (r.is_complete()) { return r.get_frames(ip, so_info, frames); } |
|
153
|
0 |
0 |
bool LookupResult::is_complete() noexcept { return cu && subprogram; } |
|
|
0 |
0 |
bool LookupResult::is_complete() noexcept { return cu && subprogram; } |
|
159
|
0 |
0 |
auto frame = StackframeSP(new Stackframe()); |
|
|
0 |
0 |
auto frame = StackframeSP(new Stackframe()); |
|
162
|
0 |
0 |
frame->library = so.name; |
|
164
|
0 |
0 |
if (details.name) frame->name = details.name; |
|
|
0 |
0 |
if (details.name) frame->name = details.name; |
|
165
|
0 |
0 |
if (details.line_no) frame->line_no = details.line_no; |
|
166
|
0 |
0 |
if (details.source) frame->file = details.source; |
|
|
0 |
0 |
if (details.source) frame->file = details.source; |
|
168
|
0 |
0 |
frames.emplace_back(std::move(frame)); |
|
171
|
0 |
0 |
if (subprogram) { |
|
177
|
0 |
0 |
while(!location->context.empty()) { |
|
196
|
0 |
0 |
} |
|
203
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
206
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
208
|
0 |
0 |
if (res == DW_DLV_OK) { return r; } |
|
216
|
0 |
0 |
while (p->parent) { p = p->parent; } |
|
225
|
0 |
0 |
if(res == DW_DLV_OK) { |
|
229
|
0 |
0 |
assert(res == DW_DLV_OK); |
|
240
|
0 |
0 |
int res = dwarf_siblingof_b(node.debug, node.die, true, &child_die, &error); |
|
241
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
242
|
0 |
0 |
DieHolder child(child_die, node.debug, node.parent); |
|
243
|
0 |
0 |
auto found = fn(child); |
|
244
|
0 |
0 |
if (found) { return found; } |
|
|
0 |
0 |
if (found) { return found; } |
|
248
|
0 |
0 |
res = dwarf_child(node.die, &child_die, &error); |
|
249
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
250
|
0 |
0 |
DieHolder child(child_die, node.debug, &node); |
|
251
|
0 |
0 |
auto found = fn(child); |
|
252
|
0 |
0 |
if (found) { return found; } |
|
|
0 |
0 |
if (found) { return found; } |
|
263
|
0 |
0 |
assert(res == DW_DLV_OK); |
|
264
|
0 |
0 |
if (off == target_offset) { return node.detach(); } |
|
265
|
0 |
0 |
if (off > target_offset) { return DieSP(); } /* do not lookup for fail branch */ |
|
272
|
0 |
0 |
if (!details.name) { |
|
277
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
278
|
0 |
0 |
iptr node = (it == die) ? iptr(this) : discover(it); |
|
286
|
0 |
0 |
if (die_spec) return refine_fn_spec(die_spec, details); |
|
289
|
0 |
0 |
if (die_ao) return refine_fn_name(die_ao, details); |
|
299
|
0 |
0 |
if (!source_die) { |
|
300
|
0 |
0 |
int res = dwarf_hasattr(it->die, DW_AT_decl_file, &has_source, &error); |
|
301
|
0 |
0 |
if (res == DW_DLV_OK && has_source) { |
|
|
0 |
0 |
if (res == DW_DLV_OK && has_source) { |
|
302
|
0 |
0 |
source_die = it; |
|
310
|
0 |
0 |
assert(res == DW_DLV_OK); |
|
316
|
0 |
0 |
while(p) { |
|
319
|
0 |
0 |
assert(res == DW_DLV_OK); |
|
320
|
0 |
0 |
if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type || tag == DW_TAG_namespace) { |
|
|
0 |
0 |
if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type || tag == DW_TAG_namespace) { |
|
|
0 |
0 |
if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type || tag == DW_TAG_namespace) { |
|
323
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
326
|
0 |
0 |
assert(res == DW_DLV_OK); |
|
344
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
351
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
352
|
0 |
0 |
LineContextHolder line_context_guard(&line_context, [](auto it){ dwarf_srclines_dealloc_b(*it); }); |
|
357
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
361
|
0 |
0 |
for (Dwarf_Signed i = base_index; i < end_index; ++i) { |
|
368
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
369
|
0 |
0 |
if (cu_name.find(source_name) != string::npos) { |
|
370
|
0 |
0 |
if (dirindex) { |
|
373
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
375
|
0 |
0 |
if (cu_name.find(dir_name) != string::npos) { |
|
386
|
0 |
0 |
if (cu_index == -1) { return; } |
|
391
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
396
|
0 |
0 |
for(Dwarf_Signed i = 0; i < linecount; ++i) { |
|
402
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
404
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
406
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
|
407
|
0 |
0 |
if (file_index != static_cast(cu_index)) { continue; } |
|
409
|
0 |
0 |
if (lineaddr >= offset) { found = true; break; } |
|
413
|
0 |
0 |
if (found) { |
|
414
|
0 |
0 |
details.line_no = prev_lineno; |
|
421
|
0 |
0 |
if (!details.line_no) { |
|
426
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
429
|
0 |
0 |
if (res == DW_DLV_OK) { details.line_no = line + 1; } |
|
439
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die->die, r); |
|
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die->die, r); |
|
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die->die, r); |
|
441
|
0 |
0 |
if (r.name_die) refine_fn_source(r.name_die->die, r, *lr.root); |
|
448
|
0 |
0 |
if (!details.source) { |
|
452
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
455
|
0 |
0 |
if (res == DW_DLV_OK && file_index) { |
|
|
0 |
0 |
if (res == DW_DLV_OK && file_index) { |
|
465
|
0 |
0 |
if (!details.name) { |
|
467
|
0 |
0 |
if (die_spec) { refine_fn_spec(die_spec, details); } |
|
482
|
0 |
0 |
if (er == Scan::found) return er; |
|
|
0 |
0 |
if (er == Scan::found) return er; |
|
|
0 |
0 |
if (er == Scan::found) return er; |
|
|
0 |
0 |
if (er == Scan::found) return er; |
|
493
|
0 |
0 |
if (sr == Scan::found) return sr; |
|
|
0 |
0 |
if (sr == Scan::found) return sr; |
|
494
|
0 |
0 |
} else if (res == DW_DLV_NO_ENTRY) { |
|
|
0 |
0 |
} else if (res == DW_DLV_NO_ENTRY) { |
|
|
0 |
0 |
} else if (res == DW_DLV_NO_ENTRY) { |
|
|
0 |
0 |
} else if (res == DW_DLV_NO_ENTRY) { |
|
501
|
0 |
0 |
if (er != Scan::dead_end) { |
|
|
0 |
0 |
if (er != Scan::dead_end) { |
|
|
0 |
0 |
if (er != Scan::dead_end) { |
|
|
0 |
0 |
if (er != Scan::dead_end) { |
|
506
|
0 |
0 |
if (sr == Scan::found) return sr; |
|
|
0 |
0 |
if (sr == Scan::found) return sr; |
|
514
|
0 |
0 |
DieCollection context{{DieSP(this)}}; |
|
520
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
526
|
0 |
0 |
res = dwarf_tag(node.die, &tag, &error); |
|
527
|
0 |
0 |
if (res != DW_DLV_OK) { return Scan::dead_end; } |
|
529
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
|
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
|
533
|
0 |
0 |
case Match::yes: context.push_back(node.detach()); break; |
|
|
0 |
0 |
case Match::yes: context.push_back(node.detach()); break; |
|
549
|
0 |
0 |
assert(!owner || owner->die); |
|
|
0 |
0 |
assert(!owner || owner->die); |
|
555
|
0 |
0 |
if (!owner) { dwarf_dealloc(debug, die,DW_DLA_DIE); } |
|
559
|
0 |
0 |
if (!owner) { |
|
560
|
0 |
0 |
DieSP parent_ptr(parent ? parent->detach() : nullptr); |
|
|
0 |
0 |
DieSP parent_ptr(parent ? parent->detach() : nullptr); |
|
561
|
0 |
0 |
owner = DieSP(new DieRC(die, debug, parent_ptr)); |
|
|
0 |
0 |
owner = DieSP(new DieRC(die, debug, parent_ptr)); |
|
572
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
576
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
577
|
0 |
0 |
if (formclass == DW_FORM_CLASS_CONSTANT) { high += low; } |
|
587
|
0 |
0 |
if (addr) { |
|
588
|
0 |
0 |
if ((addr->high >= offset) || (addr->low < offset)) { |
|
|
0 |
0 |
if ((addr->high >= offset) || (addr->low < offset)) { |
|
|
0 |
0 |
if ((addr->high >= offset) || (addr->low < offset)) { |
|
597
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
600
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
605
|
0 |
0 |
if (res == DW_DLV_OK) { |
|
607
|
0 |
0 |
for(int i = 0; i < ranges_count; ++i) { |
|
614
|
0 |
0 |
auto matches = (low <= offset) && (high > offset); |
|
|
0 |
0 |
auto matches = (low <= offset) && (high > offset); |
|
616
|
0 |
0 |
if (matches) {return Match::yes; } |
|
623
|
0 |
0 |
if (ranges_count > 0) { return Match::no; } |
|
638
|
0 |
527 |
if (sources) { |
|
639
|
0 |
0 |
for(size_t i = 0; i < static_cast(sources_count); ++i) { |
|
644
|
0 |
527 |
} |
|
647
|
0 |
0 |
assert(cu_die); |
|
661
|
0 |
0 |
assert(die.die); |
|
663
|
0 |
0 |
if (res != DW_DLV_OK) { return Scan::dead_end; } |
|
665
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
|
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
|
667
|
0 |
0 |
switch (die.contains(offset)) { |
|
676
|
0 |
0 |
else if(tag == DW_TAG_compile_unit) { |
|
680
|
0 |
0 |
return lr.is_complete() ? Scan::found : Scan::not_found; |
|
692
|
0 |
0 |
if (!sources_count) { |
|
694
|
0 |
0 |
if (res != DW_DLV_OK) { sources_count = -1; } |
|
696
|
0 |
0 |
if (sources_count > 0 && index < static_cast(sources_count)) { |
|
|
0 |
0 |
if (sources_count > 0 && index < static_cast(sources_count)) { |
|
704
|
6 |
0 |
}}} |
|
|
6 |
0 |
}}} |