jdtsmith/indent-bars

hook to `server-after-make-frame-hook` seems not work on first frame

AlynxZhou opened this issue · 25 comments

With such config:

(use-package indent-bars
  :load-path "site-lisp/indent-bars"
  :hook
  ((server-after-make-frame . (lambda ()
                                (add-hook 'prog-mode-hook  'indent-bars-mode)
                                (add-hook 'nxml-mode-hook  'indent-bars-mode)
                                (add-hook 'rpm-spec-mode-hook  'indent-bars-mode)
                                (add-hook 'yaml-ts-mode-hook  'indent-bars-mode)))))

and run emacsclient --create-frame --alternate-editor="" init.el (which will first start the daemon then open init.el, I see no bars in this file. And if I close this frame, and open another file with emacsclient --create-frame early-init.el, it will show bars correctly.

However, if I open init.el again with emacsclient --create-frame init.el, Emacs daemon will crash.

I am using PGTK Emacs 30, not sure whether it is related or not.

Maybe this package should handle frame open or not internally? Currently I cannot simply hook it, because if I only hook server-after-make-frame-hook, I cannot make it work on normal Emacs (not a daemon), but if I directly hook it with prog-mode-hook, then normal Emacs works but Emacs daemon will crash.

I got another strange crash with following normal config:

(use-package indent-bars
  :load-path "site-lisp/indent-bars"
  :hook
  ((prog-mode . indent-bars-mode)
   (nxml-mode . indent-bars-mode)
   (rpm-spec-mode . indent-bars-mode)
   (yaml-ts-mode . indent-bars-mode)))

If I run Emacs to open a file, for example emacs early-init.el or emacs init.el, it will crash after a blank frame is shown. But if I run emacs with no file (open *scratch* buffer), and then open some file with find-file, it won't crash and indent-bars works correctly.

It is wired and I don't have any idea on why it crash, if you need more info to debug, just ask me and I will provide, thanks!

Oh, I forget to attach the output when Emacs crash:

% emacs early-init.el
Fatal error 11: Segmentation fault
Backtrace:
emacs(emacs_backtrace+0x53)[0x56258ca5f1d3]
emacs(terminate_due_to_signal+0xa3)[0x56258c93f7ac]
emacs(+0x82126)[0x56258c940126]
emacs(+0x19f1e9)[0x56258ca5d1e9]
emacs(+0x19f26e)[0x56258ca5d26e]
/usr/lib/libc.so.6(+0x39ab0)[0x7f902d84fab0]
/usr/lib/libcairo.so.2(cairo_get_target+0x4)[0x7f903643eb04]
emacs(+0x2c4279)[0x56258cb82279]
emacs(image_create_bitmap_from_data+0x116)[0x56258cb87e56]
emacs(+0x15cd94)[0x56258ca1ad94]
emacs(+0x165d25)[0x56258ca23d25]
emacs(+0x1684d0)[0x56258ca264d0]
emacs(face_at_buffer_position+0x3d5)[0x56258ca29635]
emacs(+0xafaa3)[0x56258c96daa3]
emacs(+0xce7e7)[0x56258c98c7e7]
emacs(+0xc4626)[0x56258c982626]
emacs(+0xd0d78)[0x56258c98ed78]
emacs(+0xcea06)[0x56258c98ca06]
emacs(+0xcbcaf)[0x56258c989caf]
emacs(move_it_to+0x609)[0x56258c98f599]
emacs(+0xdaaa4)[0x56258c998aa4]
emacs(+0xfa5af)[0x56258c9b85af]
emacs(+0xfcd43)[0x56258c9bad43]
emacs(internal_condition_case_1+0x7c)[0x56258cad044c]
emacs(+0xae7c9)[0x56258c96c7c9]
emacs(+0xe3e8a)[0x56258c9a1e8a]
emacs(read_char+0xe65)[0x56258ca4c4d5]
emacs(+0x190ce6)[0x56258ca4ece6]
emacs(+0x192bf6)[0x56258ca50bf6]
emacs(internal_condition_case+0x77)[0x56258cad03b7]
emacs(command_loop_2+0x2f)[0x56258ca3bc2f]
emacs(internal_catch+0x4a)[0x56258cad02fa]
emacs(+0x17dbcb)[0x56258ca3bbcb]
emacs(recursive_edit_1+0x9d)[0x56258ca4334d]
emacs(Frecursive_edit+0xd6)[0x56258ca436f6]
emacs(main+0x1f1c)[0x56258c94f1fc]
/usr/lib/libc.so.6(+0x23850)[0x7f902d839850]
/usr/lib/libc.so.6(__libc_start_main+0x8a)[0x7f902d83990a]
emacs(_start+0x25)[0x56258c94f7b5]
zsh: segmentation fault (core dumped)  emacs early-init.el

A segfault is quite unexpected. I appreciate your help debugging this. I'm afraid I can't understand the sequence of steps which works, and the sequence which doesn't work. Can you isolate this down to the minimum required steps and report back?

BTW, does indent-bars work normally for you with your PGTK build, when you open a file normally with find-file? Can you post an image of indent-bars working in that setting? Others have reported anomalies with PGTK's stipple support.

Another thing to try: remove all the indent-bars config, and try something simple:

((add-hook 'prog-mode-hook (lambda () (cons (frame-char-width) (frame-char-height))))

Does this show the same segfault behavior via emacsclient?

OK, I tried to reproduce it minimally.

First create a minimal test-init.el file that loads indent-bars only:

(setq-default indent-tabs-mode nil)
(add-to-list 'load-path
             (locate-user-emacs-file "site-lisp/indent-bars/"))
(package-initialize)
(require 'indent-bars)
(add-hook 'prog-mode-hook
          'indent-bars-mode)

Then, run emacs -q --load test-init.el test-init.el so it will load this file as init file and open it, and Emacs will crash:

% emacs -q --load test-init.el test-init.el
Fatal error 11: Segmentation fault
Backtrace:
emacs(emacs_backtrace+0x53)[0x559543f401d3]
emacs(terminate_due_to_signal+0xa3)[0x559543e207ac]
emacs(+0x82126)[0x559543e21126]
emacs(+0x19f1e9)[0x559543f3e1e9]
emacs(+0x19f26e)[0x559543f3e26e]
/usr/lib/libc.so.6(+0x39ab0)[0x7f32d5efbab0]
/usr/lib/libcairo.so.2(cairo_get_target+0x4)[0x7f32debd5b04]
emacs(+0x2c4279)[0x559544063279]
emacs(image_create_bitmap_from_data+0x116)[0x559544068e56]
emacs(+0x15cd94)[0x559543efbd94]
emacs(+0x165d25)[0x559543f04d25]
emacs(+0x1684d0)[0x559543f074d0]
emacs(face_at_buffer_position+0x3d5)[0x559543f0a635]
emacs(+0xafaa3)[0x559543e4eaa3]
emacs(+0xce7e7)[0x559543e6d7e7]
emacs(+0xc4626)[0x559543e63626]
emacs(+0xd0d78)[0x559543e6fd78]
emacs(+0xcea06)[0x559543e6da06]
emacs(+0xd5422)[0x559543e74422]
emacs(try_window+0x108)[0x559543e78e48]
emacs(+0xfa494)[0x559543e99494]
emacs(+0xfcd43)[0x559543e9bd43]
emacs(internal_condition_case_1+0x7c)[0x559543fb144c]
emacs(+0xae7c9)[0x559543e4d7c9]
emacs(+0xe3e8a)[0x559543e82e8a]
emacs(read_char+0xe65)[0x559543f2d4d5]
emacs(+0x240dcf)[0x559543fdfdcf]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/subr-13adf6a6-4e74a45d.eln(F7369742d666f72_sit_for_0+0x1bf)[0x7f32c795d6ff]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F66616e63792d73706c6173682d6672616d65_fancy_splash_frame_0+0xd1)[0x7f32c1005751]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F7573652d66616e63792d73706c6173682d73637265656e732d70_use_fancy_splash_screens_p_0+0xc9)[0x7f32c1005979]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F646973706c61792d737461727475702d73637265656e_display_startup_screen_0+0x65)[0x7f32c10083c5]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F636f6d6d616e642d6c696e652d31_command_line_1_0+0xf49)[0x7f32c10097c9]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F636f6d6d616e642d6c696e65_command_line_0+0x1a76)[0x7f32c1000896]
emacs(Ffuncall+0xfe)[0x559543fb2d6e]
/usr/bin/../lib/emacs/30.0.50/native-lisp/30.0.50-431664e2/preloaded/startup-bbc6ea72-c185bd7d.eln(F6e6f726d616c2d746f702d6c6576656c_normal_top_level_0+0xda1)[0x7f32c0ffc421]
emacs(eval_sub+0x808)[0x559543fb6c98]
...
zsh: segmentation fault (core dumped)  emacs -q --load test-init.el test-init.el

