Subject: bug#37415: Asserting failure setting frame parameters to non-fixnum values in early-init.el

From: martin rudalics <[email-masked]>
Date: Sat, 21 Sep 2019 10:51:49 +0200

> If the patch below solves the original problem, please install it.  If
 > it doesn't, then please help me understand how is it related to the
 > issue at hand, because I don't think I understand.

It hardly makes sense to install a patch you don't understand.  So
let's get back to the original problem.  Juanma said that

 > This is with an empty init.el, and the following early-init.el:
 >
 > D:\...\.emacs.d> type early-init.el
 > (setq default-frame-alist '((left . (+ 0))))
 >
 > D:\...\.emacs.d> emacs.exe
 >
 > lisp.h:1231: Emacs fatal error: assertion failed: FIXNUMP (a)

and when I try that on Windows 10 with a 64-bit build of master I get
the following backtrace

(gdb) bt
#0  terminate_due_to_signal (sig=22, backtrace_limit=2147483647) at ../../src/emacs.c:375
#1  0x00000004002bb1d2 in die (msg=0x4009fdf3e <DEFAULT_REHASH_SIZE+5690> "FIXNUMP (a)", file=0x4009fdee0 <DEFAULT_REHASH_SIZE+5596> "../../src/lisp.h", line=1231) at ../../src/alloc.c:7245
#2  0x0000000400447414 in XFIXNUM (a=XIL(0x69699b3)) at ../../src/lisp.h:1231
#3  0x0000000400458b94 in my_create_window (f=0x76193d0) at ../../src/w32fns.c:5433
#4  0x0000000400458f5e in w32_window (f=0x76193d0, window_prompting=4, minibuffer_only=false) at ../../src/w32fns.c:5505
#5  0x000000040045af89 in Fx_create_frame (parameters=XIL(0x69835e3)) at ../../src/w32fns.c:6010
#6  0x0000000400319b96 in funcall_subr (subr=0x400957e00 <Sx_create_frame>, numargs=1, args=0xbfc658) at ../../src/eval.c:2867
#7  0x000000040031966f in Ffuncall (nargs=2, args=0xbfc650) at ../../src/eval.c:2794
#8  0x0000000400396404 in exec_byte_code (bytestr=XIL(0x61d586c), vector=XIL(0x61d40c5), maxdepth=make_fixnum(13), args_template=make_fixnum(256), nargs=1, args=0xbfcb90) at ../../src/bytecode.c:633
#9  0x000000040031a2c7 in funcall_lambda (fun=XIL(0x61d4095), nargs=1, arg_vector=0xbfcb88) at ../../src/eval.c:2989
#10 0x00000004003196b3 in Ffuncall (nargs=2, args=0xbfcb80) at ../../src/eval.c:2796
#11 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x61d58ac), vector=XIL(0x61d4055), maxdepth=make_fixnum(3), args_template=make_fixnum(257), nargs=1, args=0xbfd200) at ../../src/bytecode.c:633
#12 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x61d4005), nargs=1, arg_vector=0xbfd1f8) at ../../src/eval.c:2989
#13 0x00000004003196b3 in Ffuncall (nargs=2, args=0xbfd1f0) at ../../src/eval.c:2796
#14 0x00000004003184c5 in Fapply (nargs=2, args=0xbfd1f0) at ../../src/eval.c:2381
#15 0x0000000400319a8c in funcall_subr (subr=0x400952540 <Sapply>, numargs=2, args=0xbfd1f0) at ../../src/eval.c:2847
#16 0x000000040031966f in Ffuncall (nargs=3, args=0xbfd1e8) at ../../src/eval.c:2794
#17 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x6073844), vector=XIL(0x61d1325), maxdepth=make_fixnum(15), args_template=make_fixnum(128), nargs=1, args=0xbfd738) at ../../src/bytecode.c:633
#18 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x61d12f5), nargs=1, arg_vector=0xbfd738) at ../../src/eval.c:2989
#19 0x00000004003196b3 in Ffuncall (nargs=2, args=0xbfd730) at ../../src/eval.c:2796
#20 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x61e239c), vector=XIL(0x5fb9a0d), maxdepth=make_fixnum(14), args_template=make_fixnum(256), nargs=1, args=0xbfdd28) at ../../src/bytecode.c:633
#21 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x5fb99d5), nargs=1, arg_vector=0xbfdd20) at ../../src/eval.c:2989
#22 0x00000004003196b3 in Ffuncall (nargs=2, args=0xbfdd18) at ../../src/eval.c:2796
#23 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x638d3d4), vector=XIL(0x638d32d), maxdepth=make_fixnum(6), args_template=make_fixnum(0), nargs=0, args=0xbfe220) at ../../src/bytecode.c:633
#24 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x638d2fd), nargs=0, arg_vector=0xbfe220) at ../../src/eval.c:2989
#25 0x00000004003196b3 in Ffuncall (nargs=1, args=0xbfe218) at ../../src/eval.c:2796
#26 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x6393434), vector=XIL(0x638f585), maxdepth=make_fixnum(14), args_template=make_fixnum(0), nargs=0, args=0xbfed88) at ../../src/bytecode.c:633
#27 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x638f555), nargs=0, arg_vector=0xbfed88) at ../../src/eval.c:2989
#28 0x00000004003196b3 in Ffuncall (nargs=1, args=0xbfed80) at ../../src/eval.c:2796
#29 0x0000000400396404 in exec_byte_code (bytestr=XIL(0x639401c), vector=XIL(0x6393605), maxdepth=make_fixnum(12), args_template=make_fixnum(0), nargs=0, args=0xbff3d0) at ../../src/bytecode.c:633
#30 0x000000040031a2c7 in funcall_lambda (fun=XIL(0x63935d5), nargs=0, arg_vector=0xbff3d0) at ../../src/eval.c:2989
#31 0x0000000400319f4d in apply_lambda (fun=XIL(0x63935d5), args=XIL(0), count=4) at ../../src/eval.c:2926
#32 0x0000000400318106 in eval_sub (form=XIL(0x64e9d2b)) at ../../src/eval.c:2318
#33 0x00000004003173b0 in Feval (form=XIL(0x64e9d2b), lexical=XIL(0)) at ../../src/eval.c:2102
#34 0x00000004001aa0fb in top_level_2 () at ../../src/keyboard.c:1100
#35 0x00000004003154e2 in internal_condition_case (bfun=0x4001aa0d0 <top_level_2>, handlers=XIL(0x90), hfun=0x4001a9948 <cmd_error>) at ../../src/eval.c:1355
#36 0x00000004001aa153 in top_level_1 (ignore=XIL(0)) at ../../src/keyboard.c:1108
#37 0x000000040031493b in internal_catch (tag=XIL(0xdc80), func=0x4001aa101 <top_level_1>, arg=XIL(0)) at ../../src/eval.c:1116
#38 0x00000004001a9fcf in command_loop () at ../../src/keyboard.c:1069
#39 0x0000000000000000 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)

Lisp Backtrace:
"x-create-frame" (0xbfc658)
"x-create-frame-with-faces" (0xbfcb88)
0x61d4000 PVEC_COMPILED
"apply" (0xbfd1f0)
"frame-creation-function" (0xbfd738)
"make-frame" (0xbfdd20)
"frame-initialize" (0xbfe220)
"command-line" (0xbfed88)
"normal-top-level" (0xbff3d0)

I get a similar backtrace when I try the more reasonable

(setq default-frame-alist '((left . (- 100))))

in my early-init.el (more reasonable because, after all,

(setq default-frame-alist '((left . (+ 0))))

is equivalent to

(setq default-frame-alist '((left . 0)))

which _can_ be handled from within early-init.el).  Do we agree so
far?  If so, then obviously

   if (EQ (left, Qunbound))
     coords[0] = CW_USEDEFAULT;
   else
     coords[0] = XFIXNUM (left);

will choke when 'left' is something like '(+ 0)' or '(- 100)' since
neither of these pass the

eassert (FIXNUMP (a))

check we have in XFIXNUM.  Still agreed?  Then doing something like

   if (FIXNUMP (left))
     coords[0] = XFIXNUM (left);
   else
     coords[0] = CW_USEDEFAULT;

should fix the assertion failure if my poor understanding of C doesn't
let me down completely (the 'top' parameter needing a similar fix).
Does that reasoning still make sense to you?

And finally, with the sole evidence of my poor eyesight,

(setq default-frame-alist '((left . (- 100))))

seems to work here too, despite of the fact that for the first frame
the defaults are used.  Maybe you can try to verify (I attach the
patch for easier use this time).

So do you still think that we should signal an error?

Thanks, martin
diff --git a/src/w32fns.c b/src/w32fns.c
index 34abd026f9..3771d9d5f9 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -5427,14 +5427,16 @@ my_create_window (struct frame * f)
                               RES_TYPE_NUMBER);
   top = gui_display_get_arg (dpyinfo, Qnil, Qtop, "top", "Top",
                              RES_TYPE_NUMBER);
-  if (EQ (left, Qunbound))
-    coords[0] = CW_USEDEFAULT;
-  else
+
+  if (FIXNUMP (left))
     coords[0] = XFIXNUM (left);
-  if (EQ (top, Qunbound))
-    coords[1] = CW_USEDEFAULT;
   else
+    coords[0] = CW_USEDEFAULT;
+
+  if (FIXNUMP (top))
     coords[1] = XFIXNUM (top);
+  else
+    coords[1] = CW_USEDEFAULT;
 
   if (!PostThreadMessage (dwWindowsThreadId, WM_EMACS_CREATEWINDOW,
 			  (WPARAM)f, (LPARAM)coords))