[Vm-dev] Debugging Win64 Cog Spur

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Fri May 26 12:55:21 UTC 2017


2017-05-26 9:24 GMT+02:00 Nicolas Cellier <
nicolas.cellier.aka.nice at gmail.com>:

>
>
> 2017-05-25 17:49 GMT+02:00 Eliot Miranda <eliot.miranda at gmail.com>:
>
>> Hi Nicolas,
>>
>> On Wed, May 24, 2017 at 11:28 PM, Nicolas Cellier <
>> nicolas.cellier.aka.nice at gmail.com> wrote:
>>
>>> Great, you reproduced exact same behavior.
>>> The problem I have is effectively where to put the breakpoint.
>>> I think we can believe the output of (gdb) call printCallStack()
>>>
>>
>> here's one issue; the computation to see if the frame pointer is in use
>> fails.  I'm executing this at the compilation break point for FilePath
>> class>pathName:isEncoded:
>>
>> (gdb) print /x CStackPointer
>> $7 = 0xef91d0
>> (gdb) print /x CFramePointer
>> $8 = 0x0
>> (gdb) print cFramePointerInUse
>> $9 = 0
>> (gdb) info registers
>> rax            0x68588f 6838415
>> rbx            0xffffffff       4294967295
>> rcx            0x68588f 6838415
>> rdx            0xabababab003a643a       -6076574521274768326
>> rsi            0xfde9   65001
>> rdi            0x0      0
>> rbp            0xef5db0 0xef5db0
>> rsp            0xef5c50 0xef5c50
>> r8             0x0      0
>> r9             0xfffffffffbefbc48       -68174776
>> r10            0xe36e626d44726839       -2058599758222432199
>> r11            0x8101010101010100       -9151031864016699136
>> r12            0xffffffff       4294967295
>> r13            0x20     32
>> r14            0x7ffc202018f0   140720847460592
>> r15            0xf2faf0 15923952
>> rip            0x4015d9 0x4015d9 <warning+9>
>> eflags         0x206    [ PF IF ]
>> cs             0x33     51
>> ss             0x2b     43
>> ds             0x2b     43
>> es             0x2b     43
>> fs             0x53     83
>> gs             0x2b     43
>> (gdb)
>>
>>
>
> So ceCaptureStackPointers() must get the value of SP and eventually FP in
> the caller.
> For getting caller SP, it must unstack the push RBX, and the return
> address.
>
> But on Win64 ABI it's not enough, because stack space is reserved for the
> 4 register arguments even if there is less than 4...
> So we must add 32 bytes more to callee SP in order to retrieve caller SP...
>
>
Hmmm wrong guess from my side.
Some calls do explicitely reserve the stack space for saving the 4 register
parameters like:

   0x518d06 <generateCaptureCStackPointers+150>:        sub    $0x20,%rsp
   0x518d0a <generateCaptureCStackPointers+154>:        callq  0x506220
<zeroOpcodeIndexForNewOpcodes>
   0x518d0f <generateCaptureCStackPointers+159>:        add    $0x20,%rsp

but some do not:

   0x4ed822 <generateStackPointerCapture+178>:  mov
0x2071f7(%rip),%rdx        # 0x6f4a20 <methodZoneBase>
   0x4ed829 <generateStackPointerCapture+185>:  mov    %rdx,0x70(%rsp)
   0x4ed82e <generateStackPointerCapture+190>:  mov
0x207203(%rip),%rdx        # 0x6f4a38 <trampolineTableIndex>
   0x4ed835 <generateStackPointerCapture+197>:  mov    %rdx,0x68(%rsp)
   0x4ed83a <generateStackPointerCapture+202>:  callq  0x518c70
<generateCaptureCStackPointers>
   0x4ed83f <generateStackPointerCapture+207>:  callq
*0x2b199b(%rip)        # 0x79f1e0 <ceCaptureCStackPointers>
   0x4ed845 <generateStackPointerCapture+213>:  callq  0x543650
<isCFramePointerInUse>
   0x4ed84a <generateStackPointerCapture+218>:  movslq %eax,%rcx
   0x4ed84d <generateStackPointerCapture+221>:  mov
%rcx,0x2b1844(%rip)        # 0x79f098 <cFramePointerInUse>

If I put a breakpoint:
(gdb) break generateStackPointerCapture

then I see that the frame pointer is not in use in this function:

(gdb) print $rbp
$6 = (void *) 0x0

then:

(gdb) print $rsp
$7 = (void *) 0xf2f250

if I step over ceCaptureCStackPointers()
=> 0x4e00010:   push   %rbx
   0x4e00011:   mov    $0x6dc018,%rbx
   0x4e00018:   mov    %rbp,0xc3158(%rbx)
   0x4e0001f:   mov    %rsp,%rax
   0x4e00022:   add    $0x30,%rax
   0x4e00026:   mov    %rax,0xc3140(%rbx)
   0x4e0002d:   pop    %rbx

i find:

(gdb) print CFramePointer
$10 = (void *) 0x0
(gdb) print CStackPointer
$9 = (void *) 0xf2f270

0x20 too much...

The other sender of ceCaptureCStackPointers does not use sub    $0x20,%rsp
either

   0x428310 <enterSmalltalkExecutiveImplementation+144>:        xor
%eax,%eax
   0x428312 <enterSmalltalkExecutiveImplementation+146>:        mov
%al,%dl
   0x428314 <enterSmalltalkExecutiveImplementation+148>:        mov
%dl,0x4d(%rsp)
   0x428318 <enterSmalltalkExecutiveImplementation+152>:        mov
0x4d(%rsp),%al
   0x42831c <enterSmalltalkExecutiveImplementation+156>:        mov
%al,0x4c(%rsp)
   0x428320 <enterSmalltalkExecutiveImplementation+160>:        callq
*0x376eba(%rip)        # 0x79f1e0 <ceCaptureCStackPointers>
   0x428326 <enterSmalltalkExecutiveImplementation+166>:        lea
0x376c33(%rip),%rcx        # 0x79ef60 <reenterInterpreter>

So I will have to revert last VMMaker change...


>
>>
>>> I've tried other means:
>>> - analyze direct usage of registers RCX & co from VMMaker
>>>   if ever it could conflicts with WIN64 logical register assignment
>>>   But I did not find anything
>>> - compile with MSVC 2017
>>>   if ever the compiler could spit different warnings and give a clue
>>>   alas it fails very early in readImageFromFileHeapSizeStartingAt
>>> (during checkAssumedCompactClasses)
>>>  the failure is incomprehensible, because the debugger shows identical
>>> contents if I print:
>>>
>>>         *((sqInt *)(classTableFirstPage+8+(51<<3)))
>>> 140697255509608    __int64
>>>         *((sqInt *)(specialObjectsOop+8+(7<<3)))    140697255509608
>>> __int64
>>>
>>> nonetheless, the debugger enters into the if and execute
>>>         invalidCompactClassError("Array");
>>>
>>> I'll have to debug it at assembler level, but it's driving me away from
>>> the original problem...
>>>
>>
>> Hmmm.  I doubt this is a problem because the assert and debug VMs would
>> print a warning if this were wrong and they seem to be doing fine (I'm
>> using the clang build).
>>
>>
>>>
>>>
> This is a MSVC code generation bug.
>
>
>>
>>
>>
>> --
>> _,,,^..^,,,_
>> best, Eliot
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20170526/f34a47ec/attachment.html>


More information about the Vm-dev mailing list