Skip to content

Emscripten / Binaryen miscompilation #1263

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

Closed
kumpera opened this issue Nov 2, 2017 · 2 comments
Closed

Emscripten / Binaryen miscompilation #1263

kumpera opened this issue Nov 2, 2017 · 2 comments

Comments

@kumpera
Copy link

kumpera commented Nov 2, 2017

While trying to compile mono, emscripten + binaryen miscompiles the following function:

static inline void
sgen_dummy_use (gpointer v)
{
#if defined(__GNUC__)
	__asm__ volatile ("" : "=r"(v) : "r"(v));
#elif defined(_MSC_VER)
	static volatile gpointer ptr;
	ptr = v;
#else
#error "Implement sgen_dummy_use for your compiler"
#endif
}

I'm using emsdk with the following installed:

emscripten-1.37.22
clang-e1.37.22-64bit
node-4.1.1-64bit

I'm running the compiler this way:

$(EMCC) -g4 -Os -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s BINARYEN=1 -s "BINARYEN_TRAP_MODE='clamp'" -s TOTAL_MEMORY=134217728 -s ALIASING_FUNCTION_POINTERS=0 --js-library library_mono.js driver.o $(TOP)/sdks/out/wasm-interp/lib/libmonosgen-2.0.a -o mono.js

It crashes when linking in asm2wasm with this assert:

$3
Assertion failed: (mappedGlobals.find(name) != mappedGlobals.end() ? true : (std::cerr << name.str << '\n', false)), function operator(), file /Users/kumpera/src/wasm/mono/sdks/builds/toolchains/emsdk/binaryen/master/src/asm2wasm.h, line 1544.

I dug into binaryen and this was the backtrace:

* thread #1, queue = 'com.apple.main-thread', stop reason = signal SIGSTOP
    frame #0: 0x000000010c329246 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007fb0e7d2f028, ast=Ref @ 0x00007ffee3950418)::$_3::operator()(cashew::Ref) const at asm2wasm.h:1546
    frame #1: 0x000000010c328a68 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) [inlined] decltype(__f=0x00007fb0e7d2f028, __args=0x00007ffee3952430)::$_3&>(fp)(std::__1::forward<cashew::Ref>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at type_traits:4291
    frame #2: 0x000000010c328a40 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007fb0e7d2f028, __args=0x00007ffee3952430)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at __functional_base:328
    frame #3: 0x000000010c328909 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3>, wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=0x00007ffee3952430)(cashew::Ref&&) at functional:1552
    frame #4: 0x000000010c33c0d9 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=Ref @ 0x00007ffee3952430)(cashew::Ref) const at functional:1911
    frame #5: 0x000000010c3304b5 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007fb0e7d2f028, ast=Ref @ 0x00007ffee3955d08)::$_3::operator()(cashew::Ref) const at asm2wasm.h:1945
    frame #6: 0x000000010c328a68 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) [inlined] decltype(__f=0x00007fb0e7d2f028, __args=0x00007ffee3957d20)::$_3&>(fp)(std::__1::forward<cashew::Ref>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at type_traits:4291
    frame #7: 0x000000010c328a40 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007fb0e7d2f028, __args=0x00007ffee3957d20)::$_3&, cashew::Ref>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3&&&, cashew::Ref&&) at __functional_base:328
    frame #8: 0x000000010c328909 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_3>, wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=0x00007ffee3957d20)(cashew::Ref&&) at functional:1552
    frame #9: 0x000000010c33c0d9 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref)>::operator(this=0x00007fb0e7d2f020, __arg=Ref @ 0x00007ffee3957d20)(cashew::Ref) const at functional:1911
    frame #10: 0x000000010c3518e8 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007ffee3959508, ast=Ref @ 0x00007ffee3957da0, from=2)::$_5::operator()(cashew::Ref, unsigned int) const at asm2wasm.h:2612
    frame #11: 0x000000010c3517ca asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) [inlined] decltype(__f=0x00007ffee3959508, __args=0x00007ffee3957ec8, __args=0x00007ffee3957ebc)::$_5&>(fp)(std::__1::forward<cashew::Ref, unsigned int>(fp0))) std::__1::__invoke<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) at type_traits:4291
    frame #12: 0x000000010c351794 asm2wasm`wasm::Expression* std::__1::__invoke_void_return_wrapper<wasm::Expression*>::__call<wasm::Asm2WasmBuilder::processFunction(__args=0x00007ffee3959508, __args=0x00007ffee3957ec8, __args=0x00007ffee3957ebc)::$_5&, cashew::Ref, unsigned int>(wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5&&&, cashew::Ref&&, unsigned int&&) at __functional_base:328
    frame #13: 0x000000010c351699 asm2wasm`std::__1::__function::__func<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5, std::__1::allocator<wasm::Asm2WasmBuilder::processFunction(cashew::Ref)::$_5>, wasm::Expression* (cashew::Ref, unsigned int)>::operator(this=0x00007ffee3959500, __arg=0x00007ffee3957ec8, __arg=0x00007ffee3957ebc)(cashew::Ref&&, unsigned int&&) at functional:1552
    frame #14: 0x000000010c2b07e8 asm2wasm`std::__1::function<wasm::Expression* (cashew::Ref, unsigned int)>::operator(this=0x00007ffee3959500, __arg=Ref @ 0x00007ffee3957ec8, __arg=2)(cashew::Ref, unsigned int) const at functional:1911
  * frame #15: 0x000000010c2adae7 asm2wasm`wasm::Asm2WasmBuilder::processFunction(this=0x00007ffee395bb20, ast=Ref @ 0x00007ffee39585d8) at asm2wasm.h:2618
    frame #16: 0x000000010c2a4aaa asm2wasm`wasm::Asm2WasmBuilder::processAsm(this=0x00007ffee395bb20, ast=Ref @ 0x00007ffee395a1a0) at asm2wasm.h:1032
    frame #17: 0x000000010c2b55af asm2wasm`main(argc=12, argv=0x00007ffee395e5b0) at asm2wasm.cpp:164

