Skip to content

@memcpy panics on shared-memory WASM #15920

Closed
@Aandreba

Description

@Aandreba

Zig Version

0.11.0-dev.3332+76aa1fffb

Steps to Reproduce and Observed Behavior

The bug was found when executing a WASM library in Deno

Try creating an ArrayList, and then reserve capacity with ensureTotalCapacityPrecise.

Here is the code, but whith ensureTotalCapacityPrecise extracted

var alpha = std.ArrayList(u8).init(alloc);
{
    const T = u8;
    const alignment = null;
    var self = alpha;
    const new_capacity = 10;

    if (self.capacity >= new_capacity) return;

    const old_memory = self.allocatedSlice();
    if (self.allocator.resize(old_memory, new_capacity)) {
        self.capacity = new_capacity;
    } else {
        const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
        // In this line, the code panics throwing `RuntimeError: memory access out of bounds` in Deno
        @memcpy(new_memory[0..self.items.len], self.items);
        self.allocator.free(old_memory);
        self.items.ptr = new_memory.ptr;
        self.capacity = new_memory.len;
    }
}

Replace @memcpy with std.mem.copyForwards, and the code stops panicking.

var alpha = std.ArrayList(u8).init(alloc);
{
    const T = u8;
    const alignment = null;
    var self = alpha;
    const new_capacity = 10;

    if (self.capacity >= new_capacity) return;

    const old_memory = self.allocatedSlice();
    if (self.allocator.resize(old_memory, new_capacity)) {
        self.capacity = new_capacity;
    } else {
        const new_memory = try self.allocator.alignedAlloc(T, alignment, new_capacity);
        // Now this line executes as expected
        std.mem.copyForwards(u8, new_memory[0..self.items.len], self.items);
        self.allocator.free(old_memory);
        self.items.ptr = new_memory.ptr;
        self.capacity = new_memory.len;
    }
}

Expected Behavior

Well, this shoudn't panic!

My theory is that there is something about Wasm shared memory that messes up @memcpy when doing zero-sized copies (It seems to work fine when actually copying values, so it may have to do with the high value of the original undefined pointer). Apart from that, I have no idea,

Metadata

Metadata

Assignees

No one assigned

    Labels

    arch-wasm32-bit and 64-bit WebAssemblybackend-llvmThe LLVM backend outputs an LLVM IR Module.bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions