Subject: Re: bug#22975: 25.0.92; CANNOT_DUMP build can't start in tty mode

From: Ken Raeburn <[email-masked]>
Date: Mon, 14 Mar 2016 03:17:07 -0400

>> In tty mode, the normal version starts fine, and the cursor motion is mostly as you describe, though the Arabic and Hebrew text don’t look the same in the terminal emulator (Mac terminal emulator running ssh to a GNU/Linux box running Emacs) as in the X11 window.  Instead, it looks like, for example, everything after “Hebrew (” on that line is reversed from the X11 display, and the “)” replaced with “(”.  Also, the cursor positioning as I hit C-f or C-b doesn’t quite line up with where the characters are; I think it may be lining up with where it thinks they’d be if they were laid out as in the X11 display.  So it moves over whitespace here, skips a character there…
> 
> Can you show a screenshot?
> 
> It sounds like your terminal emulator is trying its own reordering of
> bidi text.  Can you find some setting to disable that?

I can’t find an option to change it in the Mac terminal emulator.  I hope the attached image doesn’t make for headaches in the bug tracker….

If I start a standard X.org xterm from the remote system and run emacs -nw in that window, the Hebrew line looks like it does on the X11 display; Arabic seems to be missing font support.

> In any case, this is unrelated to the issue at hand.
> 
>> In tty mode, the CANNOT_DUMP version get stuck in a loop at startup complaining that internal-echo-keystrokes-prefix isn’t defined.  If I set a breakpoint on Fsignal, it’s first complaining about window--resize-root-window-vertically when trying to display the long load path, presumably terminating the processing of loadup.el; the second time it’s internal-timer-start-idle, then internal-echo-keystrokes-prefix, and then we just seem to stick with that one from then on.
> 
> Please show a full C backtrace from each one of the calls to Fsignal,
> so we could see what code calls these functions.

#0  Fsignal (error_symbol=error_symbol@entry=49392, data=12582931)
    at ../../src/eval.c:1464
#1  0x0000000000552fd9 in xsignal (error_symbol=error_symbol@entry=49392, 
    data=<optimized out>) at ../../src/eval.c:1577
#2  0x0000000000553007 in xsignal1 (error_symbol=49392, arg=<optimized out>)
    at ../../src/eval.c:1592
#3  0x0000000000552612 in Ffuncall (nargs=49392, nargs@entry=4, args=0x0)
    at ../../src/eval.c:2746
#4  0x0000000000554204 in call3 (fn=fn@entry=50592, arg1=arg1@entry=12481485, 
    arg2=<optimized out>, arg3=<optimized out>) at ../../src/eval.c:2568
#5  0x0000000000472717 in grow_mini_window (w=0xbe75b0, delta=<optimized out>, 
    pixelwise=<optimized out>) at ../../src/window.c:4501
#6  0x000000000044bd32 in resize_mini_window (w=w@entry=0xbe75b0, 
    exact_p=exact_p@entry=false) at ../../src/xdisp.c:10985
#7  0x000000000044bd8e in display_echo_area_1 (a1=12481968, a2=<optimized out>)
    at ../../src/xdisp.c:10831
#8  0x000000000042b8f6 in with_echo_area_buffer (w=w@entry=0xbe75b0, 
    which=which@entry=0, fn=fn@entry=0x44bd50 <display_echo_area_1>, 
    a1=a1@entry=12481968, a2=a2@entry=0) at ../../src/xdisp.c:10609
#9  0x000000000044f46b in display_echo_area (w=0xbe75b0)
    at ../../src/xdisp.c:10797
#10 echo_area_display (update_frame_p=update_frame_p@entry=true)
    at ../../src/xdisp.c:11298
#11 0x000000000044f76a in message3_nolog (m=m@entry=12803636)
    at ../../src/xdisp.c:10311
#12 0x000000000044f8b1 in message3 (m=m@entry=12803636)
    at ../../src/xdisp.c:10240
#13 0x000000000054c31c in Fmessage (nargs=<optimized out>, args=<optimized out>)
    at ../../src/editfns.c:3686
#14 0x0000000000551ff0 in eval_sub (form=form@entry=12584899)
    at ../../src/eval.c:2137
#15 0x000000000057475f in readevalloop (readcharfun=24528, stream=0xbed7f0, 
    sourcename=12773572, printflag=false, unibyte=<optimized out>, readfun=0, 
    start=0, end=0) at ../../src/lread.c:1923
