Skip to content

ptrToInt causes compiler segfault with microzig #15712

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

Open
kuon opened this issue May 14, 2023 · 12 comments
Open

ptrToInt causes compiler segfault with microzig #15712

kuon opened this issue May 14, 2023 · 12 comments
Labels
bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals.
Milestone

Comments

@kuon
Copy link
Contributor

kuon commented May 14, 2023

When compiling the following repo with zig version 0.11.0-dev.3138+87de8212ad I get a compiler segfault.

I was not able to isolate the issue to a simple example so I made a repo.

Repo: https://github.com/kuon/zig-bug-2

Error below.
I got a coredump, but my zig is not built in debug mode so it doesn't help much. If you cannot reproduce with my repo above, I'll rebuild in debug.

zig build -Drelease=true
zig build-exe bug2 ReleaseFast thumb-freestanding-none: error: the following command terminated unexpectedly:
/usr/bin/zig build-exe /home/kuon/Playground/zig-bug-2/libs/microzig/src/start.zig -fno-strip -OReleaseFast --cache-dir /home/kuon/Playground/zig-bug-2/zig-cache --global-cache-dir /home/kuon/.cache/zig --name bug2 -fcompiler-rt -fsingle-threaded -target thumb-freestanding-none -mcpu cortex_m0plus --script /home/kuon/Playground/zig-bug-2/zig-cache/microzig/a7289ec13926489f324ef84143336b92/STM32L0x1_ARM Cortex-M0+.ld --mod cpu:microzig:/home/kuon/Playground/zig-bug-2/libs/microzig/src/modules/cpus/cortex-m.zig --mod config::/home/kuon/Playground/zig-bug-2/zig-cache/microzig/config-dd06784b0c0c6ff6ae747202d5132cc8.zig --mod app:microzig:/home/kuon/Playground/zig-bug-2/src/main.zig --mod microzig:config,chip,cpu:/home/kuon/Playground/zig-bug-2/libs/microzig/src/microzig.zig --mod chip:microzig:/home/kuon/Playground/zig-bug-2/src/registers.zig --deps app,microzig -fno-lto --listen=- 
Build Summary: 1/4 steps succeeded; 1 failed (disable with -fno-summary)
install transitive failure
└─ install bug2 transitive failure
   └─ zig build-exe bug2 ReleaseFast thumb-freestanding-none failure
      └─ linkerscript success
error: the following build command failed with exit code 1:
/home/kuon/Playground/zig-bug-2/zig-cache/o/8b257d72eafa2970f751537206867168/build /usr/bin/zig /home/kuon/Playground/zig-bug-2 /home/kuon/Playground/zig-bug-2/zig-cache /home/kuon/.cache/zig -Drelease=true
@matu3ba
Copy link
Contributor

matu3ba commented May 14, 2023

The file src/registers.zig looks huge (>5k LOC). Can you reduce it further?

@kuon
Copy link
Contributor Author

kuon commented May 14, 2023

I trimmed the file.

@llogick
Copy link
Contributor

llogick commented May 14, 2023

I happen to have a debug build, so if it'd help:

