Subject: Re: bug#48061: Unexpected result from a native-compiled function

From: Andrea Corallo <[email-masked]>
Date: Tue, 27 Apr 2021 20:02:45 +0000

Alan Mackenzie <[email-masked]> writes:

> On Tue, Apr 27, 2021 at 14:49:31 +0000, Alan Mackenzie wrote:
>> Hello, Emacs.
>
>> In certain circumstances (see below for recipe), the natively compiled
>> version of c-determine-limit-no-macro returns an invalid result, nil.
>> In the same circumstances, the edebug instrumented version returns the
>> correct result, a buffer position.
>
>> So far I have tried M-x disassemble RET c-determine-limit-no-macro, but
>> I wasn't able to follow the output (there were no symbols in the
>> listing).
>
> I've now managed to get a decent disassembly, and there is indeed a
> missing machine instruction in the code which causes it to fail:
>
> The function is:
>
> #########################################################################
> (defun c-determine-limit-no-macro (here org-start)
>   ;; If HERE is inside a macro, and ORG-START is not also in the same macro,
>   ;; return the beginning of the macro.  Otherwise return HERE.  Point is not
>   ;; preserved by this function.
>   (goto-char here)
>   (let ((here-BOM (and (c-beginning-of-macro) (point))))
>     (if (and here-BOM
>              (not (eq (progn (goto-char org-start)
>                              (and (c-beginning-of-macro) (point)))
>                       here-BOM)))
>         here-BOM
>       here)))
> #########################################################################
>
> The register use in the compiled function is:
>
> rbp     here
> r12     org-start
> r13     here-BOM
>
> The disassembly (with some added notes) is this:
>
> 00000000000264f0 <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0>:
>    264f0:       41 56                   push   %r14

[...]

>    26583:       ff 93 68 14 00 00       callq  *0x1468(%rbx)       point
>    26589:       48 89 c7                mov    %rax,%rdi
>    2658c:       4c 89 ee                mov    %r13,%rsi         here-BOM
>    2658f:       ff 93 60 27 00 00       callq  *0x2760(%rbx)       eq
>    26595:       48 85 c0                test   %rax,%rax                                  <========================================================
>    26598:       74 03                   je     2659d <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0+0xad>
>    2659a:       48 89 e8                mov    %rbp,%rax         here
>    2659d:       48 8b 54 24 18          mov    0x18(%rsp),%rdx
>    265a2:       64 48 2b 14 25 28 00    sub    %fs:0x28,%rdx
>    265a9:       00 00
>    265ab:       75 0d                   jne    265ba <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0+0xca>
>    265ad:       48 83 c4 20             add    $0x20,%rsp
>    265b1:       5b                      pop    %rbx
>    265b2:       5d                      pop    %rbp
>    265b3:       41 5c                   pop    %r12
>    265b5:       41 5d                   pop    %r13
>    265b7:       41 5e                   pop    %r14
>    265b9:       c3                      retq
>    265ba:       e8 41 12 fe ff          callq  7800 <__stack_chk_fail@plt>
>    265bf:       90                      nop
>
> After the indicated line (0x26595), when 0x0 (nil) is in rax (i.e. the
> `eq' function has returned nil) the result of the function should be
> here-BOM, i.e. r13.  There is no instruction
>
>     mov %r13,%rax
>
> to effect this return.  Instead, rax is still holding nil, and this is
> falsely returned.
>

Hi Alan,

thanks for investigating this!  I had a quick look and I think I see
what's the issue, I'll follow up when I've the fix.

Thanks

  Andrea