line |
true |
false |
branch |
29
|
527 |
17 |
for (auto& so: so_map) { |
30
|
527 |
0 |
auto info = std::make_unique(so); |
31
|
527 |
0 |
string real_path(PANDA_PATH_MAX); |
35
|
527 |
0 |
file = fopen(so.name.c_str(), "rb"); |
|
527 |
0 |
file = fopen(so.name.c_str(), "rb"); |
36
|
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); }}); |
37
|
527 |
0 |
int fd = file ? fileno(file) : 0; |
38
|
527 |
0 |
if (fd > 0) { |
39
|
527 |
0 |
auto err = dwarf_init_b(fd, DW_DLC_READ, DW_GROUPNUMBER_ANY, nullptr, &info->err_arg, &info->debug, &error); |
41
|
527 |
0 |
if (err == DW_DLV_OK) { |
51
|
527 |
0 |
result.emplace(so.name, std::move(info)); |
56
|
0 |
17 |
struct DwarfBackend: BacktraceBackend { |
69
|
3436 |
0 |
for(auto& it: info_map) { |
71
|
267 |
3169 |
if (it.second->resolve(ip_addr, frames)) return true; |
88
|
527 |
0 |
if (debug) { |
92
|
0 |
527 |
if (res != DW_DLV_OK) { |
110
|
527 |
0 |
if (res != DW_DLV_OK) { break; } |
115
|
0 |
0 |
if (res != DW_DLV_OK) { break; } |
118
|
0 |
527 |
CUs.emplace_back(std::move(cu)); |
125
|
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; } |
130
|
0 |
267 |
for(auto it = CUs.begin(); it != CUs.end(); ++it){ |
134
|
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); } |
154
|
0 |
0 |
bool LookupResult::is_complete() noexcept { return cu && subprogram; } |
|
0 |
0 |
bool LookupResult::is_complete() noexcept { return cu && subprogram; } |
160
|
0 |
0 |
auto frame = StackframeSP(new Stackframe()); |
|
0 |
0 |
auto frame = StackframeSP(new Stackframe()); |
163
|
0 |
0 |
frame->library = so.name; |
165
|
0 |
0 |
if (details.name) frame->name = details.name; |
|
0 |
0 |
if (details.name) frame->name = details.name; |
166
|
0 |
0 |
if (details.line_no) frame->line_no = details.line_no; |
167
|
0 |
0 |
if (details.source) frame->file = details.source; |
|
0 |
0 |
if (details.source) frame->file = details.source; |
169
|
0 |
0 |
frames.emplace_back(std::move(frame)); |
172
|
0 |
0 |
if (subprogram) { |
178
|
0 |
0 |
while(!location->context.empty()) { |
197
|
0 |
0 |
} |
204
|
0 |
0 |
if (res == DW_DLV_OK) { |
207
|
0 |
0 |
if (res == DW_DLV_OK) { |
209
|
0 |
0 |
if (res == DW_DLV_OK) { return new DieRC(r, source->debug, source); } |
217
|
0 |
0 |
while (p->parent) { p = p->parent; } |
224
|
0 |
0 |
if(res == DW_DLV_OK) { |
228
|
0 |
0 |
assert(res == DW_DLV_OK); |
241
|
0 |
0 |
int res = dwarf_siblingof_b(node->debug, node->die, true, &child_die, &error); |
242
|
0 |
0 |
if (res == DW_DLV_OK) { |
243
|
0 |
0 |
DieSP child = new DieRC(child_die, node->debug, node->parent); |
|
0 |
0 |
DieSP child = new DieRC(child_die, node->debug, node->parent); |
244
|
0 |
0 |
queue.push(child); |
247
|
0 |
0 |
res = dwarf_child(node->die, &child_die, &error); |
248
|
0 |
0 |
if (res == DW_DLV_OK) { |
249
|
0 |
0 |
DieSP child = new DieRC(child_die, node->debug, node); |
|
0 |
0 |
DieSP child = new DieRC(child_die, node->debug, node); |
250
|
0 |
0 |
queue.push(child); |
261
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
|
0 |
0 |
return new DieRC(child_die, node->debug, parent); |
264
|
0 |
0 |
while (node) { |
|
0 |
0 |
while (node) { |
|
0 |
0 |
while (node) { |
267
|
0 |
0 |
while (try_next) { |
|
0 |
0 |
while (try_next) { |
|
0 |
0 |
while (try_next) { |
274
|
0 |
0 |
if (res != DW_DLV_OK) { try_next = false; break; } |
|
0 |
0 |
if (res != DW_DLV_OK) { try_next = false; break; } |
|
0 |
0 |
if (res != DW_DLV_OK) { try_next = false; break; } |
282
|
0 |
0 |
if (res != DW_DLV_OK) { node = DieSP(); break; } |
|
0 |
0 |
if (res != DW_DLV_OK) { node = DieSP(); break; } |
|
0 |
0 |
if (res != DW_DLV_OK) { node = DieSP(); break; } |
294
|
0 |
0 |
res = dwarf_dieoffset(node->die, &off, &error); |
295
|
0 |
0 |
assert(res == DW_DLV_OK); |
297
|
0 |
0 |
if (off == target_offset) { return Scan::found; } |
298
|
0 |
0 |
else if (off > target_offset) { return Scan::dead_end; } |
307
|
0 |
0 |
if (!details.name) { |
312
|
0 |
0 |
if (res == DW_DLV_OK) { |
313
|
0 |
0 |
iptr node = (it->die == die) ? iptr(this) : discover(it); |
|
0 |
0 |
iptr node = (it->die == die) ? iptr(this) : discover(it); |
320
|
0 |
0 |
if (!(details.mask & MASK_SPEC)) { |
322
|
0 |
0 |
if (die_spec) { |
324
|
0 |
0 |
return refine_fn_spec(die_spec, details); |
328
|
0 |
0 |
if (!(details.mask & MASK_AO)) { |
330
|
0 |
0 |
if (die_ao) { |
344
|
0 |
0 |
if (!source_die) { |
345
|
0 |
0 |
int res = dwarf_hasattr(it->die, DW_AT_decl_file, &has_source, &error); |
346
|
0 |
0 |
if (res == DW_DLV_OK && has_source) { |
|
0 |
0 |
if (res == DW_DLV_OK && has_source) { |
347
|
0 |
0 |
source_die = it; |
355
|
0 |
0 |
assert(res == DW_DLV_OK); |
361
|
0 |
0 |
while(p) { |
364
|
0 |
0 |
assert(res == DW_DLV_OK); |
365
|
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) { |
368
|
0 |
0 |
if (res == DW_DLV_OK) { |
371
|
0 |
0 |
assert(res == DW_DLV_OK); |
389
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
396
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
397
|
0 |
0 |
LineContextHolder line_context_guard(&line_context, [](auto it){ dwarf_srclines_dealloc_b(*it); }); |
402
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
406
|
0 |
0 |
for (Dwarf_Signed i = base_index; i < end_index; ++i) { |
413
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
414
|
0 |
0 |
if (cu_name.find(source_name) != string::npos) { |
415
|
0 |
0 |
if (dirindex) { |
418
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
420
|
0 |
0 |
if (cu_name.find(dir_name) != string::npos) { |
431
|
0 |
0 |
if (cu_index == -1) { return; } |
436
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
441
|
0 |
0 |
for(Dwarf_Signed i = 0; i < linecount; ++i) { |
447
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
449
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
451
|
0 |
0 |
if (res != DW_DLV_OK) { return; } |
452
|
0 |
0 |
if (file_index != static_cast(cu_index)) { continue; } |
454
|
0 |
0 |
if (lineaddr >= offset) { found = true; break; } |
458
|
0 |
0 |
if (found) { |
459
|
0 |
0 |
details.line_no = prev_lineno; |
466
|
0 |
0 |
if (!details.line_no) { |
471
|
0 |
0 |
if (res == DW_DLV_OK) { |
474
|
0 |
0 |
if (res == DW_DLV_OK) { details.line_no = line + 1; } |
484
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die, r); |
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die, r); |
|
0 |
0 |
if (!r.line_no && r.name_die) refine_fn_line_fallback(r.name_die, r); |
486
|
0 |
0 |
if (r.name_die) refine_fn_source(r.name_die, r, *lr.root); |
493
|
0 |
0 |
if (!details.source) { |
497
|
0 |
0 |
if (res == DW_DLV_OK) { |
500
|
0 |
0 |
if (res == DW_DLV_OK && file_index) { |
|
0 |
0 |
if (res == DW_DLV_OK && file_index) { |
510
|
0 |
0 |
if (!details.name && !(details.mask & MASK_SPEC)) { |
|
0 |
0 |
if (!details.name && !(details.mask & MASK_SPEC)) { |
|
0 |
0 |
if (!details.name && !(details.mask & MASK_SPEC)) { |
512
|
0 |
0 |
if (die_spec) { |
526
|
0 |
0 |
DieCollection context{{DieSP(this)}}; |
532
|
0 |
0 |
if (res == DW_DLV_OK) { |
538
|
0 |
0 |
res = dwarf_tag(node->die, &tag, &error); |
539
|
0 |
0 |
if (res != DW_DLV_OK) { return Scan::dead_end; } |
541
|
0 |
0 |
if( tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { |
|
0 |
0 |
if( tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { |
544
|
0 |
0 |
case Scan::found: context.push_back(node); break; |
554
|
0 |
0 |
while (context.size() > max_inline) context.pop_front(); |
568
|
0 |
0 |
if (res == DW_DLV_OK) { |
572
|
0 |
0 |
if (res == DW_DLV_OK) { |
573
|
0 |
0 |
if (formclass == DW_FORM_CLASS_CONSTANT) { high += low; } |
584
|
0 |
0 |
if (addr) { |
585
|
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)) { |
594
|
0 |
0 |
if (res == DW_DLV_OK) { |
597
|
0 |
0 |
if (res == DW_DLV_OK) { |
602
|
0 |
0 |
if (res == DW_DLV_OK) { |
604
|
0 |
0 |
for(int i = 0; i < ranges_count; ++i) { |
611
|
0 |
0 |
auto matches = (low <= offset) && (high > offset); |
|
0 |
0 |
auto matches = (low <= offset) && (high > offset); |
613
|
0 |
0 |
if (matches) {return Scan::found; } |
620
|
0 |
0 |
if (ranges_count > 0) { return Scan::dead_end; } |
633
|
0 |
527 |
if (sources) { |
634
|
0 |
0 |
for(size_t i = 0; i < static_cast(sources_count); ++i) { |
639
|
0 |
527 |
} |
642
|
0 |
0 |
assert(cu_die); |
652
|
0 |
0 |
assert(node->die); |
653
|
0 |
0 |
auto res = dwarf_tag(node->die, &tag, &error); |
654
|
0 |
0 |
if (res != DW_DLV_OK) { return Scan::dead_end; } |
656
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
|
0 |
0 |
if( tag == DW_TAG_subprogram || |
658
|
0 |
0 |
switch (node->contains(offset)) { |
660
|
0 |
0 |
lr.subprogram = node; |
667
|
0 |
0 |
else if(tag == DW_TAG_compile_unit) { |
669
|
0 |
0 |
switch (scan) { |
671
|
0 |
0 |
lr.cu = node; |
672
|
0 |
0 |
return lr.is_complete() ? Scan::found : Scan::not_found; |
684
|
0 |
0 |
if (!sources_count) { |
686
|
0 |
0 |
if (res != DW_DLV_OK) { sources_count = -1; } |
688
|
0 |
0 |
if (sources_count > 0 && index < static_cast(sources_count)) { |
|
0 |
0 |
if (sources_count > 0 && index < static_cast(sources_count)) { |
696
|
6 |
0 |
}}} |
|
6 |
0 |
}}} |