Skip to content

Commit 1092b06

Browse files
authored
Make test_emsymbolizer robust (#17584)
Currently the addresses are hardcoded, but we have seen them change multiple times in the last few weeks now. I think it's worthwhile to make them computed automatically at this point. It'd been easier to use `wasm-objdump` from wabt, but it is not a dependency of emscripten, so this uses `llvm-objdump`.
1 parent 1cbaadf commit 1092b06

File tree

2 files changed

+71
-23
lines changed

2 files changed

+71
-23
lines changed

test/core/test_dwarf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ EM_JS(int, out_to_js, (int x), {})
44

55
void __attribute__((noinline)) foo() {
66
out_to_js(0); // line 6
7-
out_to_js(1); // line 7
8-
out_to_js(2); // line 8
7+
out_to_js(1);
8+
out_to_js(2);
99
}
1010

1111
void __attribute__((always_inline)) bar() {
1212
out_to_js(3);
13-
__builtin_trap();
13+
__builtin_trap(); // line 13
1414
}
1515

1616
int main() {

test/test_other.py

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8631,45 +8631,93 @@ def test(infile, source_map_added_dir=''):
86318631
test('inner/a.cpp', 'inner')
86328632

86338633
def test_emsymbolizer(self):
8634-
def check_loc_info(address, source, funcs, locs):
8634+
def check_dwarf_loc_info(address, funcs, locs):
86358635
out = self.run_process(
8636-
[emsymbolizer, '-tcode', '-s', source, 'test_dwarf.wasm', address],
8636+
[emsymbolizer, '-tcode', '-s', 'dwarf', 'test_dwarf.wasm', address],
86378637
stdout=PIPE).stdout
86388638
for func in funcs:
86398639
self.assertIn(func, out)
86408640
for loc in locs:
86418641
self.assertIn(loc, out)
86428642

8643-
# Use hard-coded addresses. This is potentially brittle, but LLVM's
8644-
# O1 output is pretty minimal so hopefully it won't break too much?
8645-
# Another option would be to disassemble the binary to look for certain
8646-
# instructions or code sequences.
8643+
def check_source_map_loc_info(address, loc):
8644+
out = self.run_process(
8645+
[emsymbolizer, '-tcode', '-s', 'sourcemap', 'test_dwarf.wasm',
8646+
address],
8647+
stdout=PIPE).stdout
8648+
self.assertIn(loc, out)
8649+
8650+
# Runs llvm-objdump to get the address of the first occurrence of the
8651+
# specified line within the given function. llvm-objdump's output format
8652+
# example is as follows:
8653+
# ...
8654+
# 00000004 <foo>:
8655+
# ...
8656+
# 6: 41 00 i32.const 0
8657+
# ...
8658+
# The addresses here are the offsets to start of the code section. Returns
8659+
# the address string in hexadecimal.
8660+
def get_addr(text):
8661+
out = self.run_process([common.LLVM_OBJDUMP, '-d', 'test_dwarf.wasm'],
8662+
stdout=PIPE).stdout.strip()
8663+
out_lines = out.splitlines()
8664+
found = False
8665+
for line in out_lines:
8666+
if text in line:
8667+
offset = line.strip().split(':')[0]
8668+
found = True
8669+
break
8670+
assert found
8671+
return '0x' + offset
8672+
8673+
# We test two locations within test_dwarf.c:
8674+
# out_to_js(0); // line 6
8675+
# __builtin_trap(); // line 13
86478676

86488677
# 1. Test DWARF + source map together
86498678
self.run_process([EMCC, test_file('core/test_dwarf.c'),
86508679
'-g', '-gsource-map', '-O1', '-o', 'test_dwarf.js'])
8651-
# 0x8 corresponds to out_to_js(0) within foo(), uninlined
8652-
# DWARF info provides function names, but source maps don't
8653-
check_loc_info('0x8', 'dwarf', ['foo'], ['test_dwarf.c:6:3'])
8654-
check_loc_info('0x8', 'sourcemap', [], ['test_dwarf.c:6:3'])
8655-
# 0x1f corresponds to __builtin_trap() within bar(), inlined into main()
8656-
# DWARF info provides inlined info, but source maps don't
8657-
check_loc_info('0x1f', 'dwarf', ['bar', 'main'],
8658-
['test_dwarf.c:13:3', 'test_dwarf.c:18:3'])
8659-
check_loc_info('0x1f', 'sourcemap', [], ['test_dwarf.c:13:3'])
8680+
# Address of out_to_js(0) within foo(), uninlined
8681+
out_to_js_call_addr = get_addr('call\t0')
8682+
# Address of __builtin_trap() within bar(), inlined into main()
8683+
unreachable_addr = get_addr('unreachable')
8684+
8685+
# Function name of out_to_js(0) within foo(), uninlined
8686+
out_to_js_call_func = ['foo']
8687+
# Function names of __builtin_trap() within bar(), inlined into main(). The
8688+
# first one corresponds to the innermost inlined function.
8689+
unreachable_func = ['bar', 'main']
8690+
8691+
# Source location of out_to_js(0) within foo(), uninlined
8692+
out_to_js_call_loc = ['test_dwarf.c:6:3']
8693+
# Source locations of __builtin_trap() within bar(), inlined into main().
8694+
# The first one corresponds to the innermost inlined location.
8695+
unreachable_loc = ['test_dwarf.c:13:3', 'test_dwarf.c:18:3']
8696+
8697+
# For DWARF, we check for the full inlined info for both function names and
8698+
# source locations. Source maps provide neither function names nor inlined
8699+
# info. So we only check for the source location of the outermost function.
8700+
check_dwarf_loc_info(out_to_js_call_addr, out_to_js_call_func,
8701+
out_to_js_call_loc)
8702+
check_source_map_loc_info(out_to_js_call_addr, out_to_js_call_loc[0])
8703+
check_dwarf_loc_info(unreachable_addr, unreachable_func, unreachable_loc)
8704+
check_source_map_loc_info(unreachable_addr, unreachable_loc[0])
86608705

86618706
# 2. Test source map only
8707+
# The addresses, function names, and source locations are the same across
8708+
# the builds because they are relative offsets from the code section, so we
8709+
# don't need to recompute them
86628710
self.run_process([EMCC, test_file('core/test_dwarf.c'),
86638711
'-gsource-map', '-O1', '-o', 'test_dwarf.js'])
8664-
check_loc_info('0x8', 'sourcemap', [], ['test_dwarf.c:6:3'])
8665-
check_loc_info('0x1f', 'sourcemap', [], ['test_dwarf.c:13:3'])
8712+
check_source_map_loc_info(out_to_js_call_addr, out_to_js_call_loc[0])
8713+
check_source_map_loc_info(unreachable_addr, unreachable_loc[0])
86668714

86678715
# 3. Test DWARF only
86688716
self.run_process([EMCC, test_file('core/test_dwarf.c'),
86698717
'-g', '-O1', '-o', 'test_dwarf.js'])
8670-
check_loc_info('0x8', 'dwarf', ['foo'], ['test_dwarf.c:6:3'])
8671-
check_loc_info('0x1f', 'dwarf', ['bar', 'main'],
8672-
['test_dwarf.c:13:3', 'test_dwarf.c:18:3'])
8718+
check_dwarf_loc_info(out_to_js_call_addr, out_to_js_call_func,
8719+
out_to_js_call_loc)
8720+
check_dwarf_loc_info(unreachable_addr, unreachable_func, unreachable_loc)
86738721

86748722
def test_separate_dwarf(self):
86758723
self.run_process([EMCC, test_file('hello_world.c'), '-g'])

0 commit comments

Comments
 (0)