[Cuis-dev] Another puzzle

Andres Valloud ten at smallinteger.com
Fri Jun 14 07:51:53 PDT 2024


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