unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#48061: Unexpected result from a native-compiled function
@ 2021-04-27 14:49 Alan Mackenzie
  2021-04-27 17:20 ` Alan Mackenzie
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Mackenzie @ 2021-04-27 14:49 UTC (permalink / raw)
  To: 48061

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).

Question: what else can I do to help isolate and fix this bug?

Recipe for reproduction:

In GNU Emacs 28.0.50 (build 4, x86_64-pc-linux-gnu, GTK+ Version
3.24.26, cairo version 1.16.0)
 of 2021-04-25 built on ACM
Repository revision: 83a915d3dfafd5f3d737afe1e13b75e4dd3aef96
Repository branch: master
System Description: Gentoo/Linux

Configured using:
 'configure --with-gif=no --with-tiff=no --with-gpm
 --with-native-compilation'


(i) emacs -Q
(ii) Make sure CC Mode is natively compiled and loaded into an Emacs
session.
(iii) Evaluate the following (an attempt to time CC Mode's indentation
speed):

(defmacro time-it (&rest forms)
  "Time the running of a sequence of forms using `float-time'.
Call like this: \"M-: (time-it (foo ...) (bar ...) ...)\"."
  `(let ((start (float-time)))
    ,@forms
    (- (float-time) start)))

(defun time-indent ()
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (while (not (eobp))
      (delete-horizontal-space)
      (beginning-of-line 2))
    (goto-char (point-min))
    (message "%s"
             (time-it
              (while (not (eobp))
                (c-indent-line)
                (beginning-of-line 2))))))

(iv) Load src/minibuf.c into a buffer.
(v) M-: (time-indent) RET
  This throws an error at line 606 in minibuf.c.  point is at 16972, at
BOL.

(vi) With the current buffer minibuf.c, M-: (c-determine-limit-no-macro
16367 16972) RET.  This returns the invalid result nil.  This looks like
a bug.

(vii) Load lisp/progmodes/cc-engine.el into another buffer.  Move to the
definition of c-determine-limit-no-macro at line 5795.  Instrument the
function for edebug with C-u C-M-x.

(viii) M-: (c-determine-limit-no-macro 16367 16972) RET, followed by the
edebug command c.  This indicates the expected result 16350, which is
different from the nil returned in (vi).


-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#48061: Unexpected result from a native-compiled function
  2021-04-27 14:49 bug#48061: Unexpected result from a native-compiled function Alan Mackenzie
@ 2021-04-27 17:20 ` Alan Mackenzie
  2021-04-27 20:02   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Mackenzie @ 2021-04-27 17:20 UTC (permalink / raw)
  To: 48061

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
   264f2:       41 55                   push   %r13
   264f4:       41 54                   push   %r12
   264f6:       49 89 f4                mov    %rsi,%r12   org-start
   264f9:       55                      push   %rbp
   264fa:       48 89 fd                mov    %rdi,%rbp   here
   264fd:       53                      push   %rbx
   264fe:       48 83 ec 20             sub    $0x20,%rsp
   26502:       64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
   26509:       00 00
   2650b:       48 89 44 24 18          mov    %rax,0x18(%rsp)
   26510:       48 8b 05 d1 2a 27 00    mov    0x272ad1(%rip),%rax        # 298fe8 <_DYNAMIC+0x1f8>
   26517:       48 8b 18                mov    (%rax),%rbx
   2651a:       ff 93 b8 14 00 00       callq  *0x14b8(%rbx)        goto-char
   26520:       48 8d 74 24 08          lea    0x8(%rsp),%rsi
   26525:       bf 01 00 00 00          mov    $0x1,%edi
   2652a:       4c 8b 35 af 2a 27 00    mov    0x272aaf(%rip),%r14        # 298fe0 <_DYNAMIC+0x1f0>
   26531:       49 8b 86 c8 00 00 00    mov    0xc8(%r14),%rax
   26538:       48 89 44 24 08          mov    %rax,0x8(%rsp)
   2653d:       ff 93 08 1a 00 00       callq  *0x1a08(%rbx)      c-beginning-of-macro
   26543:       48 85 c0                test   %rax,%rax
   26546:       74 52                   je     2659a <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0+0xaa>
   26548:       ff 93 68 14 00 00       callq  *0x1468(%rbx)      point
   2654e:       49 89 c5                mov    %rax,%r13        here-BOM
   26551:       48 85 c0                test   %rax,%rax
   26554:       74 44                   je     2659a <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0+0xaa>
   26556:       4c 89 e7                mov    %r12,%rdi         org-start
   26559:       ff 93 b8 14 00 00       callq  *0x14b8(%rbx)        goto-char
   2655f:       bf 01 00 00 00          mov    $0x1,%edi
   26564:       48 8d 74 24 10          lea    0x10(%rsp),%rsi
   26569:       49 8b 86 c8 00 00 00    mov    0xc8(%r14),%rax
   26570:       48 89 44 24 10          mov    %rax,0x10(%rsp)
   26575:       ff 93 08 1a 00 00       callq  *0x1a08(%rbx)       c-beginning-of-macro
   2657b:       48 89 c7                mov    %rax,%rdi
   2657e:       48 85 c0                test   %rax,%rax
   26581:       74 09                   je     2658c <F632d64657465726d696e652d6c696d69742d6e6f2d6d6163726f_c_determine_limit_no_macro_0+0x9c>
   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.

