Пример #1
0
void StackAnalyzer::get_symbols(std::function<void (const backtrace_symbol *)> cb, bool reversed) const {
	info_cb_data_t info_cb_data;

	for (void *pc : this->stack_addrs) {
		info_cb_data.pc = reinterpret_cast<uintptr_t>(pc);

		// note: a call to backtrace_pcinfo may, in semi-rare cases, push back
		// multiple symbols to result. That's nothing to worry about, though.
		// If you decide you don't like it, make pcinfo_callback return 1.
		backtrace_pcinfo(
			bt_state,
			info_cb_data.pc,
			backtrace_pcinfo_callback,
			backtrace_pcinfo_error_callback,
			reinterpret_cast<void *>(&info_cb_data)
		);
	}

	if (reversed) {
		// this entire vector thing would only be needed for reversed=true...
		for (size_t idx = info_cb_data.symbols.size(); idx-- > 0;) {
			cb(&info_cb_data.symbols[idx]);
		}
	} else {
		for (backtrace_symbol &symbol : info_cb_data.symbols) {
			cb(&symbol);
		}
	}
}
Пример #2
0
static _Unwind_Reason_Code
unwind (struct _Unwind_Context *context, void *vdata)
{
  struct backtrace_data *bdata = (struct backtrace_data *) vdata;
  uintptr_t pc;
  int ip_before_insn = 0;

#ifdef HAVE_GETIPINFO
  pc = _Unwind_GetIPInfo (context, &ip_before_insn);
#else
  pc = _Unwind_GetIP (context);
#endif

  if (bdata->skip > 0)
    {
      --bdata->skip;
      return _URC_NO_REASON;
    }

  if (!ip_before_insn)
    --pc;

  if (!bdata->can_alloc)
    bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
  else
    bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
				   bdata->error_callback, bdata->data);
  if (bdata->ret != 0)
    return _URC_END_OF_STACK;

  return _URC_NO_REASON;
}