From 6eb5ede6545fff07a18af5e8b630dec5de2d71c6 Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 30 Jan 2017 08:48:26 +0300 Subject: [PATCH] Fix a Lua state leak on script termination. --- src/sb_lua.c | 58 +++++++++++++++++++++++++------------------------- src/sb_lua.h | 2 ++ src/sysbench.c | 2 ++ 3 files changed, 33 insertions(+), 29 deletions(-) diff --git a/src/sb_lua.c b/src/sb_lua.c index 5867439..644ae2e 100644 --- a/src/sb_lua.c +++ b/src/sb_lua.c @@ -57,6 +57,8 @@ #define REPORT_INTERMEDIATE_HOOK "report_intermediate" #define REPORT_CUMULATIVE_HOOK "report_cumulative" +#define xfree(ptr) ({ if ((ptr) != NULL) free((void *) ptr); ptr = NULL; }) + /* Interpreter context */ typedef struct { @@ -204,12 +206,6 @@ static bool func_available(lua_State *L, const char *func) return rc; } -static void xfree(const void *ptr) -{ - if (ptr != NULL) - free((void *) ptr); -} - /* Export command line options */ static int do_export_options(lua_State *L, bool global) @@ -376,15 +372,36 @@ sb_test_t *sb_load_lua(const char *testname) error: - sb_lua_close_state(gstate); - xfree(states); - - xfree(sbtest.sname); - xfree(sbtest.lname); + sb_lua_done(); return NULL; } + +void sb_lua_done(void) +{ + sb_lua_close_state(gstate); + gstate = NULL; + + xfree(states); + + if (sbtest.args != NULL) + { + for (size_t i = 0; sbtest.args[i].name != NULL; i++) + { + xfree(sbtest.args[i].name); + xfree(sbtest.args[i].desc); + xfree(sbtest.args[i].value); + } + + xfree(sbtest.args); + } + + xfree(sbtest.sname); + xfree(sbtest.lname); +} + + /* Initialize Lua script */ int sb_lua_op_init(void) @@ -477,8 +494,6 @@ int sb_lua_op_thread_done(int thread_id) int sb_lua_op_done(void) { - xfree(states); - lua_getglobal(gstate, DONE_FUNC); if (!lua_isnil(gstate, -1)) { @@ -489,22 +504,7 @@ int sb_lua_op_done(void) } } - sb_lua_close_state(gstate); - - if (sbtest.args != NULL) - { - for (size_t i = 0; sbtest.args[i].name != NULL; i++) - { - xfree(sbtest.args[i].name); - xfree(sbtest.args[i].desc); - xfree(sbtest.args[i].value); - } - - free(sbtest.args); - } - - xfree(sbtest.sname); - xfree(sbtest.lname); + sb_lua_done(); return 0; } diff --git a/src/sb_lua.h b/src/sb_lua.h index 5edc2e6..e7fc7ac 100644 --- a/src/sb_lua.h +++ b/src/sb_lua.h @@ -27,6 +27,8 @@ sb_test_t *sb_load_lua(const char *testname); +void sb_lua_done(void); + int sb_lua_hook_call(lua_State *L, const char *name); bool sb_lua_custom_command_defined(const char *name); diff --git a/src/sysbench.c b/src/sysbench.c index e111d7e..a17f9c9 100644 --- a/src/sysbench.c +++ b/src/sysbench.c @@ -1513,6 +1513,8 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } + sb_lua_done(); + db_done(); sb_counters_done();