diff options
Diffstat (limited to 'source/creator/creator.c')
-rw-r--r-- | source/creator/creator.c | 238 |
1 files changed, 153 insertions, 85 deletions
diff --git a/source/creator/creator.c b/source/creator/creator.c index d779095c1ee..0ca5fbeccac 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -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> @@ -82,6 +75,7 @@ #include "DNA_scene_types.h" #include "DNA_userdef_types.h" +#include "BKE_appdir.h" #include "BKE_blender.h" #include "BKE_brush.h" #include "BKE_context.h" @@ -154,6 +148,10 @@ # include "CCL_api.h" #endif +#ifdef WITH_SDL_DYNLOAD +# include "sdlew.h" +#endif + /* from buildinfo.c */ #ifdef BUILD_DATE extern char build_date[]; @@ -197,12 +195,13 @@ static void setCallbacks(void); #ifndef WITH_PYTHON_MODULE static bool use_crash_handler = true; +static bool use_abort_handler = true; /* set breakpoints here when running in debug mode, useful to catch floating point errors */ #if defined(__linux__) || defined(_WIN32) || defined(OSX_SSE_FPE) static void fpe_handler(int UNUSED(sig)) { - // printf("SIGFPE trapped\n"); + fprintf(stderr, "debug: SIGFPE trapped\n"); } #endif @@ -420,6 +419,12 @@ static int disable_crash_handler(int UNUSED(argc), const char **UNUSED(argv), vo return 0; } +static int disable_abort_handler(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) +{ + use_abort_handler = false; + return 0; +} + static int background_mode(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { G.background = 1; @@ -511,73 +516,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); - } - - 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; + BLI_system_backtrace(fp); } -#endif - static void blender_crash_handler(int signum) { @@ -586,7 +530,7 @@ static void blender_crash_handler(int signum) char fname[FILE_MAX]; if (!G.main->name[0]) { - BLI_make_file_string("/", fname, BLI_temp_dir_base(), "crash.blend"); + BLI_make_file_string("/", fname, BKE_tempdir_base(), "crash.blend"); } else { BLI_strncpy(fname, G.main->name, sizeof(fname)); @@ -607,10 +551,10 @@ static void blender_crash_handler(int signum) char fname[FILE_MAX]; if (!G.main->name[0]) { - BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), "blender.crash.txt"); + BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), "blender.crash.txt"); } else { - BLI_join_dirfile(fname, sizeof(fname), BLI_temp_dir_base(), BLI_path_basename(G.main->name)); + BLI_join_dirfile(fname, sizeof(fname), BKE_tempdir_base(), BLI_path_basename(G.main->name)); BLI_replace_extension(fname, sizeof(fname), ".crash.txt"); } @@ -642,7 +586,7 @@ static void blender_crash_handler(int signum) } /* Delete content of temp dir! */ - BLI_temp_dir_session_purge(); + BKE_tempdir_session_purge(); /* really crash */ signal(signum, SIG_DFL); @@ -653,6 +597,93 @@ static void blender_crash_handler(int signum) #endif } +#ifdef WIN32 +LONG WINAPI windows_exception_handler(EXCEPTION_POINTERS *ExceptionInfo) +{ + switch (ExceptionInfo->ExceptionRecord->ExceptionCode) { + case EXCEPTION_ACCESS_VIOLATION: + fputs("Error: EXCEPTION_ACCESS_VIOLATION\n", stderr); + break; + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + fputs("Error: EXCEPTION_ARRAY_BOUNDS_EXCEEDED\n", stderr); + break; + case EXCEPTION_BREAKPOINT: + fputs("Error: EXCEPTION_BREAKPOINT\n", stderr); + break; + case EXCEPTION_DATATYPE_MISALIGNMENT: + fputs("Error: EXCEPTION_DATATYPE_MISALIGNMENT\n", stderr); + break; + case EXCEPTION_FLT_DENORMAL_OPERAND: + fputs("Error: EXCEPTION_FLT_DENORMAL_OPERAND\n", stderr); + break; + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + fputs("Error: EXCEPTION_FLT_DIVIDE_BY_ZERO\n", stderr); + break; + case EXCEPTION_FLT_INEXACT_RESULT: + fputs("Error: EXCEPTION_FLT_INEXACT_RESULT\n", stderr); + break; + case EXCEPTION_FLT_INVALID_OPERATION: + fputs("Error: EXCEPTION_FLT_INVALID_OPERATION\n", stderr); + break; + case EXCEPTION_FLT_OVERFLOW: + fputs("Error: EXCEPTION_FLT_OVERFLOW\n", stderr); + break; + case EXCEPTION_FLT_STACK_CHECK: + fputs("Error: EXCEPTION_FLT_STACK_CHECK\n", stderr); + break; + case EXCEPTION_FLT_UNDERFLOW: + fputs("Error: EXCEPTION_FLT_UNDERFLOW\n", stderr); + break; + case EXCEPTION_ILLEGAL_INSTRUCTION: + fputs("Error: EXCEPTION_ILLEGAL_INSTRUCTION\n", stderr); + break; + case EXCEPTION_IN_PAGE_ERROR: + fputs("Error: EXCEPTION_IN_PAGE_ERROR\n", stderr); + break; + case EXCEPTION_INT_DIVIDE_BY_ZERO: + fputs("Error: EXCEPTION_INT_DIVIDE_BY_ZERO\n", stderr); + break; + case EXCEPTION_INT_OVERFLOW: + fputs("Error: EXCEPTION_INT_OVERFLOW\n", stderr); + break; + case EXCEPTION_INVALID_DISPOSITION: + fputs("Error: EXCEPTION_INVALID_DISPOSITION\n", stderr); + break; + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + fputs("Error: EXCEPTION_NONCONTINUABLE_EXCEPTION\n", stderr); + break; + case EXCEPTION_PRIV_INSTRUCTION: + fputs("Error: EXCEPTION_PRIV_INSTRUCTION\n", stderr); + break; + case EXCEPTION_SINGLE_STEP: + fputs("Error: EXCEPTION_SINGLE_STEP\n", stderr); + break; + case EXCEPTION_STACK_OVERFLOW: + fputs("Error: EXCEPTION_STACK_OVERFLOW\n", stderr); + break; + default: + fputs("Error: Unrecognized Exception\n", stderr); + break; + } + + fflush(stderr); + + /* If this is a stack overflow then we can't walk the stack, so just show + * where the error happened */ + if (EXCEPTION_STACK_OVERFLOW != ExceptionInfo->ExceptionRecord->ExceptionCode) { + blender_crash_handler(SIGSEGV); + } + + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + + +static void blender_abort_handler(int UNUSED(signum)) +{ + /* Delete content of temp dir! */ + BKE_tempdir_session_purge(); +} static int set_factory_startup(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data)) { @@ -818,7 +849,7 @@ static int set_engine(int argc, const char **argv, void *data) { bContext *C = data; if (argc >= 2) { - if (!strcmp(argv[1], "help")) { + if (STREQ(argv[1], "help")) { RenderEngineType *type = NULL; printf("Blender Engine Listing:\n"); for (type = R_engines.first; type; type = type->next) { @@ -836,6 +867,7 @@ static int set_engine(int argc, const char **argv, void *data) } else { printf("\nError: engine not found '%s'\n", argv[1]); + exit(1); } } else { @@ -987,11 +1019,11 @@ static int set_ge_parameters(int argc, const char **argv, void *data) SYS_WriteCommandLineInt(syshandle, argv[a], 1); #endif /* doMipMap */ - if (!strcmp(argv[a], "nomipmap")) { + if (STREQ(argv[a], "nomipmap")) { GPU_set_mipmap(0); //doMipMap = 0; } /* linearMipMap */ - if (!strcmp(argv[a], "linearmipmap")) { + if (STREQ(argv[a], "linearmipmap")) { GPU_set_linear_mipmap(1); //linearMipMap = 1; } @@ -1191,7 +1223,7 @@ static int run_python_file(int argc, const char **argv, void *data) return 0; } #else - (void)argc; (void)argv; (void)data; /* unused */ + UNUSED_VARS(argc, argv, data); printf("This blender was built without python support\n"); return 0; #endif /* WITH_PYTHON */ @@ -1221,7 +1253,7 @@ static int run_python_text(int argc, const char **argv, void *data) return 0; } #else - (void)argc; (void)argv; (void)data; /* unused */ + UNUSED_VARS(argc, argv, data); printf("This blender was built without python support\n"); return 0; #endif /* WITH_PYTHON */ @@ -1236,7 +1268,7 @@ static int run_python_console(int UNUSED(argc), const char **argv, void *data) return 0; #else - (void)argv; (void)data; /* unused */ + UNUSED_VARS(argv, data); printf("This blender was built without python support\n"); return 0; #endif /* WITH_PYTHON */ @@ -1254,7 +1286,7 @@ static int set_addons(int argc, const char **argv, void *data) BPY_CTX_SETUP(BPY_string_exec(C, str)); free(str); #else - (void)argv; (void)data; /* unused */ + UNUSED_VARS(argv, data); #endif /* WITH_PYTHON */ return 1; } @@ -1303,7 +1335,14 @@ static int load_file(int UNUSED(argc), const char **argv, void *data) CTX_wm_manager_set(C, NULL); /* remove wm to force check */ WM_check(C); - G.relbase_valid = 1; + if (bmain->name[0]) { + G.save_over = 1; + G.relbase_valid = 1; + } + else { + G.save_over = 0; + G.relbase_valid = 0; + } if (CTX_wm_manager(C) == NULL) CTX_wm_manager_set(C, wm); /* reset wm */ /* WM_file_read would call normally */ @@ -1409,6 +1448,7 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle) BLI_argsAdd(ba, 1, "-Y", "--disable-autoexec", "\n\tDisable automatic python script execution (pydrivers & startup scripts)" PY_DISABLE_AUTO, disable_python, NULL); BLI_argsAdd(ba, 1, NULL, "--disable-crash-handler", "\n\tDisable the crash handler", disable_crash_handler, NULL); + BLI_argsAdd(ba, 1, NULL, "--disable-abort-handler", "\n\tDisable the abort handler", disable_abort_handler, NULL); #undef PY_ENABLE_AUTO #undef PY_DISABLE_AUTO @@ -1586,6 +1626,10 @@ int main( } #endif +#ifdef WITH_SDL_DYNLOAD + sdlewInit(); +#endif + C = CTX_create(); #ifdef WITH_PYTHON_MODULE @@ -1610,13 +1654,28 @@ int main( #endif setCallbacks(); + +#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE) +/* patch to ignore argument finder gives us (pid?) */ + if (argc == 2 && STREQLEN(argv[1], "-psn_", 5)) { + extern int GHOST_HACK_getFirstFile(char buf[]); + static char firstfilebuf[512]; + + argc = 1; + if (GHOST_HACK_getFirstFile(firstfilebuf)) { + argc = 2; + argv[1] = firstfilebuf; + } + } +#endif + #ifdef __FreeBSD__ fpsetmask(0); #endif /* initialize path to executable */ - BLI_init_program_path(argv[0]); + BKE_appdir_program_path_init(argv[0]); BLI_threadapi_init(); @@ -1647,9 +1706,18 @@ int main( BLI_argsParse(ba, 1, NULL, NULL); if (use_crash_handler) { +#ifdef WIN32 + SetUnhandledExceptionFilter(windows_exception_handler); +#else /* after parsing args */ signal(SIGSEGV, blender_crash_handler); +#endif + } + + if (use_abort_handler) { + signal(SIGABRT, blender_abort_handler); } + #else G.factory_startup = true; /* using preferences or user startup makes no sense for py-as-module */ (void)syshandle; @@ -1695,7 +1763,7 @@ int main( /* this is properly initialized with user defs, but this is default */ /* call after loading the startup.blend so we can read U.tempdir */ - BLI_temp_dir_init(U.tempdir); + BKE_tempdir_init(U.tempdir); } else { #ifndef WITH_PYTHON_MODULE @@ -1705,7 +1773,7 @@ int main( WM_init(C, argc, (const char **)argv); /* don't use user preferences temp dir */ - BLI_temp_dir_init(NULL); + BKE_tempdir_init(NULL); } #ifdef WITH_PYTHON /** |