Stream: bugs

Topic: Eisenbug panic (half the time)


view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 14:47):

So I’m not sure how to proceed. I’ve got a program that only panic half of the runs. It alternates between panic and fine. What should I do with this one ahah?

aoc-2025/roc on  main [?⇡] on ☁
❯ roc panic.roc
11-22
thread 14852754 panic: incorrect alignment
???:?:?: 0x104ab76a3 in ??? (panic.roc)
???:?:?: 0x1049a3527 in ??? (panic.roc)
???:?:?: 0x10494b0db in ??? (panic.roc)
???:?:?: 0x104921dbb in ??? (panic.roc)
???:?:?: 0x10491f6a7 in ??? (panic.roc)
???:?:?: 0x10491f10b in ??? (panic.roc)
???:?:?: 0x104918913 in ??? (panic.roc)
???:?:?: 0x18332ab97 in ??? (???)
???:?:?: 0x0 in ??? (???)
error: Child process /var/folders/q3/lls0f9bd6x112cdkq8bgjldr0000gn/T/roc-28950/panic.roc killed by signal: 6
error: Child process aborted (SIGABRT)

aoc-2025/roc on  main [?⇡] on ☁
❯ roc panic.roc
11-22
Part 2 (demo): 33

view this post on Zulip Richard Feldman (Dec 06 2025 at 14:47):

what's the source code? I can take a look

view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 14:48):

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.3/98T93wthPgoBRLYtPTT4RBBsQunrfDG94gihPf1zYYmE.tar.zst" }

import pf.Stdout
import pf.Stderr

demo_input = "11-22"


print! : Str => {}
print! = |msg| msg.split_on("\n").for_each!(Stdout.line!)


parse_range : Str -> Try((I64, I64), _)
parse_range = |range_str| {
    match range_str.split_on("-") {
        [a, b] => Ok((I64.from_str(a)?, I64.from_str(b)?))
        _ => Err(InvalidRangeFormat)
    }
}


is_invalid : I64 -> Bool
is_invalid = |x| {
    s = x.to_str().to_utf8()
    n = s.len()
    mid = n // 2

    left = s.sublist({ start: 0, len: mid })
    right = s.sublist({ start: mid, len: n - mid })

    left == right
}


part1! : Str => Try(I64, _)
part1! = |input| {
    var $sum = 0

    for range_str in input.trim().split_on(",") {
        print!(range_str)
        (start, end) = parse_range(range_str)?

        var $x = start
        while $x <= end {
            if is_invalid($x) {
                $sum = $sum + $x
            }
            $x = $x + 1
        }
    }

    Ok($sum)
}


repeat = |list, n| repeat_helper([], list, n)

repeat_helper = |acc, list, n| match n {
    0 => acc
    _ => repeat_helper(acc.concat(list), list, n - 1)
}

has_repeating_pattern : I64 => Bool
has_repeating_pattern = |x| {
    s = x.to_str().to_utf8()
    n = s.len()

    # Check all divisors of n
    var $d = 1
    while $d <= n // 2 {
        if n % $d == 0 {
            # Check if repeating the first d characters n/d times equals s
            slice = s.sublist({ start: 0, len: $d })
            repeated = slice->repeat(n // $d)
            if repeated == s { return True }
        }
        $d = $d + 1
    }

    False
}


part2! : Str => Try(I64, _)
part2! = |input| {
    var $sum = 0

    for range_str in input.trim().split_on(",") {
        print!(range_str)
        (start, end) = parse_range(range_str)?

        var $x = start
        while $x <= end {
            if has_repeating_pattern($x) {
                $sum = $sum + $x
            }
            $x = $x + 1
        }
    }

    Ok($sum)
}


run! = || {
    #print!("Part 1 (demo): ${part1!(demo_input.trim())?.to_str()}")
    #print!("Part 1: ${part1!(day_input.trim())?.to_str()}")
    print!("Part 2 (demo): ${part2!(demo_input.trim())?.to_str()}")
    #print!("Part 2: ${part2!(day_input.trim())?.to_str()}")
    Ok({})
}


main! = |_args| {
    match run!() {
        Ok(_) => Ok({})
        Err(_) => Err(1)
    }
}

view this post on Zulip Richard Feldman (Dec 06 2025 at 14:51):

on it!

view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 15:06):

I don’t know if it’s related at all. But I got another invalid method receiver error:

main! = || {
    n = List.len([])
    _str = n.to_str()
}

view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 15:36):

I managed to minimize it a little bit in case it helps, while still exhibiting this eisenbug behavior (I run it 4 times to make sure).

app [main!] { pf: platform "https://github.com/lukewilliamboswell/roc-platform-template-zig/releases/download/0.3/98T93wthPgoBRLYtPTT4RBBsQunrfDG94gihPf1zYYmE.tar.zst" }

import pf.Stdout

repeat = |list, n| repeat_helper([], list, n)

repeat_helper = |acc, list, n| match n {
    0 => acc
    _ => repeat_helper(acc.concat(list), list, n - 1)
}

main! = |_args| {
    s1 : List(U8)
    s1 = [1]

    repeated : List(U8)
    repeated = s1->repeat(2)

    s2 : List(U8)
    s2 = [1, 1] # no crash if s2 = [1, 1, 1]
    _ignore = repeated == s2
    Ok({})
}

view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 15:39):

Oh, maybe important to mention @Richard Feldman I’m having these panics AFTER the fix already done in https://github.com/roc-lang/roc/pull/8573 which I rebased on your main after your merges today.

view this post on Zulip Matthieu Pizenberg (Dec 06 2025 at 15:41):

So the fix for the declaration of the recursive function is already taken into account.

view this post on Zulip Matthieu Pizenberg (Dec 08 2025 at 08:21):

Have you figured out or found a clue on both these issues @Richard Feldman ?

view this post on Zulip Matthieu Pizenberg (Dec 08 2025 at 09:09):

I made a PR with a fix for the InvalidMethodReceiver error raised by a bug in the return value of List.len https://github.com/roc-lang/roc/pull/8589

view this post on Zulip Matthieu Pizenberg (Dec 08 2025 at 10:29):

I haven’t found the reason for the non-deterministic alignment panic though :(

view this post on Zulip Matthieu Pizenberg (Dec 08 2025 at 13:11):

Here is a summary of what I tried with Claude to find this.

ALIGNMENT_BUG_INVESTIGATION.md

view this post on Zulip Richard Feldman (Dec 08 2025 at 14:30):

I'm getting closer in https://github.com/roc-lang/roc/pull/8580 - there are a bunch of new debug assertions in there around alignment assumptions etc. - but haven't quite found the culprit yet

view this post on Zulip Matthieu Pizenberg (Dec 08 2025 at 14:31):

Yeah same XD. I’ll leave it to you cause I’m overtime on this one without finding the bug.


Last updated: Dec 21 2025 at 12:15 UTC