Skip to content

Resolve synthetic compilation dir /emsdk/emscripten to obtain actual path for better source map #20779

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
Binary file not shown.
113 changes: 113 additions & 0 deletions test/other/wasm_sourcemap_resolve_dummy_comp_dir/foo.wasm.dump
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
foo.wasm: file format WASM

.debug_info contents:
0x00000000: Compile Unit: length = 0x00000045, format = DWARF32, version = 0x0004, abbr_offset = 0x0000, addr_size = 0x04 (next unit at 0x00000049)

0x0000000b: DW_TAG_compile_unit
DW_AT_producer ("clang version 18.0.0 (https://github.com/llvm/llvm-project 269685545e439ad050b67740533c59f965cae955)")
DW_AT_language (DW_LANG_C11)
DW_AT_name ("no_main.c")
DW_AT_stmt_list (0x00000000)
DW_AT_comp_dir ("/emscripten/test/other/wasm_sourcemap_resolve_dummy_comp_dir")
DW_AT_low_pc (0x00000002)
DW_AT_high_pc (0x0000000d)
0x00000049: Compile Unit: length = 0x00000120, format = DWARF32, version = 0x0004, abbr_offset = 0x0034, addr_size = 0x04 (next unit at 0x0000016d)

0x00000054: DW_TAG_compile_unit
DW_AT_stmt_list (0x00000042)
DW_AT_ranges (0x00000000
[0x0000000e, 0x00000016)
[0x00000017, 0x00000021)
[0x00000022, 0x0000003c))
DW_AT_name ("system/lib/compiler-rt/stack_ops.S")
DW_AT_comp_dir ("/emsdk/emscripten")
DW_AT_producer ("clang version 18.0.0 (https://github.com/llvm/llvm-project 269685545e439ad050b67740533c59f965cae955)")
DW_AT_language (DW_LANG_Mips_Assembler)

.debug_line contents:
debug_line[0x00000000]
Line table prologue:
total_length: 0x0000003e
format: DWARF32
version: 4
prologue_length: 0x00000021
min_inst_length: 1
max_ops_per_inst: 1
default_is_stmt: 1
line_base: -5
line_range: 14
opcode_base: 13
standard_opcode_lengths[DW_LNS_copy] = 0
standard_opcode_lengths[DW_LNS_advance_pc] = 1
standard_opcode_lengths[DW_LNS_advance_line] = 1
standard_opcode_lengths[DW_LNS_set_file] = 1
standard_opcode_lengths[DW_LNS_set_column] = 1
standard_opcode_lengths[DW_LNS_negate_stmt] = 0
standard_opcode_lengths[DW_LNS_set_basic_block] = 0
standard_opcode_lengths[DW_LNS_const_add_pc] = 0
standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
standard_opcode_lengths[DW_LNS_set_isa] = 1
file_names[ 1]:
name: "no_main.c"
dir_index: 0
mod_time: 0x00000000
length: 0x00000000

Address Line Column File ISA Discriminator OpIndex Flags
------------------ ------ ------ ------ --- ------------- ------- -------------
0x0000000000000005 12 3 1 0 0 0 is_stmt prologue_end
0x000000000000000d 12 3 1 0 0 0 is_stmt end_sequence

debug_line[0x00000042]
Line table prologue:
total_length: 0x000000ea
format: DWARF32
version: 4
prologue_length: 0x0000003a
min_inst_length: 1
max_ops_per_inst: 1
default_is_stmt: 1
line_base: -5
line_range: 14
opcode_base: 13
standard_opcode_lengths[DW_LNS_copy] = 0
standard_opcode_lengths[DW_LNS_advance_pc] = 1
standard_opcode_lengths[DW_LNS_advance_line] = 1
standard_opcode_lengths[DW_LNS_set_file] = 1
standard_opcode_lengths[DW_LNS_set_column] = 1
standard_opcode_lengths[DW_LNS_negate_stmt] = 0
standard_opcode_lengths[DW_LNS_set_basic_block] = 0
standard_opcode_lengths[DW_LNS_const_add_pc] = 0
standard_opcode_lengths[DW_LNS_fixed_advance_pc] = 1
standard_opcode_lengths[DW_LNS_set_prologue_end] = 0
standard_opcode_lengths[DW_LNS_set_epilogue_begin] = 0
standard_opcode_lengths[DW_LNS_set_isa] = 1
include_directories[ 1] = "system/lib/compiler-rt"
file_names[ 1]:
name: "stack_ops.S"
dir_index: 1
mod_time: 0x00000000
length: 0x00000000

