Skip to content

Commit

Permalink
fixed stacktrace message
Browse files Browse the repository at this point in the history
  • Loading branch information
havraji6 committed Jul 14, 2021
1 parent 09836fc commit d0ecacd
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 29 deletions.
2 changes: 1 addition & 1 deletion main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ inline int error(const string &e)
void signal_handler(int sig)
{
if (sig == SIGSEGV) {
stacktrace_print(sig);
st_dump(STDERR_FILENO, sig);
abort();
}
stop = 1;
Expand Down
146 changes: 119 additions & 27 deletions stacktrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,103 @@
*/

#include <config.h>
#include <cxxabi.h>
#include <cstdio>
#include <cstdlib>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/syscall.h>
#include <sys/types.h>

#define UNW_LOCAL_ONLY
#include <libunwind.h>

#include "stacktrace.h"

void stacktrace_print(int sig)
static void st_write(int fd, const char *buffer, size_t buflen)
{
size_t total = 0;
while (total < buflen) {
ssize_t written = write(fd, buffer + total, buflen - total);
if (written < 0) {
return;
}

total += written;
}
}

static void st_write_str(int fd, const char *str)
{
st_write(fd, str, strlen(str));
}

static void st_write_num(int fd, int num, int padding=0)
{
char buf[22];
int idx = 0;
int tmp = num < 0 ? -num : num;

if (num == 0) {
buf[idx++] = '0';
}

while (tmp != 0) {
buf[idx++] = '0' + tmp % 10;
tmp /= 10;
}
if (num < 0) {
buf[idx++] = '-';
}

for (int i = 0; i < idx / 2; i++) {
char tmp = buf[i];
buf[i] = buf[idx - i - 1];
buf[idx - i - 1] = tmp;
}
while (idx < padding) {
buf[idx++] = ' ';
}
buf[idx] = 0;

st_write_str(fd, buf);
}

static char nibble2hex(uint8_t num)
{
if (num < 10) {
return '0' + num;
} else if (num < 16) {
return 'a' + num - 10;
}
return '?';
}

static void st_write_num_hex(int fd, uint64_t num, size_t size, bool nopad=false)
{
char buf[19] = "0x";
bool nonzero_seen = false;
size_t idx = 2;

for (int i = 0; i < (int) size; i++) {
uint8_t bits2shift = (size - i - 1) * size;
uint8_t byte = (num >> bits2shift) & 0xFF;
if (byte == 0 && nopad && !nonzero_seen) {
continue;
}
buf[idx] = nibble2hex(byte >> 4);
buf[idx + 1] = nibble2hex(byte & 0x0F);
idx += 2;
nonzero_seen = true;
}
buf[idx] = 0;
st_write_str(fd, buf);
}

static void st_write_word(int fd, unw_word_t num, bool nopad=false)
{
st_write_num_hex(fd, num, sizeof(num), nopad);
}

void st_dump(int fd, int sig)
{
int framenum = 0;
unw_context_t ctx;
Expand All @@ -64,51 +147,60 @@ void stacktrace_print(int sig)
unw_getcontext(&ctx);
unw_init_local(&cursor, &ctx);

fprintf(stderr, "stacktrace dump of %s %s\n", PACKAGE_NAME, PACKAGE_VERSION);
st_write_str(fd, "stacktrace dump of " PACKAGE_NAME " " PACKAGE_VERSION "\n");
st_write_str(fd, "uid: ");
st_write_num(fd, getuid());
st_write_str(fd, " pid: ");
st_write_num(fd, getpid());
#ifdef SYS_gettid
fprintf(stderr, "pid: %d uid: %d\n", getpid(), getuid());
#else
fprintf(stderr, "pid: %d tid: %d uid: %d\n", getpid(), gettid(), getuid());
st_write_str(fd, " tid: ");
st_write_num(fd, syscall(SYS_gettid));
#endif
fprintf(stderr, "received signal: %d\n", sig);
st_write_str(fd, "\n");

st_write_str(fd, "received signal: ");
st_write_num(fd, sig);
st_write_str(fd, "\n");


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

st_write_str(fd, "#");
st_write_num(fd, framenum, 2);
st_write_str(fd, " ");
if (unw_get_reg(&cursor, UNW_REG_IP, &pc) == 0) {
if (pc == 0) {
break;
}
fprintf(stderr, "#%-3d %#016lx", framenum, pc);

st_write_word(fd, pc);
} else {
fprintf(stderr, "#%-3d ???", framenum);
st_write_str(fd, "???");
}
st_write_str(fd, " ");
if (unw_get_reg(&cursor, UNW_REG_SP, &sp) == 0) {
fprintf(stderr, " %#016lx", sp);
st_write_word(fd, sp);
} else {
fprintf(stderr, " ???");
st_write_str(fd, "???");
}

framenum++;
printf(":");
st_write_str(fd, ": ");

char sym[256];
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
int status;
char *nameptr = sym;
char *demangled = abi::__cxa_demangle(sym, nullptr, nullptr, &status);
if (status == 0) {
nameptr = demangled;
}
fprintf(stderr, " %s+%#lx", nameptr, offset);
st_write_str(fd, sym);
st_write_str(fd, "+");
st_write_word(fd, offset, true);
if (unw_is_signal_frame(&cursor)) {
fprintf(stderr, " <-");
st_write_str(fd, " <-");
}
fprintf(stderr, "\n");
free(demangled);
st_write_str(fd, "\n");
} else {
fprintf(stderr, " ???\n");
st_write_str(fd, "???\n");
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion stacktrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@
#ifndef STACKTRACE_H
#define STACKTRACE_H

void stacktrace_print(int sig);
void st_dump(int fd, int sig);

#endif /* STACKTRACE_H */

0 comments on commit d0ecacd

Please sign in to comment.