Skip to content

Commit ef81024

Browse files
committed
Fix lsan test suite
1 parent 76d0e15 commit ef81024

File tree

6 files changed

+58
-23
lines changed

6 files changed

+58
-23
lines changed

.circleci/config.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ jobs:
361361
steps:
362362
- run-tests:
363363
test_targets: "posixtest"
364+
test-lsan:
365+
executor: bionic
366+
steps:
367+
- run-tests:
368+
test_targets: "lsan"
364369
test-wasm0:
365370
executor: bionic
366371
steps:
@@ -466,6 +471,9 @@ workflows:
466471
- eslint
467472
- build-docs
468473
- build-linux
474+
- test-lsan:
475+
requires:
476+
- build-linux
469477
- test-sanity:
470478
requires:
471479
- build-linux

system/lib/compiler-rt/lib/lsan/lsan_interceptors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
394394
#endif
395395

396396
#if SANITIZER_EMSCRIPTEN
397+
#define __ATTRP_C11_THREAD ((void*)(uptr)-1)
397398
extern "C" {
398399
int emscripten_builtin_pthread_create(void *thread, void *attr,
399400
void *(*callback)(void *), void *arg);
@@ -452,7 +453,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr,
452453
ENSURE_LSAN_INITED;
453454
EnsureMainThreadIDIsCorrect();
454455
__sanitizer_pthread_attr_t myattr;
455-
if (!attr) {
456+
if (!attr || attr == __ATTRP_C11_THREAD) {
456457
pthread_attr_init(&myattr);
457458
attr = &myattr;
458459
}

tests/core/test_dynamic_cast.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@ struct Derived : Support {};
1616
int main() {
1717
Support* p = new Derived;
1818
dynamic_cast<Derived*>(p)->f();
19+
delete p;
20+
return 0;
1921
}

tests/test_core.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ def can_do_standalone(self):
184184
not self.get_setting('MINIMAL_RUNTIME') and \
185185
not self.get_setting('SAFE_HEAP') and \
186186
not self.get_setting('MEMORY64') and \
187-
'-fsanitize=address' not in self.emcc_args
187+
'-fsanitize=address' not in self.emcc_args and \
188+
'-fsanitize=leak' not in self.emcc_args
188189

189190

190191
def also_with_wasmfs(func):
@@ -662,6 +663,7 @@ def test_align64(self):
662663
''')
663664

664665
@no_asan('asan errors on corner cases we check')
666+
@no_lsan('lsan errors on corner cases we check')
665667
def test_aligned_alloc(self):
666668
self.do_runf(test_file('test_aligned_alloc.c'), '',
667669
emcc_args=['-Wno-non-power-of-two-alignment'])
@@ -875,6 +877,7 @@ def test_stack_placement(self):
875877
self.do_core_test('test_stack_placement.c')
876878

877879
@no_asan('asan does not support main modules')
880+
@no_lsan('asan does not support main modules')
878881
@no_wasm2js('MAIN_MODULE support')
879882
def test_stack_placement_pic(self):
880883
self.set_setting('TOTAL_STACK', 1024)
@@ -1284,7 +1287,8 @@ def test_exceptions_allowed(self):
12841287
# empty list acts the same as fully disabled
12851288
self.assertEqual(empty_size, disabled_size)
12861289
# big change when we disable exception catching of the function
1287-
self.assertGreater(size - empty_size, 0.01 * size)
1290+
if '-fsanitize=leak' not in self.emcc_args:
1291+
self.assertGreater(size - empty_size, 0.01 * size)
12881292
# full disable can remove a little bit more
12891293
self.assertLess(disabled_size, fake_size)
12901294

@@ -1569,6 +1573,7 @@ def test_segfault(self):
15691573
15701574
struct Classey {
15711575
virtual void doIt() = 0;
1576+
virtual ~Classey() = default;
15721577
};
15731578
15741579
struct D1 : Classey {
@@ -1583,11 +1588,11 @@ def test_segfault(self):
15831588
return 0;
15841589
});
15851590
1586-
int main(int argc, char **argv)
1587-
{
1591+
int main(int argc, char **argv) {
15881592
Classey *p = argc == 100 ? new D1() : (Classey*)%s;
15891593
15901594
p->doIt();
1595+
delete p;
15911596
15921597
return 0;
15931598
}
@@ -1769,16 +1774,17 @@ def test_set_align(self):
17691774

17701775
self.do_core_test('test_set_align.c')
17711776

1772-
@no_asan('EXPORT_ALL is not compatible with Asan')
17731777
def test_emscripten_api(self):
17741778
self.set_setting('EXPORTED_FUNCTIONS', ['_main', '_save_me_aimee'])
17751779
self.do_core_test('test_emscripten_api.cpp')
17761780

1777-
# test EXPORT_ALL
1778-
self.set_setting('EXPORTED_FUNCTIONS', [])
1779-
self.set_setting('EXPORT_ALL')
1780-
self.set_setting('LINKABLE')
1781-
self.do_core_test('test_emscripten_api.cpp')
1781+
# Sanitizers are not compatible with LINKABLE (dynamic linking.
1782+
if not is_sanitizing(self.emcc_args):
1783+
# test EXPORT_ALL
1784+
self.set_setting('EXPORTED_FUNCTIONS', [])
1785+
self.set_setting('EXPORT_ALL')
1786+
self.set_setting('LINKABLE')
1787+
self.do_core_test('test_emscripten_api.cpp')
17821788

17831789
def test_emscripten_run_script_string_int(self):
17841790
src = r'''
@@ -1923,7 +1929,6 @@ def test_em_asm_2(self):
19231929
# Tests various different ways to invoke the MAIN_THREAD_EM_ASM(), MAIN_THREAD_EM_ASM_INT() and MAIN_THREAD_EM_ASM_DOUBLE() macros.
19241930
# This test is identical to test_em_asm_2, just search-replaces EM_ASM to MAIN_THREAD_EM_ASM on the test file. That way if new
19251931
# test cases are added to test_em_asm_2.cpp for EM_ASM, they will also get tested in MAIN_THREAD_EM_ASM form.
1926-
@no_asan('Cannot use ASan: test depends exactly on heap size')
19271932
def test_main_thread_em_asm(self):
19281933
src = read_file(test_file('core/test_em_asm_2.cpp'))
19291934
create_file('src.cpp', src.replace('EM_ASM', 'MAIN_THREAD_EM_ASM'))
@@ -1974,10 +1979,8 @@ def test_em_asm_direct(self):
19741979
'linked_c': (['-s', 'MAIN_MODULE'], True),
19751980
})
19761981
def test_em_js(self, args, force_c):
1977-
if 'MAIN_MODULE' in args and not self.is_wasm():
1978-
self.skipTest('main module support for non-wasm')
1979-
if '-fsanitize=address' in self.emcc_args:
1980-
self.skipTest('no dynamic library support in asan yet')
1982+
if 'MAIN_MODULE' in args:
1983+
self.check_dylink()
19811984
self.emcc_args += args + ['-s', 'EXPORTED_FUNCTIONS=_main,_malloc']
19821985