#16 0x0000000000574dec in Fload (file=49392, noerror=0, nomessage=0, 
    nosuffix=12773572, must_suffix=0) at ../../src/lread.c:1331
#17 0x0000000000551e89 in eval_sub (form=form@entry=12586851)
    at ../../src/eval.c:2180
#18 0x00000000005550a1 in Feval (form=12586851, lexical=<optimized out>)
    at ../../src/eval.c:1988
#19 0x0000000000551286 in internal_condition_case (
    bfun=bfun@entry=0x4e1fa0 <top_level_2>, handlers=handlers@entry=19056, 
    hfun=hfun@entry=0x4e67e0 <cmd_error>) at ../../src/eval.c:1309
#20 0x00000000004e45cc in top_level_1 (ignore=ignore@entry=0)
    at ../../src/keyboard.c:1117
#21 0x000000000055120b in internal_catch (tag=tag@entry=45840, 
    func=func@entry=0x4e4570 <top_level_1>, arg=arg@entry=0)
    at ../../src/eval.c:1074
#22 0x00000000004e1f38 in command_loop () at ../../src/keyboard.c:1078
#23 0x00000000004e63eb in recursive_edit_1 () at ../../src/keyboard.c:685
#24 0x00000000004e6710 in Frecursive_edit () at ../../src/keyboard.c:756
#25 0x0000000000412244 in main (argc=3, argv=0x7fffffffe5b8)
    at ../../src/emacs.c:1605

Lisp Backtrace:
"window--resize-root-window-vertically" (0xffffc8e8)
"message" (0xffffdfa0)
"load" (0xffffe2f0)

----------------

#0  Fsignal (error_symbol=error_symbol@entry=49392, data=12582483)
    at ../../src/eval.c:1464
#1  0x0000000000552fd9 in xsignal (error_symbol=error_symbol@entry=49392, 
    data=<optimized out>) at ../../src/eval.c:1577
#2  0x0000000000553007 in xsignal1 (error_symbol=49392, arg=<optimized out>)
    at ../../src/eval.c:1592
#3  0x0000000000552612 in Ffuncall (nargs=49392, nargs@entry=1, args=0x0)
    at ../../src/eval.c:2746
#4  0x00000000005529b8 in call0 (fn=525424) at ../../src/eval.c:2544
#5  0x00000000004e4636 in timer_start_idle () at ../../src/keyboard.c:4242
#6  0x00000000004ed07c in timer_start_idle () at ../../src/keyboard.c:4077
#7  read_char (commandflag=49392, commandflag@entry=1, map=12582483, 
    map@entry=12582211, prev_event=24, used_mouse_menu=0x250, 
    used_mouse_menu@entry=0x7fffffffe18b, end_time=0xc2cf88, end_time@entry=0x0)
    at ../../src/keyboard.c:2600
#8  0x00000000004edef6 in read_key_sequence (
    keybuf=keybuf@entry=0x7fffffffe260, prompt=prompt@entry=0, 
    dont_downcase_last=dont_downcase_last@entry=false, 
    can_return_switch_frame=can_return_switch_frame@entry=true, 
    fix_current_buffer=fix_current_buffer@entry=true, 
    prevent_redisplay=prevent_redisplay@entry=false, bufsize=30)
    at ../../src/keyboard.c:9054
#9  0x00000000004ef9f6 in command_loop_1 () at ../../src/keyboard.c:1358
#10 0x0000000000551286 in internal_condition_case (
    bfun=bfun@entry=0x4ef800 <command_loop_1>, handlers=handlers@entry=19056, 
    hfun=hfun@entry=0x4e67e0 <cmd_error>) at ../../src/eval.c:1309
#11 0x00000000004e1f8c in command_loop_2 (ignore=ignore@entry=0)
    at ../../src/keyboard.c:1100
#12 0x000000000055120b in internal_catch (tag=tag@entry=45840, 
    func=func@entry=0x4e1f70 <command_loop_2>, arg=arg@entry=0)
    at ../../src/eval.c:1074
#13 0x00000000004e1f49 in command_loop () at ../../src/keyboard.c:1079
#14 0x00000000004e63eb in recursive_edit_1 () at ../../src/keyboard.c:685
#15 0x00000000004e6710 in Frecursive_edit () at ../../src/keyboard.c:756
#16 0x0000000000412244 in main (argc=3, argv=0x7fffffffe5b8)
    at ../../src/emacs.c:1605

