コード例 #1
0
ファイル: CrashHandler.cpp プロジェクト: BertiKarsunke/skia
        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);
        }
コード例 #2
0
ファイル: ut_backtrace.c プロジェクト: Skyprophet/peloton
/*
 * 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);
	}
}
コード例 #3
0
ファイル: shocker.cpp プロジェクト: 499940913/moon
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;
	}
}
コード例 #4
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);
      }
    }
  }
}
コード例 #5
0
ファイル: debug.cpp プロジェクト: stelonix/tmpgl
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");
    }
  }
}
コード例 #6
0
ファイル: mc_global.cpp プロジェクト: R7R8/simgrid
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));
}
コード例 #7
0
/* TODO with some refactoring we might be able to re-use debug_symbol_name_cached()
 * instead.. otoh if using libunwind I think u_debug_symbol could just be excluded
 * from build?
 */
static const char *
symbol_name_cached(unw_cursor_t *cursor, unw_proc_info_t *pip)
{
   void *addr = (void *)(uintptr_t)pip->start_ip;
   char *name;

   mtx_lock(&symbols_mutex);
   if(!symbols_hash)
      symbols_hash = util_hash_table_create(hash_ptr, compare_ptr);
   name = util_hash_table_get(symbols_hash, addr);
   if(!name)
   {
      char procname[256];
      unw_word_t off;
      int ret;

      ret = unw_get_proc_name(cursor, procname, sizeof(procname), &off);
      if (ret && ret != -UNW_ENOMEM) {
         procname[0] = '?';
         procname[1] = 0;
      }

      if (asprintf(&name, "%s%s", procname, ret == -UNW_ENOMEM ? "..." : "") == -1) 
         name = "??";
      util_hash_table_set(symbols_hash, addr, (void*)name);
   }
   mtx_unlock(&symbols_mutex);

   return name;
}
コード例 #8
0
ファイル: S52utils.c プロジェクト: sduclos/S52
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);
}
コード例 #9
0
ファイル: gobject-list.c プロジェクト: matze/gobject-list
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
ファイル: vm_dump.c プロジェクト: sho-h/ruby
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;
}
コード例 #11
0
ファイル: longjmp.c プロジェクト: aaronbartell/jffi
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");
}
コード例 #12
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
}
コード例 #13
0
void
AS_UTL_catchCrash(int sig_num, siginfo_t *info, void *ctx) {

  WRITE_STRING("\nFailed with '");
  WRITE_STRING(strsignal(sig_num));
  WRITE_STRING("'\n");

  WRITE_STRING("\nBacktrace (mangled):\n\n");

  unw_cursor_t   cursor;
  unw_context_t  uc;
  unw_word_t     ip, sp;
  int            depth = 0;

  unw_getcontext(&uc);           //  Get state
  unw_init_local(&cursor, &uc);  //  Initialize state cursor

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

    unw_word_t off;
    char       name[256];

    if (unw_get_proc_name (&cursor, name, sizeof (name), &off) == 0) {
      if (off)
        fprintf(stderr, "%02d <%s + 0x%lx>  ip=%lx sp=%lx\n", depth, name, (long)off, ip, sp);
      else
        fprintf(stderr, "%02d <%s>  ip=%lx sp=%lx\n", depth, name, ip, sp);
    } else {
      fprintf(stderr, "%02d <?>  ip=%lx sp=%lx\n", depth, ip, sp);
    }

    depth++;
  }

  //WRITE_STRING("\nBacktrace (demangled):\n\n");

  //WRITE_STRING("\nGDB:\n\n");
  //AS_UTL_envokeGDB();

  //  Pass the signal through, only so a core file can get generated.

  struct sigaction sa;

  sa.sa_handler = SIG_DFL;
  sigemptyset (&sa.sa_mask);
  sa.sa_flags = 0;

  sigaction(sig_num, &sa, NULL);

  raise(sig_num);
}
コード例 #14
0
ファイル: FaultProtect.c プロジェクト: aaronbartell/jffi
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);
}
コード例 #15
0
ファイル: backtrace.c プロジェクト: rantala/backtracer-demo
int bt_backtrace(struct bt_data *btd, void** frames, char **buffer, int size, int resolve_name)
{
	unw_cursor_t c;
	unw_word_t ip, off;
	int n = 0, ret;
	char buf[512] = "in ";

	if (size == 0)
		return 0;

	if ((ret = unw_init_remote(&c, btd->as, btd->ui)) < 0) {
		printf("unw_init_remote() failed.\n");
		//debug(1, "bt_backtrace(): unw_init_remote() failed, ret=%d", ret);
		return -1;
	}

	do {
		if ((ret = unw_get_reg(&c, UNW_REG_IP, &ip)) < 0) {
			//debug(1, "bt_backtrace(): unw_get_reg() failed, ret=%d", ret);
			return -1;
		}
		frames[n] = (void*)ip;

		if (resolve_name) {
			char* ptr = buf;
			ret = unw_get_proc_name(&c, buf + 3, sizeof(buf) - 3, &off);
			if (ret < 0) {
				ptr = buf + 3;
				strcpy(ptr, "<undefined>");
			}
			else if (off) {
				size_t len = strlen(buf);
				/* Reserve the last 64 bytes for the offset */
				if (len >= sizeof(buf) - 64)
					len = sizeof(buf) - 64;
				sprintf(buf + len, "+0x%lx", (unsigned long)off);
			}
			buffer[n] = strdup(ptr);
		}
		n++;
		if ((ret = unw_step(&c)) < 0) {
			//debug(1, "bt_backtrace(): unw_step() failed, ret=%d", ret);
			return -1;
		}
	} while (ret > 0 && n < size);

	return n;
}
コード例 #16
0
ファイル: exceptions-ia64.c プロジェクト: moander/mono
G_GNUC_UNUSED static void
print_ctx (MonoContext *ctx)
{
	char name[256];
	unw_word_t off, ip, sp;
	unw_proc_info_t pi;
	int res;

	unw_get_proc_name (&ctx->cursor, name, 256, &off);
	unw_get_proc_info(&ctx->cursor, &pi);
	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);

	printf ("%s:%lx [%lx-%lx] SP: %lx\n", name, ip - pi.start_ip, pi.start_ip, pi.end_ip, sp);
}
コード例 #17
0
ファイル: err.cpp プロジェクト: mattconnolly/libzmq
void zmq::print_backtrace (void)
{
    static zmq::mutex_t mtx;
    mtx.lock ();
    Dl_info dl_info;
    unw_cursor_t cursor;
    unw_context_t ctx;
    unsigned frame_n = 0;

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

    while (unw_step (&cursor) > 0) {
        unw_word_t offset;
        unw_proc_info_t p_info;
        const char *file_name;
        char *demangled_name;
        char func_name[256] = "";
        void *addr;
        int rc;

        if (unw_get_proc_info (&cursor, &p_info))
            break;

        addr = (void *)(p_info.start_ip + offset);

        if (dladdr (addr, &dl_info) && dl_info.dli_fname)
            file_name = dl_info.dli_fname;
        else
            file_name = "?";

        rc = unw_get_proc_name (&cursor, func_name, 256, &offset);
        if (rc == -UNW_ENOINFO)
            strcpy(func_name, "?");

        demangled_name = abi::__cxa_demangle (func_name, NULL, NULL, &rc);

        printf ("#%u  %p in %s (%s+0x%lx)\n", frame_n++, addr, file_name,
                rc ? func_name : demangled_name, (unsigned long) offset);
        free (demangled_name);
    }
    puts ("");
    
    fflush (stdout);
    mtx.unlock ();
}
コード例 #18
0
ファイル: tommy_handler.c プロジェクト: quadpixels/resilience
void do_backtrace() {
	unw_cursor_t cursor;
	unw_context_t context;
	int ret;
	ret = unw_getcontext(&context);
	if(ret != 0) { printf("[do_backtrace] unw_getcontext returned %d.\n", ret); }
	ret = unw_init_local(&cursor, &context);
	if(ret != 0) { printf("[do_backtrace] unw_init_local returned %d.\n", ret); }

	do {
		unw_word_t offset, pc;
		char fname[64];
		unw_get_reg(&cursor, UNW_REG_IP, &pc);

		fname[0]='\0';
		(void) unw_get_proc_name(&cursor, fname, sizeof(fname), &offset);
		printf("%p : (%s+0x%x) [%p]\n", (void*)pc, fname, (unsigned int)offset, (void*)pc);
	}
	while(unw_step(&cursor) > 0);
}
コード例 #19
0
ファイル: backtrace.cpp プロジェクト: LocutusOfBorg/poedit
void backtrace() {
	unw_cursor_t cursor;
	unw_context_t context;
	unw_getcontext( & context);
	unw_init_local( & cursor, & context);
	while ( 0 < unw_step( & cursor) ) {
		unw_word_t offset, pc;
		unw_get_reg( & cursor, UNW_REG_IP, & pc);
		if ( 0 == pc) {
			break;
		}
		std::cout << "0x" << pc << ":";

		char sym[256];
		if ( 0 == unw_get_proc_name( & cursor, sym, sizeof( sym), & offset) ) {
			std::cout << " (" << sym << "+0x" << offset << ")" << std::endl;
		} else {
			std::cout << " -- error: unable to obtain symbol name for this frame" << std::endl;
		}
	}
}
コード例 #20
0
ファイル: backtrace.c プロジェクト: 010001111/darling
int bar(const char** list)
{
	char functionName[64];
	unw_cursor_t cursor; 
	unw_context_t uc;
	unw_word_t	offset;
	
	int index = 0;
	unw_getcontext(&uc);
	unw_init_local(&cursor, &uc);
	do {
		unw_get_proc_name(&cursor, functionName, 64, &offset);
		//fprintf(stderr, "in function: %s\n", functionName);
		if ( (list[index] != NULL) && (strcmp(functionName, list[index]) != 0) ) {
			//fprintf(stderr, "unexpected function: %s\n", functionName);
			exit(1);
		}
		++index;
	} while (unw_step(&cursor) > 0);
	return 0;
}
コード例 #21
0
static void
print_trace (void)
{
  unw_context_t uc;
  unw_cursor_t cursor;
  guint stack_num = 0;

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

  while (unw_step (&cursor) > 0 && stack_num < 32)
    {
      gchar name[256];
      unw_word_t off;

      if (unw_get_proc_name (&cursor, name, 255, &off) < 0)
        strcpy (name, "<no name>");

      g_print ("#%d  [%s+0x%x]\n", stack_num++, name, (unsigned int)off);
    }
}
コード例 #22
0
ファイル: tt_backtrace_native.c プロジェクト: newser/TitanSDK
tt_result_t tt_backtrace_ntv(IN tt_buf_t *buf,
                             IN OPT const tt_char_t *prefix,
                             IN OPT const tt_char_t *suffix)
{
    tt_u32_t plen, slen, i;
    unw_context_t ctx;
    unw_cursor_t cur;

    if (prefix == NULL) {
        prefix = "";
    }
    plen = (tt_u32_t)tt_strlen(prefix);

    if (suffix == NULL) {
        suffix = "";
    }
    slen = (tt_u32_t)tt_strlen(suffix);

    if ((unw_getcontext(&ctx) != 0) || (unw_init_local(&cur, &ctx) != 0)) {
        return TT_FAIL;
    }

    i = 0;
    while (unw_step(&cur) > 0) {
        unw_word_t ip, off;
        char name[128] = {0};

        if ((unw_get_reg(&cur, UNW_REG_IP, &ip) != 0) ||
            (unw_get_proc_name(&cur, name, sizeof(name) - 1, &off)) != 0) {
            break;
        }

        TT_DO_G(done, tt_buf_put(buf, (tt_u8_t *)prefix, plen));
        TT_DO_G(done,
                tt_buf_putf(buf, "#%d <%p> in %s(+0x%x)", i++, ip, name, off));
        TT_DO_G(done, tt_buf_put(buf, (tt_u8_t *)suffix, slen));
    }
done:
    return TT_SUCCESS;
}
コード例 #23
0
ファイル: debug.cpp プロジェクト: stelonix/tmpgl
void show_backtrace(void) {
	char name[256];
	unw_cursor_t cursor; unw_context_t uc;
	unw_word_t ip, sp, offp;

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

	while (unw_step(&cursor) > 0)
	{
		char file[256];
		int line = 0;

		name[0] = '\0';
		unw_get_proc_name(&cursor, name, 256, &offp);
		unw_get_reg(&cursor, UNW_REG_IP, &ip);
		unw_get_reg(&cursor, UNW_REG_SP, &sp);

		//printf ("%s ip = %lx, sp = %lx\n", name, (long) ip, (long) sp);
		getFileAndLine((long)ip, file, 256, &line);
		printf("%s in file %s line %d\n", name, file, line);
	}
}
コード例 #24
0
ファイル: logger.cpp プロジェクト: JonnyH/OpenApoc
static void print_backtrace(FILE *f)
{

	unw_cursor_t cursor;
	unw_context_t ctx;
	unw_word_t ip;
	unw_getcontext(&ctx);
	unw_init_local(&cursor, &ctx);

	fprintf(f, "  called by:\n");
	while (unw_step(&cursor) > 0)
	{
		Dl_info info;
		unw_get_reg(&cursor, UNW_REG_IP, &ip);
		if (ip == 0)
			break;
		dladdr(reinterpret_cast<void *>(ip), &info);
		if (info.dli_sname)
		{
			fprintf(f, "  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), info.dli_sname,
			        static_cast<uintptr_t>(ip) - reinterpret_cast<uintptr_t>(info.dli_saddr),
			        info.dli_fname);
			continue;
		}
		// If dladdr() failed, try libunwind
		unw_word_t offsetInFn;
		char fnName[MAX_SYMBOL_LENGTH];
		if (!unw_get_proc_name(&cursor, fnName, MAX_SYMBOL_LENGTH, &offsetInFn))
		{
			fprintf(f, "  0x%zx %s+0x%zx (%s)\n", static_cast<uintptr_t>(ip), fnName, offsetInFn,
			        info.dli_fname);
			continue;
		}
		else
			fprintf(f, "  0x%zx\n", static_cast<uintptr_t>(ip));
	}
}
コード例 #25
0
ファイル: linux.c プロジェクト: JamesLinus/mcc
static void handler(int sig)
{
    unw_cursor_t cursor;
    unw_context_t uc;
    unw_word_t offp;
    char buf[128];
    int i = 0;

    fprintf(stderr, "Stack trace:\n");
    unw_getcontext(&uc);
    unw_init_local(&cursor, &uc);
    
    while (unw_step(&cursor) > 0) {
        int ret = unw_get_proc_name(&cursor, buf, sizeof buf/sizeof buf[0], &offp);
        if (ret == 0) {
            printf("%d\t%s + %ld\n", i, buf, offp);
        } else {
            printf("%d\t???\n", i);
        }
        i++;
    }
    
    exit(EXIT_FAILURE);
}
コード例 #26
0
int
main(int argc , char **argv)
{
  unw_addr_space_t as;
  unw_cursor_t cursor;
  struct UCD_info *ui;
  unw_word_t ip, sp, off;
  char buf[512], name[256];
  int line;
  int depth = 0;
  int ret;
  bool pybt_done = false;
#define TEST_NAME_LEN 256 

  install_signal_handler();

  if (argc != 3) {
    fprintf(stderr, "Usage: %s <binary> <corefile>", argv[0]);
    exit(1);
  }

  as = unw_create_addr_space(&_UCD_accessors, 0);
  if (!as) {
    fprintf(stderr, "unw_create_addr_space() failed");
    exit(1);
  }

  ui = _UCD_create(argv[2]);
  if (!ui) {
    fprintf(stderr,"_UCD_create('%s') failed", argv[1]);
    exit(1);
  }
  ret = unw_init_remote(&cursor, as, ui);
  if (ret < 0) {
    fprintf(stderr,"unw_init_remote() failed: ret=%d\n", ret);
    exit(1);
  }

  read_elfnotes(argv[2], ui);

  while (unw_step(&cursor) > 0) {
    // Avoid going too deep
    if (depth++ > MAX_STACK_DEPTH) {
      exit(1);
    }
    unw_get_reg(&cursor, UNW_REG_IP, &ip);
    unw_get_reg(&cursor, UNW_REG_SP, &sp);


    if (unw_get_proc_name(&cursor, name, sizeof (name), &off) == 0) {
      if (off) {
        snprintf(buf, sizeof (buf), "<%s+0x%lx>", name, (long) off);
      } else {
        snprintf(buf, sizeof (buf), "<%s>", name);
      }
    }

    /* Check for Python backtrace */
    if (!strncmp(name,"PyEval_EvalFrameEx", 18) && !pybt_done) {
      pybacktrace(cursor);
      pybt_done = true;
    }
    rw_get_file_and_line((long)ip, name, argv[1], 256, &line);
    printf("%016lx %s <%s:%d> (sp=%016lx)\n",
            (long) ip, buf, basename(name), line, (long) sp);

  }
  _UCD_destroy(ui);
  unw_destroy_addr_space(as);

  return 0;
}
コード例 #27
0
ファイル: error.c プロジェクト: jcazzie/chapel
static void chpl_stack_unwind(void){
  // This is just a prototype using libunwind
  unw_cursor_t cursor;
  unw_context_t uc;
  unw_word_t wordValue;
  char buffer[128];
  unsigned int line;

#ifdef __linux__
  unw_proc_info_t info;
  // Get the exec path and name for the precise line printing
  char process_name[128];

  line = readlink("/proc/self/exe", process_name, sizeof(process_name));
  // It unlikely to happen but this means that the process name is too big 
  // for our buffer. In this case, we truncate the name
  if(line == sizeof(process_name))
    line = sizeof(process_name)-1;
  process_name[line] = '\0';
#endif

  // Check if we need to print the stack trace (default = yes)
  if(! chpl_get_rt_env_bool("UNWIND", true)) {
    return;
  }

  line = 0;
  unw_getcontext(&uc);
  unw_init_local(&cursor, &uc);

  if(chpl_sizeSymTable > 0)
    fprintf(stderr,"Stacktrace\n\n");

  // This loop does the effective stack unwind, see libunwind documentation
  while (unw_step(&cursor) > 0) {
    unw_get_proc_name(&cursor, buffer, sizeof(buffer), &wordValue);
    // Since this stack trace is printed out a program exit, we do not believe
    // it is performance sensitive. Additionally, this initial implementation
    // favors simplicity over performance.
    //
    // If it becomes necessary to improve performance, this code could use be
    // faster using one of these two strategies:
    // 1) Use a hashtable or map to find entries in chpl_funSymTable, or
    // 2) Emit chpl_funSymTable in sorted order and use binary search on it
    for(int t = 0; t < chpl_sizeSymTable; t+=2 ){
      if (!strcmp(chpl_funSymTable[t], buffer)){
#ifdef __linux__
        // Maybe we can get a more precise line number
        unw_get_proc_info(&cursor, &info);
        line = chpl_unwind_getLineNum(process_name,
                                      (void *)(info.start_ip + wordValue));
        // We wasn't able to obtain the line number, let's use the procedure
        // line number
        if(line == 0)
          line = chpl_filenumSymTable[t+1];
#else
        line = chpl_filenumSymTable[t+1];
#endif
        fprintf(stderr,"%s() at %s:%d\n",
                  chpl_funSymTable[t+1],
                  chpl_lookupFilename(chpl_filenumSymTable[t]),
                  line);
        break;
      }
    }
  }
}
コード例 #28
0
ファイル: test-coredump-unwind.c プロジェクト: A-And/coreclr
int
main(int argc UNUSED, char **argv)
{
  unw_addr_space_t as;
  struct UCD_info *ui;
  unw_cursor_t c;
  int ret;

#define TEST_FRAMES 4
#define TEST_NAME_LEN 32
  int testcase = 0;
  int test_cur = 0;
  long test_start_ips[TEST_FRAMES];
  char test_names[TEST_FRAMES][TEST_NAME_LEN];

  install_sigsegv_handler();

  const char *progname = strrchr(argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  if (!argv[1])
    error_msg_and_die("Usage: %s COREDUMP [VADDR:BINARY_FILE]...", progname);

  msg_prefix = progname;

  as = unw_create_addr_space(&_UCD_accessors, 0);
  if (!as)
    error_msg_and_die("unw_create_addr_space() failed");

  ui = _UCD_create(argv[1]);
  if (!ui)
    error_msg_and_die("_UCD_create('%s') failed", argv[1]);
  ret = unw_init_remote(&c, as, ui);
  if (ret < 0)
    error_msg_and_die("unw_init_remote() failed: ret=%d\n", ret);

  argv += 2;

  /* Enable checks for the crasher test program? */
  if (*argv && !strcmp(*argv, "-testcase"))
  {
    testcase = 1;
    logmode = LOGMODE_NONE;
    argv++;
  }

  while (*argv)
    {
      char *colon;
      unsigned long vaddr = strtoul(*argv, &colon, 16);
      if (*colon != ':')
        error_msg_and_die("Bad format: '%s'", *argv);
      if (_UCD_add_backing_file_at_vaddr(ui, vaddr, colon + 1) < 0)
        error_msg_and_die("Can't add backing file '%s'", colon + 1);
      argv++;
    }

  for (;;)
    {
      unw_word_t ip;
      ret = unw_get_reg(&c, UNW_REG_IP, &ip);
      if (ret < 0)
        error_msg_and_die("unw_get_reg(UNW_REG_IP) failed: ret=%d\n", ret);

      unw_proc_info_t pi;
      ret = unw_get_proc_info(&c, &pi);
      if (ret < 0)
        error_msg_and_die("unw_get_proc_info(ip=0x%lx) failed: ret=%d\n", (long) ip, ret);

      if (!testcase)
        printf("\tip=0x%08lx proc=%08lx-%08lx handler=0x%08lx lsda=0x%08lx\n",
				(long) ip,
				(long) pi.start_ip, (long) pi.end_ip,
				(long) pi.handler, (long) pi.lsda);

      if (testcase && test_cur < TEST_FRAMES)
        {
           unw_word_t off;

           test_start_ips[test_cur] = (long) pi.start_ip;
           if (unw_get_proc_name(&c, test_names[test_cur], sizeof(test_names[0]), &off) != 0)
           {
             test_names[test_cur][0] = '\0';
           }
           test_cur++;
        }

      log("step");
      ret = unw_step(&c);
      log("step done:%d", ret);
      if (ret < 0)
    	error_msg_and_die("FAILURE: unw_step() returned %d", ret);
      if (ret == 0)
        break;
    }
  log("stepping ended");

  /* Check that the second and third frames are equal, but distinct of the
   * others */
  if (testcase &&
       (test_cur != 4
       || test_start_ips[1] != test_start_ips[2]
       || test_start_ips[0] == test_start_ips[1]
       || test_start_ips[2] == test_start_ips[3]
       )
     )
    {
      fprintf(stderr, "FAILURE: start IPs incorrect\n");
      return -1;
    }

  if (testcase &&
       (  strcmp(test_names[0], "a")
       || strcmp(test_names[1], "b")
       || strcmp(test_names[2], "b")
       || strcmp(test_names[3], "main")
       )
     )
    {
      fprintf(stderr, "FAILURE: procedure names are missing/incorrect\n");
      return -1;
    }

  _UCD_destroy(ui);
  unw_destroy_addr_space(as);

  return 0;
}
コード例 #29
0
ファイル: stack.c プロジェクト: mmilata/seecore
static struct frame* unwind_thread(Dwfl *dwfl, unw_addr_space_t as,
                                   struct UCD_info *ui, int thread_no,
                                   struct expr_context *ctx)
{
    info("thread %d:", thread_no);

    int i, ret;
    unw_cursor_t c, c_cfa;

    _UCD_select_thread(ui, thread_no);

    ret = unw_init_remote(&c, as, ui);
    fail_if(ret < 0, "unw_init_remote");

    ret = unw_init_remote(&c_cfa, as, ui);
    fail_if(ret < 0, "unw_init_remote");

    struct frame *head = NULL, *tail = NULL;

    /* infinite loop insurance */
    int count = 1000;
    while (--count > 0)
    {
        unw_word_t ip;
        ret = unw_get_reg(&c, UNW_REG_IP, &ip);
        fail_if(ret < 0, "unw_get_reg");

        if (ip == 0)
            break;

        unw_word_t off;
        char funcname[10*1024];
        funcname[0] = '\0';
        ret = unw_get_proc_name(&c, funcname, sizeof(funcname)-1, &off);
        if (ret < 0)
        {
            warn("unw_get_proc_name failed for IP %lx", (unsigned long)ip);
        }
        info("\t%llx %s", (unsigned long long)ip, funcname);

        /* According to spec[1], CFA is RSP of the previous frame. However,
         * libunwind returns CFA = RSP of the current frame. So we need to keep
         * track of the previous (i.e. next to be unwound) frame.
         *
         * [1] System V Application Binary Interface AMD64 Architecture
         *     Processor Supplement
         *     http://www.x86-64.org/documentation/abi.pdf
         */
        ctx->cfa = 0;
        ret = unw_step(&c_cfa);
        if (ret > 0)
        {
            unw_word_t cfa;
            ret = unw_get_reg(&c_cfa, UNW_X86_64_CFA, &cfa);
            if (ret == 0)
            {
                ctx->cfa = (Dwarf_Addr)cfa;
            }
        }

        /* find compilation unit owning the IP */
        Dwarf_Die *cu = dwfl_addrdie(dwfl, (Dwarf_Addr)ip, &(ctx->bias));
        if (!cu)
        {
            warn("\t\tcannot find CU for ip %lx", (unsigned long)ip);
            goto synth_frame;
        }

        if (!supported_language(cu))
        {
            warn("\t\tunsupported CU language");
            goto synth_frame;
        }

        /* needed by child_variables */
        Dwarf_Files *files;
        ret = dwarf_getsrcfiles(cu, &files, NULL);
        fail_if(ret == -1, "dwarf_getsrcfiles");

        /* dwarf expression evaluation needs register values */
        ctx->curs = &c;
        ctx->ip = (Dwarf_Addr)ip; /* TODO: subtract 1 as this is return address? */

        /* TODO: we have CU - fall back to CU name if subprogram not found */

        /* Following code deals with inlined functions, which do not have their
         * own stack frame. It is somewhat ugly due to two constraints:
         *  - we want to produce at least one frame even if analyze_scopes
         *    fails
         *  - we may want to further process the frame that is returned the
         *    last, i.e. the one that belongs to the non-inlined function
         */
        Dwarf_Die *scopes;
        int nscopes = dwarf_getscopes(cu, (Dwarf_Addr)ip, &scopes);
        struct frame *frame = analyze_scopes(&scopes, &nscopes, ctx, files, false);

        if (frame == NULL)
        {
            goto synth_frame;
        }

        struct frame *last_frame;
        while (frame)
        {
            list_append(head, tail, frame);
            last_frame = frame;
            frame = analyze_scopes(&scopes, &nscopes, ctx, files, true);
        }
        frame = last_frame;
        /* frame->ip = (uint64_t)ip; */

        goto next;

synth_frame:
        /* synthesize frame even though we have no other information except
         * that it's there */
        frame = xalloc(sizeof(*frame));
        list_append(head, tail, frame);
        /* frame->ip = (uint64_t)ip; */

next:
        ret = unw_step(&c);
        fail_if(ret < 0, "unw_step");

        if (ret == 0)
            break;
    }

    return head;
}
コード例 #30
0
ファイル: smbcontrol.c プロジェクト: srimalik/samba
static void print_stack_trace(pid_t pid, int * count)
{
	void *		    pinfo = NULL;
	unw_addr_space_t    aspace = NULL;
	unw_cursor_t	    cursor;
	unw_word_t	    ip, sp;

	char		    nbuf[256];
	unw_word_t	    off;

	int ret;

	if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) {
		fprintf(stderr,
			"Failed to attach to process %llu: %s\n",
			(unsigned long long)pid, strerror(errno));
		return;
	}

	/* Wait until the attach is complete. */
	waitpid(pid, NULL, 0);

	if (((pinfo = _UPT_create(pid)) == NULL) ||
	    ((aspace = unw_create_addr_space(&_UPT_accessors, 0)) == NULL)) {
		/* Probably out of memory. */
		fprintf(stderr,
			"Unable to initialize stack unwind for process %llu\n",
			(unsigned long long)pid);
		goto cleanup;
	}

	if ((ret = unw_init_remote(&cursor, aspace, pinfo))) {
		fprintf(stderr,
			"Unable to unwind stack for process %llu: %s\n",
			(unsigned long long)pid, unw_strerror(ret));
		goto cleanup;
	}

	if (*count > 0) {
		printf("\n");
	}

	if (procname(pid, nbuf, sizeof(nbuf))) {
		printf("Stack trace for process %llu (%s):\n",
			(unsigned long long)pid, nbuf);
	} else {
		printf("Stack trace for process %llu:\n",
			(unsigned long long)pid);
	}

	while (unw_step(&cursor) > 0) {
		ip = sp = off = 0;
		unw_get_reg(&cursor, UNW_REG_IP, &ip);
		unw_get_reg(&cursor, UNW_REG_SP, &sp);

		ret = unw_get_proc_name(&cursor, nbuf, sizeof(nbuf), &off);
		if (ret != 0 && ret != -UNW_ENOMEM) {
			snprintf(nbuf, sizeof(nbuf), "<unknown symbol>");
		}
		printf("    %s + %#llx [ip=%#llx] [sp=%#llx]\n",
			nbuf, (long long)off, (long long)ip,
			(long long)sp);
	}

	(*count)++;

cleanup:
	if (aspace) {
		unw_destroy_addr_space(aspace);
	}

	if (pinfo) {
		_UPT_destroy(pinfo);
	}

	ptrace(PTRACE_DETACH, pid, NULL, NULL);
}