Subject: bug#17168: 24.3.50; Segfault at mark_object

From: Dmitry Antipov <[email-masked]>
Date: Thu, 03 Apr 2014 10:59:50 +0400

Hopefully I found the way to catch bogus object in 'function' slot
of a Lisp_Symbol.  100% reproducible for me, as of bzr revision 116934.

1. Apply this patch.

2. Compile with -O0 -g3 and --enable-checking.

3. Run 'emacs -Q', then M-x byte-force-recompile
    /path/to/trunk/lis/org

4. Crash ==>

#0  0x000000379220f62b in raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/pt-raise.c:37
#1  0x0000000000569aff in terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at ../../trunk/src/emacs.c:382
#2  0x00000000005f089a in die (
     msg=0x70f498 "SYMBOLP (sym->s.function) || CONSP (sym->s.function) || COMPILEDP (sym->s.function) || SUBRP (sym->s.function)",
     file=0x70e420 "../../trunk/src/alloc.c", line=6613) at ../../trunk/src/alloc.c:6913
#3  0x00000000005f00b5 in sweep_symbols () at ../../trunk/src/alloc.c:6610
#4  0x00000000005f03bb in gc_sweep () at ../../trunk/src/alloc.c:6735
#5  0x00000000005ede1e in Fgarbage_collect () at ../../trunk/src/alloc.c:5632
#6  0x0000000000567706 in maybe_gc () at ../../trunk/src/lisp.h:4520
#7  0x000000000065b95f in exec_byte_code (bytestr=..., vector=..., maxdepth=..., args_template=..., nargs=2, args=0x7fff66de7f70)
     at ../../trunk/src/bytecode.c:954

[...next frames probably irrelevant...]

Dmitry

=== modified file 'src/alloc.c'
--- src/alloc.c	2014-04-03 00:37:51 +0000
+++ src/alloc.c	2014-04-03 06:42:53 +0000
@@ -6174,6 +6174,11 @@
 	  break;
 	CHECK_ALLOCATED_AND_LIVE (live_symbol_p);
 	ptr->gcmarkbit = 1;
+	/* Attempt to catch bogus objects.  */
+	eassert (SYMBOLP (ptr->function)
+		 || CONSP (ptr->function)
+		 || COMPILEDP (ptr->function)
+		 || SUBRP (ptr->function));
 	mark_object (ptr->function);
 	mark_object (ptr->plist);
 	switch (ptr->redirect)
@@ -6601,6 +6606,11 @@
               if (!pure_p)
                 eassert (!STRING_MARKED_P (XSTRING (sym->s.name)));
               sym->s.gcmarkbit = 0;
+              /* Attempt to catch bogus objects.  */
+              eassert (SYMBOLP (sym->s.function)
+                       || CONSP (sym->s.function)
+                       || COMPILEDP (sym->s.function)
+                       || SUBRP (sym->s.function));
             }
         }