Skip to content

Adjust initial memory to handle asan shadow size #14631

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2130,12 +2130,25 @@ def check_memory_setting(setting):
max_mem = settings.INITIAL_MEMORY
if settings.ALLOW_MEMORY_GROWTH:
max_mem = settings.MAXIMUM_MEMORY
if max_mem == -1:
exit_with_error('ASan requires a finite MAXIMUM_MEMORY')

shadow_size = max_mem // 8
settings.GLOBAL_BASE = shadow_size

sanitizer_mem = (shadow_size + webassembly.WASM_PAGE_SIZE) & ~webassembly.WASM_PAGE_SIZE
# sanitizers do at least 9 page allocs of a single page during startup.
sanitizer_mem += webassembly.WASM_PAGE_SIZE * 9
# we also allocate at least 11 "regions". Each region is kRegionSize (2 << 20) but
# MmapAlignedOrDieOnFatalError adds another 2 << 20 for alignment.
sanitizer_mem += (1 << 21) * 11
# When running in the threaded mode asan needs to allocate an array of kMaxNumberOfThreads
# (1 << 22) pointers. See compiler-rt/lib/asan/asan_thread.cpp.
if settings.USE_PTHREADS:
sanitizer_mem += (1 << 22) * 4

# Increase the size of the initial memory according to how much memory
# we think the sanitizers will use.
settings.INITIAL_MEMORY += sanitizer_mem

if settings.SAFE_HEAP:
# SAFE_HEAP instruments ASan's shadow memory accesses.
# Since the shadow memory starts at 0, the act of accessing the shadow memory is detected
Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ def setUp(self):
super().setUp()
self.settings_mods = {}
self.emcc_args = ['-Werror']
self.node_args = []
self.node_args = ['--stack-trace-limit=50']
self.v8_args = []
self.env = {}
self.temp_files_before_run = []
Expand Down
5 changes: 3 additions & 2 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -8239,6 +8239,7 @@ def test_pthread_c11_threads(self):
def test_pthread_cxx_threads(self):
self.set_setting('PROXY_TO_PTHREAD')
self.clear_setting('ALLOW_MEMORY_GROWTH')
self.set_setting('INITIAL_MEMORY', '64Mb')
self.set_setting('EXIT_RUNTIME')
self.do_run_in_out_file_test('pthread/test_pthread_cxx_threads.cpp')

Expand Down Expand Up @@ -8595,9 +8596,9 @@ def setUp(self):
strict = make_run('strict', emcc_args=[], settings={'STRICT': 1})

lsan = make_run('lsan', emcc_args=['-fsanitize=leak', '--profiling', '-O2'], settings={'ALLOW_MEMORY_GROWTH': 1})
asan = make_run('asan', emcc_args=['-fsanitize=address', '--profiling', '-O2'], settings={'ALLOW_MEMORY_GROWTH': 1, 'INITIAL_MEMORY': '500mb'})
asan = make_run('asan', emcc_args=['-fsanitize=address', '--profiling', '-O2'], settings={'ALLOW_MEMORY_GROWTH': 1})
asani = make_run('asani', emcc_args=['-fsanitize=address', '--profiling', '-O2', '--pre-js', os.path.join(os.path.dirname(__file__), 'asan-no-leak.js')],
settings={'ALLOW_MEMORY_GROWTH': 1, 'INITIAL_MEMORY': '500mb'})
settings={'ALLOW_MEMORY_GROWTH': 1})

# Experimental modes (not tested by CI)
lld = make_run('lld', emcc_args=[], settings={'LLD_REPORT_UNDEFINED': 1})
Expand Down
8 changes: 4 additions & 4 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -9170,21 +9170,21 @@ def test_lsan_no_stack_trace(self):

def test_asan_null_deref(self):
self.do_smart_test(test_file('other/test_asan_null_deref.c'),
emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1', '-sINITIAL_MEMORY=314572800'],
emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1'],
assert_returncode=NON_ZERO, literals=[
'AddressSanitizer: null-pointer-dereference on address',
])

def test_asan_no_stack_trace(self):
self.do_smart_test(test_file('other/test_lsan_leaks.c'),
emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1', '-sINITIAL_MEMORY=314572800', '-DDISABLE_CONTEXT', '-s', 'EXIT_RUNTIME'],
emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1', '-DDISABLE_CONTEXT', '-s', 'EXIT_RUNTIME'],
assert_returncode=NON_ZERO, literals=[
'Direct leak of 3427 byte(s) in 3 object(s) allocated from:',
'SUMMARY: AddressSanitizer: 3427 byte(s) leaked in 3 allocation(s).',
])

def test_asan_pthread_stubs(self):
self.do_smart_test(test_file('other/test_asan_pthread_stubs.c'), emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1', '-sINITIAL_MEMORY=314572800'])
self.do_smart_test(test_file('other/test_asan_pthread_stubs.c'), emcc_args=['-fsanitize=address', '-sALLOW_MEMORY_GROWTH=1'])

@node_pthreads
def test_proxy_to_pthread_stack(self):
Expand Down Expand Up @@ -9285,7 +9285,7 @@ def test_mmap_and_munmap_anonymous(self):
self.do_other_test('test_mmap_and_munmap_anonymous.cpp', emcc_args=['-s', 'NO_FILESYSTEM'])

def test_mmap_and_munmap_anonymous_asan(self):
self.do_other_test('test_mmap_and_munmap_anonymous.cpp', emcc_args=['-s', 'NO_FILESYSTEM', '-fsanitize=address', '-s', 'ALLOW_MEMORY_GROWTH', '-sINITIAL_MEMORY=314572800'])
self.do_other_test('test_mmap_and_munmap_anonymous.cpp', emcc_args=['-s', 'NO_FILESYSTEM', '-fsanitize=address', '-s', 'ALLOW_MEMORY_GROWTH'])

def test_mmap_memorygrowth(self):
self.do_other_test('test_mmap_memorygrowth.cpp', ['-s', 'ALLOW_MEMORY_GROWTH'])
Expand Down