Ejemplo n.º 1
0
static int
remote_find_proc_info (unw_addr_space_t as, unw_word_t ip, unw_proc_info_t *pi,
                       int need_unwind_info, void *arg)
{
  Debug (3, "called, as %p, ip 0x%llx, need_unwind_info %d\n", as, (long long) ip, need_unwind_info);

  unw_fuchsia_info_t* cxt = arg;
  int ret;

  ret = get_unwind_info (cxt, as, ip);
  if (ret < 0)
  {
    Debug (3, "get_unwind_info failed: %d\n", ret);
    return -UNW_ENOINFO;
  }

  ret = -UNW_ENOINFO;
  if (ret == -UNW_ENOINFO && cxt->edi.di_cache.format != -1)
    ret = dwarf_search_unwind_table (as, ip, &cxt->edi.di_cache, pi,
                                     need_unwind_info, arg);
  if (ret == -UNW_ENOINFO && cxt->edi.di_debug.format != -1)
    ret = dwarf_search_unwind_table (as, ip, &cxt->edi.di_debug, pi,
                                     need_unwind_info, arg);

  Debug (3, "returning %d\n", ret);
  return ret;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
int main(void)
{
	unw_addr_space_t addr_space;

	addr_space = unw_create_addr_space(&accessors, 0);
	if (addr_space)
		return 0;

	unw_init_remote(NULL, addr_space, NULL);
	dwarf_search_unwind_table(addr_space, 0, NULL, NULL, 0, NULL);

	return 0;
}