zig
zig copied to clipboard
Debug info for packed structs should be a struct, but is a number
Zig Version
0.11.0-dev.1183+2b9478ce1
Steps to Reproduce and Observed Behavior
Code:
const std = @import("std");
const CacheConfig = packed struct(u16) {
pending_cache: bool = false,
entry_cache: bool = false,
pos_in_pending: u5 = 0,
name_len: u9 = 0,
};
pub fn main() anyerror!void {
var config = CacheConfig{};
config.pending_cache = true;
std.mem.doNotOptimizeAway(&config);
@breakpoint();
}
lldb:
❯ lldb repro
(lldb) target create "repro"
Current executable set to '/Users/jarred/Desktop/repro' (arm64).
(lldb) run
Process 2372 launched: '/Users/jarred/Desktop/repro' (arm64)
Process 2372 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100000b74)
frame #0: 0x0000000100000b78 repro`repro.main at repro.zig:14:5
11 var config = CacheConfig{};
12 config.pending_cache = true;
13 std.mem.doNotOptimizeAway(&config);
-> 14 @breakpoint();
15 }
(lldb) p config
(unsigned short) $0 = 1
(lldb)
Expected Behavior
It should display as a struct so that you can see the fields without lots of extra work
❯ lldb repro
(lldb) target create "repro"
Current executable set to '/Users/jarred/Desktop/repro' (arm64).
(lldb) run
Process 2481 launched: '/Users/jarred/Desktop/repro' (arm64)
Process 2481 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x100000b84)
frame #0: 0x0000000100000b88 repro`repro.main at repro.zig:14:5
11 var config = CacheConfig{};
12 config.pending_cache = true;
13 std.mem.doNotOptimizeAway(&config);
-> 14 @breakpoint();
15 }
(lldb) p config
(repro.CacheConfig) $0 = (pending_cache = true, entry_cache = false, pos_in_pending = '\0', name_len = 0)
Hi, I'm still seeing this in recent builds. Here's a bit more info on the debug symbols emitted by the compiler on Linux:
const std = @import("std");
const print = std.debug.print;
const BasicStruct = struct {
A: u3 = 1,
B: u5 = 2,
};
const PackedStruct = packed struct {
A: u3 = 1,
B: u5 = 2,
};
pub fn main() !void {
const b = BasicStruct{};
const p = PackedStruct{};
print(
"BasicStruct: {any} ({d} bytes)\nPackedStruct: {any} ({d} bytes)\n",
.{
b,
@sizeOf(BasicStruct),
p,
@sizeOf(PackedStruct),
},
);
}
$ zig version
0.11.0-dev.3395+1e7dcaa3a
$ zig build-exe main.zig && ./main
BasicStruct: main.BasicStruct{ .A = 1, .B = 2 } (2 bytes)
PackedStruct: main.PackedStruct{ .A = 1, .B = 2 } (1 bytes)
Then via dwarfdump
:
< 1><0x00016be9> DW_TAG_base_type
DW_AT_name main.PackedStruct
DW_AT_encoding DW_ATE_unsigned
DW_AT_byte_size 0x00000001
< 1><0x00016bf0> DW_TAG_structure_type
DW_AT_name main.BasicStruct
DW_AT_byte_size 0x00000002
DW_AT_alignment 0x00000001
< 2><0x00016bf7> DW_TAG_member
DW_AT_name A
DW_AT_type <0x0000197f>
DW_AT_alignment 0x00000001
DW_AT_data_member_location 0
< 2><0x00016c02> DW_TAG_member
DW_AT_name B
DW_AT_type <0x000019a6>
DW_AT_alignment 0x00000001
DW_AT_data_member_location 1