On Tue, Sep 23, 2025 at 06:22:45AM +0200, tomas wrote:
> On Mon, Sep 22, 2025 at 09:27:54PM +0200, Tomas Volf wrote:
> > <[email protected]> writes:
> >
> > > On Mon, Sep 22, 2025 at 12:50:57AM +0300, var-vniiaes--- via Bug reports
> > > for GUILE, GNU's Ubiquitous Extension Language wrote:
> > >>
> > >> Hello,
> > >>
> > >> Execution of (set-car! '(0) 1) *in compiled code* leads to segfault:
> > >
> > > First of all: you shouldn't be doing that :)
> > >
> > > You are mutating a constant. I don't know what the Scheme specification
> > > says
> > > to it (if at all).
> >
> > --8<---------------cut here---------------start------------->8---
> > As noted in section 3.4, it is an error to attempt to alter
> > a constant (i.e. the value of a literal expression) using a
> > mutation procedure like set-car! or string-set!
> > --8<---------------cut here---------------end--------------->8---
> >
> > > The other question is whether Guile should/could catch that and signal an
> > > error instead.
> >
> > I believe it should not.
>
> This is ambiguous, but from the context below I think you mean Guile
> should catch it. I agree :-)
>
> > Memory-safe languages (and, Guile is supposed
> > to be one) should never segfault but instead terminate with a sensible
> > error. I realize that 1.3.2 allows to "fail catastrophically", which
> > segfault probably qualifies as, but I believe we should do better.
>
> Definitely -- the question is whether Guile wants to rely on the
> OS/runtime to catch an out-of-bounds access (or more probably here
> an access to a region marked read-onls) or catch it itself.
Another way to trigger it is to run:
(use-modules (system vm disassembler))
(disassemble-image (compile '(set-car! (0) 1) #:to 'bytecode))
The above makes it seem like it's not a permissions error but an
out-of-bounds error, and indeed in a gdb session just after the
segfault I see:
(gdb) l
1928 {
1929 uint8_t obj, idx, val;
1930
1931 UNPACK_8_8_8 (op, obj, idx, val);
1932
1933 SCM_SET_CELL_OBJECT (SP_REF (obj), idx, SP_REF (val));
1934
1935 NEXT (1);
1936 }
(gdb) p SP_REF(obj)
Cannot access memory at address 0x7ffff7e09eb8
(gdb) info proc mappings
.
.
.
0x7ffff7e07000 0x7ffff7e09000 0x2000 0x0 rw-p
0x7ffff7e0a000 0x7ffff7e2a000 0x20000 0x0 rw-p
As you can see the memory address 0x7ffff7e09eb8 is not part of the
mappings of the process as it lies between the above two listed
mappings.