zig icon indicating copy to clipboard operation
zig copied to clipboard

Runtime segfault for reading to const

Open arthurmelton opened this issue 1 year ago • 1 comments

Zig Version

0.14.0-dev.367+a57479afc

Steps to Reproduce and Observed Behavior

You can produce it by compiling the following.

const file = try std.fs.openFileAbsolute("/proc/net/route", .{});
defer file.close();

var buf_reader = std.io.bufferedReader(file.reader());
const reader = buf_reader.reader();

const line: [129]u8 = undefined;

const read = try reader.read(@constCast(&line));
_ = read;

Expected Behavior

I found a bug where if you use a bufferedReader to read into a const, you will get a runtime segfualt, with a stack trace that does not show the offending read. I did not know if this is considered a bad compiler error, but I believe its a bug because it should not runtime segfault if anything.

It gives this stacktrace:

Segmentation fault at address 0x1004041
/home/me/Projects/KabaOS/build/zig/lib/compiler_rt/memcpy.zig:19:21: 0x10d9e8f in memcpy (compiler_rt)
            d[0] = s[0];
                    ^
/home/me/Projects/KabaOS/build/zig/lib/std/io/buffered_reader.zig:24:79: 0x1036057 in read (main)
                @memcpy(dest[dest_index..][0..written], self.buf[self.start..][0..written]);
                                                                              ^
/home/me/Projects/KabaOS/build/zig/lib/std/io.zig:94:26: 0x1035aa8 in main (main)
            return readFn(self.context, buffer);
                         ^
/home/me/Projects/KabaOS/build/zig/lib/std/start.zig:532:37: 0x10358c5 in posixCallMainAndExit (main)
            const result = root.main() catch |err| {
                                    ^
/home/me/Projects/KabaOS/build/zig/lib/std/start.zig:277:5: 0x10353e1 in _start (main)
    asm volatile (switch (native_arch) {
    ^
???:?:?: 0x0 in ??? (???)
[1]    4019 IOT instruction  ~/Projects/KabaOS/build/zig/zig run main.zig

Not only does it skip over the read line, but if you put it in a different function from main, it will say that the function was called, but still never talk about the read function.

Applying this diff makes it work as expected

10c10
<     const line: [129]u8 = undefined;
---
>     var line: [129]u8 = undefined;
12c12
<     const read = try reader.read(@constCast(&line));
---
>     const read = try reader.read(&line);

In my mind it should either be a compiler error, or the read function should return an error. I don't know what would be better in this situation though. I will also add that in the dev versions of v0.13 and (I believe) early versions of 0.14 that would not segfault and would work just like if you applied the diff.

arthurmelton avatar Jul 21 '24 12:07 arthurmelton

what you're doing is illegal and not a valid use case of @constCast, a crash like this at the very least is expected. the reason it used to work was because of a bug where constants were stored in the wrong section of the binary which has since been fixed. https://github.com/ziglang/zig/issues/20225 was a similar situation

xdBronch avatar Jul 21 '24 15:07 xdBronch

Using @constCast here is the bug, const read = try reader.read(@constCast(&line)); missing from the stack trace is #19407

Vexu avatar Jul 22 '24 13:07 Vexu