Lisp Backtrace:
"internal-timer-start-idle" (0xffffdb10)

----------------

#0  Fsignal (error_symbol=error_symbol@entry=49392, data=12826339)
    at ../../src/eval.c:1464
#1  0x0000000000552fd9 in xsignal (error_symbol=error_symbol@entry=49392, 
    data=<optimized out>) at ../../src/eval.c:1577
#2  0x0000000000553007 in xsignal1 (error_symbol=49392, arg=<optimized out>)
    at ../../src/eval.c:1592
#3  0x0000000000552612 in Ffuncall (nargs=49392, nargs@entry=1, args=0x0)
    at ../../src/eval.c:2746
#4  0x00000000005529b8 in call0 (fn=28368) at ../../src/eval.c:2544
#5  0x00000000004ed2fe in read_char (commandflag=49392, commandflag@entry=1, 
    map=12826339, map@entry=12826307, prev_event=15, used_mouse_menu=0x2e0, 
    used_mouse_menu@entry=0x7fffffffe18b, end_time=0x3, end_time@entry=0x0)
    at ../../src/keyboard.c:2609
#6  0x00000000004edef6 in read_key_sequence (
    keybuf=keybuf@entry=0x7fffffffe260, prompt=prompt@entry=0, 
    dont_downcase_last=dont_downcase_last@entry=false, 
    can_return_switch_frame=can_return_switch_frame@entry=true, 
    fix_current_buffer=fix_current_buffer@entry=true, 
    prevent_redisplay=prevent_redisplay@entry=false, bufsize=30)
    at ../../src/keyboard.c:9054
#7  0x00000000004ef9f6 in command_loop_1 () at ../../src/keyboard.c:1358
#8  0x0000000000551286 in internal_condition_case (
    bfun=bfun@entry=0x4ef800 <command_loop_1>, handlers=handlers@entry=19056, 
    hfun=hfun@entry=0x4e67e0 <cmd_error>) at ../../src/eval.c:1309
#9  0x00000000004e1f8c in command_loop_2 (ignore=ignore@entry=0)
    at ../../src/keyboard.c:1100
#10 0x000000000055120b in internal_catch (tag=tag@entry=45840, 
    func=func@entry=0x4e1f70 <command_loop_2>, arg=arg@entry=0)
    at ../../src/eval.c:1074
#11 0x00000000004e1f49 in command_loop () at ../../src/keyboard.c:1079
#12 0x00000000004e63eb in recursive_edit_1 () at ../../src/keyboard.c:685
#13 0x00000000004e6710 in Frecursive_edit () at ../../src/keyboard.c:756
#14 0x0000000000412244 in main (argc=3, argv=0x7fffffffe5b8)
    at ../../src/emacs.c:1605

Lisp Backtrace:
"internal-echo-keystrokes-prefix" (0xffffdb30)

> 
>> Obviously the long message lines need to be handled, or at least need to not cause us to error out of the startup.  Maybe C or Lisp could define a simple, dumb version of window--resize-root-window-vertically that gets us past this point?  That might be cheaper than testing on every call to verify that the function has been defined so that we can fall back to some other behavior in this rare case.
> 
> Let's defer this discussion till after we see the backtraces.
> 
> In general, the above is the price we pay for moving more basic stuff
> to Lisp.  But I very much doubt that these problem cannot have some
> simple solution.  Whether dumb versions in C are it, I don't know: it
> depends on who calls them and what does that code expect from the
> call.

After glancing at the code you and Martin discussed, as a quick experiment, I did try adding:

(fset 'window--resize-root-window-vertically '(lambda (&rest ignored)))

to loadup.el before it prints the load path, and the CANNOT_DUMP emacs seems to have started up okay… as long as I didn’t make the window so narrow that the “Loading loadup” message itself was too wide and required wrapping.  Since the Lisp files can't control things any earlier than that, I think the stub version, if we use one, ought to be in C.

>> Given how much even basic operation depends on various bits of Lisp code being available, I’m starting to think that if loadup.el cannot load successfully (with the possible exception of site initialization files), maybe Emacs should just refuse to start, instead of continuing on to the top level loop.
> 
> No, I don't think so: aborting will remove the error messages and
> other phenomena that are needed to debug these problems.

I’d assume we’d print out error messages when quitting.  But if we want to keep Emacs running enough to interactively pull out other information, it looks like we’re going to have to have stub versions of a few more routines.