-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
(posting this here instead of only IRC)
I was trying some wasm code with allocations and got a segmentation fault while running it.
To reproduce:
- use wasmtime from choose which function should be executed #21 (commits 4a28542 or 6854dec should be fine)
- compile this rust file to
wasm32-unknown-unknown:
#![feature(link_args)]
#![link_args = "--import-memory --initial-memory=1114112 --max-memory=65536000"]
#[no_mangle]
pub extern "C" fn hello(ctx: *const *mut u8) {
let v = "hello".to_string();
}(note: I tried using std::alloc directly, but could not reproduce)
I get the following output with lldb:
$ lldb ./target/debug/wasmtime
(lldb) target create "./target/debug/wasmtime"
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 52, in <module>
import weakref
File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/weakref.py", line 14, in <module>
from _weakref import (
ImportError: cannot import name _remove_dead_weakref
Current executable set to './target/debug/wasmtime' (x86_64).
(lldb) r ./testalloc.wasm --function=hello
Process 55272 launched: './target/debug/wasmtime' (x86_64)
Process 55272 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x2029ffff0)
frame #0: 0x000000010179ecb9
-> 0x10179ecb9: movl %eax, (%rdx,%rcx)
0x10179ecbd: movl $0x5, %eax
0x10179ecc3: movl 0x14(%rsp), %ecx
0x10179eccb: movl %ecx, %ecx
Target 0: (wasmtime) stopped.
(lldb) register read
General Purpose Registers:
rax = 0x0000000000110008
rbx = 0x0000000102821000
rcx = 0x00000000fffffff0
rdx = 0x0000000102a00000
rdi = 0x0000000102a00000
rsi = 0x0000000102a00000
rbp = 0x00007ffeefbfd660
rsp = 0x00007ffeefbfd640
r8 = 0x000000000000006f
r9 = 0x0000000000000005
r10 = 0x000000010160d008
r11 = 0x00007ffdee465e60
r12 = 0x0000000000000000
r13 = 0x0000000000000000
r14 = 0x00007ffeefbfed00
r15 = 0x00007ffeefbfecc0
rip = 0x000000010179ecb9
rflags = 0x0000000000010206
cs = 0x000000000000002b
fs = 0x0000000000000000
gs = 0x0000000000000000
This happens right after grow_memory is called. It adds a page and returns 17 (17 pages specified by the --initial-memory link arg).
From the debugger output, I see in the movl %eax, (%rdx,%rcx) instructions that rdx = 0x0000000102a00000, which is the base address for the LinearMemory, to which rcx = 0x00000000fffffff0 is added.
What I suspect here is that it's not trying to write rax = 0x0000000000110008 (which is 1114120 ie the initial memory size + 8) at the address 0x2029ffff0, but at the LinearMemory's base address minus 16 bytes, using an addition with overflow. Wasm32 assumes 32bit addresses and offsets, but here we're compiling to x86_64, so it won't ovrflow.