Closed
Description
In case of memory leak sanitized program exit with non zero exit code. But we do not check the exit code for luatest.server
instance on server:stop()
or server:drop()
. As a result test will pass. In order to test for memory leaks we should fail in this case.
Or may be we should fail if there is ERROR: LeakSanitizer: detected memory leaks
in stderr output of the program.
Changes for demo:
diff --git a/asan/lsan.supp b/asan/lsan.supp
index 3432da22c..914b7cc2a 100644
--- a/asan/lsan.supp
+++ b/asan/lsan.supp
@@ -55,7 +55,7 @@ leak:tt_bitset_iterator_init
# test: box-py/args.test.py
# source: /lib/x86_64-linux-gnu/libc.so*
-leak:libc.so*
+# leak:libc.so*
# test: box-tap/schema_mt.test.lua
# source: src/lib/salad/mhash.h
diff --git a/extra/exports b/extra/exports
index 1dbfedc5c..0dfb2e431 100644
--- a/extra/exports
+++ b/extra/exports
@@ -678,4 +678,6 @@ luaM_sysprof_stop
# favor to it.
luaopen_misc
+tarantool_do_leak
+
# }}} LuaJIT API
diff --git a/src/main.cc b/src/main.cc
index 42f3a68a2..3d4b565a4 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -737,6 +737,9 @@ print_help(FILE *stream)
fprintf(stream, help_msg, tarantool_version());
}
+int tarantool_do_leak;
+static char *leaked_pointer;
+
int
main(int argc, char **argv)
{
@@ -1108,6 +1111,11 @@ main(int argc, char **argv)
/* freeing resources */
free((void *)instance.name);
free((void *)instance.config);
+ if (tarantool_do_leak) {
+ leaked_pointer = (char *)malloc(10000);
+ leaked_pointer[0] = 'a';
+ leaked_pointer = NULL;
+ }
tarantool_free();
ERROR_INJECT(ERRINJ_MAIN_MAKE_FILE_ON_RETURN, do {
int fd = open("tt_exit_file.txt.inprogress",
Test for leak detection on simple run:
-- test.lua
local ffi = require('ffi')
ffi.cdef[[
int tarantool_do_leak;
]]
ffi.C.tarantool_do_leak = 1
[tarantool]$ ./build-asan-debug/src/tarantool test.lua
=================================================================
==1450109==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 10000 byte(s) in 1 object(s) allocated from:
#0 0x55ac66db9489 in malloc (/home/shiny/dev/tarantool/build-asan-debug/src/tarantool+0x11d4489) (BuildId: 265ed52bc3d20d699bdbce56ab8fbd720ee399cf)
#1 0x55ac66e0c005 in main /home/shiny/dev/tarantool/src/main.cc:1115:28
#2 0x7fc95d445ccf in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
SUMMARY: AddressSanitizer: 10000 byte(s) leaked in 1 allocation(s).
[tarantool]$ echo $?
1
Test for leak detection in luatest:
-- test/app-luatest/exit_code_test.lua
local t = require('luatest')
local server = require('luatest.server')
local g = t.group()
g.test = function(cg)
cg.server = server:new()
cg.server:start()
cg.server:exec(function()
local ffi = require('ffi')
ffi.cdef[[
int tarantool_do_leak;
]]
ffi.C.tarantool_do_leak = 1
t.assert(true)
end)
end
[tarantool]$ test/test-run.py --builddir ../build-asan-debug app-luatest/exit_code
<snip>
======================================================================================
WORKR TEST PARAMS RESULT
---------------------------------------------------------------------------------
[001] app-luatest/exit_code_test.lua [ pass ]
---------------------------------------------------------------------------------
Top 10 tests by occupied memory (RSS, Mb):
* 102.1 app-luatest/exit_code_test.lua
(Tests quicker than 0.1 seconds may be missed.)
---------------------------------------------------------------------------------
Top 10 longest tests (seconds):
* 1.03 app-luatest/exit_code_test.lua
---------------------------------------------------------------------------------
Statistics:
* pass: 1
[tarantool]$
There is similar issue for core = tarantool
tests tarantool/test-run#416.