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