Пример #1
0
/*
 * ut_dump_backtrace -- dump stacktrace to error log using libunwind
 */
void
ut_dump_backtrace(void)
{
	unw_context_t context;
	unw_proc_info_t pip;

	pip.unwind_info = NULL;
	int ret = unw_getcontext(&context);
	if (ret) {
		ERR("unw_getcontext: %s [%d]", unw_strerror(ret), ret);
		return;
	}

	unw_cursor_t cursor;
	ret = unw_init_local(&cursor, &context);
	if (ret) {
		ERR("unw_init_local: %s [%d]", unw_strerror(ret), ret);
		return;
	}

	ret = unw_step(&cursor);

	char procname[PROCNAMELEN];
	unsigned i = 0;

	while (ret > 0) {
		ret = unw_get_proc_info(&cursor, &pip);
		if (ret) {
			ERR("unw_get_proc_info: %s [%d]", unw_strerror(ret),
					ret);
			break;
		}

		unw_word_t off;
		ret = unw_get_proc_name(&cursor, procname, PROCNAMELEN, &off);
		if (ret && ret != -UNW_ENOMEM) {
			if (ret != -UNW_EUNSPEC) {
				ERR("unw_get_proc_name: %s [%d]",
					unw_strerror(ret), ret);
			}

			strcpy(procname, "?");
		}

		void *ptr = (void *)(pip.start_ip + off);
		Dl_info dlinfo;
		const char *fname = "?";

		if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname &&
				*dlinfo.dli_fname)
			fname = dlinfo.dli_fname;

		ERR("%u: %s (%s%s+0x%lx) [%p]", i++, fname, procname,
				ret == -UNW_ENOMEM ? "..." : "", off, ptr);

		ret = unw_step(&cursor);
		if (ret < 0)
			ERR("unw_step: %s [%d]", unw_strerror(ret), ret);
	}
}
Пример #2
0
vector<long> StackUnwind::fullUnwind() {

#ifdef MAKE_DYNA
	return dynaUnwind();
#endif

	unw_getcontext(&uc);
	unw_init_local(&cursor, &uc);

	vector<long> call_stack;

	/* Need to step twice to remove mention of WMTrace from the call stack */
	if (unw_step(&cursor) <= 0)
		return call_stack;
	if (unw_step(&cursor) <= 0)
		return call_stack;

	int counter = 0;
	while (unw_step(&cursor) > 0 && counter < unw_max_depth) {
		unw_get_reg(&cursor, UNW_REG_IP, &ip);
		call_stack.push_back((long) ip);
		counter++;
	}

	return call_stack;
}
Пример #3
0
int xbt_libunwind_backtrace(void** bt, int size){
  int i = 0;
  for(i=0; i < size; i++)
    bt[i] = nullptr;

  i=0;

  unw_cursor_t c;
  unw_context_t uc;

  unw_getcontext (&uc);
  unw_init_local (&c, &uc);

  unw_word_t ip;

  unw_step(&c);

  while(unw_step(&c) >= 0 && i < size){
    unw_get_reg(&c, UNW_REG_IP, &ip);
    bt[i] = (void*)(long)ip;
    i++;
  }

  return i;
}
Пример #4
0
int
backtrace(void **trace, int size)
{
    unw_cursor_t cursor; unw_context_t uc;
    unw_word_t ip;
    int n = 0;

    unw_getcontext(&uc);
    unw_init_local(&cursor, &uc);
    while (unw_step(&cursor) > 0) {
	unw_get_reg(&cursor, UNW_REG_IP, &ip);
	trace[n++] = (void *)ip;
	{
	    char buf[256];
	    unw_get_proc_name(&cursor, buf, 256, &ip);
	    if (strncmp("_sigtramp", buf, sizeof("_sigtramp")) == 0) {
		goto darwin_sigtramp;
	    }
	}
    }
    return n;
darwin_sigtramp:
    /* darwin's bundled libunwind doesn't support signal trampoline */
    {
	ucontext_t *uctx;
	/* get _sigtramp's ucontext_t and set values to cursor
	 * http://www.opensource.apple.com/source/Libc/Libc-825.25/i386/sys/_sigtramp.s
	 * http://www.opensource.apple.com/source/libunwind/libunwind-35.1/src/unw_getcontext.s
	 */
	unw_get_reg(&cursor, UNW_X86_64_RBX, &ip);
	uctx = (ucontext_t *)ip;
	unw_set_reg(&cursor, UNW_X86_64_RAX, uctx->uc_mcontext->__ss.__rax);
	unw_set_reg(&cursor, UNW_X86_64_RBX, uctx->uc_mcontext->__ss.__rbx);
	unw_set_reg(&cursor, UNW_X86_64_RCX, uctx->uc_mcontext->__ss.__rcx);
	unw_set_reg(&cursor, UNW_X86_64_RDX, uctx->uc_mcontext->__ss.__rdx);
	unw_set_reg(&cursor, UNW_X86_64_RDI, uctx->uc_mcontext->__ss.__rdi);
	unw_set_reg(&cursor, UNW_X86_64_RSI, uctx->uc_mcontext->__ss.__rsi);
	unw_set_reg(&cursor, UNW_X86_64_RBP, uctx->uc_mcontext->__ss.__rbp);
	unw_set_reg(&cursor, UNW_X86_64_RSP, 8+(uctx->uc_mcontext->__ss.__rsp));
	unw_set_reg(&cursor, UNW_X86_64_R8,  uctx->uc_mcontext->__ss.__r8);
	unw_set_reg(&cursor, UNW_X86_64_R9,  uctx->uc_mcontext->__ss.__r9);
	unw_set_reg(&cursor, UNW_X86_64_R10, uctx->uc_mcontext->__ss.__r10);
	unw_set_reg(&cursor, UNW_X86_64_R11, uctx->uc_mcontext->__ss.__r11);
	unw_set_reg(&cursor, UNW_X86_64_R12, uctx->uc_mcontext->__ss.__r12);
	unw_set_reg(&cursor, UNW_X86_64_R13, uctx->uc_mcontext->__ss.__r13);
	unw_set_reg(&cursor, UNW_X86_64_R14, uctx->uc_mcontext->__ss.__r14);
	unw_set_reg(&cursor, UNW_X86_64_R15, uctx->uc_mcontext->__ss.__r15);
	ip = *(unw_word_t*)uctx->uc_mcontext->__ss.__rsp;
	unw_set_reg(&cursor, UNW_REG_IP, ip);
	trace[n++] = (void *)uctx->uc_mcontext->__ss.__rip;
	trace[n++] = (void *)ip;
    }
    while (unw_step(&cursor) > 0) {
	unw_get_reg(&cursor, UNW_REG_IP, &ip);
	trace[n++] = (void *)ip;
    }
    return n;
}
Пример #5
0
void
fill_in_backtrace(FaultData* fdp)
{
    unw_context_t uc;
    unw_cursor_t c;
    int i, boff;

    memset(&uc, 0, sizeof(uc));
    memset(&c, 0, sizeof(c));
    if (unw_getcontext(&uc) < 0) {
        abort();
    }

    if (unw_init_local(&c, &uc) < 0) {
        abort();
    }

    // Skip the signal handler, and the signal trampoline
    for (i = 0; i < SKIP_FRAME_COUNT; i++) {
        if (unw_step(&c) <= 0) {
            break;
        }
    }

    memset(fdp->frame, 0, sizeof(fdp->frame));
    fdp->frame_count = 0;
    boff = 0;

    do {
        char fn[256];
        unw_word_t off, ip;
        Dl_info dli;
        unw_proc_info_t pi;

        unw_get_reg (&c, UNW_REG_IP, &ip);
        fdp->frame[fdp->frame_count].addr = (uintptr_t) ip;
        fdp->frame[fdp->frame_count].procname = (uintptr_t) &fdp->backtrace_buf[boff];
        unw_get_proc_name(&c, (char *) fdp->frame[fdp->frame_count].procname, sizeof(fdp->backtrace_buf) - boff, &off);
        unw_get_proc_info(&c, &pi);
        boff += strlen((char *) fdp->frame[fdp->frame_count].procname) + 1;
        fdp->frame[fdp->frame_count].libname = (uintptr_t) &fdp->backtrace_buf[boff];
        dladdr((void *)(uintptr_t) ip, &dli);
        strcpy((char *) (uintptr_t) fdp->frame[fdp->frame_count].libname, dli.dli_fname);
        boff += strlen((char *) fdp->frame[fdp->frame_count].libname) + 1;
        fdp->frame_count++;

    } while (unw_step(&c) > 0);
}
Пример #6
0
ssize_t getStackTraceSafe(uintptr_t* addresses, size_t maxAddresses) {
  if (maxAddresses == 0) {
    return 0;
  }
  unw_context_t context;
  if (unw_getcontext(&context) < 0) {
    return -1;
  }
  unw_cursor_t cursor;
  if (unw_init_local(&cursor, &context) < 0) {
    return -1;
  }
  if (!getFrameInfo(&cursor, *addresses)) {
    return -1;
  }
  ++addresses;
  size_t count = 1;
  for (; count != maxAddresses; ++count, ++addresses) {
    int r = unw_step(&cursor);
    if (r < 0) {
      return -1;
    }
    if (r == 0) {
      break;
    }
    if (!getFrameInfo(&cursor, *addresses)) {
      return -1;
    }
  }
  return count;
}
Пример #7
0
void dumpStack(FILE* file, unw_cursor_t cursor)
{
  int nframe = 0;
  char buffer[100];

  unw_word_t off;
  do {
    const char * name = !unw_get_proc_name(&cursor, buffer, 100, &off) ? buffer : "?";

    int status;

    // Unmangle C++ names:
    char* realname = abi::__cxa_demangle(name, 0, 0, &status);

#if defined(__x86_64__)
    unw_word_t rip = 0;
    unw_word_t rsp = 0;
    unw_get_reg(&cursor, UNW_X86_64_RIP, &rip);
    unw_get_reg(&cursor, UNW_X86_64_RSP, &rsp);
    fprintf(file, "  %i: %s (RIP=0x%" PRIx64 " RSP=0x%" PRIx64 ")\n",
      nframe, realname ? realname : name, (std::uint64_t) rip, (std::uint64_t) rsp);
#else
    fprintf(file, "  %i: %s\n", nframe, realname ? realname : name);
#endif

    free(realname);
    ++nframe;
  } while(unw_step(&cursor));
}
Пример #8
0
void backtrace() {
  unw_cursor_t cursor;
  unw_context_t context;

  // Initialize cursor to current frame for local unwinding.
  unw_getcontext(&context);
  unw_init_local(&cursor, &context);

  // Unwind frames one by one, going up the frame stack.
  while (unw_step(&cursor) > 0) {
    unw_word_t offset, pc;
    unw_get_reg(&cursor, UNW_REG_IP, &pc);
    if (pc == 0) {
      break;
    }
    printf("0x%lx:", pc);

    char sym[256];
    if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
      char* nameptr = sym;
      int status;
      char* demangled = abi::__cxa_demangle(sym, nullptr, nullptr, &status);
      if (status == 0) {
        nameptr = demangled;
      }
	char file[256];
	int line = 0;
	getFileAndLine((long)pc, file, 256, &line);
      printf(" (%s+0x%lx) in %s:%d\n", nameptr, offset, file, line);
      free(demangled);
    } else {
      printf(" -- error: unable to obtain symbol name for this frame\n");
    }
  }
}
Пример #9
0
static void
print_trace (void)
{
#ifdef HAVE_LIBUNWIND
  unw_context_t uc;
  unw_cursor_t cursor;
  guint stack_num = 0;

  if (!display_filter (DISPLAY_FLAG_BACKTRACE))
    return;

  unw_getcontext (&uc);
  unw_init_local (&cursor, &uc);

  while (unw_step (&cursor) > 0)
    {
      gchar name[129];
      unw_word_t off;
      int result;

      result = unw_get_proc_name (&cursor, name, sizeof (name) - 1, &off);
      if (result < 0 && result != UNW_ENOMEM)
        {
          g_print ("Error getting proc name\n");
          break;
        }

      g_print ("#%d  %s + [0x%08x]\n", stack_num++, name, (unsigned int)off);
    }
}
Пример #10
0
int getCurrentStackTrace(size_t skip, StackTrace* trace) {
  trace->frameIPs = NULL;
  trace->frameCount = 0;

  struct Context ctx;
  ctx.trace = trace;
  ctx.skip = skip;
  ctx.capacity = 0;

  unw_context_t uctx;
  int r = unw_getcontext(&uctx);
  int err = checkError("unw_get_context", r);
  if (err) return err;

  unw_cursor_t cursor;
  r = unw_init_local(&cursor, &uctx);
  err = checkError("unw_init_local", r);
  if (err) return err;

  while ((r = unw_step(&cursor)) > 0) {
    if ((err = addIP(&ctx, &cursor)) != 0) {
      destroyStackTrace(trace);
      return err;
    }
  }
  err = checkError("unw_step", r);
  if (err) return err;

  return 0;
}
Пример #11
0
        static void handler(int sig) {
            unw_context_t context;
            unw_getcontext(&context);

            unw_cursor_t cursor;
            unw_init_local(&cursor, &context);

            SkDebugf("\nSignal %d:\n", sig);
            while (unw_step(&cursor) > 0) {
                static const size_t kMax = 256;
                char mangled[kMax], demangled[kMax];
                unw_word_t offset;
                unw_get_proc_name(&cursor, mangled, kMax, &offset);

                int ok;
                size_t len = kMax;
                abi::__cxa_demangle(mangled, demangled, &len, &ok);

                SkDebugf("%s (+0x%zx)\n", ok == 0 ? demangled : mangled, (size_t)offset);
            }
            SkDebugf("\n");

            // Exit NOW.  Don't notify other threads, don't call anything registered with atexit().
            _Exit(sig);
        }
