Stream: platform development

Topic: ✔ Zig: General protection exception (no address available)


view this post on Zulip Oskar Hahn (Dec 04 2024 at 17:24):

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?

view this post on Zulip Oskar Hahn (Dec 04 2024 at 17:37):

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.

view this post on Zulip Oskar Hahn (Dec 04 2024 at 17:55):

I think I found the bug. But I have to test it. I am am away for some hours. I report later

view this post on Zulip Anton (Dec 04 2024 at 18:09):

running it with valgrind can help provide additional info

view this post on Zulip Brendan Hansknecht (Dec 04 2024 at 19:10):

It's trying to increment a refcount

view this post on Zulip Brendan Hansknecht (Dec 04 2024 at 19:10):

Either of the list itself or an element

view this post on Zulip Oskar Hahn (Dec 04 2024 at 22:23):

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.

view this post on Zulip Notification Bot (Dec 04 2024 at 22:24):

Oskar Hahn has marked this topic as resolved.

view this post on Zulip Luke Boswell (Dec 05 2024 at 00:04):

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