You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Working on a UEFI zig project and keep hitting a random panic when trying to get an ownedSlice from an arraylist. Eventually narrowed it down to only be occurring when capacity and length match on an array list. Manually incrementing the capacity by 1 causes the panic branch to be missed.
The following code will reliably hit the panic branch on my machine. I know its not perfect, pretty, or correct however, it does its job just fine. It could probably be cleaned up by a fair bit but this is what I was able to quickly throw together to get around the compiler optimizing away the code.
const list = std.ArrayList(*u8);
var u8_list = list.init(std.os.uefi.pool_allocator);
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(8))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(1))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(2))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(3))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(4))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(5))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(6))))) catch @panic(":(");
u8_list.append(@constCast(@as(*u8, (@ptrFromInt(7))))) catch @panic(":(");
// Len & Cap are now both 8
const s = u8_list.toOwnedSlice() catch @panic("Failure");
for (s) |t| {
_ = t;
}
@panic("Should have hit unreachable code");
The code panics with the msg reached unreachable code. Digging around the code further revealed it to be caused by the resize method being performed in the toOwnedSlice() call allocator.resize(old_memory, self.items.len)
This bug probably exhibits itself in a lot of different scenarios. pool_allocator and raw_pool_allocator pass log2_old_ptr_align to mem.alignAllocLen, which expects len_align (which would be 2^log2_old_ptr_align).
Further: neither of these resize functions has any reason to call mem.alignAllocLen because it immediately throws away the result.
Fixesziglang#21446
Both UefiPoolAllocator and UefiRawPoolAllocator were
passing the value of `log2_ptr_align` directly to
`mem.alignAllocLen` which expects a alignment value.
Both of these calls to `mem.alignAllocLen` are pointless
and the result of the alignment both always true, and
was thrown away anyway.
I have removed these calls entirely.
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
Working on a UEFI zig project and keep hitting a random panic when trying to get an ownedSlice from an arraylist. Eventually narrowed it down to only be occurring when capacity and length match on an array list. Manually incrementing the capacity by 1 causes the panic branch to be missed.
The following code will reliably hit the panic branch on my machine. I know its not perfect, pretty, or correct however, it does its job just fine. It could probably be cleaned up by a fair bit but this is what I was able to quickly throw together to get around the compiler optimizing away the code.
The code panics with the msg
reached unreachable code
. Digging around the code further revealed it to be caused by the resize method being performed in thetoOwnedSlice()
callallocator.resize(old_memory, self.items.len)
https://ziglang.org/documentation/master/std/#src/std/array_list.zig
Currently dont have any way to debug zig UEFI applications so this is as far as I was able to take this atm.
Expected Behavior
Standard library should not panic
The text was updated successfully, but these errors were encountered: