Commit 25fa18f4 authored by Kirill Smelkov's avatar Kirill Smelkov

bigfile/virtmem: Print traceback on segmentation fault

Do what we can do without gdb and then tail to regular segmentation
fault. With core file gdb can still be used, but it is handy if we
already can get traceback of the crash into the log automatically.

TODO better use https://github.com/ianlancetaylor/libbacktrace because
backtrace_symbols often does not provide symbolic information.

We do not do this now because libbacktrace is not always automatically
installed.
parent e7cea028
......@@ -182,6 +182,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,28 @@ 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;
/* TODO better use https://github.com/ianlancetaylor/libbacktrace
* because backtrace_symbols often does not provide symbolic information */
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