Skip to content

Fuzz failures after #2702 #2788

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
kripken opened this issue Apr 22, 2020 · 11 comments · Fixed by #2790
Closed

Fuzz failures after #2702 #2788

kripken opened this issue Apr 22, 2020 · 11 comments · Fixed by #2790

Comments

@kripken
Copy link
Member

kripken commented Apr 22, 2020

$ 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

a.wasm.gz

Bisected this to have started with #2702

cc @dcodeIO

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

Have a feeling that this has something to do with the runner being a bit more forgiving now, going to look into this!

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

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

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

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)

@tlively
Copy link
Member

tlively commented Apr 22, 2020

Try adding BINARYEN_CORES=1 to avoid all the messy thread interleaving stuff.

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

Thanks, updated the output :)

@tlively
Copy link
Member

tlively commented Apr 22, 2020

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?

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

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 :)

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

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.

@kripken
Copy link
Member Author

kripken commented Apr 22, 2020

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.

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

Oh, appears the cause is the std::move in visitLocalGet, corrupting the value down the road.

@dcodeIO
Copy link
Contributor

dcodeIO commented Apr 22, 2020

Postmortem: dcode should not use std::move since he doesn't understand it. Upcoming fix is to remove any std::moves introduced by dcode.

kripken pushed a commit that referenced this issue Apr 23, 2020
Fixes #2788 found by the fuzzer, introduced in #2702, which turned
out to be incorrect usage of std::move, by removing any std::moves
introduced in that PR to be better safe than sorry. Also fixes
problems with WASM_INTERPRETER_DEBUG spotted during
debugging.
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

Successfully merging a pull request may close this issue.

3 participants