Пример #12
0
static int vmprof_unw_step(unw_cursor_t *cp, int first_run) {
	void* ip;
    void* sp;
    ptrdiff_t sp_offset;
    unw_get_reg (cp, UNW_REG_IP, (unw_word_t*)&ip);
    unw_get_reg (cp, UNW_REG_SP, (unw_word_t*)&sp);
	if (!first_run)
		// make sure we're pointing to the CALL and not to the first
		// instruction after. If the callee adjusts the stack for us
		// it's not safe to be at the instruction after
		ip -= 1;
    sp_offset = vmprof_unw_get_custom_offset(ip, cp);

    if (sp_offset == -1) {
        // it means that the ip is NOT in JITted code, so we can use the
        // stardard unw_step
        return unw_step(cp);
    }
    else {
        // this is a horrible hack to manually walk the stack frame, by
        // setting the IP and SP in the cursor
        vmprof_hacked_unw_cursor_t *cp2 = (vmprof_hacked_unw_cursor_t*)cp;
        void* bp = (void*)sp + sp_offset;
        cp2->sp = bp;
		bp -= sizeof(void*);
        cp2->ip = ((void**)bp)[0];
        // the ret is on the top of the stack minus WORD
        return 1;
    }
}
Пример #13
0
UINT64 Extrae_get_caller (int offset)
{
	int current_deep = 0;
	unw_cursor_t cursor;
	unw_context_t uc;
	unw_word_t ip;

	if (unw_getcontext(&uc) < 0)
		return 0;

	if (unw_init_local(&cursor, &uc))
		return 0;

	offset --; /* Don't compute call to unw_getcontext */
	while (current_deep <= offset)
	{
		if (unw_get_reg(&cursor, UNW_REG_IP, &ip) < 0)
			break;

#if defined(DEBUG)
		fprintf (stderr, "DEBUG: offset %d depth %d address %08llx %c\n", offset, current_deep, ip, (offset == current_deep)?'*':' ');
#endif
		if (unw_step (&cursor) <= 0)
			return 0;
		current_deep ++;
	}
	return (UINT64) ip;
}
Пример #14
0
static void _adjust_stack_pre_safepoint(hlt_execution_context* ctx)
{
    // Climb up the stack and adjust the reference counts for live objects
    // referenced there so that it reflects reality.

    unw_cursor_t cursor;
    unw_context_t uc;
    unw_word_t ip, sp;

    unw_getcontext(&uc);
    unw_init_local(&cursor, &uc);

    int level = 0;

    while ( unw_step(&cursor) > 0 ) {
        unw_get_reg(&cursor, UNW_REG_IP, &ip);
        unw_get_reg(&cursor, UNW_REG_SP, &sp);
        printf("level = %d ip = %lx, sp = %lx\n", level, (long)ip, (long)sp);
        level++;
    }

#ifdef DEBUG
// DBG_LOG("hilti-mem", "%10s stack-adjust-ctor %p %d %s::%s = %s", obj, level, func, id, render);
#endif
}
Пример #15
0
void VSDebugLib::printStack() {

  unw_cursor_t cursor; 
  unw_context_t uc;
  unw_word_t ip, sp, off;
  unw_proc_info_t pi;
  char file[256], name[256];
  int line;
  int status;

  unw_getcontext(&uc);
  unw_init_local(&cursor, &uc);
  while (unw_step(&cursor) > 0) {
    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);

    unw_get_proc_name (&cursor, name, sizeof (name), &off);
    getFileAndLine((long)ip, file, 256, &line);

    if (line >= 0) {
      char *realname;
      realname = abi::__cxa_demangle(name, 0, 0, &status);
      
      if (realname) {
	printf("%s: %s, %d\n", realname, file, line);
	free(realname);
      } else {
	printf("%s: %s, %d\n", name, file, line);
      }
    }
  }
}
Пример #16
0
static ALWAYS_INLINE int
slow_backtrace (void **buffer, int size, unw_context_t *uc, int skip)
{
  unw_cursor_t cursor;
  unw_word_t ip;
  int n = 0;

  if (unlikely (unw_init_local (&cursor, uc) < 0))
    return 0;

  while (unw_step (&cursor) > 0)
    {
      if (n >= size)
	return n;

      if (unw_get_reg (&cursor, UNW_REG_IP, &ip) < 0)
	return n;

      if (skip > 0)
        skip--;
      else
        buffer[n++] = (void *) (uintptr_t) ip;
    }
  return n;
}
Пример #17
0
int dwarf_backtrace(CallStack **returnStack) {
  *returnStack = calloc(1, sizeof(CallStack));

  CallStack *callStack = *returnStack;
  callStack->stack = calloc(INITIAL_LIVE_FUNCTION_SIZE, sizeof(LiveFunction));
  callStack->count = 0;
  callStack->capacity = INITIAL_LIVE_FUNCTION_SIZE;

  unw_cursor_t cursor;

  unw_context_t uc;
  unw_word_t ip, sp;

  unw_getcontext(&uc);
  unw_init_local(&cursor, &uc);
  while (unw_step(&cursor) > 0) {
    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);

    if (callStack->count >= callStack->capacity) {
      callStack->capacity *= 2;
      callStack->stack = realloc(callStack->stack,
                                 callStack->capacity * sizeof(LiveFunction *));
    }
    callStack->stack[callStack->count].cursor = cursor;
    callStack->stack[callStack->count].pc = (void *)ip;
    callStack->stack[callStack->count].sp = (void *)sp;
    printf("%p => %p\n", (void *)ip, (void *)sp);
    callStack->count++;
  }

  return callStack->count;
}
Пример #18
0
void fakegc()
{
  std::cout << "GC\n";
  unw_cursor_t cursor;
  unw_word_t ip, sp;
  unw_context_t uc;
  root_info_t root_info_ptr;

  unw_getcontext(&uc);
  unw_init_local(&cursor, &uc);

  do
    {
      unw_get_reg(&cursor, UNW_REG_IP, &ip);
      unw_get_reg(&cursor, UNW_REG_SP, &sp);
      // printf("ip=%p sp=%p\n", ip, sp);

      if (stk_map.find_root_info((void*)ip, root_info_ptr))
        {
          for(auto it : root_info_ptr)
            {
              int *cptr = *((int**)sp - it);
              printf("x=%p\n", cptr);
              printf("i=%d\n", *cptr);
              *cptr = *cptr + 1;
            }
        }
    } while (unw_step(&cursor) > 0);
}
Пример #19
0
void              _dump_crash_report(unsigne pid)
// shortened code from android's debuggerd
// to get a backtrace on ARM
{
    unw_addr_space_t as;
    struct UPT_info *ui;
    unw_cursor_t     cursor;

    as = unw_create_addr_space(&_UPT_accessors, 0);
    ui = _UPT_create(pid);

    int ret = unw_init_remote(&cursor, as, ui);
    if (ret < 0) {
        PRINTF("WARNING: unw_init_remote() failed [pid %i]\n", pid);
        _UPT_destroy(ui);
        return;
    }

    PRINTF("DEBUG: backtrace of the remote process (pid %d) using libunwind-ptrace:\n", pid);

    do {
        unw_word_t ip, sp, offp;
        char buf[512];

        unw_get_reg(&cursor, UNW_REG_IP, &ip);
        unw_get_reg(&cursor, UNW_REG_SP, &sp);
        unw_get_proc_name(&cursor, buf, sizeof (buf), &offp);

        PRINTF("DEBUG:   ip: %10p, sp: %10p   %s\n", (void*) ip, (void*) sp, buf);

    } while ((ret = unw_step (&cursor)) > 0);

    _UPT_destroy (ui);
}
Пример #20
0
static void findRealErrorOnStack (ShockerScriptableControlObject* obj) {
	unw_context_t uc;
	unw_cursor_t cursor, prev;
	unw_word_t bp;

	unw_getcontext(&uc);
	unw_init_local(&cursor, &uc);

	char framename [1024];
	int count = 0;

	while (unw_step(&cursor) > 0 && count < 18) {
		count++;
		unw_get_proc_name (&cursor, framename, sizeof(framename), 0);
		if (!*framename)
			continue;
		if (strstr (framename, "js_ReportErrorAgain")) {
#if (__i386__)
			unw_get_reg(&prev, UNW_X86_EBP, &bp);
#elif (__amd64__)
			unw_get_reg(&prev, UNW_X86_64_RBP, &bp);
#endif
			bp += 12;
			char ** n = (char**)bp;
			obj->GetLogProvider ()->LogError (*n);
			break;
		}
		prev = cursor;
	}
}
Пример #21
0
void collectStackRoots(TraceStack *stack) {
    unw_cursor_t cursor;
    unw_context_t uc;
    unw_word_t ip, sp, bp;

    // force callee-save registers onto the stack:
    // Actually, I feel like this is pretty brittle:
    // collectStackRoots itself is allowed to save the callee-save registers
    // on its own stack.
    jmp_buf registers __attribute__((aligned(sizeof(void*))));
#ifdef VALGRIND
    memset(&registers, 0, sizeof(registers));
    memset(&cursor, 0, sizeof(cursor));
    memset(&uc, 0, sizeof(uc));
    memset(&ip, 0, sizeof(ip));
    memset(&sp, 0, sizeof(sp));
    memset(&bp, 0, sizeof(bp));
#endif
    setjmp(registers);

    assert(sizeof(registers) % 8 == 0);
    //void* stack_bottom = __builtin_frame_address(0);
    collectRoots(&registers, &registers + 1, stack);

    unw_getcontext(&uc);
    unw_init_local(&cursor, &uc);

    TraceStackGCVisitor visitor(stack);

    int code;
    while (true) {
        int code = unw_step(&cursor);
        assert(code > 0 && "something broke unwinding!");

        unw_get_reg(&cursor, UNW_REG_IP, &ip);
        unw_get_reg(&cursor, UNW_REG_SP, &sp);
        unw_get_reg(&cursor, UNW_TDEP_BP, &bp);

        void* cur_sp = (void*)sp;
        void* cur_bp = (void*)bp;

        //std::string name = g.func_addr_registry.getFuncNameAtAddress((void*)ip, true);
        //if (VERBOSITY()) printf("ip = %lx (%s), stack = [%p, %p)\n", (long) ip, name.c_str(), cur_sp, cur_bp);

        unw_proc_info_t pip;
        unw_get_proc_info(&cursor, &pip);

        if (pip.start_ip == (uintptr_t)&__libc_start_main) {
            break;
        }

        if (pip.start_ip == (intptr_t)interpretFunction) {
            // TODO Do we still need to crawl the interpreter itself?
            gatherInterpreterRootsForFrame(&visitor, cur_bp);
        }

        collectRoots(cur_sp, (char*)cur_bp, stack);
    }
}
Пример #22
0
static void
throw_exception (MonoObject *exc, guint64 rethrow)
{
	unw_context_t unw_ctx;
	MonoContext ctx;
	MonoJitInfo *ji;
	unw_word_t ip, sp;
	int res;

	if (mono_object_isinst (exc, mono_defaults.exception_class)) {
		MonoException *mono_ex = (MonoException*)exc;
		if (!rethrow) {
			mono_ex->stack_trace = NULL;
			mono_ex->trace_ips = NULL;
		}
	}

	res = unw_getcontext (&unw_ctx);
	g_assert (res == 0);
	res = unw_init_local (&ctx.cursor, &unw_ctx);
	g_assert (res == 0);

	/* 
	 * Unwind until the first managed frame. This is needed since 
	 * mono_handle_exception expects the variables in the original context to
	 * correspond to the method returned by mono_find_jit_info.
	 */
	while (TRUE) {
		res = unw_get_reg (&ctx.cursor, UNW_IA64_IP, &ip);
		g_assert (res == 0);

		res = unw_get_reg (&ctx.cursor, UNW_IA64_SP, &sp);
		g_assert (res == 0);

		ji = mini_jit_info_table_find (mono_domain_get (), (gpointer)ip, NULL);

		//printf ("UN: %s %lx %lx\n", ji ? jinfo_get_method (ji)->name : "", ip, sp);

		if (ji)
			break;

		res = unw_step (&ctx.cursor);

		if (res == 0) {
			/*
			 * This means an unhandled exception during the compilation of a
			 * topmost method like Main
			 */
			break;
		}
		g_assert (res >= 0);
	}
	ctx.precise_ip = FALSE;

	mono_handle_exception (&ctx, exc);
	restore_context (&ctx);

	g_assert_not_reached ();
}
Пример #23
0
__SHIM__CALLER __SHIM__get_caller()
{
	unw_cursor_t cursor;
	unw_word_t sp;
	unw_word_t ip;
	unw_context_t uc;

	unw_getcontext(&uc);
	unw_init_local(&cursor, &uc);
	if((unw_step(&cursor) > 0) && (unw_step(&cursor) > 0)) {
		unw_get_reg(&cursor, UNW_REG_IP, &ip);
		return ip - CALLER0;
	} else {
		perror("caller");
		exit(1);
	}
}
Пример #24
0
bool UnwindCurrent::UnwindFromContext(size_t num_ignore_frames, bool resolve) {
  // The cursor structure is pretty large, do not put it on the stack.
  unw_cursor_t* cursor = new unw_cursor_t;
  int ret = unw_init_local(cursor, &context_);
  if (ret < 0) {
    BACK_LOGW("unw_init_local failed %d", ret);
    delete cursor;
    return false;
  }

  std::vector<backtrace_frame_data_t>* frames = GetFrames();
  frames->reserve(MAX_BACKTRACE_FRAMES);
  size_t num_frames = 0;
  do {
    unw_word_t pc;
    ret = unw_get_reg(cursor, UNW_REG_IP, &pc);
    if (ret < 0) {
      BACK_LOGW("Failed to read IP %d", ret);
      break;
    }
    unw_word_t sp;
    ret = unw_get_reg(cursor, UNW_REG_SP, &sp);
    if (ret < 0) {
      BACK_LOGW("Failed to read SP %d", ret);
      break;
    }

    if (num_ignore_frames == 0) {
      frames->resize(num_frames+1);
      backtrace_frame_data_t* frame = &frames->at(num_frames);
      frame->num = num_frames;
      frame->pc = static_cast<uintptr_t>(pc);
      frame->sp = static_cast<uintptr_t>(sp);
      frame->stack_size = 0;

      if (num_frames > 0) {
        // Set the stack size for the previous frame.
        backtrace_frame_data_t* prev = &frames->at(num_frames-1);
        prev->stack_size = frame->sp - prev->sp;
      }

      if (resolve) {
        frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
        frame->map = FindMap(frame->pc);
      } else {
        frame->map = NULL;
        frame->func_offset = 0;
      }
      num_frames++;
    } else {
      num_ignore_frames--;
    }
    ret = unw_step (cursor);
  } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);

  delete cursor;
  return true;
}
Пример #25
0
static void luw_backtrace()
{
	unw_cursor_t cursor;
	unw_context_t context;

	unw_getcontext(&context);
	unw_init_local(&cursor, &context);

	std::stringstream output;

	output << "Traceback (most recent call first):" << std::endl;

	while (unw_step(&cursor) > 0)
	{
		unw_word_t pc;

		unw_get_reg(&cursor, UNW_REG_IP, &pc);

		if (pc == 0)
			break;

		const char *file = NULL;
		const char *func = NULL;
		unsigned line = 0;
		resolve(pc, &file, &line, &func);

		if (file != NULL)
		{
			if (strcmp("__cxa_throw", func) == 0) continue;
			if (strncmp(func, "_Z", 2) == 0)
			{
				// This is a C++ mangled name (as per the IA-64 spec)
				output << "  0x" << std::hex << pc << std::dec << " " << demangle(func) << " (" << file << ":" << line << ")" << std::endl;
			} else {
				output << "  0x" << std::hex << pc << std::dec << " " << func << " (" << file << ":" << line << ")" << std::endl;
			}

			// Try to load the file and print the offending line
			std::ifstream f;
			f.open(file);
			if (!f.is_open())
			{
				output << "    <unable to find file>" << std::endl;
			} else
			{
				seek_to_line(f, line);
				std::string line;
				std::getline(f, line);
				output << "    " << line << std::endl;
			}
		} else {
			output << "  <unknown> (<unknown file>:<unknown line>)" << std::endl;
		}
	}
	output << std::endl;

	__latest_backtrace = output.str();
}
Пример #26
0
void
jffi_longjmp (jmp_buf env, int val)
{
    extern int _jffi_longjmp_cont;
    unw_context_t uc;
    unw_cursor_t c;
    unw_word_t sp, ip, bp = 0;
    uintptr_t *wp = (uintptr_t *) env;
    int i, setjmp_frame;

    if (unw_getcontext (&uc) < 0 || unw_init_local (&c, &uc) < 0) {
        debug("failed to get context");
        abort ();
    }
#ifdef __x86_86__
# define UNW_REG_BP UNW_X86_64_RBP
#else
# define UNW_REG_BP UNW_X86_EBP
#endif
    setjmp_frame = 0;

    do {
        char name[256];
        unw_proc_info_t pi;
        unw_word_t off;
        if (unw_get_reg (&c, UNW_REG_BP, &bp) < 0) {
            abort();
        }
        if (unw_get_reg (&c, UNW_REG_SP, &sp) < 0) {
            abort();
        }
        if (unw_get_reg (&c, UNW_REG_IP, &ip) < 0) {
            abort();
        }
        unw_get_proc_name(&c, name, sizeof(name), &off);
        unw_get_proc_info(&c, &pi);
//        debug("frame %s ip=%llx sp=%llx bp=%llx wp[RP]=%p wp[SP]=%p, pi.start_ip=%llx, pi.end_ip=%llx",
//            name, (long long) ip, (long long) sp, (long long) bp, (void *) wp[JB_RP], (void *) wp[JB_SP],
//            pi.start_ip, pi.end_ip);

        if (wp[JB_SP] > sp || wp[JB_RP] < pi.start_ip || wp[JB_RP] > pi.end_ip) continue;

        /* found the right frame: */
//        debug("found frame to jump back to");
        assert (UNW_NUM_EH_REGS >= 2);
        if (unw_set_reg (&c, UNW_REG_EH + 0, wp[JB_RP]) < 0
            || unw_set_reg (&c, UNW_REG_EH + 1, val) < 0
            || unw_set_reg (&c, UNW_REG_IP, (unw_word_t) (uintptr_t) &_jffi_longjmp_cont))
            abort ();

        unw_resume (&c);
        // should not reach here
        abort ();
    } while (unw_step (&c) > 0);
//    debug("failed to find correct frame to jmp to");
}
Пример #27
0
bool BacktraceOffline::Unwind(size_t num_ignore_frames, ucontext_t* context) {
  if (context == nullptr) {
    BACK_LOGW("The context is needed for offline backtracing.");
    return false;
  }
  context_ = context;

  unw_addr_space_t addr_space = unw_create_addr_space(&accessors, 0);
  unw_cursor_t cursor;
  int ret = unw_init_remote(&cursor, addr_space, this);
  if (ret != 0) {
    BACK_LOGW("unw_init_remote failed %d", ret);
    unw_destroy_addr_space(addr_space);
    return false;
  }
  size_t num_frames = 0;
  do {
    unw_word_t pc;
    ret = unw_get_reg(&cursor, UNW_REG_IP, &pc);
    if (ret < 0) {
      BACK_LOGW("Failed to read IP %d", ret);
      break;
    }
    unw_word_t sp;
    ret = unw_get_reg(&cursor, UNW_REG_SP, &sp);
    if (ret < 0) {
      BACK_LOGW("Failed to read SP %d", ret);
      break;
    }

    if (num_ignore_frames == 0) {
      frames_.resize(num_frames + 1);
      backtrace_frame_data_t* frame = &frames_[num_frames];
      frame->num = num_frames;
      frame->pc = static_cast<uintptr_t>(pc);
      frame->sp = static_cast<uintptr_t>(sp);
      frame->stack_size = 0;

      if (num_frames > 0) {
        backtrace_frame_data_t* prev = &frames_[num_frames - 1];
        prev->stack_size = frame->sp - prev->sp;
      }
      frame->func_name = GetFunctionName(frame->pc, &frame->func_offset);
      FillInMap(frame->pc, &frame->map);
      num_frames++;
    } else {
      num_ignore_frames--;
    }
    ret = unw_step(&cursor);
  } while (ret > 0 && num_frames < MAX_BACKTRACE_FRAMES);

  unw_destroy_addr_space(addr_space);
  context_ = nullptr;
  return true;
}
Пример #28
0
void log_stack_trace(const char *msg)
{
#ifdef USE_UNWIND
  unw_context_t ctx;
  unw_cursor_t cur;
  unw_word_t ip, off;
  unsigned level;
  char sym[512], *dsym;
  int status;
  const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str();
#endif

  if (msg)
    ST_LOG(msg);
  ST_LOG("Unwound call stack:");

#ifdef USE_UNWIND
  if (unw_getcontext(&ctx) < 0) {
    ST_LOG("Failed to create unwind context");
    return;
  }
  if (unw_init_local(&cur, &ctx) < 0) {
    ST_LOG("Failed to find the first unwind frame");
    return;
  }
  for (level = 1; level < 999; ++level) { // 999 for safety
    int ret = unw_step(&cur);
    if (ret < 0) {
      ST_LOG("Failed to find the next frame");
      return;
    }
    if (ret == 0)
      break;
    if (unw_get_reg(&cur, UNW_REG_IP, &ip) < 0) {
      ST_LOG("  " << std::setw(4) << level);
      continue;
    }
    if (unw_get_proc_name(&cur, sym, sizeof(sym), &off) < 0) {
      ST_LOG("  " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip);
      continue;
    }
    dsym = abi::__cxa_demangle(sym, NULL, NULL, &status);
    ST_LOG("  " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off);
    free(dsym);
  }
#else
  std::stringstream ss;
  ss << el::base::debug::StackTrace();
  std::vector<std::string> lines;
  std::string s = ss.str();
  boost::split(lines, s, boost::is_any_of("\n"));
  for (const auto &line: lines)
    ST_LOG(line);
#endif
}
Пример #29
0
static int jl_unw_step(bt_cursor_t *cursor, uintptr_t *ip, uintptr_t *sp)
{
    unw_word_t reg;
    if (unw_get_reg(cursor, UNW_REG_IP, &reg) < 0)
        return 0;
    *ip = reg;
    if (unw_get_reg(cursor, UNW_REG_SP, &reg) < 0)
        return 0;
    *sp = reg;
    return unw_step(cursor) > 0;
}
Пример #30
0
static void
sighandler (int signal)
{
  unw_cursor_t cursor, cursor2;
  unw_word_t ip;
  unw_context_t uc;

  if (verbose)
    printf ("caught signal %d\n", signal);

  unw_getcontext (&uc);
  if (unw_init_local (&cursor, &uc) < 0)
    panic ("unw_init() failed!\n");

  /* get cursor for caller of sighandler: */
  if (unw_step (&cursor) < 0)
    panic ("unw_step() failed!\n");

  cursor2 = cursor;
  while (!unw_is_signal_frame (&cursor2))
    if (unw_step (&cursor2) < 0)
      panic ("failed to find signal frame!\n");

  if (unw_step (&cursor2) < 0)
    panic ("unw_step() failed!\n");

  if (unw_get_reg (&cursor2, UNW_REG_IP, &ip) < 0)
    panic ("failed to get IP!\n");

  /* skip faulting instruction (doesn't handle MLX template) */
  ++ip;
  if ((ip & 0x3) == 0x3)
    ip += 13;

  if (unw_set_reg (&cursor2, UNW_REG_IP, ip) < 0)
    panic ("failed to set IP!\n");

  unw_resume (&cursor);	/* update context & return to caller of sighandler() */

  panic ("unexpected return from unw_resume()!\n");
}