I ran into an memory error in a zig platform.
The roc code that is running is with lukes roc-parser. The smallest example I could build is:
import parser.Parser exposing [many, map, sepBy]
import parser.String exposing [parseStr, codeunit, codeunitSatisfies]
part1 : Str -> Result Str _
part1 = \_rawInput ->
input = "XXX"
_ = parseStr puzzleParser input
Err TODO
puzzleParser =
lineParser |> sepBy (codeunit 'X')
lineParser =
many symbolParser
symbolParser =
codeunitSatisfies (\c -> c != 'X') |> map \_ -> Other
When I run this, the platform crashes with the message General protection exception (no address available)
. I don't know what that means.
I also get a traceback. The top most functions are:
./roc_app:0:0: 0x5be3cba551d4 in #Attr_#inc_3 (roc_app)
./roc_app:0:0: 0x5be3cba54793 in List_prepend_2cc6e6d3c5a48a76ea218c439d44b6318e7bd267419a22dcb25b258a2c06a (roc_app)
./roc_app:0:0: 0x5be3cba531ff in Parser_82_d0954aeb42c3a999750fa5b4068c6679ed2537c3257fc7e6c4e91bdc4133ae0 (roc_app)
./roc_app:0:0: 0x5be3cba540db in Result_map_8acb95ddb9a746c2bf4dc0f4f96ce3b3e1f1e4f2559e7641b193db1f161d1c41 (roc_app)
I think, it is this line from the parser package: https://github.com/lukewilliamboswell/roc-parser/blob/327ae1c3f59fc998390e1ce201e1f79ac53ba98f/package/Parser.roc#L360
What does #Attr_#inc_3
mean? Can I assume, that this is from inside the builtins?
It seems to have something to do with my allocator. I am using a zig allocator and not C.alloc. If I switch to C.alloc, everything works. But I don't understand what I am doing differently. I tried to set the alignment to always 16
, but this did not help.
I have no idea, how to debug this further. Do you have any idea?
One other think. I am using zig 0.13. For the builtins in my host code, I am using the builtins from this PR. But I don't think that that this is relevant, since all the data is allocated inside roc and not from the platform.
I think I found the bug. But I have to test it. I am am away for some hours. I report later
running it with valgrind can help provide additional info
It's trying to increment a refcount
Either of the list itself or an element
Ok. I found the bug. And after I saw it, it is painful, that I even started this thread...
For the zig allocator, I have to save the size of each allocation, because allocator.free() functions requires it, and roc does not provide it.
Therefore I allocate a bit more memory and safe the size before the actual memory.
This works for roc_alloc. But for roc_realloc, I returned the pointer to my size-value instead of the pointer to the actual memory. The fix was as simple as changing return new_slice.ptr
to return new_slice.ptr + alignment
.
Oskar Hahn has marked this topic as resolved.
Nice. I'm glad you found it. That zig allocator is really helpful for zig platforms. :grinning:
Last updated: Jul 06 2025 at 12:14 UTC