From 3fc0d2691ddc1a0c8b1a808791924561b306cec1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 11 Jan 2013 01:30:44 +0000 Subject: include a stacktrace in the crashlog text written by the segfault handler. --- source/blender/blenkernel/BKE_report.h | 2 +- source/blender/blenkernel/intern/report.c | 4 +- source/creator/creator.c | 75 ++++++++++++++++++++++++------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/source/blender/blenkernel/BKE_report.h b/source/blender/blenkernel/BKE_report.h index 72611de107e..e659954a3ac 100644 --- a/source/blender/blenkernel/BKE_report.h +++ b/source/blender/blenkernel/BKE_report.h @@ -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 diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3acb35260cb..1fd7dc14c23 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -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) { diff --git a/source/creator/creator.c b/source/creator/creator.c index 7dd43840c91..f564e8c8fbf 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -40,11 +40,16 @@ # include #endif +/* crash handler */ #ifdef WIN32 # include /* getpid */ #else # include /* getpid */ #endif +/* for backtrace */ +#ifndef WIN32 +# include +#endif #ifdef WIN32 # include @@ -54,6 +59,7 @@ #include #include #include +#include /* 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"); - } + 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); + printf("Writing: %s\n", fname); + fflush(stdout); - BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); + BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_STRING_FMT); - BKE_report_write_file(fname, &wm->reports, header); + /* 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); -- cgit v1.2.3