zig build-exe bug2 Debug thumb-freestanding-none: error: thread 14955 panic: reached unreachable code
Analyzing libs/microzig/src/start.zig: start.zig:microzig_main
      %348 = dbg_stmt(27, 13)
      %349 = call(.auto, %203, []) 
    > %350 = is_non_err(%349) 
      %351 = condbr(%350, {
        %353 = err_union_payload_unsafe(%349) 
        %399 = break(%352, %353)
      }, {
        %354 = save_err_ret_index(@Zir.Inst.Ref.none)
        %355 = err_union_code(%349) 
        %356 = block({
          %357 = dbg_block_begin()
          %358 = dbg_stmt(31, 13)
          %359 = block_comptime({
            %360 = int(64)
            %361 = array_type(%360, @Zir.Inst.Ref.u8_type) 
            %362 = break(%359, %361)
          }) 
          %363 = alloc_mut(%359) 
          %364 = store_node(%363, @Zir.Inst.Ref.undef) 
          %365 = dbg_var_ptr(%363, "msg")
          %366 = dbg_stmt(32, 13)
          %384 = block({
            %367 = decl_ref("std") 
            %368 = dbg_stmt(32, 23)
            %369 = field_ptr(%367, "fmt") 
            %370 = dbg_stmt(32, 27)
            %371 = field_call_bind(%369, "bufPrint") 
            %372 = dbg_stmt(32, 36)
            %373 = call(.auto, %371, [
              {
                %374 = break_inline(%373, %363)
              },
              {
                %375 = str("main() returned error {s}")
                %376 = break_inline(%373, %375)
              },
              {
                %377 = as_node(@Zir.Inst.Ref.anyerror_type, %355) 
                %378 = dbg_stmt(32, 74)
                %379 = error_name(%377) 
                %380 = array_init_anon({%379}) 
                %381 = break_inline(%373, %380)
              },
            ]) 
            %382 = is_non_err(%373) 
            %383 = condbr(%382, {
              %385 = err_union_payload_unsafe(%373) 
              %386 = as_node(@Zir.Inst.Ref.const_slice_u8_type, %385) 
              %392 = break(%384, %386)
            }, {
              %387 = save_err_ret_index(@Zir.Inst.Ref.none)
              %388 = dbg_stmt(32, 98)
              %389 = str("main() returned error.")
              %390 = as_node(@Zir.Inst.Ref.const_slice_u8_type, %389) 
              %391 = panic(%390) 
            }) 
          }) 
          %393 = as_node(@Zir.Inst.Ref.const_slice_u8_type, %384) 
          %394 = panic(%393) 
          %395 = dbg_block_end()
          %396 = restore_err_ret_index(%356, @Zir.Inst.Ref.none)
          %397 = break(%356, @Zir.Inst.Ref.void_value)
        }) 
        %398 = restore_err_ret_index(%352, @Zir.Inst.Ref.none)
        %400 = break(%352, @Zir.Inst.Ref.void_value)
      }) 
    For full context, use the command
      zig ast-check -t libs/microzig/src/start.zig

  in libs/microzig/src/start.zig: start.zig:microzig_main
    > %352 = block({%348..%351}) 
  in libs/microzig/src/start.zig: start.zig:microzig_main
    > %345 = block({%346..%404}) 
  in libs/microzig/src/start.zig: start.zig:microzig_main
    > %342 = condbr(%341, {%344..%416}, {%406..%417}) 
  in libs/microzig/src/start.zig: start.zig:microzig_main
    > %343 = block({%336..%342}) 
  in libs/microzig/src/start.zig: start.zig:microzig_main
    > %176 = block({%177..%427}) 

/home/rad/lab/zig/src/value.zig:1161:21: 0x6584d6c in toBigIntAdvanced (zig)
            else => unreachable,
                    ^
/home/rad/lab/zig/src/value.zig:1100:36: 0x61e0b5c in toBigInt (zig)
        return val.toBigIntAdvanced(space, target, null) catch unreachable;
                                   ^
/home/rad/lab/zig/src/codegen/llvm.zig:3279:51: 0x5fcfcbb in lowerValue (zig)
                    const bigint = tv.val.toBigInt(&bigint_space, target);
                                                  ^
/home/rad/lab/zig/src/codegen/llvm.zig:4502:48: 0x6997f6f in resolveValue (zig)
        const llvm_val = try self.dg.lowerValue(tv);
                                               ^
