예제 #1
0
void get_callstack(size_t n, callstack *pbt) {
  pbt->alloc_size = n;
  pbt->count = 0;

  // static void *gHandle = NULL;
  // static unwindFn unwind_backtrace = NULL;
  // const char so_path[] = "/system/lib/libcorkscrew.so";

  // if(gHandle == NULL)
  //   gHandle = dlopen(so_path, RTLD_NOW);

  // if (gHandle != NULL && !unwind_backtrace)
  //   unwind_backtrace = (unwindFn)dlsym(gHandle, "unwind_backtrace");

  // if (unwind_backtrace == NULL)
  //   return;

  // backtrace_frame_t stacks[20];
  // int count = unwind_backtrace(stacks, 1, 20);
  // if (count <= 0)
  //   return;

  // for (int i = 0; i < size; ++i) {
  //   pbt->stacks[i] = stacks[i]; // stacks[i].absolute_pc;
  // }

  // pbt->count = size;
  _Unwind_Backtrace(unwind_callback, pbt);
}
예제 #2
0
int
__gnat_backtrace (void ** traceback, int max_len,
		  void * exclude_min, void * exclude_max,
		  int  skip_frames)
{
#if defined (__USING_SJLJ_EXCEPTIONS__)
  /* We have no unwind material (tables) at hand with sjlj eh, and no
     way to retrieve complete and accurate call chain information from
     the context stack we maintain.  */
  return 0;
#else
  uw_data_t uw_data;
  /* State carried over during the whole unwinding process.  */

  uw_data.traceback   = traceback;
  uw_data.max_len     = max_len;
  uw_data.exclude_min = exclude_min;
  uw_data.exclude_max = exclude_max;

  uw_data.n_frames_to_skip = skip_frames;

  uw_data.n_frames_skipped = 0;
  uw_data.n_entries_filled = 0;

  _Unwind_Backtrace ((_Unwind_Trace_Fn)trace_callback, &uw_data);

  return uw_data.n_entries_filled;
#endif
}
예제 #3
0
파일: CCRef.cpp 프로젝트: ourgames/dc208
size_t captureBacktrace(void** buffer, size_t max)
{
    test_debug::BacktraceState state = {buffer, buffer + max};
    _Unwind_Backtrace(test_debug::unwindCallback, &state);
    
    return state.current - buffer;
}
예제 #4
0
void
Util_BacktraceToBuffer(uintptr_t *basePtr,  // IN:
                       uintptr_t *buffer,   // IN:
                       int len)             // IN:
{
#if defined(UTIL_BACKTRACE_USE_UNWIND)
   struct UtilBacktraceToBufferData data;

   data.basePtr = (uintptr_t)basePtr;
   data.buffer = buffer;
   data.len = len;
   _Unwind_Backtrace(UtilBacktraceToBufferCallback, &data);
#elif !defined(VM_X86_64)
   uintptr_t *x = basePtr;
   int i;

   for (i = 0; i < 256 && i < len; i++) {
      if (x < basePtr ||
	  (uintptr_t) x - (uintptr_t) basePtr > 0x8000) {
         break;
      }
      buffer[i] = x[1];
      x = (uintptr_t *) x[0];
   }
#endif
}
void FAndroidPlatformStackWalk::CaptureStackBackTrace(uint64* BackTrace, uint32 MaxDepth, void* Context)
{
	// Make sure we have place to store the information
	if (BackTrace == NULL || MaxDepth == 0)
	{
		return;
	}

	// zero results
	FPlatformMemory::Memzero(BackTrace, MaxDepth*sizeof(uint64));
	
#if PLATFORM_ANDROID_ARM
	if (Context != nullptr)
	{
		// Android signal handlers always catch signals before user handlers and passes it down to user later
		// _Unwind_Backtrace does not use signal context and will produce wrong callstack in this case
		// We use code from libcorkscrew to unwind backtrace using actual signal context
		// Code taken from https://android.googlesource.com/platform/system/core/+/jb-dev/libcorkscrew/arch-arm/backtrace-arm.c
		unwind_backtrace_signal(Context, BackTrace, MaxDepth);
		return;
	}
#endif //PLATFORM_ANDROID_ARM
	
	AndroidStackWalkHelpers::BackTrace = BackTrace;
	AndroidStackWalkHelpers::MaxDepth = MaxDepth;
	uint32 Depth = 0;
	_Unwind_Backtrace(AndroidStackWalkHelpers::BacktraceCallback, &Depth);
}
예제 #6
0
/* Copy context infos (signal code, etc.) */
static void coffeecatch_copy_context(native_code_handler_struct *const t,
                                     const int code, siginfo_t *const si,
                                     void *const sc) {
  t->code = code;
  t->si = *si;
  if (sc != NULL) {
    ucontext_t *const uc = (ucontext_t*) sc;
    t->uc = *uc;
  } else {
    memset(&t->uc, 0, sizeof(t->uc));
  }

#ifdef USE_UNWIND
  /* Frame buffer initial position. */
  t->frames_size = 0;

  /* Skip us and the caller. */
  t->frames_skip = 2;

  /* Use the corkscrew library to extract the backtrace. */
#ifdef USE_CORKSCREW
  t->frames_size = coffeecatch_backtrace_signal(si, sc, t->frames, 0,
                                                BACKTRACE_FRAMES_MAX);
#else
  /* Unwind frames (equivalent to backtrace()) */
  _Unwind_Backtrace(coffeecatch_unwind_callback, t);
#endif

  if (t->frames_size != 0) {
    DEBUG(print("called _Unwind_Backtrace()\n"));
  } else {
    DEBUG(print("called _Unwind_Backtrace(), but no traces\n"));
  }
#endif
}
예제 #7
0
int
backtrace_full (struct backtrace_state *state, int skip,
		backtrace_full_callback callback,
		backtrace_error_callback error_callback, void *data)
{
  struct backtrace_data bdata;
  void *p;

  bdata.skip = skip + 1;
  bdata.state = state;
  bdata.callback = callback;
  bdata.error_callback = error_callback;
  bdata.data = data;
  bdata.ret = 0;

  /* If we can't allocate any memory at all, don't try to produce
     file/line information.  */
  p = backtrace_alloc (state, 4096, NULL, NULL);
  if (p == NULL)
    bdata.can_alloc = 0;
  else
    {
      backtrace_free (state, p, 4096, NULL, NULL);
      bdata.can_alloc = 1;
    }

  _Unwind_Backtrace (unwind, &bdata);
  return bdata.ret;
}
예제 #8
0
__LIBC_HIDDEN__ int get_backtrace(uintptr_t* frames, size_t max_depth) {
  ScopedDisableDebugCalls disable;

  stack_crawl_state_t state(frames, max_depth);
  _Unwind_Backtrace(trace_function, &state);
  return state.frame_count;
}
예제 #9
0
void test_backtrace() {
  int n = 0;
  _Unwind_Backtrace(&callback, &n);
  if (n < EXPECTED_NUM_FRAMES) {
    abort();
  }
}
예제 #10
0
int xbt_backtrace_no_malloc(void **array, int size) {

  int i = 0;
  for(i=0; i < size; i++)
    array[i] = NULL;

  struct trace_arg arg = { .array = array, .size = size, .cnt = -1 };

  if (size >= 1)
    _Unwind_Backtrace(backtrace_helper, &arg);

  /* _Unwind_Backtrace on IA-64 seems to put NULL address above
     _start.  Fix it up here.  */
  if (arg.cnt > 1 && arg.array[arg.cnt - 1] == NULL)
    --arg.cnt;
  return arg.cnt != -1 ? arg.cnt : 0;
}

