include a stacktrace in the crashlog text written by the segfault handler.

This commit is contained in:
Campbell Barton 2013-01-11 01:30:44 +00:00
parent 0deb074f1c
commit 3fc0d2691d
3 changed files with 65 additions and 22 deletions

@ -74,7 +74,7 @@ Report *BKE_reports_last_displayable(ReportList *reports);
int BKE_reports_contain(ReportList *reports, ReportType level);
// int BKE_report_write_file_fp(struct FILE *fp, ReportList *reports, const char *header);
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header);
bool BKE_report_write_file(const char *filepath, ReportList *reports, const char *header);
#ifdef __cplusplus

@ -302,7 +302,7 @@ int BKE_reports_contain(ReportList *reports, ReportType level)
return FALSE;
}
static bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
bool BKE_report_write_file_fp(FILE *fp, ReportList *reports, const char *header)
{
Report *report;
@ -321,8 +321,6 @@ bool BKE_report_write_file(const char *filepath, ReportList *reports, const char
{
FILE *fp;
/* first try create the file, if it exists call without 'O_CREAT',
* to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
errno = 0;
fp = BLI_fopen(filepath, "wb");
if (fp == NULL) {

@ -40,11 +40,16 @@
# include <xmmintrin.h>
#endif
/* crash handler */
#ifdef WIN32
# include <process.h> /* getpid */
#else
# include <unistd.h> /* getpid */
#endif
/* for backtrace */
#ifndef WIN32
# include <execinfo.h>
#endif
#ifdef WIN32
# include <Windows.h>
@ -54,6 +59,7 @@
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
/* This little block needed for linking to Blender... */
@ -438,6 +444,32 @@ static int set_fpe(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(dat
return 0;
}
static void blender_crash_handler_backtrace(FILE *fp)
{
#ifndef WIN32
#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);
}
free(strings);
#undef SIZE
#else /* WIN32 */
/* TODO */
(void)fp;
#endif
}
static void blender_crash_handler(int signum)
{
@ -460,27 +492,40 @@ static void blender_crash_handler(int signum)
}
#endif
{
char header[512];
wmWindowManager *wm = G.main->wm.first;
FILE *fp;
char header[512];
wmWindowManager *wm = G.main->wm.first;
char fname[FILE_MAX];
char fname[FILE_MAX];
if (!G.main->name[0]) {
BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt");
}
else {
BLI_strncpy(fname, G.main->name, sizeof(fname));
BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
}
printf("Writing: %s\n", fname);
fflush(stdout);
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT);
BKE_report_write_file(fname, &wm->reports, header);
if (!G.main->name[0]) {
BLI_make_file_string("/", fname, BLI_temporary_dir(), "blender.crash.txt");
}
else {
BLI_strncpy(fname, G.main->name, sizeof(fname));
BLI_replace_extension(fname, sizeof(fname), ".crash.txt");
}
printf("Writing: %s\n", fname);
fflush(stdout);
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT);
/* open the crash log */
errno = 0;
fp = BLI_fopen(fname, "wb");
if (fp == NULL) {
fprintf(stderr, "Unable to save '%s': %s\n",
fname, errno ? strerror(errno) : "Unknown error opening file");
}
else {
BKE_report_write_file_fp(fp, &wm->reports, header);
blender_crash_handler_backtrace(fp);
fclose(fp);
}
/* really crash */
signal(signum, SIG_DFL);