/home/rad/lab/zig/src/codegen/llvm.zig:4493:47: 0x699847f in resolveInst (zig)
        const llvm_val = try self.resolveValue(.{
                                              ^
/home/rad/lab/zig/src/codegen/llvm.zig:8209:49: 0x69c899f in airStore (zig)
        const src_operand = try self.resolveInst(bin_op.rhs);
                                                ^
/home/rad/lab/zig/src/codegen/llvm.zig:4652:53: 0x64059ed in genBody (zig)
                .store          => try self.airStore(inst, false),
                                                    ^
/home/rad/lab/zig/src/codegen/llvm.zig:1232:19: 0x64008b4 in updateFunc (zig)
        fg.genBody(air.getMainBody()) catch |err| switch (err) {
                  ^
/home/rad/lab/zig/src/link/Elf.zig:2562:74: 0x640920e in updateFunc (zig)
        if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(module, func, air, liveness);
                                                                         ^
/home/rad/lab/zig/src/link.zig:578:77: 0x6164f87 in updateFunc (zig)
            .elf   => return @fieldParentPtr(Elf,   "base", base).updateFunc(module, func, air, liveness),
                                                                            ^
/home/rad/lab/zig/src/Module.zig:4392:37: 0x5f6eefc in ensureFuncBodyAnalyzed (zig)
            comp.bin_file.updateFunc(mod, func, air, liveness) catch |err| switch (err) {
                                    ^
/home/rad/lab/zig/src/Sema.zig:28906:36: 0x6b04557 in ensureFuncBodyAnalyzed (zig)
    sema.mod.ensureFuncBodyAnalyzed(func) catch |err| {
                                   ^
/home/rad/lab/zig/src/Sema.zig:31577:40: 0x6549d46 in resolveInferredErrorSet (zig)
        try sema.ensureFuncBodyAnalyzed(ies.func);
                                       ^
/home/rad/lab/zig/src/Sema.zig:29195:49: 0x650b633 in analyzeIsNonErrComptimeOnly (zig)
                try sema.resolveInferredErrorSet(block, src, ies);
                                                ^
/home/rad/lab/zig/src/Sema.zig:29222:56: 0x6a4e0dc in analyzeIsNonErr (zig)
    const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand);
                                                       ^
/home/rad/lab/zig/src/Sema.zig:16940:32: 0x64531f7 in zirIsNonErr (zig)
    return sema.analyzeIsNonErr(block, src, operand);
                               ^
/home/rad/lab/zig/src/Sema.zig:966:66: 0x617ef20 in analyzeBodyInner (zig)
            .is_non_err                   => try sema.zirIsNonErr(block, inst),
                                                                 ^
/home/rad/lab/zig/src/Sema.zig:5506:34: 0x6a72a89 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/rad/lab/zig/src/Sema.zig:5489:33: 0x650eb38 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/rad/lab/zig/src/Sema.zig:1462:49: 0x6190674 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/rad/lab/zig/src/Sema.zig:5506:34: 0x6a72a89 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/rad/lab/zig/src/Sema.zig:5489:33: 0x650eb38 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/rad/lab/zig/src/Sema.zig:1462:49: 0x6190674 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/rad/lab/zig/src/Sema.zig:16989:37: 0x6509452 in zirCondbr (zig)
        return sema.analyzeBodyInner(parent_block, body);
                                    ^
/home/rad/lab/zig/src/Sema.zig:1571:61: 0x618d3bb in analyzeBodyInner (zig)
                if (!block.is_comptime) break sema.zirCondbr(block, inst);
                                                            ^
/home/rad/lab/zig/src/Sema.zig:5506:34: 0x6a72a89 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/rad/lab/zig/src/Sema.zig:5489:33: 0x650eb38 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/rad/lab/zig/src/Sema.zig:1462:49: 0x6190674 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/rad/lab/zig/src/Sema.zig:5506:34: 0x6a72a89 in resolveBlockBody (zig)
        if (sema.analyzeBodyInner(child_block, body)) |_| {
                                 ^
/home/rad/lab/zig/src/Sema.zig:5489:33: 0x650eb38 in zirBlock (zig)
    return sema.resolveBlockBody(parent_block, src, &child_block, body, inst, &label.merges);
                                ^
/home/rad/lab/zig/src/Sema.zig:1462:49: 0x6190674 in analyzeBodyInner (zig)
                    break :blk try sema.zirBlock(block, inst, tags[inst] == .block_comptime);
                                                ^
/home/rad/lab/zig/src/Sema.zig:804:30: 0x63eaa78 in analyzeBody (zig)
    _ = sema.analyzeBodyInner(block, body) catch |err| switch (err) {
                             ^
/home/rad/lab/zig/src/Module.zig:5695:21: 0x61629ca in analyzeFnBody (zig)
    sema.analyzeBody(&inner_block, fn_info.body) catch |err| switch (err) {
                    ^
/home/rad/lab/zig/src/Module.zig:4324:40: 0x5f6e541 in ensureFuncBodyAnalyzed (zig)
            var air = mod.analyzeFnBody(func, sema_arena) catch |err| switch (err) {
                                       ^
/home/rad/lab/zig/src/Compilation.zig:3127:42: 0x5f6c633 in processOneJob (zig)
            module.ensureFuncBodyAnalyzed(func) catch |err| switch (err) {
                                         ^
/home/rad/lab/zig/src/Compilation.zig:3064:30: 0x5e1ca9e in performAllTheWork (zig)
            try processOneJob(comp, work_item, main_progress_node);
                             ^
/home/rad/lab/zig/src/Compilation.zig:2020:31: 0x5e191ad in update (zig)
    try comp.performAllTheWork(main_progress_node);
                              ^
/home/rad/lab/zig/src/main.zig:3403:36: 0x5e448d8 in serve (zig)
                    try comp.update(main_progress_node);
                                   ^
/home/rad/lab/zig/src/main.zig:3217:22: 0x5cc995c in buildOutputType (zig)
            try serve(
                     ^
/home/rad/lab/zig/src/main.zig:268:31: 0x5c9e471 in mainArgs (zig)
        return buildOutputType(gpa, arena, args, .{ .build = .Exe });
                              ^
/home/rad/lab/zig/src/main.zig:212:20: 0x5c9dae5 in main (zig)
    return mainArgs(gpa, arena, args);
                   ^
/home/rad/lab/zig/lib/std/start.zig:609:37: 0x5ca0258 in main (zig)
            const result = root.main() catch |err| {
                                    ^

zig build-exe bug2 Debug thumb-freestanding-none: error: the following command terminated unexpectedly:
/home/rad/lab/zig/build/stage3/bin/zig build-exe -freference-trace=256 /home/rad/lab/zta/zig-bug-2/libs/microzig/src/start.zig -fno-strip --cache-dir /home/rad/lab/zta/zig-bug-2/zig-cache --global-cache-dir /home/rad/.cache/zig --name bug2 -fcompiler-rt -fsingle-threaded -target thumb-freestanding-none -mcpu cortex_m0plus --script /home/rad/lab/zta/zig-bug-2/zig-cache/microzig/590102268d89866a601b4aa09edb9090/STM32L0x1_ARM Cortex-M0+.ld --mod microzig:config,chip,cpu:/home/rad/lab/zta/zig-bug-2/libs/microzig/src/microzig.zig --mod cpu:microzig:/home/rad/lab/zta/zig-bug-2/libs/microzig/src/modules/cpus/cortex-m.zig --mod chip:microzig:/home/rad/lab/zta/zig-bug-2/src/registers.zig --mod app:microzig:/home/rad/lab/zta/zig-bug-2/src/main.zig --mod config::/home/rad/lab/zta/zig-bug-2/zig-cache/microzig/config-4dafd40c6a22e11d752590ea0491f999.zig --deps app,microzig -fno-lto --listen=- 
Build Summary: 1/4 steps succeeded; 1 failed
install transitive failure
└─ install bug2 transitive failure
   └─ zig build-exe bug2 Debug thumb-freestanding-none failure
      └─ linkerscript success
error: the following build command failed with exit code 1:
/home/rad/lab/zta/zig-bug-2/zig-cache/o/67aa5454eeec0ac96d6eecba5e586177/build /home/rad/lab/zig/build/stage3/bin/zig /home/rad/lab/zta/zig-bug-2 /home/rad/lab/zta/zig-bug-2/zig-cache /home/rad/.cache/zig -freference-trace -freference-trace -fsummary

@kuon
Copy link
Contributor Author

kuon commented May 14, 2023

I was able to reproduce a segfault without microzig, I am not sure if this is the same bug, I added main2.zig to the repository.

@llogick
Copy link
Contributor

llogick commented May 14, 2023

I was able to reproduce a segfault without microzig, I am not sure if this is the same bug, I added main2.zig to the repository.

I think this one triggers #15513

@matu3ba
Copy link
Contributor

matu3ba commented May 14, 2023

pub fn main() !void {
    var int_values: [5]u32 = .{0} ** 5;
    var rx: [21]u8 = .{0} ** 21;

    @memcpy(@ptrCast([*]u8, &int_values), rx[1..]);
}

might be fixed with #15704.

@kuon
Copy link
Contributor Author

kuon commented May 14, 2023

Yes this seems different, good call.

@matu3ba
Copy link
Contributor

matu3ba commented May 19, 2023

Running the repo now produces:

/home/user/dev/git/zi/zig/buildrel/stage3/bin/zig build-exe /home/user/try/tryzig/zig-bug-2/libs/microzig/src/start.zig -fno-strip -OReleaseFast --cache-dir /home/user/try/tryzig/zig-bug-2/zig-cache --global-cache-dir /home/user/.cache/zig --name bug2 -fcompiler-rt -fsingle-threaded -target thumb-freestanding-none -mcpu cortex_m0plus --script /home/user/try/tryzig/zig-bug-2/zig-cache/microzig/c695ee9a1010a79ae3523a2e12d9cea0/STM32L0x1_ARM Cortex-M0+.ld --mod cpu:microzig:/home/user/try/tryzig/zig-bug-2/libs/microzig/src/modules/cpus/cortex-m.zig --mod chip:microzig:/home/user/try/tryzig/zig-bug-2/src/registers.zig --mod config::/home/user/try/tryzig/zig-bug-2/zig-cache/microzig/config-d8618022b2e27976a8aa8539a992690a.zig --mod app:microzig:/home/user/try/tryzig/zig-bug-2/src/main.zig --mod microzig:config,chip,cpu:/home/user/try/tryzig/zig-bug-2/libs/microzig/src/microzig.zig --deps app,microzig -fno-lto --listen=-
error: unrecognized file extension of parameter 'Cortex-M0+.ld'

The simplified example runs fine.

@matu3ba
Copy link
Contributor

matu3ba commented May 19, 2023

Suggestion to close and, if needed, clarify with a new issue for feature detection.

@kuon
Copy link
Contributor Author

kuon commented May 19, 2023

Running the repo now produces:

/home/user/dev/git/zi/zig/buildrel/stage3/bin/zig build-exe /home/user/try/tryzig/zig-bug-2/libs/microzig/src/start.zig -fno-strip -OReleaseFast --cache-dir /home/user/try/tryzig/zig-bug-2/zig-cache --global-cache-dir /home/user/.cache/zig --name bug2 -fcompiler-rt -fsingle-threaded -target thumb-freestanding-none -mcpu cortex_m0plus --script /home/user/try/tryzig/zig-bug-2/zig-cache/microzig/c695ee9a1010a79ae3523a2e12d9cea0/STM32L0x1_ARM Cortex-M0+.ld --mod cpu:microzig:/home/user/try/tryzig/zig-bug-2/libs/microzig/src/modules/cpus/cortex-m.zig --mod chip:microzig:/home/user/try/tryzig/zig-bug-2/src/registers.zig --mod config::/home/user/try/tryzig/zig-bug-2/zig-cache/microzig/config-d8618022b2e27976a8aa8539a992690a.zig --mod app:microzig:/home/user/try/tryzig/zig-bug-2/src/main.zig --mod microzig:config,chip,cpu:/home/user/try/tryzig/zig-bug-2/libs/microzig/src/microzig.zig --deps app,microzig -fno-lto --listen=-
error: unrecognized file extension of parameter 'Cortex-M0+.ld'

If you execute the command manually in a shell, you need to quote the file name as there is a space in it.

/usr/bin/zig build-exe /home/kuon/Playground/zig-bug-2/libs/microzig/src/start.zig -fno-strip -OReleaseFast --cache-dir /home/kuon/Playground/zig-bug-2/zig-cache --global-cache-dir /home/kuon/.cache/zig --name bug2 -fcompiler-rt -fsingle-threaded -target thumb-freestanding-none -mcpu cortex_m0plus --script "/home/kuon/Playground/zig-bug-2/zig-cache/microzig/bc8bf26f5ea5af870d018d26f6a49393/STM32L0x1_ARM Cortex-M0+.ld" --mod config::/home/kuon/Playground/zig-bug-2/zig-cache/microzig/config-dd06784b0c0c6ff6ae747202d5132cc8.zig --mod microzig:config,chip,cpu:/home/kuon/Playground/zig-bug-2/libs/microzig/src/microzig.zig --mod cpu:microzig:/home/kuon/Playground/zig-bug-2/libs/microzig/src/modules/cpus/cortex-m.zig --mod chip:microzig:/home/kuon/Playground/zig-bug-2/src/registers.zig --mod app:microzig:/home/kuon/Playground/zig-bug-2/src/main.zig --deps app,microzig -fno-lto
fish: Job 1, '/usr/bin/zig build-exe /home/ku…' terminated by signal SIGSEGV (Address boundary error)

The simplified example runs fine.

Yes, this was issue #15704 and is fixed.

Suggestion to close and, if needed, clarify with a new issue for feature detection.

The original issue stands, I sidetracked with the second example, but it had nothing to do with the original issue.

I will try to bundle everything in a single file.

@kuon
Copy link
Contributor Author

kuon commented May 19, 2023

const std = @import("std");
const assert = std.debug.assert;

pub fn Mmio(comptime PackedT: type) type {
    const size = @bitSizeOf(PackedT);
    const IntT = std.meta.Int(.unsigned, size);
    return extern struct {
        const Self = @This();

        raw: IntT,

        pub const underlying_type = PackedT;
    };
}

pub const devices = struct {
    pub const AES = @intToPtr(*volatile types.AES, 0x40026000);
};

pub const types = struct {
    ///  Advanced encryption standard hardware accelerator
    pub const AES = extern struct {
        ///  control register
        CR: Mmio(packed struct(u32) {
            EN: u1,
            padding: u31,
        }),
    };
};

pub fn main() !void {
    var addr = @ptrToInt(&devices.AES.CR.raw);
    _ = addr;
}

Triggers the bug (repo updated too).

/usr/bin/zig build-exe /home/kuon/Playground/zig-bug-2/src/main.zig -OReleaseFast --cache-dir /home/kuon/Playground/zig-bug-2/zig-cache --global-cache-dir /home/kuon/.cache/zig --name bug2 -fno-lto                          3105ms  ven 19 mai 2023 18:55:20
fish: Job 1, '/usr/bin/zig build-exe /home/ku…' terminated by signal SIGSEGV (Address boundary error)

@andrewrk andrewrk added the bug Observed behavior contradicts documented or intended behavior label Jul 23, 2023
@andrewrk
Copy link
Member

Thanks for the reduction. No longer reproduces with 0.11.0-dev.4186+c72a9feab. Just needs test coverage and then this issue can be closed.

@andrewrk andrewrk added the contributor friendly This issue is limited in scope and/or knowledge of Zig internals. label Jul 23, 2023
@andrewrk andrewrk added this to the 0.14.0 milestone Jul 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior contributor friendly This issue is limited in scope and/or knowledge of Zig internals.
Projects
None yet
Development

No branches or pull requests

4 participants