void xbt_backtrace_current(xbt_ex_t * e)
{
  e->used = backtrace((void **) e->bt, XBT_BACKTRACE_SIZE);
  if (e->used == 0) {
    fprintf(stderr, "The backtrace() function failed, which probably means that the memory is exhausted. Here is a crude dump of the exception that I was trying to build:");
    fprintf(stderr, "%s(%d) [%s:%d] %s",
            e->procname, e->pid, e->file, e->line, e->msg);
    fprintf(stderr, "Bailing out now since there is nothing I can do without a decent amount of memory. Please go fix the memleaks\n");
    exit(1);
  }
}
예제 #11
0
void backtrace_startup() {
  ScopedDisableDebugCalls disable;

  g_map_data = MapData::Create();
  if (g_map_data) {
    _Unwind_Backtrace(find_current_map, nullptr);
  }
}
예제 #12
0
static inline
int get_backtrace(intptr_t* addrs, size_t max_entries)
{
    stack_crawl_state_t state;
    state.count = max_entries;
    state.addrs = (intptr_t*)addrs;
    _Unwind_Backtrace(trace_function, (void*)&state);
    return max_entries - state.count;
}
예제 #13
0
파일: backtrace.c 프로젝트: songhtdo/vespa
int
backtrace (void **array, int size)
{
    struct trace_context t;
    t.array = array;
    t.size = size;
    t.index = 0;
    _Unwind_Backtrace(trace_fn, &t);
    return t.index - 1;
}
예제 #14
0
int
main (void)
{
  /* Arrange for this test to be killed if _Unwind_Backtrace runs into an
     endless loop.  We cannot use the test driver because the complete
     call chain needs to be compiled with -funwind-tables so that
     _Unwind_Backtrace is able to reach _start.  */
  alarm (DEFAULT_TIMEOUT);
  _Unwind_Backtrace (callback, 0);
}
예제 #15
0
static
int backtrace(const void** addrs, size_t ignore, size_t size)
{
    stack_crawl_state_t state;
    state.count = size;
    state.ignore = ignore;
    state.addrs = addrs;
    _Unwind_Backtrace(trace_function, (void*)&state);
    return size - state.count;
}
예제 #16
0
int32
runtime_callers (int32 skip, uintptr *pcbuf, int32 m)
{
  struct callers_data arg;

  arg.skip = skip + 1;
  arg.pcbuf = pcbuf;
  arg.index = 0;
  arg.max = m;
  _Unwind_Backtrace (backtrace, &arg);
  return arg.index;
}
예제 #17
0
파일: backtrace.cpp 프로젝트: K-ballo/hpx
        HPX_API_EXPORT std::size_t trace(void **array,std::size_t n)
        {
            trace_data d(array,n);

            if (1 <= n)
                _Unwind_Backtrace(trace_callback, reinterpret_cast<void*>(&d));

            if ((1 < d.count_) && d.array_[d.count_ - 1])
                --d.count_;

            return (std::size_t(-1) != d.count_) ? d.count_ : 0;
        }
