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

ArrayList - segmentation fault when appending an indexed member. #8655

Closed
samhattangady opened this issue Apr 30, 2021 · 2 comments
Closed
Milestone

Comments

@samhattangady
Copy link
Contributor

When we create an std.ArrayList of a struct, if we try to append a new value into the arraylist, it raises a segmentation fault when the capacity is being expanded.

const std = @import("std");
var gpa = std.heap.GeneralPurposeAllocator(.{}){};

const Basket = struct {
    x: f32 = 0.0,
    y: f32 = 0.0,
    z: f32 = 0.0,
};

pub fn main() anyerror!void {
    var basket_list = std.ArrayList(Basket).init(&gpa.allocator);
    basket_list.append(.{}) catch unreachable;
    var i: usize = 0;
    while (i < 20) : (i += 1) {
        std.debug.print("i =  {d}\n", .{i});
        // This line fails at i = 7
        basket_list.append(basket_list.items[0]) catch unreachable;
        // This always succeeds 
        // var first = basket_list.items[0];
        // basket_list.append(first) catch unreachable;
    }
}
Segmentation fault at address 0x1dcfd5e0000
C:\Users\user\zig-windows-x86_64-0.8.0-dev.1983+e2cc02717\lib\zig\std\array_list.zig:183:30: 0x7ff70d8ca85f in std.array_list.ArrayListAligned(Basket,null)::std.array_list.ArrayListAligned(Basket,null).append (error1.obj)
            new_item_ptr.* = item;
                             ^
C:\Users\user\zig_playground\error1\src\main.zig:17:27: 0x7ff70d8b407b in main (error1.obj)
        basket_list.append(basket_list.items[0]) catch unreachable;
                          ^
thread 3688 panic: integer overflow
C:\Users\user\zig-windows-x86_64-0.8.0-dev.1983+e2cc02717\lib\zig\std\debug.zig:139:69: 0x7ff70d8d2426 in std.debug.dumpStackTraceFromBase (error1.obj)
            printSourceAtAddress(debug_info, stderr, return_address - 1, tty_config) catch return;
                                                                    ^
C:\Users\user\zig-windows-x86_64-0.8.0-dev.1983+e2cc02717\lib\zig\std\debug.zig:1876:31: 0x7ff70d8ca5ce in std.debug.handleSegfaultWindowsExtra (error1.obj)
        dumpStackTraceFromBase(regs.bp, regs.ip);
                              ^
C:\Users\user\zig-windows-x86_64-0.8.0-dev.1983+e2cc02717\lib\zig\std\debug.zig:1853:73: 0x7ff70d8b3ee8 in std.debug.handleSegfaultWindows (error1.obj)
        windows.EXCEPTION_ACCESS_VIOLATION => handleSegfaultWindowsExtra(info, 1, null),

I am not sure if this is the assumed behaviour. From what I understand, we should be passing the value of the item at index 0, and not a pointer, whereas the error makes it appear like we are passing a pointer.
This only happens when the ArrayList holds a struct. With other types like f32, the issue does not seem to arise.

I am using version 0.8.0-dev.1983+e2cc0271 on Windows.

@SpexGuy
Copy link
Contributor

SpexGuy commented Apr 30, 2021

This is another bug caused by the implicit value-to-pointer conversion of struct parameters. The first parameter to append is transformed to a pointer with &basket_list.items[0]. Within the function, the array is expanded and the old array is deallocated. This pointer now points to invalid memory. Then the code attempts to copy from this pointer into the new array, causing the segfault.

@Vexu
Copy link
Member

Vexu commented Apr 30, 2021

Duplicate of #5455, root cause is #5973.

@Vexu Vexu closed this as completed Apr 30, 2021
@andrewrk andrewrk added this to the 0.8.0 milestone Jun 4, 2021
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

No branches or pull requests

4 participants