IRC channel logs

2025-10-09.log

back to list of logs

<ekaitz>sneek: later tell ArneBab https://codeberg.org/guile/guile/pulls/27 added the pr. Thanks
<sneek>Got it.
<ekaitz>sneek: botsnack
<sneek>:)
<daviid>sneek
<sneek>daviid, you have 1 message!
<sneek>daviid, mwette says: if fluidsynth.h only includes other files you won't get anything, in which case you should use an #:inc-filter. See some of the examples/ffi files (e.g., cairo.ffi).
<daviid>sneek later tell mwette I chaned the definotion to add #:inc-filter (lambda (file path) (string-contains path "fluidsynth/" 0)), which i sort of blindingly takefrom the dbus.h example, and that seems to generate the complete low level api, tx
<sneek>Will do.
<encryptedwhispe->guile on savannah git seems to be having a lot of trouble, not really cloning for me :(
<daviid>encryptedwhispe-: you should clone https://codeberg.org/guile/guile.git
<rlb>encryptedwhispe-: you probably want https://codeberg.org/guile/guile now -- repo moved recently.
<encryptedwhispe->Aha, thank you
<encryptedwhispe->(both)
<ArneBab>sneek: later tell ekaitz: merged -- thank you!
<sneek>ArneBab, you have 1 message!
<sneek>ArneBab, ekaitz says: https://codeberg.org/guile/guile/pulls/27 added the pr. Thanks
<sneek>Will do.
<adamhume>ArneBab: I've taken your comment in https://codeberg.org/guile/guile/pulls/26#issuecomment-7643683 and revised the NEWS
<ArneBab>adamhume: thank you! merged.
<sneek>ekaitz: Greetings!
<ekaitz>sneek: botsnack
<sneek>Welcome back ekaitz, you have 1 message!
<sneek>ekaitz, ArneBab says: merged -- thank you!
<sneek>:)
<ekaitz>ArneBab: thank *you*
<euouae>Hello. Hmmm.... I'm witnessing a really strange bug where (string-ref (string-copy s) i) works but (string-ref s i) returns a garbage byte
<sneek>Welcome back euouae, you have 1 message!
<sneek>euouae, ekaitz says: I added a package in guix with guile-rope
<euouae>nice, thanks ekaitz
<euouae>ACTION needs to write a test case
<euouae>furthermore it's only witnessed in my test files and not in the repl
<euouae>Hm. works on the REPL, works by invoking the test suite with guile, but fails when using the test driver.
<euouae>hm, it has something to do with autocompile. now I'm really thrown off heh
<ekaitz>euouae: it might be related with compilation, yeah
<euouae>but how is it involved?
<euouae>I've put a reproducer here <https://lists.gnu.org/archive/html/bug-guile/2025-10/msg00003.html>
<ekaitz>euouae: take a look to eval-when
<ekaitz>(i'm writing a macro expander and scheme compiler. I have nightmares)
<ekaitz>euouae: https://www.gnu.org/software/guile/manual/guile.html#Eval-When
<euouae>but why would eval-when matter
<euouae>which of the procedures involved would use it and why would that happen? It should be a bug if this behavior is exhibited
<ekaitz>it depends
<ekaitz>I'm not sure which part is affected by this
<ekaitz>but it seems like your random state is generated in a moment in time you did not expect
<ekaitz>or something like that
<ekaitz>or maybe I'm just obsessed with this, because of my work
<euouae>you can remove the seed and the bug is exhibited still
<ekaitz>hm
<euouae>it has something to do with the freakin string-ref
<euouae>(string-ref (string-copy s) i) does not exhibit the bug
<ekaitz>maybe substring/shared does some weird optimization trick in here or something
<euouae>Any optimization should be irrelevant
<ekaitz>i mean a badly implemented one :)
<euouae>think of this, (string-ref s i) bugs out when (string-ref (string-copy s) i) does not
<euouae>yeah I'm having a hard time debugging this from inside guile
<euouae>I think I might need to use gdb
<ekaitz>yeah, that's pretty crazy
<euouae>I am guessing it has to do with the CoW mechanism
<euouae>but there is no write happening for one, and I don't think the CoW being triggered should affect anything *anyway*
<euouae>Thanks for confirming
<euouae>I'll try to round down the reproducer to an even smaller example and then I'll try to use gdb
<euouae>good luck with your macro expander/compiler :P
<ekaitz>haha
<ekaitz>make it as small as you can
<ekaitz>and i might take a look to it
<ekaitz>I have (some) experience debugging guile
<dsmith>rlb: For 00-repl-server.test "HTTP inter-protocol attack", I wrapped the write-request in a catch, and now it's no longer failing.
<dsmith>rlb, And I did get it to fail running as single test.
<dsmith>rlb, As `while ./check-guile 00-repl-server.test; do : ; done`
<dsmith>Very very rarely did it fail
<wehlutyk>Hello all
<euouae>hi wehlutyk
<euouae>So I have this 4 line procedure: <https://termbin.com/1zzz> that I invoke in my unit test: <https://termbin.com/m6sv> and somehow this unit test fails when I compile the module but not the unit test and I run without autocompile on
<euouae>What is going on?
<ekaitz>euouae: did you try to disassemble?
<euouae>That would probably be my weakest approach as I don't know anything about Guile's compilation
<ekaitz>guile vm instructions are kind of easy to read
<euouae>What I'll do is I'll put it all up in a simple project online that demonstrates the bug with a `make` and a `./run`
<ekaitz>great
<ekaitz>but don't lose the chance to learn something new!
<euouae>Maybe -- but I also want to verify that the bug exhists on HEAD
<euouae>right now testing with 3.0.10
<euouae>ekaitz: here it is, <https://codeberg.org/annoyingusername/guile-string-shared-bug>
<euouae>ACTION will try with HEAD guile now
<euouae>okay I just checked that it is still a bug with HEAD
<euouae>debugging with gdb is going to be awful due to all the threads that guile spawns
<euouae>hm...
<euouae>ekaitz: I don't think this bug can be exhibited in the disassembly
<euouae>It's something to do with compiled and uncompiled code
<euouae>getting mixed
<rlb>euouae: while I haven't looked carefully, you can simplify your test by dropping srfi-64 altogether. This shows why it's failing (i.e. \nul for second ref)
<rlb>(use-modules (bug))
<rlb>(let ((x "hello"))
<rlb> (write (string-ref x 0)) (newline)
<rlb> (write (string-ref-0 (substring/shared x 0 2))) (newline))
<rlb>dsmith: hmm, did you think the catch was a proper fix wrt whatever the test is doing?
<dsmith>rlb, No, I was just trying to get more insight into what/where the error was.
<rlb>ahh, ok, thx
<rlb>failed here on the first try -- I must just be lucky :)
<dsmith>rlb, Unfortunately, the original code has been running in a loop with no errors since then. :(
<rlb>guessing it's something about my system making it more likely...
<dsmith>Something like this: https://bpa.st/ERAQ but that never failed. And now the original is never failing.
<rlb>Here I'm typically running "make -j4 check" or "make -j5 check" -- I've vaguely suspected it might be encouraged by contention.
<rlb>I suppose you could try that for a suitable -jN if you don't mind keeping your system busy :)
<dsmith>I wonder if just running some other tasks to soak up cpu and resources would help trigger it.
<rlb>perhaps -- all I know is that here -j triggers it a lot more often than I'd like
<rlb>I was assuming it was probably just a bug in the test, but haven't taken the time to really understand what it's doing/expecting.
<dsmith>The test tries to shove an http GET request to the repl socket,right? And that fails with a "broken pipe"?
<dsmith>So maybe the Guile repl socket has not spun up yet?
<rlb>I've hit the reverse a few times recently, i.e. "foo | bar" breaking because bar (testing something) read part of the output, reached its conclusion and then exited "0" without consuming all of foo's output, and "boom" SIGPIPE.
<rlb>(in other contexts)
<rlb>e.g. test pipelines involving say "... head -1... "
<dsmith>rlb, I wonder if a simple sleep before the write-request changes things.
<rlb>euouae: can also add a (write s) (newline) to string-ref-0 and see that s is "correct" even though the subsequent string-ref returns #\nul.
<rlb>So offhand, yeah, unless I'm missing something I'd guess maybe the string-ref in string-ref-0 is being compiled/optimized wrong.
<rlb>(I'm not good enough with our disassembly to have time to try to evaluate that right now.)
<euouae>rlb: I agree with what you said, I have inspected those values before
<euouae>It's #\nul which I'm sure means \0, but it can be other values too
<rlb>Oh, that is interesting -- i.e. if you've seen other values.
<euouae>rlb: If you change (substring/shared "hello" 0 2) to (substring/shared "hello" 0) it passes
<euouae>there's something seriously wrong but I can't figure it out
<euouae>rlb: do you know if there's a way to put a "mark" in the lisp code that I can break on to from gdb side?
<euouae>hm, I could check if it is related to compilation by invoking the compiler from within the test instead of using a module
<rlb>Offhand, I'd guess that one of the most likely things is that the compiled code in that guild disassemble bug.go output is just not quite right.
<euouae>ah I rounded it down to a one-liner
<euouae>((local-compile '(lambda (s) (string-ref s 0)) (the-environment)) (substring/shared "hello" 0 2))
<euouae>The above returns #\nul
<euouae>Okay, so it must be the compiled code
<euouae>interestingly, running that from the REPL gives me no errors, but it fails when invoking guile
<euouae>rlb: one more question.
<euouae>If <https://codeberg.org/annoyingusername/guile-string-shared-bug/src/branch/main/test.scm> fails but compiling substring/shared as well works, doesn't that mean it's an issue with substring/shared?
<rlb>hmm, don't know offhand.
<euouae>I checked that it's a bug with 3.0.8, 3.0.10 and HEAD. How do you propose I attempt to debug this? I can't just use the REPL because it's not happening in the REPL
<rlb>I don't know -- but if I knew the dissasembly better, I'd verify that first.
<dsmith>sneek, seen civodul
<sneek>civodul was last seen in #guix 2 hours and 30 minutes ago, saying: possibly related is this milestone: https://codeberg.org/guix/guix/milestone/26398.
<dsmith>I wonder if the optimizer is turning (substring/shared "hello" 0 2) to "he" ? Probably not?
<dsmith>euouae, What if you provide some of the current literals as args instead?
<euouae>dsmith: the latest iteration of this bug is here, <https://codeberg.org/annoyingusername/guile-string-shared-bug/src/branch/main/test.scm>
<euouae>You can play around with it if you want, just do `guile --no-auto-compile test.scm`
<euouae>dsmith: what would the optimization into "he" change?
<euouae>You can change proc into (define proc (local-compile '(lambda (s) (string-ref (substring/shared s 0 2) 0)) (the-environment))) and the bug will still occur with (proc "hello")
<euouae>but if you put "hello" inside as well and turn proc into a thun, then it works fine.
<euouae>thunk*
<dsmith>euouae, No idea. Just thinking something that might be different from the repl
<euouae>dsmith: it's an ugly bug, I don't know how to use gdb to debug it, and it's much harder to debug because of the threads that guile launches
<euouae>I think I figured out by breaking on write(2) and looking at the backtrace that a full_write() is called somewhere, and I suppose those are to read/write data
<euouae>but I can't really debug it
<dsmith>I've never got the hang of using gdb effectively. Just the occasional backtrace on a segfault.
<euouae>Oh I'm decent with it but it requires being able to navigate the C/++ source too
<euouae>and I'm too unfamiliar with Guile (plus I lack a lot of the compiler theory)
<dariqq>hello, how would I use a a C function with multiple optional arguments: I would need to pass SCM_UNDEFINED somehow, not sure if this is possible
<rlb>euouae: at some point probably worth filing a bug (at bug-guile@gnu.org)
<euouae>rlb: It's already there <https://lists.gnu.org/archive/html/bug-guile/2025-09/msg00009.html> and for some reason it doesn't show my responses in thread, but <https://lists.gnu.org/archive/html/bug-guile/2025-10/msg00005.html>
<euouae>I think what I'll do is I will try to dig into the C source and learn it
<rlb>Offhand, I'm not sure the C source is going to matter.
<euouae>Why not?
<rlb>and I did annotate some of the related strings.c code a bit and the values seemed fine.
<rlb>My guess is still that the compiler/optimizer might be emitting incorrect code there, and that's not C.
<euouae>okay, we can test your hypthesis
<euouae>I can compile bug.scm and load it from the REPL, if it gives a bug, it's that
<rlb>Of course it could also be a bug in the *vm*, which would be C, but personally, I'd still be inclined to try to make sure I believed the "guild disassemble bug.go" output wasn't wrong somehow.
<rlb>(which means I'd need to learn our assembly a lot better first :) )
<rlb>Oh, one other thing to perhaps try since it's easy -- turn off the jit.
<rlb>(I forget exactly how offhand.)
<rlb>envt var I think
<rlb>If that fixes it, then we probably have our culprit :)
<dsmith>+1
<rlb>Looks like GUILE_JIT_THRESHOLD=-1 will do it.
<euouae>Okay here's the thing, I loaded bug.go from REPL and tried the line, and it works fine
<euouae>If the issue was with the compiled code in bug.go, it should probably be exhibited right?
<rlb>I don't know.
<rlb>i.e. don't know everything that differs from from the repl.
<rlb>s/from from/from/
<euouae>I tried GUILE_JIT_THRESHOLD but it had no effect
<rlb>same here, fwiw
<euouae>rlb: well then I'll start by learning more about the Guile Implementation section instead
<euouae>See where I'll get with that
<rlb>some little bits I know -- you can see various optimizations/changes related to say string-ref in compile-bytecode, effects-analysis, lower-primcalls, reify-primitives cps-primitives tree-il/effects tree-il/primitives etc.
<rlb>the latter moreso
<rlb>And vm/assembler has code to be able to operate on the native byte-representation of strings/stringbufs that has to match whatever strings.c is doing, etc.
<rlb>s/byte representation/memory representation/
<rlb>since we write literal strings into .go files in the heap format (iirc)
<rlb>So they can be used directly after mmapping the .go file.
<dsmith>And in a rodata section too, IIRC
<euouae>this is something to do with compiled and uncompiled parts being mixed together
<rlb>Are we sure of that? i.e. could it just be that we're writing something wrong (code or data format) to the .go file?
<euouae>if you compile both files (or both parts of the code,) it works fine
<euouae>I'm not sure of anything, just reasoning from the effects I observe
<rlb>suppose that could be due to the compiler writing "wrong" data, i.e. that doesn't actually match the heap format when it should.
<rlb>And when they're both compiled, they're both using the same ("wrong") representation.
<dsmith>Ew
<rlb>Of course might not be that at all -- I was just sensitized to that when working on the utf8 conversion.
<rlb>i.e. had to learn because things started crashing after I changed the string/stringbuf structure, and wingo pointed me to those assembler.scm operations, etc.
<rlb>Had to make adjustments to handle the new format and/or just stop optimizing some operations (drop them from the optimizer, so there's nothing that can be wrong).
<euouae>rlb: I just had some progress. -O0 does not exhibit the bug
<euouae>I can try to bisect to figure out which optimization causes it
<rlb>Oh, right good idea.
<euouae>The bug seems to lie in '-O0 -Ocps -Oresolve-primitives'
<rlb>might try looking at differences in the disassembly...
<dpk>in what sense does an object used as a prompt tag need to be the same in abort-to-prompt as in call-with-prompt?
<dpk>eqv?, or eq? ?
<dpk>okay, eq?, it seems
<dpk> https://codeberg.org/guile/guile/src/commit/f54a7cf264b2ef69a453cd04151f11656661426c/libguile/dynstack.c#L520
<rlb>...probably belongs in the docs.
<dpk>i wonder if it would be disastrous to change that to eqv? … probably using things that aren’t location dependent as prompt tags would be a good idea, but i’m looking at SRFI-fying Guile’s delimited control as a lighter-weight alternative to SRFI 226, and eq? is generally a spec smell when it shows up in the semantics of things because it’s so very implementation-dependent
<dpk>err, *wouldn’t* be a good idea
<euouae>This is the disassembly of the three different options <https://termbin.com/8ihs>
<rlb>Hmm, what does eq? formally specify -- I'd always thought it was at least symbols (and kewords?), aside from "same object"?
<rlb>"keywords"
<rlb>If it does specify at least those, then I'd assume the main criteria is whether the situation calls for "only the (presumed) fastest thing"...
<dpk>rlb: eq?, effectively, is always a pointer comparison, while eqv? is a pointer comparison on things that may be mutable and a value comparison on things that are definitely immutable. mostly this makes a difference for numbers (because the fixnum range is implementation dependent, and indeed R6RS doesn’t even guarantee that fixnums aren’t heap allocated) and characters (can also be heap allocated). it also makes a difference for empty instances of
<dpk>things like strings and vectors, which can be treated as globally eq? constants
<rlb>Unless there's a compelling argument for numbers/chars there, though, and if eq? does promise symbols, then I might think eq? was reasonable for that?
<dpk>as i say, using those things as a prompt tag … probably you’re going to have a bad time anyway
<rlb>Unless we think integers might be useful/important there.
<rlb>Right, I've always assumed eq? was effectively pointer eq.
<dpk>maybe if i do SRFI-fy it, i should just leave it open as an issue to be discussed during the SRFI draft period
<rlb>Sounds like a good idea.
<dpk>yes, but theoretically an implementation that does (define eq? eqv?) is also conforming – for hysterical raisins: back in the pre-R5RS days committee members thought it would be cleaner to make them the officially both have eqv? behaviour one day … but that day never came
<rlb>...just offhand, iF it were being used heavily, say in a tight loop, I might be able to see an argument for being very strict there (i.e. "pointer" eq), so a compiler could run with it.
<dpk>yeah, i definitely get the efficiency argument
<rlb>So I'd probably favor having to justify eqv?, again offhand.
<dpk>it could also just be unspecified behaviour to use something that doesn’t come from (make-prompt-tag) as a prompt tag. Guile’s docs kind of already imply you’re not meant to …
<rlb>oh, I suppose that's another reasonable option, i.e. "opaque" ish.
<rlb>I'd probably lean toward one of those two, but I only kinda know what we're talking about -- need to refresh there.
<rlb>euouae: perhaps send a reply to the bug with that additional information -- I suspect it might let someone like Andy see the problem fairly "easily".
<rlb>(i.e. with https://termbin.com/8ihs )
<rlb>The content, not the link :)
<euouae>Will do soon