I inspected the bottom processFunction frame, which is how I found out what was the offending function and took the change to call dump on the body. I got this:

foo: [
  ["$0", [
    "binary",
    "|",
    "$0",
    0
  ]],
  [
    "var",
    [
      [
        "$1",
        0
      ],
      [
        "$2",
        0
      ],
      [
        "label",
        0
      ],
      [
        "sp",
        0
      ]
    ]
  ],
  ["sp", "STACKTOP"],
  ["STACKTOP", [
    "binary",
    "|",
    [
      "binary",
      "+",
      "STACKTOP",
      16
    ],
    0
  ]],
  ["$1", "sp"],
  [
    "call",
    "store4",
    [
      "$1",
      "$0"
    ]
  ],
  ["$2", [
    "call",
    "load4",
    [
      "$1"
    ]
  ]],
  [
    "call",
    "emscripten_debuginfo",
    [
      88,
      1142
    ]
  ],
  [
    "call",
    "emscripten_debuginfo",
    [
      88,
      1142
    ]
  ],
  [
    "call",
    "store4",
    [
      "$1",
      "$3"
    ]
  ],
  [
    "call",
    "emscripten_debuginfo",
    [
      88,
      1142
    ]
  ],
  ["STACKTOP", "sp"],
  [
    "return",
    null
  ],
  [
    "call",
    "emscripten_debuginfo",
    [
      88,
      1149
    ]
  ]
]
@kripken
Copy link
Member

kripken commented Nov 2, 2017

I tried to compile just that function (replacing gpointer with void*, and adding code to keep that function alive) but I don't see an error, with that command.

Can you provide the full files necessary to reproduce this crash? The intermediate .asm.js or bitcode file for example.

@tlively
Copy link
Member

tlively commented Jan 11, 2025

asm2wasm no longer exists.

@tlively tlively closed this as completed Jan 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants