[Cuis-dev] Another puzzle

Jan Vraný Jan.Vrany at labware.com
Fri Jun 14 08:06:13 PDT 2024


Another possibility is to install a "orange zone" at the bottom
of the stack marking it read only (couple pages). Then when you get
segfault, you check whether it happened in this orange zone and if
so, arrange for throwing "RecursionInterrupt" (possibly making 
orange zone read-write) and restart execution.

Does not handle all cases but in my experience - dead useful :-)

On Fri, 2024-06-14 at 07:51 -0700, Andres Valloud via Cuis-dev wrote:
> Aha, and that interrupt check should also be checking for stack
> overflow...
> 
> On 6/14/24 4:46 AM, Jan Vraný via Cuis-dev wrote:
> > On Fri, 2024-06-14 at 08:59 +0000, Jaromir Matas via Cuis-dev
> > wrote:
> > > 
> > > On 14-Jun-24 1:12:35 AM, "Andres Valloud via Cuis-dev"
> > > <cuis-dev at lists.cuis.st> wrote:
> > > 
> > > > Hello, continuing with the puzzling behavior, here's one from a
> > > > book signature I got back in the year 1999 or so.
> > > > 
> > > > a := Array new: 2.
> > > > a at: 1 put: #perform:withArguments:.
> > > > a at: 2 put: a.
> > > > a perform: (a at: 1) withArguments: (a at: 2)
> > > 
> > > wicked :)  My guess is because #perform:withArguments: is a
> > > primitive
> > > the infinite loop happens inside the VM when the VM tries to
> > > evaluate
> > > the arguments.
> > 
> > The VM just runs out of stack. Let's have a look in GDB:
> > 
> > ...
> > Thread 1 "pharo" received signal SIGSEGV, Segmentation fault.
> > 0x00005555555cc1cf in primitivePerformWithArgs ()
> >      at /redacted/Pharo/pharo-vm/spur64src/vm/gcc3x-
> > cointerp.c:37631
> > 37631	{   DECL_MAYBE_SQ_GLOBAL_STRUCT
> > 
> > What the VM was doing when it crashed?
> > 
> > (gdb) bt 5
> > #0  0x00005555555cc1cf in primitivePerformWithArgs ()
> >      at /redacted/Pharo/pharo-vm/spur64src/vm/gcc3x-
> > cointerp.c:37631
> > #1  0x00005555555ca33b in slowPrimitiveResponse ()
> >      at /redacted/Pharo/pharo-vm/spur64src/vm/gcc3x-
> > cointerp.c:24422
> > #2  executeNewMethod () at /redacted/Pharo/pharo-
> > vm/spur64src/vm/gcc3x-
> > cointerp.c:19557
> > #3  0x00005555555cc318 in primitivePerformWithArgs ()
> >      at /redacted/Pharo/pharo-vm/spur64src/vm/gcc3x-
> > cointerp.c:37735
> > #4  0x00005555555ca33b in slowPrimitiveResponse ()
> >      at /redacted/Pharo/pharo-vm/spur64src/vm/gcc3x-
> > cointerp.c:24422
> > #5  executeNewMethod () at /redacted/Pharo/pharo-
> > vm/spur64src/vm/gcc3x-
> > cointerp.c:19557
> > (More stack frames follow...)
> > 
> > Let's see what code exactly was executed when it crashed?
> > 
> > Dump of assembler code from 0x5555555cc1c5 to 0x5555555cc1d9:
> >     0x00005555555cc1c5 <primitivePerformWithArgs+37>:	jne
> > 0x5555555cc330 <primitivePerformWithArgs+400>
> >     0x00005555555cc1cb <primitivePerformWithArgs+43>:	push  
> > %rbp
> >     0x00005555555cc1cc <primitivePerformWithArgs+44>:	mov
> > %rsp,%rbp
> > => 0x00005555555cc1cf <primitivePerformWithArgs+47>:	push  
> > %r14
> >     0x00005555555cc1d1 <primitivePerformWithArgs+49>:	push  
> > %r13
> >     0x00005555555cc1d3 <primitivePerformWithArgs+51>:	push  
> > %r12
> >     0x00005555555cc1d5 <primitivePerformWithArgs+53>:	push  
> > %rbx
> >     0x00005555555cc1d6 <primitivePerformWithArgs+54>:	movzbl
> > 0x7(%rcx),%r12d
> > End of assembler dump.
> > 
> > Pushing a value onto a stack, what's the value of stack pointer:
> > 
> > (gdb) p $rsp
> > $1 = (void *) 0x7fffff7ff000
> > 
> > That's a bit funny value...
> > 
> > (gdb) info proc mapping $rsp
> > Mapped address space for 0x7fffff7ff000:
> > 
> >            Start Addr           End Addr       Size     Offset 
> > Perms
> > objfile
> >        0x7fffff7ff000     0x7ffffffff000   0x800000        0x0  rw-
> > p
> > [stack]
> > 
> > So, stack pointer points just to the bottom of the stack segment.
> > Executing push instruction would store value to unmapped address,
> > causing the crash.
> > 
> > Fixing this issue is left as an excercise for the reader :-)
> > 
> > Best, Jan
> > 
> > 
> > > I have no idea whether it is even possible to interrupt
> > > such a loop by `Alt+.` escape sequence. I'm looking forward to
> > > what
> > > others have to say. Thanks! Jaromir
> > > 
> > > 
> > > > 
> > > > 
> > > > Currently this expression crashes the VM.
> > > > 
> > > > Eem... the person that signed that in my book is well aware of
> > > > this
> > > > example :p.
> > > > 
> > > > Even if this doesn't crash, you should still be able to break
> > > > out
> > > > of it by invoking the debugger.  An infinite loop that you
> > > > can't
> > > > interrupt is unacceptable behavior too.
> > > > 
> > > > Andres.
> > > > -- Cuis-dev mailing list
> > > > Cuis-dev at lists.cuis.st
> > > > https://lists.cuis.st/mailman/listinfo/cuis-dev
> > > > 
> > > > 
> > 



More information about the Cuis-dev mailing list