Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-06-24 03:05:23 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-06-24 03:05:23 +0300
commit823ab66ecae218da6f96588b4bf01eb4f977ec8d (patch)
tree78f7f2f81bee63cfff3df8848135f0c185078463 /source/creator
parent25866aa149968919a5b4ea01b94c5f31227cbd71 (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/creator')
-rw-r--r--source/creator/creator.c56
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