[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