Commit d0789a99 authored by Kirill Smelkov's avatar Kirill Smelkov

X print traceback on segmentation fault

Do what we can do without gdb and then tail to regular segmentation
fault. With core gdb can still be useed, but if we already get in the
log traceback of the crash automatically.
parent 5e647b59
......@@ -197,6 +197,7 @@ tfault := bigfile/tests/tfault
FAULTS := $(shell grep '{"fault.*"' $(tfault).c | sed 's/"/ /g' |awk '{print $$2}')
test.fault : $(FAULTS:%=%.tfault)
$(tfault).t: CFLAGS += -rdynamic # so that backtrace_symbols works
%.tfault : $(tfault).t
t/tfault-run $< $* $(shell grep '{"$*"' $(tfault).c | awk '{print $$NF}')
......
/* Wendelin.bigfile | Low-level pagefault handler
* Copyright (C) 2014-2019 Nexedi SA and Contributors.
* Copyright (C) 2014-2021 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com>
*
* This program is free software: you can Use, Study, Modify and Redistribute
......@@ -44,7 +44,7 @@ static struct sigaction prev_segv_act;
static int segv_act_installed;
static int faulted_by(const ucontext_t *uc);
static const char hexdigit[16] = "0123456789abcdef";
/* SIGSEGV handler */
static void on_pagefault(int sig, siginfo_t *si, void *_uc)
......@@ -150,6 +150,24 @@ dont_handle:
// XXX how to know access size? we just proceed here with 1byte ...
// FIXME don't touch memory on SI_USER - just BUG.
volatile uint8_t *p = (uint8_t *)si->si_addr;
uintptr_t a = (uintptr_t)si->si_addr;
char msg[256], *s=msg;
*s = 0;
strcat(s, "Segmentation fault: ");
strcat(s, write ? "write" : "read");
strcat(s, " @");
s += strlen(s);
for (int byte=sizeof(a); byte > 0; byte--) {
*s = hexdigit[(a>>((byte-1)*8+4)) & 0xf]; s++;
*s = hexdigit[(a>>((byte-1)*8 )) & 0xf]; s++;
}
*s = 0;
strcat(s, "\n");
xwrite(1, msg, strlen(msg));
dump_traceback(1);
if (write)
*p = *p;
else
......
......@@ -2,7 +2,7 @@
#define _WENDELIN_UTILS_H_
/* Wendelin. Miscellaneous utilities
* Copyright (C) 2014-2015 Nexedi SA and Contributors.
* Copyright (C) 2014-2021 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com>
*
* This program is free software: you can Use, Study, Modify and Redistribute
......@@ -88,6 +88,11 @@ void xpthread_sigmask(int how, const sigset_t *set, sigset_t *oldset);
void xpthread_mutex_lock(pthread_mutex_t *);
void xpthread_mutex_unlock(pthread_mutex_t *);
void xwrite(int fd, const void *buf, size_t count);
/* dump traceback */
void dump_traceback(int fd);
#ifdef __cplusplus
}
#endif
......
/* Wendelin. Miscellaneous utilities
* Copyright (C) 2014-2015 Nexedi SA and Contributors.
* Copyright (C) 2014-2021 Nexedi SA and Contributors.
* Kirill Smelkov <kirr@nexedi.com>
*
* This program is free software: you can Use, Study, Modify and Redistribute
......@@ -28,6 +28,7 @@
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <execinfo.h>
/* ilog2 that must be exact */
......@@ -161,3 +162,26 @@ void xpthread_mutex_unlock(pthread_mutex_t *lock)
if (err)
BUGerr(err);
}
void xwrite(int fd, const void *buf, size_t count)
{
ssize_t n;
while (count != 0) {
n = write(fd, buf, count);
if (n == -1)
BUGe();
count -= n;
}
}
/* dump traceback to fd */
void dump_traceback(int fd)
{
void *pcv[256];
int n;
n = backtrace(pcv, 256);
backtrace_symbols_fd(pcv, n, fd);
}
......@@ -25,6 +25,9 @@ ulimit -c unlimited
$tfault $arg 2>&1 |tee run.out
grep -q "^# going to fault" run.out || die "test didn't run to faulting point"
if [ $mustdie == "on_pagefault" ]; then
grep -q "dump_traceback" run.out || die "on_pagefault didn't print traceback"
fi
test -e core || die "no core after run"
gdb -q -batch $tfault core >core.info || die "can't gdb(core)"
grep -q "Program terminated with signal SIGSEGV, Segmentation fault." core.info || die "not SIGSEGV"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment