Last April I reported a problem building cc-align.el using a non-Mule
21.4 on my Linux box; see
http://list-archive.xemacs.org/xemacs-beta/200204/msg00506.html
I promised to look into this if I got time, and lo and behold, a mere
10 months later I decided to investigate. The traceback can be
consistently reproduced here at home; I have used a very stripped down
XEmacs to speed up rebuilding and to help in isolating the failure:
#0 0x401000a8 in realloc () from /lib/i686/libc.so.6
#1 0x400ffe80 in realloc () from /lib/i686/libc.so.6
#2 0x080724b0 in xrealloc (block=0x401c9268, size=1075499840) at alloc.c:276
#3 0x0809df68 in grow_specpdl (reserved=1) at eval.c:4821
#4 0x0809e11f in specbind (symbol=1075711632, value=136809784) at eval.c:4901
#5 0x08098db1 in Flet (args=1075614312) at eval.c:938
#6 0x0809bbf5 in Feval (form=136811284) at eval.c:3308
#7 0x080989d7 in Fprogn (args=136810024) at eval.c:775
#8 0x0809bbf5 in Feval (form=136810012) at eval.c:3308
#9 0x0809c257 in Ffuncall (nargs=2, args=0xbfffc2a0) at eval.c:3536
#10 0x0807c48d in execute_optimized_program (
program=0x82d50f8
"Æ\032Ç\216\t\034Æ\211\e\035\f:«%\f@\211\023\211A\023@\025È\r!«\a\r\211KBª\002\r\nB\022\rÉ\vBM\210\fA\211\024ªÚÊ\b!-\207",
stack_depth=1, constants_data=0x828e150)
at bytecode.c:748
#11 0x0807c1a9 in funcall_compiled_function (fun=136786992, nargs=1, args=0xbfffc380)
at bytecode.c:516
#12 0x0809bf5a in Feval (form=136895292) at eval.c:3392
#13 0x0809be52 in Feval (form=136895244) at eval.c:3352
#14 0x080989d7 in Fprogn (args=136895388) at eval.c:775
#15 0x0809c9de in funcall_lambda (fun=136895196, nargs=1, args=0xbfffc73c) at eval.c:3863
Here is the full traceback:
Using dmalloc and repeatedly calling dmalloc_verify(0) in gdb, I was
able to isolate the failure somewhat. The specpdl gets overwritten in
the function execute_optimized_program() on the 4th time through this
code:
line 714:
if (!SYMBOL_VALUE_MAGIC_P (old_value) || UNBOUNDP (old_value))
{
specpdl_ptr->symbol = symbol;
specpdl_ptr->old_value = old_value;
specpdl_ptr->func = 0;
specpdl_ptr++;
specpdl_depth_counter++;
symbol_ptr->value = new_value;
}
If I go back to funcall_compiled_function(), which calls
execute_optimized_program(), I see:
line 480:
if (!OPAQUEP (f->instructions))
/* Lazily munge the instructions into a more efficient form */
optimize_compiled_function (fun);
/* optimize_compiled_function() guaranteed that f->specpdl_depth is
the required space on the specbinding stack for binding the args
and local variables of fun. So just reserve it once. */
SPECPDL_RESERVE (f->specpdl_depth);
In this case, f->specpdl_depth is 5, and if I increase it to 6
before calling SPECPDL_RESERVE, no crash occurs, because the size of
specpdl is increased before calling execute_optimized_program().
2 questions:
1. In this case, optimize_compiled_function() is not called, so does
anything guarantee that "f->specpdl_depth is the required space
on the specbinding stack for binding the args and local variables
of fun"?
2. Did the bytecompiler just make a mistake in calculating the
specpdl depth required for the specified function?
Can anyone help here? I'm slightly out of my depth in messing with
the bytecode interpreter, but I'm happy to continue investigating if
anyone can give me a gentle nudge in the right direction.
Let me know if there are more details I need to provide.
Thanks in advance,
Vin