Skip to content
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

Memory bug on Windows x64 #52

Closed
kg opened this issue Sep 8, 2015 · 12 comments · Fixed by #84
Closed

Memory bug on Windows x64 #52

kg opened this issue Sep 8, 2015 · 12 comments · Fixed by #84

Comments

@kg
Copy link
Contributor

kg commented Sep 8, 2015

On my x64 Windows 10 box memory.wasm fails mysteriously:

-- Assert invoking...
Result: 42. : f64
Expect: 42. : f64
-- Error:
test/memory.wasm:151.1-151.45: assertion failed

Not sure what's going on here, don't know ocaml well enough to debug.

@lukewagner
Copy link
Member

I'm guessing that, though the text strings are identical, the float bits don't line up. I think you can confirm by changing the float case of values.ml:string_of_value to return Int64.to_string (Int64.of_float z).

@kg
Copy link
Contributor Author

kg commented Sep 8, 2015

Int64.to_string (Int64.of_float z) just prints '42'.

@lukewagner
Copy link
Member

Oops, I meant Int64.bits_of_float, not Int64.of_float.

@kg
Copy link
Contributor Author

kg commented Sep 8, 2015

Yeah, that's the problem:

Result: 4631107791820423180 : f64
Expect: 4631107791820423168 : f64

I'm not sure what to do about this. Does this indicate that our implementation is actually incorrect, at least on this os/arch combination?

@kg
Copy link
Contributor Author

kg commented Sep 8, 2015

Also fails:

(assert_eq (invoke "cast") (f64.convert_s/i32 (i32.const 42)))

@pjuftring
Copy link
Contributor

I compared the disassembled code of the windows-version of main.native with the linux-version and noticed, that windows only makes use of fpu commands, while linux uses SSE-like commands. Could this make the difference?

@kg
Copy link
Contributor Author

kg commented Sep 14, 2015

x87 vs SSE was my guess as well. I guess wasm on windows is doing 80-bit arithmetic and truncating, then?

@sunfishcode
Copy link
Member

There are ways that using x87 (fpu) instructions instead of SSE instructions can causes differences, but in the testcase here, all the values are small whole integers, so we ought to get the same answer regardless of which floating point unit is used.

@sunfishcode
Copy link
Member

@kg Would you mind trying a few more experiments:

  • modify the cast function to replace the last two stores with a single store of 4631107791820423168 to address 9 directly
  • change the store and subsequent load to use an aligned address instead of address 9
  • change the return value of the cast function to (f64.const 42.0) instead of doing a load
  • change the return value of the cast function to (f64.convert_s/i32 (i32.const 42))

@kg
Copy link
Contributor Author

kg commented Sep 15, 2015

Sure thing, I'll try all that the next time I'm at home.

@AndrewScheidecker
Copy link
Contributor

I'm running the 32-bit ocaml build on Windows that the ml-prototype README recommends. Before this change, I see the same thing as @kg. With that change, I get a segfault running either the unaligned or cast assert_eqs in memory.wasm. I narrowed it down to something triggered by using the result of a f64.load. Some testing shows that it can evaluate this without crashing:

    (i32.store (i32.const 8) (i32.const 0))
    (i64.store (i32.const 8) (i64.const 0))
    (f32.store (i32.const 8) (f32.const 0))
    (f64.store (i32.const 8) (f64.const 0))
    (i32.load (i32.const 8))
    (i64.load (i32.const 8))
    (f32.load (i32.const 8))
    (f64.load (i32.const 8))
    (i32.eq (i32.load (i32.const 8)) (i32.const 0))
    (i64.eq (i64.load (i32.const 8)) (i64.const 0))
    (f32.eq (f32.load (i32.const 8)) (f32.const 0))

But either of these operations will cause a segfault:

    (f64.eq (f64.load (i32.const 8)) (f64.const 0))
    (f64.add (f64.load (i32.const 8)) (f64.const 0))

I am highly suspicious of the Obj.magic in the memory module.

@maurer
Copy link

maurer commented Sep 22, 2015

It may be possible to use Genarray.map_file to produce differently typed views of the same memory without using Obj.magic.

I would expect this would prevent the unusual segfault behavior that people are seeing.

eqrion pushed a commit to eqrion/wasm-spec that referenced this issue Sep 18, 2019
dhil pushed a commit to dhil/webassembly-spec that referenced this issue Mar 2, 2023
dhil pushed a commit to dhil/webassembly-spec that referenced this issue Aug 30, 2024
Including a new `stack.new` instruction. Also add new descriptions of the
semantics of each instruction and a section on potential future instructions we
might want to add.
rossberg pushed a commit that referenced this issue Nov 6, 2024
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.

6 participants