$ bin/wasm-opt a.wasm -Oz -all
expected (v128, anyref), seeing v128 from
0x557a7c7f08e8
wasm-opt: src/wasm-interpreter.h:258: wasm::Flow wasm::ExpressionRunner<SubType>::visit(wasm::Expression*) [with SubType = wasm::PrecomputingExpressionRunner]: Assertion `Type::isSubType(type, curr->type)' failed.
Aborted
Bisected this to have started with #2702
cc @dcodeIO
Have a feeling that this has something to do with the runner being a bit more forgiving now, going to look into this!
So far found that
$> wasm-opt --all-features --precompute-propagte a.wasm
triggers the problem. Now throwing it at wasm-reduce, while hoping that I'm doing this right :)
Reduced: a.reduced.wasm.gz
After fixing WASM_INTERPRETER_DEBUG and activating it I'm seeing:
1: visit Unreachable : 0x7fffc1242a90
1: exit Unreachable
1: visit Unreachable : 0x7fffc1242b40
1: exit Unreachable
1: visit Unreachable : 0x7fffc1242c60
1: exit Unreachable
1: visit Unreachable : 0x7fffc1242d80
1: exit Unreachable
1: visit Unreachable : 0x7fffc1242dd8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243000
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243058
1: exit Unreachable
1: visit Unreachable : 0x7fffc12432d8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243410
1: exit Unreachable
1: visit Unreachable : 0x7fffc12434d8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243530
1: exit Unreachable
1: visit Unreachable : 0x7fffc12435f8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243730
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243788
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243838
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243890
1: exit Unreachable
1: visit Unreachable : 0x7fffc12438e8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243ad8
1: exit Unreachable
1: visit Unreachable : 0x7fffc1243bf8
1: exit Unreachable
1: visit GlobalGet : 0x7fffc1244278
1: name (global$2)
1: exit GlobalGet
1: visit Unreachable : 0x7fffc1244330
1: exit Unreachable
1: visit Block : 0x7fffc12444b0
2: visit RefNull : 0x7fffc12444e8
2: exit RefNull
1: exit Block
1: visit Unreachable : 0x7fffc1244600
1: exit Unreachable
1: visit Block : 0x7fffc12446c8
2: visit Drop : 0x7fffc1245680
3: visit Block : 0x7fffc1244700
4: visit Drop : 0x7fffc1245640
5: visit Block : 0x7fffc1244738
6: visit Drop : 0x7fffc12455f0
7: visit Block : 0x7fffc1244770
8: visit Drop : 0x7fffc12455b0
9: visit Block : 0x7fffc12447a8
10: visit Drop : 0x7fffc1245560
11: visit Block : 0x7fffc12447e0
12: visit Drop : 0x7fffc1245520
13: visit Block : 0x7fffc1244818
14: visit Drop : 0x7fffc12454d0
15: visit Block : 0x7fffc1244850
16: visit Drop : 0x7fffc1245400
17: visit Block : 0x7fffc1244888
18: visit Drop : 0x7fffc12453b0
19: visit Block : 0x7fffc12448c0
20: visit Drop : 0x7fffc1245378
21: visit Block : 0x7fffc12448f8
22: visit Drop : 0x7fffc1245338
23: visit Block : 0x7fffc1244930
24: visit Drop : 0x7fffc12452e8
25: visit Block : 0x7fffc1244968
26: visit Drop : 0x7fffc12452a8
27: visit Block : 0x7fffc12449a0
28: visit Drop : 0x7fffc1245258
29: visit Block : 0x7fffc12449d8
30: visit Drop : 0x7fffc1245218
31: visit Block : 0x7fffc1244a10
32: visit Drop : 0x7fffc12451c8
33: visit Block : 0x7fffc1244a48
34: visit Drop : 0x7fffc1245190
35: visit Block : 0x7fffc1244a80
36: visit Drop : 0x7fffc1245150
37: visit Block : 0x7fffc1244ab8
38: visit Drop : 0x7fffc1245100
39: visit Block : 0x7fffc1244af0
40: visit Drop : 0x7fffc12450c0
41: visit Block : 0x7fffc1244b28
42: visit Drop : 0x7fffc1245070
43: visit Block : 0x7fffc1244b60
44: visit LocalSet : 0x7fffc1244c88
44: eval curr->index (163)
45: visit Block : 0x7fffc1244b98
46: visit tuple.make : 0x7fffc1244c30
47: visit generateArguments
48: visit Const : 0x7fffc1244bd0
48: eval curr->value (i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
48: exit Const
47: eval flow.values (i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
48: visit RefNull : 0x7fffc1244bf8
48: exit RefNull
47: eval flow.values (nullref)
48: visit Const : 0x7fffc1244c08
48: eval curr->value (0)
48: exit Const
47: eval flow.values (0)
47: exit generateArguments
46: exit tuple.make
45: exit Block
44: exit LocalSet
44: visit Drop : 0x7fffc1244e30
45: visit Block : 0x7fffc1244e48
46: visit LocalSet : 0x7fffc1244e90
46: eval curr->index (165)
47: visit tuple.extract : 0x7fffc1244cc0
48: visit LocalGet : 0x7fffc1244ca8
48: eval curr->index (163)
48: exit LocalGet
47: exit tuple.extract
46: exit LocalSet
46: visit Drop : 0x7fffc1244d68
47: visit Block : 0x7fffc1244d80
48: visit LocalSet : 0x7fffc1244dc8
48: eval curr->index (164)
49: visit tuple.extract : 0x7fffc1244cf8
50: visit LocalGet : 0x7fffc1244ce0
50: eval curr->index (163)
50: exit LocalGet
expected (v128, anyref, i64), seeing v128 from
0x7fffece0bce0
wasm-opt: /path/to/wasm-interpreter.h:258: wasm::Flow wasm::ExpressionRunner<SubType>::visit(wasm::Expression*) [with SubType = wasm::PrecomputingExpressionRunner]: Assertion `Type::isSubType(type, curr->type)' failed.
Aborted (core dumped)
Try adding BINARYEN_CORES=1 to avoid all the messy thread interleaving stuff.
Thanks, updated the output :)
Is this after running wasm-reduce? I'm surprised it wouldn't have reduced the program more. Otherwise my next step would be to dive in with gdb:
$ gdb --args <bad wasm-opt invocation>
... blah blah blah GDB stuff ...
(gdb) run
... program runs until it crashes ...
(gdb) backtrace
... helpful backtrace printed with frame numbers ...
(gdb) frame <n>
... now we're at the interesting frame. We can go up and down frames with `up` and `down`
(gdb) tui enable
... now we have a nice text UI in the terminal and we can see where in the code we are ...
(gdb) print <some interesting C++ expression>
... now we can examine variables and their contents and figure out the issue ...
Side note: I'm not sure when WASM_INTERPRETER_DEBUG has ever been useful. Maybe can just get rid of it?
Yeah, that's after wasm-reduce. Perhaps I did something wrong? Invocation was
wasm-reduce --command 'wasm-opt --all-features --precompute-propagate testing.wasm' --test testing.wasm --working working.wasm a.wasm
Going to look into using gdb, hope this doesn't have unforeseen consequences in WSL :)
What I can tell so far is that there's a
(local.get $163)
returning a Flow with a single (v128) value where values should be (v128, anyref, i64) after being set from a tuple.make.
The corresponding tuple.make of the local.set is
(tuple.make
(v128.const i32x4 0x00000000 0x00000000 0x00000000 0x00000000)
(ref.null)
(i64.const 0)
)
running through a block, stored to the local, then stuff happens and the respective local.get returns something wrong.
wasm-reduce doesn't work well on testcases like this, because the multivalue stuff increases the size every time you save. So it think it's failing to reduce and stops early. I thought I opened an issue for that but looks like not?
You can reduce with --text so it's on the wat format which avoids most of that.
Oh, appears the cause is the std::move in visitLocalGet, corrupting the value down the road.
Postmortem: dcode should not use std::move since he doesn't understand it. Upcoming fix is to remove any std::moves introduced by dcode.
Most helpful comment
Postmortem: dcode should not use
std::movesince he doesn't understand it. Upcoming fix is to remove anystd::moves introduced by dcode.