BLI_assert: print a backtrace with the error

Add BLI_system_backtrace()
This commit is contained in:
Campbell Barton 2014-11-18 00:20:56 +01:00
parent 1e5d508567
commit 94f0d18470
5 changed files with 90 additions and 70 deletions

@ -27,6 +27,10 @@
int BLI_cpu_support_sse2(void);
#if !defined(NDEBUG) && !defined(__BLI_UTILDEFINES_H__)
void BLI_system_backtrace(FILE *fp);
#endif
/* getpid */
#ifdef WIN32
# define BLI_SYSTEM_PID_H <process.h>
@ -35,4 +39,3 @@ int BLI_cpu_support_sse2(void);
#endif
#endif /* __BLI_SYSTEM_H__ */

@ -510,6 +510,7 @@
* for aborting need to define WITH_ASSERT_ABORT
*/
#ifndef NDEBUG
extern void BLI_system_backtrace(FILE *fp);
# ifdef WITH_ASSERT_ABORT
# define _BLI_DUMMY_ABORT abort
# else
@ -519,6 +520,7 @@
# define BLI_assert(a) \
(void)((!(a)) ? ( \
( \
BLI_system_backtrace(stderr), \
fprintf(stderr, \
"BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \
__FILE__, __LINE__, __func__, STRINGIFY(a)), \

@ -22,9 +22,18 @@
* \ingroup bli
*/
#include <stdio.h>
#include <stdlib.h>
#include "BLI_system.h"
/* for backtrace */
#if defined(__linux__) || defined(__APPLE__)
# include <execinfo.h>
#elif defined(_MSV_VER)
# include <DbgHelp.h>
#endif
int BLI_cpu_support_sse2(void)
{
#if defined(__x86_64__) || defined(_M_X64)
@ -57,3 +66,69 @@ int BLI_cpu_support_sse2(void)
#endif
}
/**
* Write a backtrace into a file for systems which support it.
*/
void BLI_system_backtrace(FILE *fp)
{
/* ------------- */
/* Linux / Apple */
#if defined(__linux__) || defined(__APPLE__)
#define SIZE 100
void *buffer[SIZE];
int nptrs;
char **strings;
int i;
/* include a backtrace for good measure */
nptrs = backtrace(buffer, SIZE);
strings = backtrace_symbols(buffer, nptrs);
for (i = 0; i < nptrs; i++) {
fputs(strings[i], fp);
fputc('\n', fp);
}
free(strings);
#undef SIZE
/* -------- */
/* Windows */
#elif defined(_MSC_VER)
(void)fp;
#if 0
#define MAXSYMBOL 256
unsigned short i;
void *stack[SIZE];
unsigned short nframes;
SYMBOL_INFO *symbolinfo;
HANDLE process;
process = GetCurrentProcess();
SymInitialize(process, NULL, true);
nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table");
symbolinfo->MaxNameLen = MAXSYMBOL - 1;
symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
for (i = 0; i < nframes; i++) {
SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo);
fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address);
}
MEM_freeN(symbolinfo);
#undef MAXSYMBOL
#endif
/* ------------------ */
/* non msvc/osx/linux */
#else
(void)fp;
#endif
}
/* end BLI_system_backtrace */

@ -47,6 +47,14 @@
# endif
#endif
/* stub for BLI_abort() */
#ifndef NDEBUG
void BLI_system_backtrace(FILE *fp)
{
(void)fp;
}
#endif
/* Replace if different */
#define TMP_EXT ".tmp"

@ -48,13 +48,6 @@
# include "utfconv.h"
#endif
/* for backtrace */
#if defined(__linux__) || defined(__APPLE__)
# include <execinfo.h>
#elif defined(_MSV_VER)
# include <DbgHelp.h>
#endif
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@ -515,73 +508,12 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat
return 0;
}
#if defined(__linux__) || defined(__APPLE__)
/* Unix */
static void blender_crash_handler_backtrace(FILE *fp)
{
#define SIZE 100
void *buffer[SIZE];
int nptrs;
char **strings;
int i;
fputs("\n# backtrace\n", fp);
/* include a backtrace for good measure */
nptrs = backtrace(buffer, SIZE);
strings = backtrace_symbols(buffer, nptrs);
for (i = 0; i < nptrs; i++) {
fputs(strings[i], fp);
fputc('\n', fp);
BLI_system_backtrace(fp);
}
free(strings);
#undef SIZE
}
#elif defined(_MSC_VER)
static void blender_crash_handler_backtrace(FILE *fp)
{
(void)fp;
#if 0
#define MAXSYMBOL 256
unsigned short i;
void *stack[SIZE];
unsigned short nframes;
SYMBOL_INFO *symbolinfo;
HANDLE process;
process = GetCurrentProcess();
SymInitialize(process, NULL, true);
nframes = CaptureStackBackTrace(0, SIZE, stack, NULL);
symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table");
symbolinfo->MaxNameLen = MAXSYMBOL - 1;
symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO);
for (i = 0; i < nframes; i++) {
SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo);
fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address);
}
MEM_freeN(symbolinfo);
#endif
}
#else /* non msvc/osx/linux */
static void blender_crash_handler_backtrace(FILE *fp)
{
(void)fp;
}
#endif
static void blender_crash_handler(int signum)
{