-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
segmentation fault when allocating #23
Comments
Thanks for debugging this to this point! I'll take a closer look next week. |
BTW, I was able to reproduce with a much smaller example: #![feature(link_args)]
#![allow(unused_attributes)] // link_args actually is used
#![link_args = "--import-memory --initial-memory=1114112 --max-memory=65536000"]
fn address(v: *mut u8) {
unsafe {
let v2 = (v as usize - 16) as *mut u8;
*v2 = 0x32;
};
}
#[no_mangle]
pub extern "C" fn load() {
unsafe {
let v: *mut u8 = 2_147_483_647 as *mut u8;
address(v);
}
} (module
(type $t0 (func))
(type $t1 (func (param i32)))
(import "env" "memory" (memory $env.memory 17 1000))
(func $testload::address::hfcb094981e27477e (type $t1) (param $p0 i32)
(local $l0 i32) (local $l1 i32) (local $l2 i32)
(set_local $l0
(i32.const 50))
(set_local $l1
(i32.const 16))
(set_local $l2
(i32.sub
(get_local $p0)
(get_local $l1)))
(i32.store8
(get_local $l2)
(get_local $l0))
(return))
(func $load (export "load") (type $t0)
(local $l0 i32)
(set_local $l0
(i32.const 2147483647))
(call $testload::address::hfcb094981e27477e
(get_local $l0))
(return))
(table $__indirect_function_table (export "__indirect_function_table") 1 1 anyfunc)
(global $__heap_base (export "__heap_base") i32 (i32.const 1048576))
(global $__data_end (export "__data_end") i32 (i32.const 1048576))) LLDB output:
|
here is the wat without memory imports: (module
(type $t0 (func))
(type $t1 (func (param i32)))
(func $testload::address::hfcb094981e27477e (type $t1) (param $p0 i32)
(local $l0 i32) (local $l1 i32) (local $l2 i32)
(set_local $l0
(i32.const 50))
(set_local $l1
(i32.const 16))
(set_local $l2
(i32.sub
(get_local $p0)
(get_local $l1)))
(i32.store8
(get_local $l2)
(get_local $l0))
(return))
(func $load (export "load") (type $t0)
(local $l0 i32)
(set_local $l0
(i32.const 2147483647))
(call $testload::address::hfcb094981e27477e
(get_local $l0))
(return))
(table $__indirect_function_table (export "__indirect_function_table") 1 1 anyfunc)
(memory $memory (export "memory") 16)
(global $__heap_base (export "__heap_base") i32 (i32.const 1048576))
(global $__data_end (export "__data_end") i32 (i32.const 1048576))) |
This wat file is doing a store to an arbitrary memory address which is beyond the end of the linear memory, so the expected behavior is to trap. On master, it now reports the trap. |
this last file was an example to demonstrate the issue of going from 32 bit wasm to x86_64 pointers. I have not tested yet if the first example would now work, since memory imports changed recently |
There have now been a bunch more changes, and lots of bugs fixed -- Wasmtime now passes the entire spec testsuite! So it'd be interesting to retry your testcase here now. |
Closing; if there are any further issues, please report them! |
Fix for ctz and clz
* Implement the `fd_readdir` function This roughly matches the implementation in `wasi-common` today where it uses the directory entry stream as a form of iterator and the `cookie` represents the `n`th iteration. Not exactly efficient if the `buf` provided to the hostcall is too small to hold many of the entries but there's not a whole lot else that can be done at this time. This also updates the WIT for `read-dir-entry` to return `option<dir-entry>` instead of `dir-entry` to indicate EOF. * Fix host compile * Add a specific method to close a dir-entry-stream * Add a cache to avoid quadratic dirent behavior When a readdir call is truncated due to the output buffer not being large enough save the final state of the readdir iterator into `State` to possibly get reused on the next call to `readdir`. Some limits are put in place such as: * The next call to readdir must be for the same fd and the required cookie. * The dirent that didn't fit must have its full name fit within the path cache. * If `fd_close` is called after a readdir it clears the cache so a future `fd_readdir` doesn't actually resume now-stale state. There's a fair bit of trickiness here so I've attempted to structure things as "simply" as possible to hopefully reduce the chance there's an issue, but this is all untested so there's still likely an off-by-one or similar bug.
* Implement the `fd_readdir` function This roughly matches the implementation in `wasi-common` today where it uses the directory entry stream as a form of iterator and the `cookie` represents the `n`th iteration. Not exactly efficient if the `buf` provided to the hostcall is too small to hold many of the entries but there's not a whole lot else that can be done at this time. This also updates the WIT for `read-dir-entry` to return `option<dir-entry>` instead of `dir-entry` to indicate EOF. * Fix host compile * Add a specific method to close a dir-entry-stream * Add a cache to avoid quadratic dirent behavior When a readdir call is truncated due to the output buffer not being large enough save the final state of the readdir iterator into `State` to possibly get reused on the next call to `readdir`. Some limits are put in place such as: * The next call to readdir must be for the same fd and the required cookie. * The dirent that didn't fit must have its full name fit within the path cache. * If `fd_close` is called after a readdir it clears the cache so a future `fd_readdir` doesn't actually resume now-stale state. There's a fair bit of trickiness here so I've attempted to structure things as "simply" as possible to hopefully reduce the chance there's an issue, but this is all untested so there's still likely an off-by-one or similar bug.
Latest changes from upstream
(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:
wasm32-unknown-unknown
:(note: I tried using
std::alloc
directly, but could not reproduce)I get the following output with lldb:
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 thatrdx = 0x0000000102a00000
, which is the base address for theLinearMemory
, to whichrcx = 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 address0x2029ffff0
, but at theLinearMemory
'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.The text was updated successfully, but these errors were encountered: