bug#79483: Segmentation fault: set-car! in compiled code
Nikolaos Chatzikonstantinou <[email protected]> Tue, 21 Oct 2025 02:04:54 -0400
| Newsgroups | gmane.lisp.guile.bugs |
|---|---|
| Message-ID | <CAAQmekeYkqTq76zwkvQoDNgHaw4sUe1a=1NrhQ8srYz3MS14bA@mail.gmail.com> |
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.