Subject: bug#16986: Fw: Re: Crash when idle

From: Dmitry Antipov <[email-masked]>
Date: Fri, 01 Aug 2014 12:17:31 +0400

On 07/23/2014 02:09 PM, YAMAMOTO Mitsuharu wrote:

> I suspect there are no direct references to the value of `directory'
> from stack contents or register values, and thus GC triggered by the
> above DECODE_FILE has collected the value of `directory' as a garbage.
> If that is the case, %rax at <+730> (i.e., &XSTRING(directory)->data)
> would become invalid.

Nice shot.

Clang 3.4 with -O2 -g3 generates:

0x0000000000531c21 <+721>:      callq  0x551570 <make_uninit_multibyte_string>
0x0000000000531c26 <+726>:      mov    %rax,%rbp
0x0000000000531c29 <+729>:      mov    0x17(%rbp),%rdi
0x0000000000531c2d <+733>:      mov    0x28(%rsp),%rax
0x0000000000531c32 <+738>:      mov    (%rax),%rsi
0x0000000000531c35 <+741>:      mov    0x38(%rsp),%rdx
0x0000000000531c3a <+746>:      callq  0x413050 <memcpy@plt>

GCC 4.8.3 with -O2 -g3 generates:

0x0000000000520e0d <+573>:      callq  0x5407e0 <make_uninit_multibyte_string>
0x0000000000520e12 <+578>:      mov    0x38(%rsp),%rsi
0x0000000000520e17 <+583>:      lea    -0x1(%rax),%r15
0x0000000000520e1b <+587>:      mov    0x20(%rsp),%rdx
0x0000000000520e20 <+592>:      mov    0x18(%r15),%rdi
0x0000000000520e24 <+596>:      mov    %rax,%rbx
0x0000000000520e27 <+599>:      mov    0x18(%rsi),%rsi
0x0000000000520e2b <+603>:      callq  0x413270 <memcpy@plt>

With an attached patch, clang generates:

0x0000000000531c01 <+689>:      callq  0x551560 <make_uninit_multibyte_string>
0x0000000000531c06 <+694>:      mov    0x17(%rax),%rdi
0x0000000000531c0a <+698>:      mov    %rax,%rbp
0x0000000000531c0d <+701>:      mov    0x68(%rsp),%rax
0x0000000000531c12 <+706>:      mov    0x17(%rax),%rsi
0x0000000000531c16 <+710>:      mov    0x50(%rsp),%rdx
0x0000000000531c1b <+715>:      callq  0x413050 <memcpy@plt>

I.e. with a displacement to %rsi.  OK to install?

Dmitry

=== modified file 'src/dired.c'
--- src/dired.c	2014-04-16 19:43:46 +0000
+++ src/dired.c	2014-08-01 08:11:30 +0000
@@ -133,7 +133,7 @@
    In the latter case, ID_FORMAT is passed to Ffile_attributes.  */
 
 Lisp_Object
-directory_files_internal (Lisp_Object directory, Lisp_Object full,
+directory_files_internal (Lisp_Object dir, Lisp_Object full,
 			  Lisp_Object match, Lisp_Object nosort, bool attrs,
 			  Lisp_Object id_format)
 {
@@ -149,6 +149,16 @@
 #ifdef WINDOWSNT
   Lisp_Object w32_save = Qnil;
 #endif
+#ifdef __clang__
+  /* It is suspected that clang (as of 3.4 running with -O2) can
+     optimize DIR away so there is no reference from C stack to
+     this object.  Since this can crash GC, we're using volatile
+     variable to disable such an optimization.  For details, see
+     http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16986#32.  */
+  volatile Lisp_Object directory = dir;
+#else
+  Lisp_Object directory = dir;
+#endif
 
   /* Because of file name handlers, these functions might call
      Ffuncall, and cause a GC.  */