Add support for backtraces - if the compiler and libc version supports it (probably only glibc/gcc) then a stack trace is printed on serious bugs

darcs-hash:20070120023649-ac50b-5efa310bea0deddfa1d8dfca1000163eee89c7cb.gz
This commit is contained in:
axel 2007-01-20 12:36:49 +10:00
parent 1a76f2ecb9
commit 1300e68fa5
6 changed files with 66 additions and 16 deletions

View file

@ -44,6 +44,10 @@ parts of fish.
#include <sys/time.h>
#include <fcntl.h>
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#ifndef HOST_NAME_MAX
/**
Maximum length of hostname return. It is ok if this is too short,
@ -110,6 +114,28 @@ static struct winsize termsize;
*/
static string_buffer_t *setlocale_buff=0;
void show_stackframe()
{
void *trace[32];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 32);
messages = backtrace_symbols(trace, trace_size);
if( messages )
{
debug( 0, L"Backtrace:" );
for( i=0; i<trace_size; i++ )
{
fwprintf( stderr, L"%s\n", messages[i]);
}
free( messages );
}
}
wchar_t **list_to_char_arr( array_list_t *l )
{
wchar_t ** res = malloc( sizeof(wchar_t *)*(al_get_count( l )+1) );

View file

@ -86,9 +86,22 @@ extern wchar_t *program_name;
__func__, \
#arg ); \
bugreport(); \
show_stackframe(); \
return retval; \
}
/**
Cause fish to crash. If supported, print a backtrace first.
*/
#define CRASH() \
{ \
char c; \
show_stackframe(); \
read( 0, &c, 1 ); \
exit(1 ); \
} \
/**
Exit program at once, leaving an error message about running out of memory.
*/
@ -98,17 +111,7 @@ extern wchar_t *program_name;
L"fish: Out of memory on line %d of file %s, shutting down fish\n", \
__LINE__, \
__FILE__ ); \
exit(1); \
}
/**
Cause fish to crash. This should only be used for debugging. If
this function is ever called in shipped code, this is a bug.
*/
#define CRASH() \
{ \
int *n = 0; \
*n = 1; \
CRASH(); \
}
/**
@ -122,6 +125,7 @@ extern wchar_t *program_name;
_( L"function %s called while blocking signals. " ), \
__func__); \
bugreport(); \
show_stackframe(); \
return retval; \
}
@ -137,6 +141,8 @@ extern wchar_t *program_name;
#define N_(wstr) wstr
void show_stackframe();
/**
Take an array_list_t containing wide strings and converts them to a
single null-terminated wchar_t **. The array is allocated using

View file

@ -279,6 +279,12 @@ if test "$CC" = gcc; then
CFLAGS="$CFLAGS -Wall"
#
# This is needed in order to get the really cool backtraces
#
LDFLAGS="$LDFLAGS -rdynamic"
fi
@ -451,7 +457,7 @@ AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv impl
# Check presense of various header files
#
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h sys/termios.h libintl.h])
AC_CHECK_HEADERS([getopt.h termio.h sys/resource.h term.h ncurses/term.h ncurses.h curses.h stropts.h siginfo.h sys/select.h sys/ioctl.h sys/termios.h libintl.h execinfo.h])
AC_CHECK_HEADER(
[regex.h],
@ -594,8 +600,8 @@ fi
AC_CHECK_FUNCS( wcsdup wcsndup wcslen wcscasecmp wcsncasecmp fwprintf )
AC_CHECK_FUNCS( futimes wcwidth wcswidth wcstok fputwc fgetwc )
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg gettext dcgettext )
AC_CHECK_FUNCS( wcstol wcslcat wcslcpy lrand48_r killpg gettext )
AC_CHECK_FUNCS( dcgettext backtrace backtrace_symbols)
#
# The Makefile also needs to know if we have gettext, so it knows if

2
env.c
View file

@ -665,7 +665,7 @@ int env_set( const wchar_t *key,
event_t ev;
int is_universal = 0;
CHECK( key, ENV_INVALID );
if( (var_mode & ENV_USER ) &&

View file

@ -1091,3 +1091,16 @@ int getopt_long( int argc,
#endif
#ifndef HAVE_BACKTRACE
int backtrace (void **buffer, int size)
{
return 0;
}
#endif
#ifndef HAVE_BACKTRACE_SYMBOLS
char ** backtrace_symbols (void *const *buffer, int size)
{
return 0;
}
#endif

1
main.c
View file

@ -312,7 +312,6 @@ int main( int argc, char **argv )
reader_init();
history_init();
if( read_init() )
{
if( cmd != 0 )