19831986
self.do_core_test('test_em_js.cpp', force_c=force_c)
@@ -2110,6 +2113,7 @@ def test_memorygrowth_3_force_fail_reallocBuffer(self):
21102113
'grow': (['-sALLOW_MEMORY_GROWTH', '-sMAXIMUM_MEMORY=18MB'],)
21112114
})
21122115
@no_asan('requires more memory when growing')
2116+
@no_lsan('requires more memory when growing')
21132117
@no_memory64('does not fail under wasm64')
21142118
def test_aborting_new(self, args):
21152119
# test that C++ new properly errors if we fail to malloc when growth is
@@ -2119,6 +2123,7 @@ def test_aborting_new(self, args):
21192123

21202124
@no_wasm2js('no WebAssembly.Memory()')
21212125
@no_asan('ASan alters the memory size')
2126+
@no_lsan('LSan alters the memory size')
21222127
def test_module_wasm_memory(self):
21232128
self.emcc_args += ['--pre-js', test_file('core/test_module_wasm_memory.js')]
21242129
self.set_setting('IMPORTED_MEMORY')
@@ -5290,6 +5295,7 @@ def test_utf8_invalid(self):
52905295
def test_minimal_runtime_utf8_invalid(self):
52915296
self.set_setting('EXPORTED_RUNTIME_METHODS', ['UTF8ToString', 'stringToUTF8'])
52925297
self.set_setting('MINIMAL_RUNTIME')
5298+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
52935299
for decoder_mode in [False, True]:
52945300
self.set_setting('TEXTDECODER', decoder_mode)
52955301
print(str(decoder_mode))
@@ -5847,6 +5853,7 @@ def test_whets(self):
58475853
# node is slower, and fail on 64-bit
58485854
@require_v8
58495855
@no_asan('depends on the specifics of memory size, which for asan we are forced to increase')
5856+
@no_lsan('depends on the specifics of memory size, which for lsan we are forced to increase')
58505857
def test_dlmalloc_inline(self):
58515858
# needed with typed arrays
58525859
self.set_setting('INITIAL_MEMORY', '128mb')
@@ -5858,6 +5865,7 @@ def test_dlmalloc_inline(self):
58585865
# node is slower, and fail on 64-bit
58595866
@require_v8
58605867
@no_asan('depends on the specifics of memory size, which for asan we are forced to increase')
5868+
@no_lsan('depends on the specifics of memory size, which for lsan we are forced to increase')
58615869
def test_dlmalloc(self):
58625870
# needed with typed arrays
58635871
self.set_setting('INITIAL_MEMORY', '128mb')
@@ -5889,11 +5897,13 @@ def test_dlmalloc(self):
58895897

