tarantool / test-run

Tarantool functional testing framework
14 stars 14 forks source link

Memory leak is not checked for core = tarantool tests #416

Open nshy opened 6 months ago

nshy commented 6 months ago

In case of memory leak sanitized program exit with non zero exit code. But we do not care for the exit code for core = tarantool tests. 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 for core = tarantool test:

-- test/app/exit_code.test.lua
ffi = require('ffi')
ffi.cdef('int tarantool_do_leak;')
ffi.C.tarantool_do_leak = 1
 $ test/test-run.py --builddir ../build-asan-debug app/exit_code
<snip>
======================================================================================
WORKR TEST                                            PARAMS          RESULT
---------------------------------------------------------------------------------
[001] app/exit_code.test.lua                                          [ pass ]
[001] [pass: 1]
[001]
[001] [Instance "app" returns with non-zero exit code: 1]
[001]
[001] [test-run server "app"] Last 15 lines of the log file /tmp/t/001_app/app.log:
[001] 2024-01-15 10:55:30.881 [1513443] main/103/app/box.load_cfg I> set 'listen' configuration option to "/tmp/t/001_app/app.i"
[001] 2024-01-15 10:55:30.882 [1513443] main/106/checkpoint_daemon I> scheduled next checkpoint for Mon Jan 15 12:21:42 2024
[001] 2024-01-15 10:55:30.883 [1513443] main/114/console/unix/:/tmp/t/001_app/app.c/socket I> started
[001] 2024-01-15 10:55:30.883 [1513443] main I> entering the event loop
[001] 2024-01-15 10:55:30.891 [1513443] main/117/iproto.shutdown I> tx_binary: stopped
[001]
[001] =================================================================
[001] ==1513443==ERROR: LeakSanitizer: detected memory leaks
[001]
[001] Direct leak of 10000 byte(s) in 1 object(s) allocated from:
[001]     #0 0x55632b1a1489 in malloc (/home/shiny/dev/tarantool/build-asan-debug/src/tarantool+0x11d4489) (BuildId: 265ed52bc3d20d699bdbce56ab8fbd720ee399cf)
[001]     #1 0x55632b1f4005 in main /home/shiny/dev/tarantool/src/main.cc:1115:28
[001]     #2 0x7f79e5c45ccf in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
[001]
[001] SUMMARY: AddressSanitizer: 10000 byte(s) leaked in 1 allocation(s).
---------------------------------------------------------------------------------
Top 10 tests by occupied memory (RSS, Mb):
*  121.1 app/exit_code.test.lua

(Tests quicker than 0.1 seconds may be missed.)

---------------------------------------------------------------------------------
Top 10 longest tests (seconds):
*   0.20 app/exit_code.test.lua
---------------------------------------------------------------------------------
Statistics:
* pass: 1
 $ echo $?
0

There is similar issue for luatest https://github.com/tarantool/luatest/issues/349.