Address Line Column File ISA Discriminator OpIndex Flags
------------------ ------ ------ ------ --- ------------- ------- -------------
0x000000000000000e 18 0 1 0 0 0 is_stmt
0x0000000000000011 19 0 1 0 0 0 is_stmt
0x0000000000000012 19 0 1 0 0 0 is_stmt end_sequence
0x0000000000000013 23 0 1 0 0 0 is_stmt
0x0000000000000016 24 0 1 0 0 0 is_stmt
0x0000000000000018 25 0 1 0 0 0 is_stmt
0x0000000000000019 25 0 1 0 0 0 is_stmt end_sequence
0x000000000000001f 30 0 1 0 0 0 is_stmt
0x0000000000000021 32 0 1 0 0 0 is_stmt
0x0000000000000023 34 0 1 0 0 0 is_stmt
0x0000000000000024 36 0 1 0 0 0 is_stmt
0x0000000000000026 37 0 1 0 0 0 is_stmt
0x0000000000000027 38 0 1 0 0 0 is_stmt
0x0000000000000029 39 0 1 0 0 0 is_stmt
0x000000000000002b 40 0 1 0 0 0 is_stmt
0x000000000000002d 41 0 1 0 0 0 is_stmt
0x000000000000002e 41 0 1 0 0 0 is_stmt end_sequence

13 changes: 13 additions & 0 deletions test/other/wasm_sourcemap_resolve_dummy_comp_dir/no_main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright 2023 The Emscripten Authors. All rights reserved.
* Emscripten is available under two separate licenses, the MIT license and the
* University of Illinois/NCSA Open Source License. Both these licenses can be
* found in the LICENSE file.
*/

// embuilder build libcompiler_rt --force
// emcc -nostartfiles -sASSERTIONS=0 -sSUPPORT_ERRNO=0 \
// -sEXPORTED_FUNCTIONS=_foo -Wl,--no-entry -g -o foo.wasm no_main.c
// llvm-dwarfdump -debug-info -debug-line --recurse-depth=0 foo.wasm \
// >foo.wasm.dump
int foo() { return 42; }
18 changes: 15 additions & 3 deletions test/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -9561,6 +9561,18 @@ def test_wasm_sourcemap_dead(self):
# has only two entries
self.assertRegexpMatches(output, r'"mappings":\s*"[A-Za-z0-9+/]+,[A-Za-z0-9+/]+"')

