@@ -9771,7 +9771,33 @@ def test(dump_file):
9771
9771
test('foo.wasm.dump')
9772
9772
test('bar.wasm.dump')
9773
9773
9774
- def test_emsymbolizer(self):
9774
+ def get_instr_addr(self, text, filename):
9775
+ '''
9776
+ Runs llvm-objdump to get the address of the first occurrence of the
9777
+ specified line within the given function. llvm-objdump's output format
9778
+ example is as follows:
9779
+ ...
9780
+ 00000004 <foo>:
9781
+ ...
9782
+ 6: 41 00 i32.const 0
9783
+ ...
9784
+ The addresses here are the offsets to the start of the file. Returns
9785
+ the address string in hexadecimal.
9786
+ '''
9787
+ out = self.run_process([common.LLVM_OBJDUMP, '-d', filename],
9788
+ stdout=PIPE).stdout.strip()
9789
+ out_lines = out.splitlines()
9790
+ found = False
9791
+ for line in out_lines:
9792
+ if text in line:
9793
+ offset = line.strip().split(':')[0]
9794
+ found = True
9795
+ break
9796
+ assert found
9797
+ return '0x' + offset
9798
+
9799
+ def test_emsymbolizer_srcloc(self):
9800
+ 'Test emsymbolizer use cases that provide src location granularity info'
9775
9801
def check_dwarf_loc_info(address, funcs, locs):
9776
9802
out = self.run_process(
9777
9803
[emsymbolizer, '-s', 'dwarf', 'test_dwarf.wasm', address],
@@ -9783,45 +9809,19 @@ def check_dwarf_loc_info(address, funcs, locs):
9783
9809
9784
9810
def check_source_map_loc_info(address, loc):
9785
9811
out = self.run_process(
9786
- [emsymbolizer, '-s', 'sourcemap', 'test_dwarf.wasm',
9787
- address],
9812
+ [emsymbolizer, '-s', 'sourcemap', 'test_dwarf.wasm', address],
9788
9813
stdout=PIPE).stdout
9789
9814
self.assertIn(loc, out)
9790
9815
9791
- # Runs llvm-objdump to get the address of the first occurrence of the
9792
- # specified line within the given function. llvm-objdump's output format
9793
- # example is as follows:
9794
- # ...
9795
- # 00000004 <foo>:
9796
- # ...
9797
- # 6: 41 00 i32.const 0
9798
- # ...
9799
- # The addresses here are the offsets to the start of the file. Returns
9800
- # the address string in hexadecimal.
9801
- def get_addr(text):
9802
- out = self.run_process([common.LLVM_OBJDUMP, '-d', 'test_dwarf.wasm'],
9803
- stdout=PIPE).stdout.strip()
9804
- out_lines = out.splitlines()
9805
- found = False
9806
- for line in out_lines:
9807
- if text in line:
9808
- offset = line.strip().split(':')[0]
9809
- found = True
9810
- break
9811
- assert found
9812
- return '0x' + offset
9813
-
9814
9816
# We test two locations within test_dwarf.c:
9815
9817
# out_to_js(0); // line 6
9816
9818
# __builtin_trap(); // line 13
9817
-
9818
- # 1. Test DWARF + source map together
9819
9819
self.run_process([EMCC, test_file('core/test_dwarf.c'),
9820
9820
'-g', '-gsource-map', '-O1', '-o', 'test_dwarf.js'])
9821
9821
# Address of out_to_js(0) within foo(), uninlined
9822
- out_to_js_call_addr = get_addr ('call\t0')
9822
+ out_to_js_call_addr = self.get_instr_addr ('call\t0', 'test_dwarf.wasm ')
9823
9823
# Address of __builtin_trap() within bar(), inlined into main()
9824
- unreachable_addr = get_addr ('unreachable')
9824
+ unreachable_addr = self.get_instr_addr ('unreachable', 'test_dwarf.wasm ')
9825
9825
9826
9826
# Function name of out_to_js(0) within foo(), uninlined
9827
9827
out_to_js_call_func = ['foo']
@@ -9835,6 +9835,7 @@ def get_addr(text):
9835
9835
# The first one corresponds to the innermost inlined location.
9836
9836
unreachable_loc = ['test_dwarf.c:13:3', 'test_dwarf.c:18:3']
9837
9837
9838
+ # 1. Test DWARF + source map together
9838
9839
# For DWARF, we check for the full inlined info for both function names and
9839
9840
# source locations. Source maps provide neither function names nor inlined
9840
9841
# info. So we only check for the source location of the outermost function.
@@ -9860,6 +9861,27 @@ def get_addr(text):
9860
9861
out_to_js_call_loc)
9861
9862
check_dwarf_loc_info(unreachable_addr, unreachable_func, unreachable_loc)
9862
9863
9864
+ def test_emsymbolizer_functions(self):
9865
+ 'Test emsymbolizer use cases that only provide function-granularity info'
9866
+ def check_func_info(filename, address, func):
9867
+ out = self.run_process(
9868
+ [emsymbolizer, filename, address], stdout=PIPE).stdout
9869
+ self.assertIn(func, out)
9870
+
9871
+ # 1. Test name section only
9872
+ self.run_process([EMCC, test_file('core/test_dwarf.c'),
9873
+ '--profiling-funcs', '-O1', '-o', 'test_dwarf.js'])
9874
+ with webassembly.Module('test_dwarf.wasm') as wasm:
9875
+ self.assertTrue(wasm.has_name_section())
9876
+ self.assertIsNone(wasm.get_custom_section('.debug_info'))
9877
+ # Address of out_to_js(0) within foo(), uninlined
9878
+ out_to_js_call_addr = self.get_instr_addr('call\t0', 'test_dwarf.wasm')
9879
+ # Address of __builtin_trap() within bar(), inlined into main()
9880
+ unreachable_addr = self.get_instr_addr('unreachable', 'test_dwarf.wasm')
9881
+ check_func_info('test_dwarf.wasm', out_to_js_call_addr, 'foo')
9882
+ # The name section will not show bar, as it's inlined into main
9883
+ check_func_info('test_dwarf.wasm', unreachable_addr, '__original_main')
9884
+
9863
9885
def test_separate_dwarf(self):
9864
9886
self.run_process([EMCC, test_file('hello_world.c'), '-g'])
9865
9887
self.assertExists('a.out.wasm')
0 commit comments