bool BacktraceOffline::FindProcInfo(unw_addr_space_t addr_space, uint64_t ip, unw_proc_info_t* proc_info, int need_unwind_info) { backtrace_map_t map; FillInMap(ip, &map); if (!BacktraceMap::IsValid(map)) { return false; } const std::string& filename = map.name; DebugFrameInfo* debug_frame = GetDebugFrameInFile(filename); if (debug_frame == nullptr) { return false; } if (debug_frame->is_eh_frame) { uint64_t ip_offset = ip - map.start + map.offset; uint64_t ip_vaddr; // vaddr in the elf file. bool result = FileOffsetToVaddr(debug_frame->eh_frame.program_headers, ip_offset, &ip_vaddr); if (!result) { return false; } // Calculate the addresses where .eh_frame_hdr and .eh_frame stay when the process was running. eh_frame_hdr_space_.start = (ip - ip_vaddr) + debug_frame->eh_frame.eh_frame_hdr_vaddr; eh_frame_hdr_space_.end = eh_frame_hdr_space_.start + debug_frame->eh_frame.eh_frame_hdr_data.size(); eh_frame_hdr_space_.data = debug_frame->eh_frame.eh_frame_hdr_data.data(); eh_frame_space_.start = (ip - ip_vaddr) + debug_frame->eh_frame.eh_frame_vaddr; eh_frame_space_.end = eh_frame_space_.start + debug_frame->eh_frame.eh_frame_data.size(); eh_frame_space_.data = debug_frame->eh_frame.eh_frame_data.data(); unw_dyn_info di; memset(&di, '\0', sizeof(di)); di.start_ip = map.start; di.end_ip = map.end; di.format = UNW_INFO_FORMAT_REMOTE_TABLE; di.u.rti.name_ptr = 0; di.u.rti.segbase = eh_frame_hdr_space_.start; di.u.rti.table_data = eh_frame_hdr_space_.start + debug_frame->eh_frame.fde_table_offset_in_eh_frame_hdr; di.u.rti.table_len = (eh_frame_hdr_space_.end - di.u.rti.table_data) / sizeof(unw_word_t); int ret = dwarf_search_unwind_table(addr_space, ip, &di, proc_info, need_unwind_info, this); return ret == 0; } eh_frame_hdr_space_.Clear(); eh_frame_space_.Clear(); unw_dyn_info_t di; unw_word_t segbase = map.start - map.offset; int found = dwarf_find_debug_frame(0, &di, ip, segbase, filename.c_str(), map.start, map.end); if (found == 1) { int ret = dwarf_search_unwind_table(addr_space, ip, &di, proc_info, need_unwind_info, this); return ret == 0; } return false; }
int main(void) { dwarf_find_debug_frame(0, NULL, 0, 0, NULL, 0, 0); return 0; }