> -- 
> Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#48061: Unexpected result from a native-compiled function
  2021-04-27 17:20 ` Alan Mackenzie
@ 2021-04-27 20:02   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-04-27 21:03     ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 5+ messages in thread
From: Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-04-27 20:02 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: 48061

Alan Mackenzie <acm@muc.de> 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





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#48061: Unexpected result from a native-compiled function
  2021-04-27 20:02   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-04-27 21:03     ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2021-04-28  9:19       ` Alan Mackenzie
  0 siblings, 1 reply; 5+ messages in thread
From: Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2021-04-27 21:03 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: 48061

Andrea Corallo via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <bug-gnu-emacs@gnu.org> writes:

> Alan Mackenzie <acm@muc.de> 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.

Hi Alan,

looking at the intermediate representation of this interesting function
I've fixed a bug, I can't prove it solves your issue as I've no
reproducer tho.

Could you try if as of 4e1e0b9dec this is solved?  If is not the case
could you provide a reproducer so I'll not disturb next time until is
solved :)

Thanks

  Andrea





^ permalink raw reply	[flat|nested] 5+ messages in thread

* bug#48061: Unexpected result from a native-compiled function
  2021-04-27 21:03     ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2021-04-28  9:19       ` Alan Mackenzie
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Mackenzie @ 2021-04-28  9:19 UTC (permalink / raw)
  To: Andrea Corallo; +Cc: 48061-done, acm

Hello, Andrea.

On Tue, Apr 27, 2021 at 21:03:05 +0000, Andrea Corallo wrote:
> Andrea Corallo via "Bug reports for GNU Emacs, the Swiss army knife of
> text editors" <bug-gnu-emacs@gnu.org> writes:

[ .... ]

> >> 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.

> Hi Alan,

> looking at the intermediate representation of this interesting function
> I've fixed a bug, I can't prove it solves your issue as I've no
> reproducer tho.

> Could you try if as of 4e1e0b9dec this is solved?  If is not the case
> could you provide a reproducer so I'll not disturb next time until is
> solved :)

The bug fix does indeed fix my problem.  :-)  My test case now runs to
the end without error, and I had a look at the disassembly too, in which
I no longer see the problem from yesterday.

I'm closing the bug with this post.

Thanks!

> Thanks

>   Andrea

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2021-04-28  9:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-04-27 14:49 bug#48061: Unexpected result from a native-compiled function Alan Mackenzie
2021-04-27 17:20 ` Alan Mackenzie
2021-04-27 20:02   ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-04-27 21:03     ` Andrea Corallo via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-04-28  9:19       ` Alan Mackenzie

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).