diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-06-24 03:05:23 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-06-24 03:05:23 +0300 |
commit | 823ab66ecae218da6f96588b4bf01eb4f977ec8d (patch) | |
tree | 78f7f2f81bee63cfff3df8848135f0c185078463 /source | |
parent | 25866aa149968919a5b4ea01b94c5f31227cbd71 (diff) |
Avoid memory leaks on exit during argument parsing
Exiting Blender during argument parsing would leak memory
(tests, documentation generation, utilities).
While harmless, it hides real leaks which should be resolved.
Diffstat (limited to 'source')
-rw-r--r-- | source/creator/creator.c | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/source/creator/creator.c b/source/creator/creator.c index 315d0d40243..e2761c9ef38 100644 --- a/source/creator/creator.c +++ b/source/creator/creator.c @@ -148,6 +148,35 @@ static void main_callback_setup(void) MEM_set_error_callback(callback_mem_error); } +/* free data on early exit (if Python calls 'sys.exit()' while parsing args for eg). */ +struct CreatorAtExitData { + bArgs *ba; +#ifdef WIN32 + const char **argv; + int argv_num; +#endif +}; + +static void callback_main_atexit(void *user_data) +{ + struct CreatorAtExitData *app_init_data = user_data; + + if (app_init_data->ba) { + BLI_argsFree(app_init_data->ba); + app_init_data->ba = NULL; + } + +#ifdef WIN32 + if (app_init_data->argv) { + while (app_init_data->argv_num) { + free(app_init_data->argv[--app_init_data->argv_num]); + } + free(app_init_data->argv); + app_init_data->argv = NULL; + } +#endif +} + /** \} */ @@ -199,6 +228,9 @@ int main( /* --- end declarations --- */ + /* ensure we free data on early-exit */ + struct CreatorAtExitData app_init_data = {NULL}; + BKE_blender_atexit_register(callback_main_atexit, &app_init_data); #ifdef WIN32 /* We delay loading of openmp so we can set the policy here. */ @@ -222,6 +254,10 @@ int main( argv[argv_num] = alloc_utf_8_from_16(argv_16[argv_num], 0); } LocalFree(argv_16); + + /* free on early-exit */ + app_init_data.argv = argv; + app_init_data.argv_num = argv_num; } #endif /* WIN32 */ @@ -336,6 +372,10 @@ int main( /* first test for background */ #ifndef WITH_PYTHON_MODULE ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */ + + /* ensure we free on early exit */ + app_init_data.ba = ba; + main_args_setup(C, ba, &syshandle); BLI_argsParse(ba, 1, NULL, NULL); @@ -432,16 +472,22 @@ int main( #endif + /* Explicitly free data allocated for argument parsing: + * - 'ba' + * - 'argv' on WIN32. + */ + callback_main_atexit(&app_init_data); + BKE_blender_atexit_unregister(callback_main_atexit, &app_init_data); + + /* paranoid, avoid accidental re-use */ #ifndef WITH_PYTHON_MODULE - BLI_argsFree(ba); + ba = NULL; + (void)ba; #endif #ifdef WIN32 - while (argv_num) { - free(argv[--argv_num]); - } - free(argv); argv = NULL; + (void)argv; #endif #ifdef WITH_PYTHON_MODULE |