I don't remember whether I posted this before. It's an external that
doesn't define any classes, but installs a crash report handler that
prints to the terminal. It requires <execinfo.h> which is linux-specific.
It decodes C++ symbols using <cxxabi.h> (provided by glibc). This means
you don't need to run gdb to get a basic listing of what happens. However
you will still need gdb if you need to know what the function arguments
were.
If you run an older version of GridFlow (9.11 or earlier) you will need to
ensure "segfault" appears after "gridflow" in the Startup menu. If not,
the order does not matter (unless you need to trap a crash at load-time).
------------------8<--------cut-here--------8<------------------
// segfault.cxx 1.0 by Mathieu Bouchard, 2010
// compile with : g++ segfault.cxx -shared -o segfault.pd_linux
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <execinfo.h>
#include <signal.h>
#include <cxxabi.h>
static void fault (int sig) {
const char *s;
if (sig==SIGSEGV) s="Segmentation Fault";
if (sig==SIGABRT) s="Abort";
if (sig==SIGILL) s="Invalid Instruction";
if (sig==SIGBUS) s="Bus Error";
fprintf(stderr,"\n------------------------------ caught %s\n",s);
#if defined(MACOSX) || defined(__WIN32__)
fprintf(stderr,"unhandled exception\n");
#else
void *array[100]; char demangled[1024]; size_t length=1024; int status;
int nSize = backtrace(array,100);
char **symbols = backtrace_symbols(array, nSize);
// for (int i=0; i<nSize; i++) fprintf(stderr,"%d: %s\n",i,symbols[i]);
for (int i=1; i<nSize; i++) {
char *a = strchr(symbols[i],'(');
char *b = strchr(symbols[i],'+');
if (a&&b) {
char mangled[1024];
sprintf(mangled,"%.*s",int(b-a-1),a+1);
if
(abi::__cxa_demangle(mangled,demangled,&length,&status))
fprintf(stderr,"%3d:
%.*s\n",i,int(length),demangled);
else
fprintf(stderr,"%3d: %s\n",i,symbols[i]);
}
else fprintf(stderr,"%3d: %s\n",i,symbols[i]);
}
#endif
fprintf(stderr,"-------- crash report displayed by segfault.pd_linux 1.0
(by matju)\n\n");
signal(sig,SIG_DFL);
_exit(128+sig);
}
extern "C" void segfault_setup (void) {
signal(SIGSEGV,fault);
signal(SIGABRT,fault);
signal(SIGILL, fault);
signal(SIGBUS, fault);
}
_______________________________________________________________________
| Mathieu Bouchard ------------------------------ Villeray, Montréal, QC