예제 #18
0
static tracy_force_inline void* Callstack( int depth )
{
    assert( depth >= 1 && depth < 63 );

    auto trace = (uintptr_t*)tracy_malloc( ( 1 + depth ) * sizeof( uintptr_t ) );
    BacktraceState state = { (void**)(trace+1), (void**)(trace+1+depth) };
    _Unwind_Backtrace( tracy_unwind_callback, &state );

    *trace = (uintptr_t*)state.current - trace + 1;

    return trace;
}
size_t
backtrace(void **arr, size_t len)
{
	struct tracer_context ctx;

	ctx.arr = arr;
	ctx.len = len;
	ctx.n = (size_t)~0;

	_Unwind_Backtrace(tracer, &ctx);
	if (ctx.n != (size_t)~0 && ctx.n > 0)
		ctx.arr[--ctx.n] = NULL;	/* Skip frame below __start */

	return ctx.n;
}
예제 #20
0
파일: simple.c 프로젝트: WojciechMigda/gcc
int
backtrace_simple (struct backtrace_state *state, int skip,
		  backtrace_simple_callback callback,
		  backtrace_error_callback error_callback, void *data)
{
  struct backtrace_simple_data bdata;

  bdata.skip = skip + 1;
  bdata.state = state;
  bdata.callback = callback;
  bdata.error_callback = error_callback;
  bdata.data = data;
  bdata.ret = 0;
  _Unwind_Backtrace (simple_unwind, &bdata);
  return bdata.ret;
}
void FAndroidPlatformStackWalk::CaptureStackBackTrace(uint64* BackTrace, uint32 MaxDepth, void* Context)
{
	// Make sure we have place to store the information
	if (BackTrace == NULL || MaxDepth == 0)
	{
		return;
	}

	// zero results
	FPlatformMemory::Memzero(BackTrace, MaxDepth*sizeof(uint64));

	// backtrace
	AndroidStackWalkHelpers::BackTrace = BackTrace;
	AndroidStackWalkHelpers::MaxDepth = MaxDepth;
	uint32 Depth = 0;
	_Unwind_Backtrace(AndroidStackWalkHelpers::BacktraceCallback, &Depth);
}
예제 #22
0
isc_result_t
isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
    trace_arg_t arg;

    /* Argument validation: see above. */
    if (addrs == NULL || nframes == NULL)
        return (ISC_R_FAILURE);

    arg.skip_count = 1;
    arg.result = addrs;
    arg.max_depth = maxaddrs;
    arg.count = 0;
    _Unwind_Backtrace(btcallback, &arg);

    *nframes = arg.count;

    return (ISC_R_SUCCESS);
}
예제 #23
0
int xbt_backtrace_no_malloc(void **array, int size) {
  int i = 0;
  for(i=0; i < size; i++)
    array[i] = nullptr;

  struct trace_arg arg;
  arg .array = array;
  arg.size = size;
  arg.cnt = -1;

  if (size >= 1)
    _Unwind_Backtrace(backtrace_helper, &arg);

  /* _Unwind_Backtrace on IA-64 seems to put nullptr address above
     _start.  Fix it up here.  */
  if (arg.cnt > 1 && arg.array[arg.cnt - 1] == nullptr)
    --arg.cnt;
  return arg.cnt != -1 ? arg.cnt : 0;
}
예제 #24
0
_Unwind_Reason_Code trace_fcn(_Unwind_Context *ctx, void *d)
{
	int *depth = (int*)d;
	uintptr_t pc = _Unwind_GetIP(ctx);
#ifdef CONFIG_ARCH_JUMP_ADDR_ODD
	if (pc == (((uintptr_t) &taskReturnFunction) - 1)) {
#else
	if (pc == ((uintptr_t) &taskReturnFunction)) {
#endif
		printf("\t#%d: End of Stack\n", *depth);
		return _URC_END_OF_STACK;
	}
	printf("\t#%d: program counter at 0x%x\n", *depth, pc);
	(*depth)++;
	return _URC_NO_REASON;
}
void backtrace() {
	int depth = 0;
	printf("Backtrace:\n");
	_Unwind_Backtrace(&trace_fcn, &depth);
}
예제 #25
0
int
__gnat_backtrace (void ** traceback, int max_len,
		  void * exclude_min, void * exclude_max,
		  int  skip_frames)
{
  uw_data_t uw_data;
  /* State carried over during the whole unwinding process.  */

  uw_data.traceback   = traceback;
  uw_data.max_len     = max_len;
  uw_data.exclude_min = exclude_min;
  uw_data.exclude_max = exclude_max;

  uw_data.n_frames_to_skip = skip_frames;

  uw_data.n_frames_skipped = 0;
  uw_data.n_entries_filled = 0;

  _Unwind_Backtrace ((_Unwind_Trace_Fn)trace_callback, &uw_data);

  return uw_data.n_entries_filled;
}
예제 #26
0
ssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth) {
    ALOGV("Unwinding current thread %d.", gettid());

    map_info_t* milist = acquire_my_map_info_list();

    backtrace_state_t state;
    state.backtrace = backtrace;
    state.ignore_depth = ignore_depth;
    state.max_depth = max_depth;
    state.ignored_frames = 0;
    state.returned_frames = 0;
    init_memory(&state.memory, milist);

    _Unwind_Reason_Code rc = _Unwind_Backtrace(unwind_backtrace_callback, &state);

    release_my_map_info_list(milist);

    if (state.returned_frames) {
        return state.returned_frames;
    }
    return rc == _URC_END_OF_STACK ? 0 : -1;
}
예제 #27
0
static void
gum_gcc_backtracer_generate (GumBacktracer * backtracer,
                             const GumCpuContext * cpu_context,
                             GumReturnAddressArray * return_addresses)
{
  GumGccBacktraceCtx btctx;

  btctx.return_addresses = return_addresses;
  if (cpu_context != NULL)
  {
#ifdef HAVE_I386
    btctx.start_address = GSIZE_TO_POINTER (GUM_CPU_CONTEXT_XSP (cpu_context));
#else
    btctx.start_address = GSIZE_TO_POINTER (cpu_context->sp);
#endif
  }
  else
  {
    btctx.start_address = ((gsize *) &return_addresses) + 1;
  }

  return_addresses->len = 0;
  _Unwind_Backtrace (gum_gcc_backtracer_append_address, &btctx);
}
예제 #28
0
void
Util_BacktraceFromPointerWithFunc(uintptr_t *basePtr,       // IN:
                                  Util_OutputFunc outFunc,  // IN:
                                  void *outFuncData)        // IN:
{
#if defined(UTIL_BACKTRACE_USE_UNWIND)
   struct UtilBacktraceFromPointerData data;

   data.basePtr = (uintptr_t)basePtr;
   data.outFunc = outFunc;
   data.outFuncData = outFuncData;
   data.frameNr = 0;
   data.skippedFrames = 0;
   _Unwind_Backtrace(UtilBacktraceFromPointerCallback, &data);

#if !defined(_WIN32) && !defined(VMX86_TOOLS)
   /*
    * We do a separate pass here that includes symbols in order to
    * make sure the base backtrace that does not call dladdr() etc.
    * is safely produced.
    */
   data.basePtr = (uintptr_t)basePtr;
   data.outFunc = outFunc;
   data.outFuncData = outFuncData;
   data.frameNr = 0;
   data.skippedFrames = 0;
   _Unwind_Backtrace(UtilSymbolBacktraceFromPointerCallback, &data);
#endif

#elif !defined(VM_X86_64)
   uintptr_t *x = basePtr;
   int i;
#if !defined(_WIN32) && !defined(VMX86_TOOLS) && !defined(__ANDROID__)
   Dl_info dli;
#endif

   for (i = 0; i < 256; i++) {
      if (x < basePtr ||
	  (uintptr_t) x - (uintptr_t) basePtr > 0x8000) {
         break;
      }
      outFunc(outFuncData, "Backtrace[%d] %#08x eip %#08x \n", i, x[0], x[1]);
      x = (uintptr_t *) x[0];
   }

#if !defined(_WIN32) && !defined(VMX86_TOOLS) && !defined(__ANDROID__)
   /*
    * We do a separate pass here that includes symbols in order to
    * make sure the base backtrace that does not call dladdr() etc.
    * is safely produced.
    */
   x = basePtr;
   for (i = 0; i < 256; i++) {
      if (x < basePtr ||
	  (uintptr_t) x - (uintptr_t) basePtr > 0x8000) {
         break;
      }
      if (dladdr((uintptr_t *)x[1], &dli)) {
         outFunc(outFuncData, "SymBacktrace[%d] %#08x eip %#08x in function %s "
                              "in object %s loaded at %#08x\n",
                               i, x[0], x[1], dli.dli_sname, dli.dli_fname,
                                dli.dli_fbase);
      } else {
         outFunc(outFuncData, "SymBacktrace[%d] %#08x eip %#08x \n", i, x[0], x[1]);
      }
      x = (uintptr_t *) x[0];
   }
#endif
#endif
}
예제 #29
0
void thumb_function_2(int*p)
{
    int a = 0;
    printf("unwinding...\n");
    _Unwind_Backtrace(trace_function, (void*)"backtrace!");
}
예제 #30
0
void assertStackDump(void)
{
	printf("\nStack dump:\n");
	int depth = 0;
	_Unwind_Backtrace(unwind_cb, &depth);
}