Skip to content

Compiler error with malformed symbol generated #12551

Closed
@earwig

Description

@earwig

I'm tracking down a strange Emscripten error on a large project. Here's a minimal reproducible example:

#include <setjmp.h>

namespace foo {
    class Bar {
      public:
        void func() {}
    };
}

int main() {
    foo::Bar bar = foo::Bar();
    jmp_buf env;
    setjmp(env);
    bar.func();
}

The error (full text collapsed):

$ em++ -Wall main.cpp -o main.js
emscripten:ERROR: emscript: failure to parse metadata output from wasm-emscripten-finalize. raw output is:
{
...
  "declares": [
    "getTempRet0",
    "__invoke_void_%"class.foo::Bar"*",
    "emscripten_longjmp",
    "setTempRet0",
    "emscripten_resize_heap",
    "emscripten_memcpy_big"
  ],
...
}

Traceback (most recent call last):
...
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 869, in load_metadata_wasm
    metadata_json = json.loads(metadata_raw)
...
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 9 column 22 (char 146)
Full error
$ em++ -Wall main.cpp -o main.js
emscripten:ERROR: emscript: failure to parse metadata output from wasm-emscripten-finalize. raw output is:
{
  "staticBump": 536,
  "tableSize": 2,
  "initializers": [
    "__wasm_call_ctors"
  ],
  "declares": [
    "getTempRet0",
    "__invoke_void_%"class.foo::Bar"*",
    "emscripten_longjmp",
    "setTempRet0",
    "emscripten_resize_heap",
    "emscripten_memcpy_big"
  ],
  "externs": [
  ],
  "exports": [
    "__wasm_call_ctors",
    "malloc",
    "saveSetjmp",
    "testSetjmp",
    "free",
    "main",
    "__errno_location",
    "fflush",
    "stackSave",
    "stackRestore",
    "stackAlloc",
    "realloc",
    "setThrew"
  ],
  "namedGlobals": {
    "__data_end" : "1560"
  },
  "invokeFuncs": [
  ],
  "mainReadsParams": 1,
  "features": [
  ]
}

Traceback (most recent call last):
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/em++.py", line 14, in <module>
    sys.exit(emcc.run(sys.argv))
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emcc.py", line 2182, in run
    emscripten.run(tmp_wasm, final_js, memfile)
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 964, in run
    return temp_files.run_and_clean(lambda: emscript(
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/tools/tempfiles.py", line 105, in run_and_clean
    return func()
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 964, in <lambda>
    return temp_files.run_and_clean(lambda: emscript(
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 387, in emscript
    metadata = finalize_wasm(infile, memfile, DEBUG)
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 566, in finalize_wasm
    return load_metadata_wasm(stdout, DEBUG)
  File "/usr/local/Cellar/emscripten/2.0.7/libexec/emscripten.py", line 869, in load_metadata_wasm
    metadata_json = json.loads(metadata_raw)
  File "/usr/local/Cellar/python@3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/local/Cellar/python@3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/Cellar/python@3.8/3.8.6/Frameworks/Python.framework/Versions/3.8/lib/python3.8/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 9 column 22 (char 146)

A symbol named __invoke_void_%"class.foo::Bar"* is created, which is then dumped into JSON without any escaping.

Indeed, after setting EMCC_DEBUG=1 and inspecting the generated object file, the oddly named symbol is present:

$ llvm-objdump -t /.../emscripten_temp/main_0.o

main_0.o: file format wasm

SYMBOL TABLE:
00000001 g     F CODE .hidden __original_main
00000000         *UND* __stack_pointer
00000000       F *UND* malloc
00000000 l     O DATA .L__const.main.bar
00000000       F *UND* saveSetjmp
00000000       F *UND* getTempRet0
000001ad  w    F CODE .hidden _ZN3foo3Bar4funcEv
00000000       O *UND* __THREW__
00000000       F *UND* __invoke_void_%"class.foo::Bar"*
00000000       O *UND* __threwValue
00000000       F *UND* testSetjmp
00000000       F *UND* emscripten_longjmp
00000000       F *UND* setTempRet0
00000000       F *UND* free
000001cd g     F CODE .hidden main

I'm not sure if the bug is just (1) wasm-emscripten-finalize needs to escape symbols properly, or also (2) the symbol name is wrong. Certainly a symbol name with a double quote in it feels extremely wrong, but I'm not sure if it actually is.

Environment:

  • macOS 10.14.6 (I think this might be macOS-specific)
  • emcc 2.0.7
  • Apple clang 11.0.0
  • emscripten_temp.zip

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions