#Different behavior when I run "zig build run" and './zig-out/bin/myapp'

1 messages · Page 1 of 1 (latest)

neon lion
#

I was playing around with zig, when I produced the following code which is totally questionable:

const std = @import("std");

pub const Foo = struct {
    buffer: [5586936]u8 = undefined,

    pub fn init(self: Foo) *Foo {
        const x = @constCast(&self);
        return x;
    }

    pub fn dosomething(_: *Foo) void {}
};

pub fn main() !void {
    var p = (Foo{}).init();
    p.dosomething();
}

This code has several problems, but what intrigued me the most was that when I run it with the zig build run command it runs without any errors, but if I run zig build -Doptimize=Debug && ./zig-out/bin/executable it throws a segmentation fault error.

Could someone explain why the behavior is different for the two commands?

Another interesting point is that if I decrease the buffer size from 5586936 to 5586935, the error does not occur with either command.

graceful rapids
#

zig build setting an ulimit?

#

im guessing based on the fact, that buffer seems to take up a lot of stack

#

also line 7 is returning a stack address, that should go out of scope

#

could you also try building with llvm

neon lion
# graceful rapids zig build setting an ulimit?

I did a test and it seems to be this, zig build run runs with a different stack size than the system default, I set ulimit -s 16384 and the error did not occur when I ran it using zig build -Doptimize=Debug && ./zig-out/bin/executabl

#

but now the question remains what is the stack size of zig build run

graceful rapids
#

than maybe strace -f the zig build

neon lion
#

running the same command multiple times without changing the code, sometimes I get an error, sometimes I don't

graceful rapids
#

don't know much about the wsl env

tall steppe
#

You are returning pointer to a temporary

#

Use after free

tall steppe
#

Might work in non safe modes as you dont really do anything with the ptr. Safe modes or debug prob inserts code that touches it

neon lion
#

Apparently it's something related to wsl, because I ran the same code on a linux vps and the error didn't appear in any of the executions.

neon lion
tired storm
#

Assuming the problem is not stack overflow

#

@constCast is kind of a code smell. You are trying to work around the issue you've created for yourself, causing more memory problems

tired storm
#
const std = @import("std");

pub const Foo = struct {
    // Are you sure this doesn't overflow the stack?
    // buffer: [5586936]u8 = undefined,

    buffer: [100]u8 = undefined,

    // Not necessary, initialization happens up the stack
    // pub fn init(self: Foo) *Foo {
    //     const x = @constCast(&self);
    //     return x;
    // }

    pub fn dosomething(self: *Foo) void {
        // In safe modes there is an assert that `.len > 0`
        self.buffer[0] = 1;
    }
};

pub fn main() !void {
    // This instance must be mutable, because you are mutating it later.
    var foo: Foo = .{};
    // the pointer can be constant (the address is not going to change)
    const p = &foo;
    p.dosomething();
}
neon lion
#

My interest is not to fix this code, I know it's wrong. My question was why it sometimes worked and sometimes didn't, and apparently it's something related to WSL.

tired storm