If only load it as init file, but do not open any file (just run emacs -q --load test-init.el), it won't crash.

BTW, does indent-bars work normally for you with your PGTK build, when you open a file normally with find-file? Can you post an image of indent-bars working in that setting? Others have reported anomalies with PGTK's stipple support.

No, I got the same bug with #3.

Another thing to try: remove all the indent-bars config, and try something simple:

((add-hook 'prog-mode-hook (lambda () (cons (frame-char-width) (frame-char-height))))

Does this show the same segfault behavior via emacsclient?

This won't crash, both daemon and normal.

For Emacs daemon, still with this minimal test-init.el:

(setq-default indent-tabs-mode nil)
(add-to-list 'load-path
             (locate-user-emacs-file "site-lisp/indent-bars/"))
(package-initialize)
(require 'indent-bars)
(add-hook 'prog-mode-hook
          'indent-bars-mode)

and run emacs -q --load test-init.el --fg-daemon, and open a file with emacsclient -c test-init.el, first run works fine, but if run emacsclient -c test-init.el again, the frame will disappear, and Emacs daemon outputs such error:

% emacs -q --load test-init.el --fg-daemon
Due to a limitation in GTK 3, Emacs built with PGTK will simply exit when a
display connection is closed.  The problem is especially difficult to fix,
such that Emacs on Wayland with multiple displays is unlikely ever to be able
to survive disconnects.
Starting Emacs daemon.
When done with a buffer, type C-x #

(emacs:32249): Gtk-CRITICAL **: 10:49:44.588: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
Use M-x make-directory RET RET to create the directory and its parents
When done with a buffer, type C-x #

(emacs:32249): Gtk-CRITICAL **: 10:49:44.622: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
M-[ is undefined
When done with a buffer, type C-x #

(emacs:32249): Gtk-CRITICAL **: 10:49:56.890: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
Use M-x make-directory RET RET to create the directory and its parents
When done with a buffer, type C-x #

(emacs:32249): Gtk-CRITICAL **: 10:49:56.911: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
M-[ is undefined

Thanks for the reproducers. Unfortunately I cannot reproduce the problem on this end on emacs-mac (though --daemon has never worked well with my build, but at least no crash). It seems the PGTK port has some issues with stipples and maybe other display bugs.

Maybe try to add (frame-parameter nil 'background-color) to the very simple lambda above? The only other suggestion I have is to comment out half of the function indent-bars-setup (removing the .elc file), see if the crash recurs, if so, uncomment half of that, etc. E.g. to bisect the issue.

Functions in the crash output really looks like what has been mentioned in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=64969, so maybe we could just wait for the PGTK issue being fixed and then see if this bug is fixed.

Perhaps it is just drawing stipples overall that is the problem, i.e. their display is corrupted in some cases, but cause actual crashes in others. Does the simple test (omitting any mention of indent-bars), crash when loaded from file as you do now? I'll leave this open in case other experience this crash and can help identify the culprit.

Perhaps it is just drawing stipples overall that is the problem, i.e. their display is corrupted in some cases, but cause actual crashes in others. Does the simple test (omitting any mention of indent-bars), crash when loaded from file as you do now? I'll leave this open in case other experience this crash and can help identify the culprit.

No, it does not crash.

No, it does not crash.

Hmm. In that case it may be valuable to bisect the setup function and isolate which particular call is causing the crash.

With the latest commit on Emacs master that fix stripe on PGTK (emacs-mirror/emacs@74d6604), my Emacs won't crash, but instead the newly created frame will close.

Reproduce step:

Create test-init.el file with following content:

(setq-default indent-tabs-mode nil)
(add-to-list 'load-path
             (locate-user-emacs-file "site-lisp/indent-bars/"))
(package-initialize)
(require 'indent-bars)
(add-hook 'prog-mode-hook
          'indent-bars-mode)

Start daemon with emacs -q --load test-init.el --fg-daemon.

Then open a file with emacsclient -c test-init.el. It will show a frame normally.

But if run emacsclient -c test-init.el again, I can never open a frame, the frame popup, and close soon.

Error output:

(emacs:210635): Gtk-CRITICAL **: 17:05:30.117: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
When done with a buffer, type C-x #

(emacs:210635): Gtk-CRITICAL **: 17:05:30.129: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
M-[ is undefined
When done with a buffer, type C-x #

(emacs:210635): Gtk-CRITICAL **: 17:05:32.123: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
When done with a buffer, type C-x #

(emacs:210635): Gtk-CRITICAL **: 17:05:32.138: gtk_distribute_natural_allocation: assertion 'extra_space >= 0' failed
M-[ is undefined

Great, so the crash was indeed related to the :stipple mishandling in PGTK builds. Unfortunately I can't reproduce your remaining problem this here, since my version of emacs does not support opening GUI frames via --daemon . The obvious candidates, like frame-width, etc. (did you try frame-parameters too?) don't seem to be the cause.

@AlynxZhou I suppose you tried opening multiple frames without having loaded indent-bars and it works as expected?

@magthe, could you assist here? The hope is to reproduce this 2nd-frame-quickly-closing behavior, then bisect indent-bars-setup down by commenting out half, then quarter, etc. until the issue is isolated.

@AlynxZhou I suppose you tried opening multiple frames without having loaded indent-bars and it works as expected?

Yes.

OK, thanks. I'll leave this open for a bit in case anyone wants to bisect indent-bars-setup and zero in on the things giving PGTK builds problems on 2nd-frame open via emacsclient. In the meantime, can I confirm that with normal find-file, indent-bars is working as expected?

OK, thanks. I'll leave this open for a bit in case anyone wants to bisect indent-bars-setup and zero in on the things giving PGTK builds problems on 2nd-frame open via emacsclient. In the meantime, can I confirm that with normal find-file, indent-bars is working as expected?

With find-file frame does not crash, but I just find a new thing, with the test-init.el I mentioned above, I don't need to open the same file twice, but just open any file with emacsclient -c after first running, the frame will disappear.

magthe commented

I can't seem to reproduce this behaviour.

The steps I take:

  1. emacs -q --load test-init.el test-init.el where test-init.el is a slightly modified version of @AlynxZhou's file above. I needed to adjust it to find the packages indent-bars and compat in my setup.
  2. I run M-x server-mode in the opened Emacs.
  3. I run emacslient -c from a terminal.

What I end up with is two Emacs frames

  • the initial showing test-init.el in one window and *GNU Emacs* in another, and
  • a second frame showing *scratch*.

The version of indent-bars I'm using is f5b61da.

3. I run `emacslient -c` from a terminal.

That's the difference, you need to emacsclient -c some_file to open a file, instead of starting *scratch*, mine won't crash if I run emacsclient-c only.

Thanks for checking @magthe. Does emacsclient -c file.yaml or whatever give you the same behavior?

Thanks for checking @magthe. Does emacsclient -c file.yaml or whatever give you the same behavior?

Just a reminder that yaml-mode is not a prog-mode, so maybe other file type is needed to reproduce.

magthe commented

Thanks for checking @magthe. Does emacsclient -c file.yaml or whatever give you the same behavior?

Yes, that gave the same behaviour.

Thanks for checking. So to confirm, not exhibiting @AlynxZhou's problem?

magthe commented

Indeed, sorry to express myself a bit unclearly. I don't see the @AlynxZhou describes at all.

OK, thanks, sounds like a configuration or build problem then.