58905898
# Tests that a large allocation should gracefully fail
58915899
@no_asan('the memory size limit here is too small for asan')
5900+
@no_lsan('the memory size limit here is too small for lsan')
58925901
def test_dlmalloc_large(self):
58935902
self.emcc_args += ['-s', 'ABORTING_MALLOC=0', '-s', 'ALLOW_MEMORY_GROWTH=1', '-s', 'MAXIMUM_MEMORY=128MB']
58945903
self.do_runf(test_file('dlmalloc_test_large.c'), '0 0 0 1')
58955904

58965905
@no_asan('asan also changes malloc, and that ends up linking in new twice')
5906+
@no_lsan('lsan also changes malloc, and that ends up linking in new twice')
58975907
def test_dlmalloc_partial(self):
58985908
# present part of the symbols of dlmalloc, not all
58995909
src = read_file(test_file('new.cpp')).replace('{{{ NEW }}}', 'new int').replace('{{{ DELETE }}}', 'delete') + '''
@@ -5907,6 +5917,7 @@ def test_dlmalloc_partial(self):
59075917
self.do_run(src, 'new 4!\n*1,0*')
59085918

59095919
@no_asan('asan also changes malloc, and that ends up linking in new twice')
5920+
@no_lsan('lsan also changes malloc, and that ends up linking in new twice')
59105921
def test_dlmalloc_partial_2(self):
59115922
if 'SAFE_HEAP' in str(self.emcc_args):
59125923
self.skipTest('we do unsafe stuff here')
@@ -6400,7 +6411,7 @@ def do_test():
64006411
self.set_setting('ALLOW_MEMORY_GROWTH', 0)
64016412
do_test()
64026413

6403-
if '-fsanitize=address' in self.emcc_args:
6414+
if is_sanitizing(self.emcc_args):
64046415
# In ASan mode we need a large initial memory (or else wasm-ld fails).
64056416
# The OpenJPEG CMake will build several executables (which we need parts
64066417
# of in our testing, see above), so we must enable the flag for them all.
@@ -7718,6 +7729,7 @@ def test_asyncify_during_exit(self):
77187729
self.do_core_test('test_asyncify_during_exit.cpp', emcc_args=['-DNO_ASYNC'], out_suffix='_no_async')
77197730

77207731
@no_asan('asyncify stack operations confuse asan')
7732+
@no_lsan('undefined symbol __global_base')
77217733
@no_wasm2js('dynamic linking support in wasm2js')
77227734
def test_asyncify_main_module(self):
77237735
self.set_setting('ASYNCIFY', 1)
@@ -7744,7 +7756,7 @@ def test_emscripten_lazy_load_code(self, conditional):
77447756
second_size = os.path.getsize('emscripten_lazy_load_code.wasm.lazy.wasm')
77457757
print('first wasm size', first_size)
77467758
print('second wasm size', second_size)
7747-
if not conditional and self.is_optimizing() and '-g' not in self.emcc_args:
7759+
if not conditional and self.is_optimizing() and '-g' not in self.emcc_args and '-fsanitize=leak' not in self.emcc_args:
77487760
# If the call to lazy-load is unconditional, then the optimizer can dce
77497761
# out more than half
77507762
self.assertLess(first_size, 0.6 * second_size)
@@ -7809,6 +7821,7 @@ def verify_broken(args=['0']):
78097821

78107822
# Test basic wasm2js functionality in all core compilation modes.
78117823
@no_asan('no wasm2js support yet in asan')
7824+
@no_lsan('no wasm2js support yet in lsan')
78127825
def test_wasm2js(self):
78137826
if not self.is_wasm():
78147827
self.skipTest('redundant to test wasm2js in wasm2js* mode')
@@ -7824,6 +7837,7 @@ def test_wasm2js(self):
78247837
self.assertNotExists('test_hello_world.js.mem')
78257838

78267839
@no_asan('no wasm2js support yet in asan')
7840+
@no_lsan('no wasm2js support yet in lsan')
78277841
def test_maybe_wasm2js(self):
78287842
if not self.is_wasm():
78297843
self.skipTest('redundant to test wasm2js in wasm2js* mode')
@@ -7993,10 +8007,12 @@ def test_brk(self):
79938007
# Tests that we can use the dlmalloc mallinfo() function to obtain information
79948008
# about malloc()ed blocks and compute how much memory is used/freed.
79958009
@no_asan('mallinfo is not part of ASan malloc')
8010+
@no_lsan('mallinfo is not part of LSan malloc')
79968011
def test_mallinfo(self):
79978012
self.do_runf(test_file('mallinfo.cpp'), 'OK.')
79988013

79998014
@no_asan('cannot replace malloc/free with ASan')
8015+
@no_lsan('cannot replace malloc/free with LSan')
80008016
def test_wrap_malloc(self):
80018017
self.do_runf(test_file('wrap_malloc.cpp'), 'OK.')
80028018

@@ -8073,6 +8089,7 @@ def test_minimal_runtime_no_declare_asm_module_exports(self):
80738089
self.set_setting('WASM_ASYNC_COMPILATION', 0)
80748090
self.maybe_closure()
80758091
self.set_setting('MINIMAL_RUNTIME')
8092+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
80768093
self.do_runf(test_file('declare_asm_module_exports.cpp'), 'jsFunction: 1')
80778094

80788095
# Tests that -s MINIMAL_RUNTIME=1 works well in different build modes
@@ -8098,6 +8115,7 @@ def test_minimal_runtime_hello_world(self, args):
80988115
@no_asan('TODO: ASan support in minimal runtime')
80998116
def test_minimal_runtime_hello_printf(self, extra_setting):
81008117
self.set_setting('MINIMAL_RUNTIME')
8118+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
81018119
self.set_setting(extra_setting)
81028120
# $FS is not fully compatible with MINIMAL_RUNTIME so fails with closure
81038121
# compiler. lsan also pulls in $FS
@@ -8109,6 +8127,7 @@ def test_minimal_runtime_hello_printf(self, extra_setting):
81098127
@no_asan('TODO: ASan support in minimal runtime')
81108128
def test_minimal_runtime_safe_heap(self):
81118129
self.set_setting('MINIMAL_RUNTIME')
8130+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
81128131
self.set_setting('SAFE_HEAP')
81138132
# $FS is not fully compatible with MINIMAL_RUNTIME so fails with closure
81148133
# compiler.
@@ -8121,6 +8140,7 @@ def test_minimal_runtime_safe_heap(self):
81218140
@no_asan('TODO: ASan support in minimal runtime')
81228141
def test_minimal_runtime_global_initializer(self):
81238142
self.set_setting('MINIMAL_RUNTIME')
8143+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
81248144
self.maybe_closure()
81258145
self.do_runf(test_file('test_global_initializer.cpp'), 't1 > t0: 1')
81268146

@@ -8131,6 +8151,7 @@ def test_return_address(self):
81318151

81328152
@no_wasm2js('TODO: sanitizers in wasm2js')
81338153
@no_asan('-fsanitize-minimal-runtime cannot be used with ASan')
8154+
@no_lsan('-fsanitize-minimal-runtime cannot be used with LSan')
81348155
def test_ubsan_minimal_too_many_errors(self):
81358156
self.emcc_args += ['-fsanitize=undefined', '-fsanitize-minimal-runtime']
81368157
if not self.is_wasm():
@@ -8143,6 +8164,7 @@ def test_ubsan_minimal_too_many_errors(self):
81438164

81448165
@no_wasm2js('TODO: sanitizers in wasm2js')
81458166
@no_asan('-fsanitize-minimal-runtime cannot be used with ASan')
8167+
@no_lsan('-fsanitize-minimal-runtime cannot be used with LSan')
81468168
def test_ubsan_minimal_errors_same_place(self):
81478169
self.emcc_args += ['-fsanitize=undefined', '-fsanitize-minimal-runtime']
81488170
if not self.is_wasm():
@@ -8701,6 +8723,7 @@ def test_minimal_runtime_emscripten_get_exported_function(self):
87018723
# Could also test with -s ALLOW_TABLE_GROWTH=1
87028724
self.set_setting('RESERVED_FUNCTION_POINTERS', 2)
87038725
self.set_setting('MINIMAL_RUNTIME')
8726+
self.emcc_args += ['--pre-js', test_file('minimal_runtime_exit_handling.js')]
87048727
self.emcc_args += ['-lexports.js']
87058728
self.do_core_test('test_get_exported_function.cpp')
87068729

tests/third_party/libiberty/cp-demangle.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4220,7 +4220,9 @@ is_gnu_v3_mangled_dtor (const char *name)
42204220
int main(int argc, char **argv)
42214221
{
42224222
int status;
4223-
printf("*%s*\n", __cxa_demangle(argv[1], 0, 0, &status));
4223+
char* s = __cxa_demangle(argv[1], 0, 0, &status);
4224+
printf("*%s*\n", s);
4225+
free(s);
42244226
return 0;
42254227
}
42264228

tools/system_libs.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1730,14 +1730,13 @@ def add_library(libname):
17301730
add_library('libstandalonewasm')
17311731
add_library('libc_rt')
17321732

1733-
if settings.USE_LSAN:
1734-
force_include.add('liblsan_rt')
1735-
add_library('liblsan_rt')
1736-
17371733
if settings.USE_ASAN:
17381734
force_include.add('libasan_rt')
17391735
add_library('libasan_rt')
17401736
add_library('libasan_js')
1737+
elif settings.USE_LSAN:
1738+
force_include.add('liblsan_rt')
1739+
add_library('liblsan_rt')
17411740

17421741
if settings.UBSAN_RUNTIME == 1:
17431742
add_library('libubsan_minimal_rt')

0 commit comments

Comments
 (0)