def test_wasm_sourcemap_resolve_dummy_comp_dir(self):
wasm_map_cmd = [PYTHON, path_from_root('tools/wasm-sourcemap.py'),
'--dwarfdump-output',
test_file('other/wasm_sourcemap_resolve_dummy_comp_dir/foo.wasm.dump'),
'-o', 'a.out.wasm.map',
test_file('other/wasm_sourcemap_resolve_dummy_comp_dir/foo.wasm'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use use just compile test/hello_world.c here rather then checking in the foo.wasm binary?

Also it looks like you accidentally added the .dump file to git too.

'--basepath=' + path_from_root()]
self.run_process(wasm_map_cmd, stdout=PIPE, stderr=PIPE)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe don't capture stdout and stderr here since if this command ever fails it could be good to show the output.

output = read_file('a.out.wasm.map')
# has an actual path to the source file of system library, not a dummy path (/emsdk/emscripten/**)
self.assertIn('"system/lib/compiler-rt/stack_ops.S"', output)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use assertContains here instead?


def test_wasm_sourcemap_relative_paths(self):
ensure_dir('build')

Expand Down Expand Up @@ -9803,11 +9815,11 @@ def test_dwarf_system_lib(self):
if config.FROZEN_CACHE:
self.skipTest("test doesn't work with frozen cache")
self.run_process([EMBUILDER, 'build', 'libemmalloc', '--force'])
libc = os.path.join(config.CACHE, 'sysroot', 'lib', 'wasm32-emscripten', 'libemmalloc.a')
self.assertExists(libc)
system_lib = os.path.join(config.CACHE, 'sysroot', 'lib', 'wasm32-emscripten', 'libemmalloc.a')
self.assertExists(system_lib)

dwdump = self.run_process(
[LLVM_DWARFDUMP, libc, '-debug-info', '-debug-line', '--recurse-depth=0'],
[LLVM_DWARFDUMP, system_lib, '-debug-info', '-debug-line', '--recurse-depth=0'],
stdout=PIPE).stdout
# Check that the embedded location of the source file is correct.
self.assertIn('DW_AT_name\t("system/lib/emmalloc.c")', dwdump)
Expand Down
11 changes: 7 additions & 4 deletions tools/system_libs.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
# link time.
USE_NINJA = int(os.environ.get('EMCC_USE_NINJA', '0'))

# A dummy path used as a compilation directory for deterministic builds.
DUMMY_EMSCRIPTEN_ROOT = '/emsdk/emscripten'


def files_in_path(path, filenames):
srcdir = utils.path_from_root(path)
Expand Down Expand Up @@ -472,9 +475,9 @@ def generate_ninja(self, build_dir, libname):
if self.deterministic_paths:
source_dir = utils.path_from_root()
relative_source_dir = os.path.relpath(source_dir, build_dir)
cflags += [f'-ffile-prefix-map={source_dir}=/emsdk/emscripten',
cflags += [f'-ffile-prefix-map={source_dir}={DUMMY_EMSCRIPTEN_ROOT}',
f'-ffile-prefix-map={relative_source_dir}/=',
'-fdebug-compilation-dir=/emsdk/emscripten']
f'-fdebug-compilation-dir={DUMMY_EMSCRIPTEN_ROOT}']
asflags = get_base_cflags(preprocess=False)
input_files = self.get_files()
ninja_file = os.path.join(build_dir, 'build.ninja')
Expand All @@ -494,9 +497,9 @@ def build_objects(self, build_dir):
if self.deterministic_paths:
source_dir = utils.path_from_root()
relative_source_dir = os.path.relpath(source_dir, build_dir)
cflags += [f'-ffile-prefix-map={source_dir}=/emsdk/emscripten',
cflags += [f'-ffile-prefix-map={source_dir}={DUMMY_EMSCRIPTEN_ROOT}',
f'-ffile-prefix-map={relative_source_dir}/=',
'-fdebug-compilation-dir=/emsdk/emscripten']
f'-fdebug-compilation-dir={DUMMY_EMSCRIPTEN_ROOT}']
case_insensitive = is_case_insensitive(build_dir)
for src in self.get_files():
ext = shared.suffix(src)
Expand Down
4 changes: 4 additions & 0 deletions tools/wasm-sourcemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
sys.path.insert(0, __rootdir__)

from tools import utils
from tools import system_libs

logger = logging.getLogger('wasm-sourcemap')

Expand Down Expand Up @@ -238,6 +239,9 @@ def read_dwarf_entries(wasm, options):
for file in re.finditer(r"file_names\[\s*(\d+)\]:\s+name: \"([^\"]*)\"\s+dir_index: (\d+)", line_chunk):
dir = include_directories[file.group(3)]
file_path = os.path.join(dir, file.group(2))
if file_path.startswith(f'{system_libs.DUMMY_EMSCRIPTEN_ROOT}{os.path.sep}'):
sub_dir = os.path.relpath(file_path, system_libs.DUMMY_EMSCRIPTEN_ROOT)
file_path = utils.path_from_root(sub_dir)
files[file.group(1)] = file_path

for line in re.finditer(r"\n0x([0-9a-f]+)\s+(\d+)\s+(\d+)\s+(\d+)(.*?end_sequence)?", line_chunk):
Expand Down