all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
@ 2024-08-18  8:29 Eval EXEC
  2024-08-18  8:58 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eval EXEC @ 2024-08-18  8:29 UTC (permalink / raw)
  To: 72692

Hello,

I'm help to tesing Emacs master branch (commit: 40eecd594ac) on Linux.

I compile emacs source code by:

```bash

make extraclean
./autogen.sh \
   && ./configure \
   --prefix=$(realpath ../emacs-build/$(git branch --show-current | sed 
's/\//_/g'))\
   --with-imagemagick --with-xwidgets \
   --with-modules --with-x-toolkit=gtk3 --without-compress-install \
   --without-toolkit-scroll-bars --with-native-compilation --with-mailutils\
   --with-tree-sitter --with-xinput2  \
   --with-dbus  --with-native-compilation=aot \
   --with-file-notification=inotify\
   && make -j30 install
```


When I using emacs, I got crash, the backtrace is :

```

line to your configuration file "/home/exec/.config/gdb/gdbinit".
For more information about this security protection see the
"Auto-loading safe path" section in the GDB manual.  E.g., run from the 
shell:
         info "(gdb)Auto-loading safe path"
warning: File 
"/nix/store/x47hg342iyiw50c1fhqjzz4n0rqy3dhh-isl-0.20/lib/libisl.so.19.1.0-gdb.py" 
auto-loading has been declined by your `auto-load safe-path' set to 
"$debugdir:$datadir/auto-load:/nix/store/40yjzm7r5ki59kkk9423dnwbm86x7pyd-gcc-13.2.0-lib".
(gdb) c
The program is not being run.
(gdb) bt
#0  0x00007f9eaeea2efc in __pthread_kill_implementation () from 
/nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
#1  0x00007f9eaee52e86 in raise () from 
/nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
#2  0x0000000000473791 in terminate_due_to_signal (sig=sig@entry=11, 
backtrace_limit=backtrace_limit@entry=40) at emacs.c:469
#3  0x0000000000473ccd in handle_fatal_signal (sig=sig@entry=11) at 
sysdep.c:1800
#4  0x00000000005c4bf8 in deliver_thread_signal (sig=sig@entry=11, 
handler=0x473cc2 <handle_fatal_signal>) at sysdep.c:1792
#5  0x00000000005c4c7c in deliver_fatal_thread_signal (sig=11) at 
sysdep.c:1812
#6  handle_sigsegv (sig=11, siginfo=<optimized out>, arg=<optimized 
out>) at sysdep.c:1950
#7  <signal handler called>
#8  fontset_find_font (fontset=fontset@entry=0x0, c=c@entry=127802, 
face=face@entry=0x13fec610, charset_id=charset_id@entry=-1, 
fallback=fallback@entry=false)
     at /home/exec/Projects/git.savannah.gnu.org/git/emacs/src/lisp.h:2127
#9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=0x0, 
c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
#10 0x00000000006dddce in face_for_char (f=0x28b8ee0, 
face=face@entry=0x13fec610, c=127802, pos=<optimized out>, 
object=<optimized out>) at fontset.c:1031
#11 0x00000000004b503c in FACE_FOR_CHAR (object=<optimized out>, 
pos=<optimized out>, character=<optimized out>, face=0x13fec610, 
f=<optimized out>)
     at 
/home/exec/Projects/git.savannah.gnu.org/git/emacs/src/dispextern.h:1962
#12 get_next_display_element (it=it@entry=0x7ffe5294f4c0) at xdisp.c:8547
#13 0x00000000004c4258 in display_string (string=string@entry=0x0, 
lisp_string=lisp_string@entry=0x765cc214, 
face_string=face_string@entry=0x0, 
face_string_pos=face_string_pos@entry=0, start=<optimized out>,
     it=it@entry=0x7ffe5294f4c0, field_width=<optimized out>, 
precision=<optimized out>, max_x=496, multibyte=<optimized out>) at 
xdisp.c:29274
#14 0x00000000004c4d78 in display_mode_element 
(it=it@entry=0x7ffe5294f4c0, depth=<optimized out>, depth@entry=1, 
field_width=<optimized out>, field_width@entry=0, precision=<optimized 
out>, precision@entry=0,
     elt=<optimized out>, props=<optimized out>, risky=<optimized out>) 
at xdisp.c:27822
#15 0x00000000004c5210 in display_mode_element 
(it=it@entry=0x7ffe5294f4c0, depth=1, depth@entry=0, 
field_width=field_width@entry=0, precision=precision@entry=0, 
elt=<optimized out>, elt@entry=0xef4fb43,
     props=props@entry=0x0, risky=false) at xdisp.c:28007
#16 0x00000000004c7d00 in display_mode_line (w=w@entry=0x3064de10, 
face_id=MODE_LINE_INACTIVE_FACE_ID, format=0xef4fb43) at xdisp.c:27495
#17 0x00000000004c9fdd in display_mode_lines (w=w@entry=0x3064de10) at 
xdisp.c:27408
#18 0x00000000004dfb25 in redisplay_window (window=<optimized out>, 
just_this_one_p=just_this_one_p@entry=false) at xdisp.c:20981
#19 0x00000000004e372b in redisplay_window_0 
(window=window@entry=0x3064de15) at xdisp.c:18070
#20 0x000000000063315c in internal_condition_case_1 
(bfun=bfun@entry=0x4e3700 <redisplay_window_0>, 
arg=arg@entry=0x3064de15, handlers=<optimized out>, 
hfun=hfun@entry=0x49b6a0 <redisplay_window_error>)
     at eval.c:1637
#21 0x0000000000497ff9 in redisplay_windows (window=0x3064de15) at 
xdisp.c:18039
#22 0x000000000049801d in redisplay_windows (window=0x3064dbf5) at 
xdisp.c:18033
#23 0x00000000004cb2d3 in redisplay_internal () at xdisp.c:17438
#24 0x00000000004cc8d5 in redisplay () at xdisp.c:16613
#25 0x00000000005b3dfc in read_char (commandflag=1, 
map=map@entry=0x7650ab73, prev_event=0x0, 
used_mouse_menu=used_mouse_menu@entry=0x7ffe52955ecb, 
end_time=end_time@entry=0x0) at keyboard.c:2678
#26 0x00000000005b6f34 in read_key_sequence 
(keybuf=keybuf@entry=0x7ffe52956050, prompt=prompt@entry=0x0, 
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, 
disable_text_conversion_p=false) at keyboard.c:10736
#27 0x00000000005b8fd8 in command_loop_1 () at keyboard.c:1429
#28 0x00000000006330cf in internal_condition_case 
(bfun=bfun@entry=0x5b8e00 <command_loop_1>, 
handlers=handlers@entry=0x90, hfun=hfun@entry=0x5a8e20 <cmd_error>) at 
eval.c:1613
#29 0x00000000005a3fb6 in command_loop_2 (handlers=handlers@entry=0x90) 
at keyboard.c:1168
#30 0x0000000000632ff3 in internal_catch (tag=tag@entry=0x12450, 
func=func@entry=0x5a3f90 <command_loop_2>, arg=arg@entry=0x90) at 
eval.c:1292
#31 0x00000000005a3f51 in command_loop () at keyboard.c:1146
#32 0x00000000005a898a in recursive_edit_1 () at keyboard.c:754
#33 0x00000000005a8d0f in Frecursive_edit () at keyboard.c:837
#34 0x000000000047ca5a in main (argc=1, argv=<optimized out>) at 
emacs.c:2624
```

I believe the crash is related to the font, but I can't reproduce it. It 
happens about once a day.

What information should I provide to help investigate this bug?

And my OS info is:

```

❯ nix-info -m
  - system: `"x86_64-linux"`
  - host os: `Linux 6.6.45, NixOS, 24.05 (Uakari), 24.05.20240813.4a92571`
  - multi-user?: `yes`
  - sandbox: `yes`
  - version: `nix-env (Nix) 2.18.5`
  - channels(exec): `""`
  - channels(root): `""`
  - nixpkgs: `/nix/store/qszplw617r895nbcprgyj139c9a3r0xs-source`
```

Thank you!






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  8:29 bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland) Eval EXEC
@ 2024-08-18  8:58 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18  9:08   ` Eval EXEC
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18  8:58 UTC (permalink / raw)
  To: Eval EXEC; +Cc: 72692

"Eval EXEC" <execvy@gmail.com> writes:

> I'm help to tesing Emacs master branch (commit: 40eecd594ac) on Linux.

Thank you!

> I compile emacs source code by:
>
> ```bash
>
> make extraclean
> ./autogen.sh \
>    && ./configure \
>    --prefix=$(realpath ../emacs-build/$(git branch --show-current | sed
> 's/\//_/g'))\
>    --with-imagemagick --with-xwidgets \
>    --with-modules --with-x-toolkit=gtk3 --without-compress-install \
>    --without-toolkit-scroll-bars --with-native-compilation --with-mailutils\
>    --with-tree-sitter --with-xinput2  \
>    --with-dbus  --with-native-compilation=aot \
>    --with-file-notification=inotify\
>    && make -j30 install
> ```

You might want to consider adding --enable-checking and CFLAGS="-O0 -g3
-ggdb" or equivalent to that until this bug has been found.

> When I using emacs, I got crash, the backtrace is :
>
> ```
>
> line to your configuration file "/home/exec/.config/gdb/gdbinit".
> For more information about this security protection see the
> "Auto-loading safe path" section in the GDB manual.  E.g., run from the
> shell:
>          info "(gdb)Auto-loading safe path"
> warning: File
> "/nix/store/x47hg342iyiw50c1fhqjzz4n0rqy3dhh-isl-0.20/lib/libisl.so.19.1.0-gdb.py"
> auto-loading has been declined by your `auto-load safe-path' set to
> "$debugdir:$datadir/auto-load:/nix/store/40yjzm7r5ki59kkk9423dnwbm86x7pyd-gcc-13.2.0-lib".
> (gdb) c
> The program is not being run.
> (gdb) bt
> #0  0x00007f9eaeea2efc in __pthread_kill_implementation () from
> /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
> #1  0x00007f9eaee52e86 in raise () from
> /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
> #2  0x0000000000473791 in terminate_due_to_signal (sig=sig@entry=11,
> backtrace_limit=backtrace_limit@entry=40) at emacs.c:469
> #3  0x0000000000473ccd in handle_fatal_signal (sig=sig@entry=11) at
> sysdep.c:1800
> #4  0x00000000005c4bf8 in deliver_thread_signal (sig=sig@entry=11,
> handler=0x473cc2 <handle_fatal_signal>) at sysdep.c:1792
> #5  0x00000000005c4c7c in deliver_fatal_thread_signal (sig=11) at
> sysdep.c:1812
> #6  handle_sigsegv (sig=11, siginfo=<optimized out>, arg=<optimized
> out>) at sysdep.c:1950
> #7  <signal handler called>
> #8  fontset_find_font (fontset=fontset@entry=0x0, c=c@entry=127802,
> face=face@entry=0x13fec610, charset_id=charset_id@entry=-1,
> fallback=fallback@entry=false)
>      at /home/exec/Projects/git.savannah.gnu.org/git/emacs/src/lisp.h:2127
> #9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=0x0,
> c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793

Do you still have the core file?

Can you print *face in this stack frame? The relevant gdb commands are
"frame 9" followed by "p *face".

c is ?🌺 .  Are you using that character in your mode line, by any
chance?  Does it show up for you in Emacs?

> I believe the crash is related to the font, but I can't reproduce it. It
> happens about once a day.

What would also be helpful would be to source .gdbinit from your src/
directory, (gdb:
"source/home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit"),
then "pp Vfontset_table" to see how large it is.

Thanks!

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  8:58 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18  9:08   ` Eval EXEC
  2024-08-18  9:23     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eval EXEC @ 2024-08-18  9:08 UTC (permalink / raw)
  To: Pip Cet; +Cc: 72692

[-- Attachment #1: Type: text/plain, Size: 7469 bytes --]

the "p *face" in "frame 9" is:
```
(gdb) frame 9
#9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=0x0, 
c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
(gdb) p *face
$1 = {lface = {0x8220, 0x28bdef4, 0x28bdf34, 0xe340, 0x16a, 0xe340, 
0xe340, 0x0, 0x0, 0x4417994, 0x233c9c4, 0x0, 0x0, 0x0, 0x7f9ea6b05d63, 
0xbdc613ad, 0x0, 0x2aabee4, 0x13500, 0x0}, id = 40, gc = 0x0, stipple = 0,
  foreground = 4288059542, background = 4278190080, underline_color = 0, 
overline_color = 0, strike_through_color = 0, box_color = 4281545523, 
font = 0x1e4970c0, fontset = 26, box_vertical_line_width = -1,
  box_horizontal_line_width = -1, underline_pixels_above_descent_line = 
0, box = FACE_SIMPLE_BOX, underline = FACE_NO_UNDERLINE, 
use_box_color_for_shadows_p = true, overline_p = false, strike_through_p 
= false,
  foreground_defaulted_p = false, background_defaulted_p = false, 
underline_defaulted_p = false, overline_color_defaulted_p = false, 
strike_through_color_defaulted_p = false, box_color_defaulted_p = true,
  underline_at_descent_line_p = false, tty_bold_p = false, tty_italic_p 
= false, tty_reverse_p = false, tty_strike_through_p = false, 
colors_copied_bitwise_p = true, overstrike = false, hash = 322003229,
  next = 0x54da8550, prev = 0x4d7343a0, ascii_face = 0x4d7343a0, extra = 
0x0}
(gdb)
```

> c is ?🌺 .  Are you using that character in your mode line, by any
chance?  Does it show up for you in Emacs?

Yes, I'm using the flower emoji in treemacs, related customize config is:
```elisp
(setq    treemacs-user-mode-line-format
   '(:eval (format "🌳🌺🌻: %s :🌽🍅🥦"
                                       (treemacs-project->name
                     (car (treemacs-workspace->projects 
(treemacs-current-workspace)))
                     )
                    )
            )
   )
```

I executed ```
(gdb) source 
/home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit
......
Breakpoint 5 at 0x4736d9: file emacs.c, line 431.
Breakpoint 6 at 0x562640: file xterm.c, line 27093.
(gdb) pp Vfontset_table
Cannot access memory at address 0xc82684
(gdb)

```


after I source the 
`/home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit` file 
in gdb. then I switch to frame 9:

got:

```

(gdb) frame 9
#9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=XIL(0), 
c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
(gdb) p *face
$4 = {
   lface = {XIL(0x8220), XIL(0x28bdef4), XIL(0x28bdf34), XIL(0xe340), 
make_fixnum(90), XIL(0xe340), XIL(0xe340), XIL(0), XIL(0), 
XIL(0x4417994), XIL(0x233c9c4), XIL(0), XIL(0), XIL(0), XIL(0x7f9ea6b05d63),
     XIL(0xbdc613ad), XIL(0), XIL(0x2aabee4), XIL(0x13500), XIL(0)},
   id = 40,
   gc = 0x0,
   stipple = 0,
   foreground = 4288059542,
   background = 4278190080,
   underline_color = 0,
   overline_color = 0,
   strike_through_color = 0,
   box_color = 4281545523,
   font = 0x1e4970c0,
   fontset = 26,
   box_vertical_line_width = -1,
   box_horizontal_line_width = -1,
   underline_pixels_above_descent_line = 0,
   box = FACE_SIMPLE_BOX,
   underline = FACE_NO_UNDERLINE,
   use_box_color_for_shadows_p = true,
   overline_p = false,
   strike_through_p = false,
   foreground_defaulted_p = false,
   background_defaulted_p = false,
   underline_defaulted_p = false,
   overline_color_defaulted_p = false,
   strike_through_color_defaulted_p = false,
   box_color_defaulted_p = true,
   underline_at_descent_line_p = false,
   tty_bold_p = false,
   tty_italic_p = false,
   tty_reverse_p = false,
   tty_strike_through_p = false,
   colors_copied_bitwise_p = true,
   overstrike = false,
   hash = 322003229,
   next = 0x54da8550,
   prev = 0x4d7343a0,
   ascii_face = 0x4d7343a0,
   extra = 0x0
}
(gdb)
```




On 8/18/24 16:58, Pip Cet wrote:
> "Eval EXEC"<execvy@gmail.com>  writes:
>
>> I'm help to tesing Emacs master branch (commit: 40eecd594ac) on Linux.
> Thank you!
>
>> I compile emacs source code by:
>>
>> ```bash
>>
>> make extraclean
>> ./autogen.sh \
>>     && ./configure \
>>     --prefix=$(realpath ../emacs-build/$(git branch --show-current | sed
>> 's/\//_/g'))\
>>     --with-imagemagick --with-xwidgets \
>>     --with-modules --with-x-toolkit=gtk3 --without-compress-install \
>>     --without-toolkit-scroll-bars --with-native-compilation --with-mailutils\
>>     --with-tree-sitter --with-xinput2  \
>>     --with-dbus  --with-native-compilation=aot \
>>     --with-file-notification=inotify\
>>     && make -j30 install
>> ```
> You might want to consider adding --enable-checking and CFLAGS="-O0 -g3
> -ggdb" or equivalent to that until this bug has been found.
>
>> When I using emacs, I got crash, the backtrace is :
>>
>> ```
>>
>> line to your configuration file "/home/exec/.config/gdb/gdbinit".
>> For more information about this security protection see the
>> "Auto-loading safe path" section in the GDB manual.  E.g., run from the
>> shell:
>>           info "(gdb)Auto-loading safe path"
>> warning: File
>> "/nix/store/x47hg342iyiw50c1fhqjzz4n0rqy3dhh-isl-0.20/lib/libisl.so.19.1.0-gdb.py"
>> auto-loading has been declined by your `auto-load safe-path' set to
>> "$debugdir:$datadir/auto-load:/nix/store/40yjzm7r5ki59kkk9423dnwbm86x7pyd-gcc-13.2.0-lib".
>> (gdb) c
>> The program is not being run.
>> (gdb) bt
>> #0  0x00007f9eaeea2efc in __pthread_kill_implementation () from
>> /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
>> #1  0x00007f9eaee52e86 in raise () from
>> /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6
>> #2  0x0000000000473791 in terminate_due_to_signal (sig=sig@entry=11,
>> backtrace_limit=backtrace_limit@entry=40) at emacs.c:469
>> #3  0x0000000000473ccd in handle_fatal_signal (sig=sig@entry=11) at
>> sysdep.c:1800
>> #4  0x00000000005c4bf8 in deliver_thread_signal (sig=sig@entry=11,
>> handler=0x473cc2 <handle_fatal_signal>) at sysdep.c:1792
>> #5  0x00000000005c4c7c in deliver_fatal_thread_signal (sig=11) at
>> sysdep.c:1812
>> #6  handle_sigsegv (sig=11, siginfo=<optimized out>, arg=<optimized
>> out>) at sysdep.c:1950
>> #7  <signal handler called>
>> #8  fontset_find_font (fontset=fontset@entry=0x0, c=c@entry=127802,
>> face=face@entry=0x13fec610, charset_id=charset_id@entry=-1,
>> fallback=fallback@entry=false)
>>       at /home/exec/Projects/git.savannah.gnu.org/git/emacs/src/lisp.h:2127
>> #9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=0x0,
>> c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
> Do you still have the core file?
>
> Can you print *face in this stack frame? The relevant gdb commands are
> "frame 9" followed by "p *face".
>
> c is ?🌺 .  Are you using that character in your mode line, by any
> chance?  Does it show up for you in Emacs?
>
>> I believe the crash is related to the font, but I can't reproduce it. It
>> happens about once a day.
> What would also be helpful would be to source .gdbinit from your src/
> directory, (gdb:
> "source/home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit"),
> then "pp Vfontset_table" to see how large it is.
>
> Thanks!
>
> Pip
>

[-- Attachment #2: Type: text/html, Size: 9830 bytes --]

^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  9:08   ` Eval EXEC
@ 2024-08-18  9:23     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18  9:24       ` execvy
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18  9:23 UTC (permalink / raw)
  To: Eval EXEC; +Cc: 72692

"Eval EXEC" <execvy@gmail.com> writes:

> I executed ``` 
> (gdb) source /home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit 
> ...... 
> Breakpoint 5 at 0x4736d9: file emacs.c, line 431. 
> Breakpoint 6 at 0x562640: file xterm.c, line 27093. 
> (gdb) pp Vfontset_table 
> Cannot access memory at address 0xc82684 
> (gdb) 
>
> ``` 

Oh. Sorry about that, I guess we can't use pp without a live process.

Can you try:

(gdb) x/32gx (*(long *)&Vfontset_table - 5)

That should work even without debug symbols.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  9:23     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18  9:24       ` execvy
  2024-08-18  9:34         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: execvy @ 2024-08-18  9:24 UTC (permalink / raw)
  To: Pip Cet, 72692

It's
```
(gdb) x/32gx (*(long *)&Vfontset_table - 5)
0x4de32f40:     0x00000000000000f3      0x00007f9ea734b695
0x4de32f50:     0x00000000028b8c65      0x00000000028bee1d
0x4de32f60:     0x00000000765a7d45      0x00000000765a7fad
0x4de32f70:     0x00000000765a83d5      0x00000000765a863d
0x4de32f80:     0x00000000765a88a5      0x00000000765a8d55
0x4de32f90:     0x00000000765a8fbd      0x00000000765a9225
0x4de32fa0:     0x00000000765a948d      0x00000000765a96f5
0x4de32fb0:     0x00000000765a995d      0x00000000765a9d65
0x4de32fc0:     0x00000000765a9fcd      0x00000000765aa235
0x4de32fd0:     0x00000000765aa49d      0x00000000765aa705
0x4de32fe0:     0x00000000765aa96d      0x00000000765aad75
0x4de32ff0:     0x00000000765aafdd      0x00000000765c2ce5
0x4de33000:     0x0000000002ab84d5      0x00000000765c4e15
0x4de33010:     0x00000000765dbf75      0x0000000000000000
0x4de33020:     0x0000000000000000      0x0000000000000000
0x4de33030:     0x0000000000000000      0x0000000000000000
(gdb)
```

Eval Exec

On 8/18/24 5:23 PM, Pip Cet <pipcet@protonmail.com> wrote:
> "Eval EXEC" <execvy@gmail.com> writes:
> 
> > I executed ```
> > (gdb) source /home/exec/Projects/git.savannah.gnu.org/git/emacs/src/.gdbinit
> > ......
> > Breakpoint 5 at 0x4736d9: file emacs.c, line 431.
> > Breakpoint 6 at 0x562640: file xterm.c, line 27093.
> > (gdb) pp Vfontset_table
> > Cannot access memory at address 0xc82684
> > (gdb)
> >
> > ```
> 
> Oh. Sorry about that, I guess we can't use pp without a live process.
> 
> Can you try:
> 
> (gdb) x/32gx (*(long *)&Vfontset_table - 5)
> 
> That should work even without debug symbols.
> 
> Pip
> 
> 





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  9:24       ` execvy
@ 2024-08-18  9:34         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18  9:36           ` execvy
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18  9:34 UTC (permalink / raw)
  To: execvy; +Cc: 72692

<execvy@gmail.com> writes:

> It's
> ```
> (gdb) x/32gx (*(long *)&Vfontset_table - 5)
> 0x4de32f40:     0x00000000000000f3      0x00007f9ea734b695
> 0x4de32f50:     0x00000000028b8c65      0x00000000028bee1d
> 0x4de32f60:     0x00000000765a7d45      0x00000000765a7fad
> 0x4de32f70:     0x00000000765a83d5      0x00000000765a863d
> 0x4de32f80:     0x00000000765a88a5      0x00000000765a8d55
> 0x4de32f90:     0x00000000765a8fbd      0x00000000765a9225
> 0x4de32fa0:     0x00000000765a948d      0x00000000765a96f5
> 0x4de32fb0:     0x00000000765a995d      0x00000000765a9d65
> 0x4de32fc0:     0x00000000765a9fcd      0x00000000765aa235
> 0x4de32fd0:     0x00000000765aa49d      0x00000000765aa705
> 0x4de32fe0:     0x00000000765aa96d      0x00000000765aad75
> 0x4de32ff0:     0x00000000765aafdd      0x00000000765c2ce5
> 0x4de33000:     0x0000000002ab84d5      0x00000000765c4e15
> 0x4de33010:     0x00000000765dbf75      0x0000000000000000
> 0x4de33020:     0x0000000000000000      0x0000000000000000
> 0x4de33030:     0x0000000000000000      0x0000000000000000
> (gdb)
> ```

Thanks. It looks like the entry in the fontset table has been freed
(that's entry 26, which is Qnil), but is still referenced by
face->fontset.  Can you go back to the same stack frame in which you
printed face and "p *face->ascii_face"?

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  9:34         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18  9:36           ` execvy
  2024-08-18 12:43             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: execvy @ 2024-08-18  9:36 UTC (permalink / raw)
  To: Pip Cet, 72692

It's
```
Redefine command "xbacktrace"? (y or n) [answered Y; input not from terminal]
Redefine command "xprintbytestr"? (y or n) [answered Y; input not from terminal]
Redefine command "xwhichsymbols"? (y or n) [answered Y; input not from terminal]
Redefine command "hookpost-backtrace"? (y or n) [answered Y; input not from terminal]
Redefine command "ff"? (y or n) [answered Y; input not from terminal]
DISPLAY = :0
TERM = tmux-256color
Breakpoint 3 at 0x4736d9: file emacs.c, line 431.
Breakpoint 4 at 0x562640: file xterm.c, line 27093.
(gdb) frame 9
#9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=XIL(0), c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
(gdb) p *face->ascii_face
$1 = {
  lface = {XIL(0x8220), XIL(0x28bdef4), XIL(0x28bdf34), XIL(0xe340), make_fixnum(90), XIL(0xe340), XIL(0xe340), XIL(0), XIL(0), XIL(0x4417994), XIL(0x233c9c4), XIL(0), XIL(0), XIL(0), XIL(0x7f9ea6b05d63),
    XIL(0x765a8285), XIL(0), XIL(0x2aabee4), XIL(0x13500), XIL(0)},
  id = 2,
  gc = 0x0,
  stipple = 0,
  foreground = 4288059542,
  background = 4278190080,
  underline_color = 0,
  overline_color = 0,
  strike_through_color = 0,
  box_color = 4281545523,
  font = 0x1e4370d0,
  fontset = 5,
  box_vertical_line_width = -1,
  box_horizontal_line_width = -1,
  underline_pixels_above_descent_line = 0,
  box = FACE_SIMPLE_BOX,
  underline = FACE_NO_UNDERLINE,
  use_box_color_for_shadows_p = true,
  overline_p = false,
  strike_through_p = false,
  foreground_defaulted_p = false,
  background_defaulted_p = false,
  underline_defaulted_p = false,
  overline_color_defaulted_p = false,
  strike_through_color_defaulted_p = false,
  box_color_defaulted_p = true,
  underline_at_descent_line_p = false,
  tty_bold_p = false,
  tty_italic_p = false,
  tty_reverse_p = false,
  tty_strike_through_p = false,
  colors_copied_bitwise_p = false,
  overstrike = false,
  hash = 322003229,
  next = 0x13fec610,
  prev = 0x0,
  ascii_face = 0x4d7343a0,
  extra = 0x0
}
(gdb)
```

Eval Exec

On 8/18/24 5:34 PM, Pip Cet <pipcet@protonmail.com> wrote:
> <execvy@gmail.com> writes:
> 
> > It's
> > ```
> > (gdb) x/32gx (*(long *)&Vfontset_table - 5)
> > 0x4de32f40:     0x00000000000000f3      0x00007f9ea734b695
> > 0x4de32f50:     0x00000000028b8c65      0x00000000028bee1d
> > 0x4de32f60:     0x00000000765a7d45      0x00000000765a7fad
> > 0x4de32f70:     0x00000000765a83d5      0x00000000765a863d
> > 0x4de32f80:     0x00000000765a88a5      0x00000000765a8d55
> > 0x4de32f90:     0x00000000765a8fbd      0x00000000765a9225
> > 0x4de32fa0:     0x00000000765a948d      0x00000000765a96f5
> > 0x4de32fb0:     0x00000000765a995d      0x00000000765a9d65
> > 0x4de32fc0:     0x00000000765a9fcd      0x00000000765aa235
> > 0x4de32fd0:     0x00000000765aa49d      0x00000000765aa705
> > 0x4de32fe0:     0x00000000765aa96d      0x00000000765aad75
> > 0x4de32ff0:     0x00000000765aafdd      0x00000000765c2ce5
> > 0x4de33000:     0x0000000002ab84d5      0x00000000765c4e15
> > 0x4de33010:     0x00000000765dbf75      0x0000000000000000
> > 0x4de33020:     0x0000000000000000      0x0000000000000000
> > 0x4de33030:     0x0000000000000000      0x0000000000000000
> > (gdb)
> > ```
> 
> Thanks. It looks like the entry in the fontset table has been freed
> (that's entry 26, which is Qnil), but is still referenced by
> face->fontset.  Can you go back to the same stack frame in which you
> printed face and "p *face->ascii_face"?
> 
> Pip
> 
> 





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18  9:36           ` execvy
@ 2024-08-18 12:43             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 12:53               ` execvy
  2024-08-18 13:35               ` Eli Zaretskii
  0 siblings, 2 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 12:43 UTC (permalink / raw)
  To: execvy; +Cc: 72692

<execvy@gmail.com> writes:

> It's
> ```
> Redefine command "xbacktrace"? (y or n) [answered Y; input not from terminal]
> Redefine command "xprintbytestr"? (y or n) [answered Y; input not from terminal]
> Redefine command "xwhichsymbols"? (y or n) [answered Y; input not from terminal]
> Redefine command "hookpost-backtrace"? (y or n) [answered Y; input not from terminal]
> Redefine command "ff"? (y or n) [answered Y; input not from terminal]
> DISPLAY = :0
> TERM = tmux-256color
> Breakpoint 3 at 0x4736d9: file emacs.c, line 431.
> Breakpoint 4 at 0x562640: file xterm.c, line 27093.
> (gdb) frame 9
> #9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=XIL(0), c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
> 793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
> (gdb) p *face->ascii_face
> $1 = {
>   lface = {XIL(0x8220), XIL(0x28bdef4), XIL(0x28bdf34), XIL(0xe340), make_fixnum(90), XIL(0xe340), XIL(0xe340), XIL(0), XIL(0), XIL(0x4417994), XIL(0x233c9c4), XIL(0), XIL(0), XIL(0), XIL(0x7f9ea6b05d63),
>     XIL(0x765a8285), XIL(0), XIL(0x2aabee4), XIL(0x13500), XIL(0)},
>   id = 2,
>   gc = 0x0,
>   stipple = 0,
>   foreground = 4288059542,
>   background = 4278190080,
>   underline_color = 0,
>   overline_color = 0,
>   strike_through_color = 0,
>   box_color = 4281545523,
>   font = 0x1e4370d0,
>   fontset = 5,
>   box_vertical_line_width = -1,
>   box_horizontal_line_width = -1,
>   underline_pixels_above_descent_line = 0,
>   box = FACE_SIMPLE_BOX,
>   underline = FACE_NO_UNDERLINE,
>   use_box_color_for_shadows_p = true,
>   overline_p = false,
>   strike_through_p = false,
>   foreground_defaulted_p = false,
>   background_defaulted_p = false,
>   underline_defaulted_p = false,
>   overline_color_defaulted_p = false,
>   strike_through_color_defaulted_p = false,
>   box_color_defaulted_p = true,
>   underline_at_descent_line_p = false,
>   tty_bold_p = false,
>   tty_italic_p = false,
>   tty_reverse_p = false,
>   tty_strike_through_p = false,
>   colors_copied_bitwise_p = false,
>   overstrike = false,
>   hash = 322003229,
>   next = 0x13fec610,
>   prev = 0x0,
>   ascii_face = 0x4d7343a0,
>   extra = 0x0
> }
> (gdb)
> ```

Thanks. That has a different fontset, so it looks like a fontset was
prematurely freed while still being referred to by a face.  I think the
assumption made in xfaces.c, that it's always safe to free a fontset if
we're freeing the realized ASCII face, is incorrect.

I can confirm that we're sometimes leaving a frame's fontset field
invalid by running this code:

diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..34bab822022 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4598,7 +4598,23 @@ free_realized_face (struct frame *f, struct face *face)
 	{
 	  /* Free fontset of FACE if it is ASCII face.  */
 	  if (face->fontset >= 0 && face == face->ascii_face)
-	    free_face_fontset (f, face);
+	    {
+	      struct face_cache *cache = FRAME_FACE_CACHE (f);
+	      if (cache)
+		{
+		  for (int i = 0; i < cache->used; i++)
+		    {
+		      struct face *face2 = cache->faces_by_id[i];
+		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
+			{
+			  message ("Freeing fontset %d that's still in use!", face->fontset);
+			  goto dont;
+			}
+		    }
+		}
+	      free_face_fontset (f, face);
+	    }
+	dont:
 
 #ifdef HAVE_X_WINDOWS
 	  /* This function might be called with the frame's display

However, that's not a fix; it would leak fontsets, and it's slow.

Will investigate further.

Thanks
Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 12:43             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 12:53               ` execvy
  2024-08-18 13:35               ` Eli Zaretskii
  1 sibling, 0 replies; 66+ messages in thread
From: execvy @ 2024-08-18 12:53 UTC (permalink / raw)
  To: Pip Cet, 72692

Thanks for the detailed explanation, thank you. :heart:

Eval Exec

On 8/18/24 8:43 PM, Pip Cet <pipcet@protonmail.com> wrote:
> <execvy@gmail.com> writes:
> 
> > It's
> > ```
> > Redefine command "xbacktrace"? (y or n) [answered Y; input not from terminal]
> > Redefine command "xprintbytestr"? (y or n) [answered Y; input not from terminal]
> > Redefine command "xwhichsymbols"? (y or n) [answered Y; input not from terminal]
> > Redefine command "hookpost-backtrace"? (y or n) [answered Y; input not from terminal]
> > Redefine command "ff"? (y or n) [answered Y; input not from terminal]
> > DISPLAY = :0
> > TERM = tmux-256color
> > Breakpoint 3 at 0x4736d9: file emacs.c, line 431.
> > Breakpoint 4 at 0x562640: file xterm.c, line 27093.
> > (gdb) frame 9
> > #9  0x00000000006dd64d in fontset_font (fontset=fontset@entry=XIL(0), c=c@entry=127802, face=face@entry=0x13fec610, id=-1) at fontset.c:793
> > 793       rfont_def = fontset_find_font (fontset, c, face, id, 0);
> > (gdb) p *face->ascii_face
> > $1 = {
> >    lface = {XIL(0x8220), XIL(0x28bdef4), XIL(0x28bdf34), XIL(0xe340), make_fixnum(90), XIL(0xe340), XIL(0xe340), XIL(0), XIL(0), XIL(0x4417994), XIL(0x233c9c4), XIL(0), XIL(0), XIL(0), XIL(0x7f9ea6b05d63),
> >      XIL(0x765a8285), XIL(0), XIL(0x2aabee4), XIL(0x13500), XIL(0)},
> >    id = 2,
> >    gc = 0x0,
> >    stipple = 0,
> >    foreground = 4288059542,
> >    background = 4278190080,
> >    underline_color = 0,
> >    overline_color = 0,
> >    strike_through_color = 0,
> >    box_color = 4281545523,
> >    font = 0x1e4370d0,
> >    fontset = 5,
> >    box_vertical_line_width = -1,
> >    box_horizontal_line_width = -1,
> >    underline_pixels_above_descent_line = 0,
> >    box = FACE_SIMPLE_BOX,
> >    underline = FACE_NO_UNDERLINE,
> >    use_box_color_for_shadows_p = true,
> >    overline_p = false,
> >    strike_through_p = false,
> >    foreground_defaulted_p = false,
> >    background_defaulted_p = false,
> >    underline_defaulted_p = false,
> >    overline_color_defaulted_p = false,
> >    strike_through_color_defaulted_p = false,
> >    box_color_defaulted_p = true,
> >    underline_at_descent_line_p = false,
> >    tty_bold_p = false,
> >    tty_italic_p = false,
> >    tty_reverse_p = false,
> >    tty_strike_through_p = false,
> >    colors_copied_bitwise_p = false,
> >    overstrike = false,
> >    hash = 322003229,
> >    next = 0x13fec610,
> >    prev = 0x0,
> >    ascii_face = 0x4d7343a0,
> >    extra = 0x0
> > }
> > (gdb)
> > ```
> 
> Thanks. That has a different fontset, so it looks like a fontset was
> prematurely freed while still being referred to by a face.  I think the
> assumption made in xfaces.c, that it's always safe to free a fontset if
> we're freeing the realized ASCII face, is incorrect.
> 
> I can confirm that we're sometimes leaving a frame's fontset field
> invalid by running this code:
> 
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 684b6ccfac7..34bab822022 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -4598,7 +4598,23 @@ free_realized_face (struct frame *f, struct face *face)
>   	{
>   	  /* Free fontset of FACE if it is ASCII face.  */
>   	  if (face->fontset >= 0 && face == face->ascii_face)
> -	    free_face_fontset (f, face);
> +	    {
> +	      struct face_cache *cache = FRAME_FACE_CACHE (f);
> +	      if (cache)
> +		{
> +		  for (int i = 0; i < cache->used; i++)
> +		    {
> +		      struct face *face2 = cache->faces_by_id[i];
> +		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
> +			{
> +			  message ("Freeing fontset %d that's still in use!", face->fontset);
> +			  goto dont;
> +			}
> +		    }
> +		}
> +	      free_face_fontset (f, face);
> +	    }
> +	dont:
>   
>   #ifdef HAVE_X_WINDOWS
>   	  /* This function might be called with the frame's display
> 
> However, that's not a fix; it would leak fontsets, and it's slow.
> 
> Will investigate further.
> 
> Thanks
> Pip
> 
> 





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 12:43             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 12:53               ` execvy
@ 2024-08-18 13:35               ` Eli Zaretskii
  2024-08-18 13:44                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 13:35 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Cc: 72692@debbugs.gnu.org
> Date: Sun, 18 Aug 2024 12:43:06 +0000
> From:  Pip Cet via "Bug reports for GNU Emacs,
>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> 
> Thanks. That has a different fontset, so it looks like a fontset was
> prematurely freed while still being referred to by a face.  I think the
> assumption made in xfaces.c, that it's always safe to free a fontset if
> we're freeing the realized ASCII face, is incorrect.

Why do you think that?  free_realized_face frees a face, so what other
face can still use the same fontset, if it's a so-called "ASCII face"?

> I can confirm that we're sometimes leaving a frame's fontset field
> invalid by running this code:

If face2->ascii_face is equal to face->ascii_face, then I see no
reason not to free the fontset because of that other face.  The
comment in dispextern.h says:

  /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
     from the same ASCII face have the same fontset.  */
  int fontset;

And how did you see that a frame's fontset was left invalid here?  A
frame doesn't have a fontset, AFAIK.

I don't object to using this code as a means of investigation, of
course, but I think we should have a clear idea of what the diagnostic
it emits means.

I also think it might be unsafe to call 'message' from this place,
because 'message' might trigger redisplay.  It is better to call
message_dolog or add_to_log (and ask the user to look at *Messages*).





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 13:35               ` Eli Zaretskii
@ 2024-08-18 13:44                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 14:12                   ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 13:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Cc: 72692@debbugs.gnu.org
>> Date: Sun, 18 Aug 2024 12:43:06 +0000
>> From:  Pip Cet via "Bug reports for GNU Emacs,
>>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>
>> Thanks. That has a different fontset, so it looks like a fontset was
>> prematurely freed while still being referred to by a face.  I think the
>> assumption made in xfaces.c, that it's always safe to free a fontset if
>> we're freeing the realized ASCII face, is incorrect.
>
> Why do you think that?  free_realized_face frees a face, so what other
> face can still use the same fontset, if it's a so-called "ASCII face"?

I was under the impression two faces could share the same fontset.  That
certainly is what my debugging sessions so far indicate.  Maybe that's
the bug?

>> I can confirm that we're sometimes leaving a frame's fontset field
>> invalid by running this code:
>
> If face2->ascii_face is equal to face->ascii_face,

Yes, face2->ascii_face == face == face->ascii_face.

> then I see no
> reason not to free the fontset because of that other face.  The
> comment in dispextern.h says:
>
>   /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
>      from the same ASCII face have the same fontset.  */
>   int fontset;

So, indeed, the fontset id is shared between the ASCII face and the
non-ASCII face.  If we free the fontset because the ASCII face is
unrealized, but the non-ASCII face is not, we hit the bug...

> And how did you see that a frame's fontset was left invalid here?  A
> frame doesn't have a fontset, AFAIK.

I meant "face", sorry!  The non-ASCII face remains in the font cache,
and its fontset is set to the newly freed fontset's ID, which is likely
soon to be reused; only if it isn't, we see a crash.

> I don't object to using this code as a means of investigation, of
> course, but I think we should have a clear idea of what the diagnostic
> it emits means.
>
> I also think it might be unsafe to call 'message' from this place,
> because 'message' might trigger redisplay.  It is better to call
> message_dolog or add_to_log (and ask the user to look at *Messages*).

It is, thank you! Yes, fprintf or message_dolog would have been better.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 13:44                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 14:12                   ` Eli Zaretskii
  2024-08-18 14:59                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 14:12 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 13:44:41 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> >> Cc: 72692@debbugs.gnu.org
> >> Date: Sun, 18 Aug 2024 12:43:06 +0000
> >> From:  Pip Cet via "Bug reports for GNU Emacs,
> >>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
> >>
> >> Thanks. That has a different fontset, so it looks like a fontset was
> >> prematurely freed while still being referred to by a face.  I think the
> >> assumption made in xfaces.c, that it's always safe to free a fontset if
> >> we're freeing the realized ASCII face, is incorrect.
> >
> > Why do you think that?  free_realized_face frees a face, so what other
> > face can still use the same fontset, if it's a so-called "ASCII face"?
> 
> I was under the impression two faces could share the same fontset.  That
> certainly is what my debugging sessions so far indicate.  Maybe that's
> the bug?

We are talking about a fontset identified by face->fontset.  AFAIU,
face->fontset is only non-negative for so-called "ASCII faces".

> >> I can confirm that we're sometimes leaving a frame's fontset field
> >> invalid by running this code:
> >
> > If face2->ascii_face is equal to face->ascii_face,
> 
> Yes, face2->ascii_face == face == face->ascii_face.
> 
> > then I see no
> > reason not to free the fontset because of that other face.  The
> > comment in dispextern.h says:
> >
> >   /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
> >      from the same ASCII face have the same fontset.  */
> >   int fontset;
> 
> So, indeed, the fontset id is shared between the ASCII face and the
> non-ASCII face.  If we free the fontset because the ASCII face is
> unrealized, but the non-ASCII face is not, we hit the bug...

But AFAIK a non-ASCII face is always released together with its ASCII
face, so how can this be a problem?  A "non-ASCII face" is basically
the same face as its "ASCII face" counterpart, it just uses a
different font.  An example would be some well-known face, like 'bold'
or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
character in this face, and the "ASCII face"s font doesn't support the
character, we internally create a new face that uses the same fontset
as the "ASCII face".  This new face basically shadows the "ASCII face"
(and is never exposed to Lisp) and is for every practical purpose an
integral part of that "ASCII face" -- they always go together.

> > And how did you see that a frame's fontset was left invalid here?  A
> > frame doesn't have a fontset, AFAIK.
> 
> I meant "face", sorry!  The non-ASCII face remains in the font cache,
> and its fontset is set to the newly freed fontset's ID, which is likely
> soon to be reused; only if it isn't, we see a crash.

That shouldn't happen, AFAIU, except for very brief periods of time,
since we free the cached faces one by one, see free_realized_faces.

> > I also think it might be unsafe to call 'message' from this place,
> > because 'message' might trigger redisplay.  It is better to call
> > message_dolog or add_to_log (and ask the user to look at *Messages*).
> 
> It is, thank you! Yes, fprintf or message_dolog would have been better.

fprintf is indeed the safest, but it requires Emacs to be launched
from the shell prompt.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 14:12                   ` Eli Zaretskii
@ 2024-08-18 14:59                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 15:38                       ` Eli Zaretskii
  2024-08-18 19:24                       ` Eli Zaretskii
  0 siblings, 2 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 14:59 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Sun, 18 Aug 2024 13:44:41 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> >> Cc: 72692@debbugs.gnu.org
>> >> Date: Sun, 18 Aug 2024 12:43:06 +0000
>> >> From:  Pip Cet via "Bug reports for GNU Emacs,
>> >>  the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>> >>
>> >> Thanks. That has a different fontset, so it looks like a fontset was
>> >> prematurely freed while still being referred to by a face.  I think the
>> >> assumption made in xfaces.c, that it's always safe to free a fontset if
>> >> we're freeing the realized ASCII face, is incorrect.
>> >
>> > Why do you think that?  free_realized_face frees a face, so what other
>> > face can still use the same fontset, if it's a so-called "ASCII face"?
>>
>> I was under the impression two faces could share the same fontset.  That
>> certainly is what my debugging sessions so far indicate.  Maybe that's
>> the bug?
>
> We are talking about a fontset identified by face->fontset.  AFAIU,
> face->fontset is only non-negative for so-called "ASCII faces".

Not what I'm seeing. base_face->fontset is copied into the new face by
realize_non_ascii_face.

>> > then I see no
>> > reason not to free the fontset because of that other face.  The
>> > comment in dispextern.h says:
>> >
>> >   /* Fontset ID if for this face's fontset.  Non-ASCII faces derived
>> >      from the same ASCII face have the same fontset.  */
>> >   int fontset;
>>
>> So, indeed, the fontset id is shared between the ASCII face and the
>> non-ASCII face.  If we free the fontset because the ASCII face is
>> unrealized, but the non-ASCII face is not, we hit the bug...
>
> But AFAIK a non-ASCII face is always released together with its ASCII
> face,

Also not what I'm seeing. When 'realize_basic_faces' is called, we call
'realize_face', which destroys the fontset, even though it's still in
use by the non-ASCII face.

> so how can this be a problem?

I don't understand yet what underlying assumption is violated, and what
precisely happened.

But I have just reproduced the crash, I think. It does need this patch,
which means we will actually crash when accessing a formerly-valid
fontset, rather than accessing random and inappropriate data, so I think
we need to first establish that this patch doesn't break things and
cause a different crash.

diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..41d845c9bc5 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
   ASET (Vfontset_table, face->fontset, Qnil);
-  if (face->fontset < next_fontset_id)
-    next_fontset_id = face->fontset;
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
@@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
       eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       eassert (f == XFRAME (FONTSET_FRAME (fontset)));
       ASET (Vfontset_table, id, Qnil);
-      if (id < next_fontset_id)
-	next_fontset_id = face->fontset;
     }
   face->fontset = -1;
 }

and this Emacs Lisp script:

(display-time-mode t)
(let ((i 0))
  (while t
    (dolist (f (frame-list))
      (push (concat (make-string 1 (floor (random 132000)))
                    (make-string 1 (floor (random 132000)))
                    (make-string 1 (floor (random 132000)))
                    (make-string 1 (floor (random 132000))))
            mode-line-format)
      (set-frame-parameter f 'alpha-background 1.0)
      (sit-for 0)
      (cl-incf i)
      (message "%S" i)
      (set-frame-parameter f 'alpha-background 0.9)
      (sit-for 0)
      (garbage-collect))))

(Not minimized yet).

> A "non-ASCII face" is basically
> the same face as its "ASCII face" counterpart, it just uses a
> different font.  An example would be some well-known face, like 'bold'
> or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
> character in this face, and the "ASCII face"s font doesn't support the
> character, we internally create a new face that uses the same fontset
> as the "ASCII face".  This new face basically shadows the "ASCII face"
> (and is never exposed to Lisp) and is for every practical purpose an
> integral part of that "ASCII face" -- they always go together.

Except they're not freed together?

>> > And how did you see that a frame's fontset was left invalid here?  A
>> > frame doesn't have a fontset, AFAIK.
>>
>> I meant "face", sorry!  The non-ASCII face remains in the font cache,
>> and its fontset is set to the newly freed fontset's ID, which is likely
>> soon to be reused; only if it isn't, we see a crash.
>
> That shouldn't happen, AFAIU, except for very brief periods of time,
> since we free the cached faces one by one, see free_realized_faces.

Again, not what I'm seeing, because 'free_realized_faces' isn't where the
font is actually removed from the cache; it's 'free_realized_face'.

I'd like to understand what is happening a bit better before submitting
a proposed fix.

Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 14:59                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 15:38                       ` Eli Zaretskii
  2024-08-18 16:08                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 19:24                       ` Eli Zaretskii
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 15:38 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 14:59:51 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> I don't understand yet what underlying assumption is violated, and what
> precisely happened.
> 
> But I have just reproduced the crash, I think. It does need this patch,
> which means we will actually crash when accessing a formerly-valid
> fontset, rather than accessing random and inappropriate data, so I think
> we need to first establish that this patch doesn't break things and
> cause a different crash.

I don't understand: is this patch needed to trigger a crash, or are
you saying we need it to fix crashes?

next_fontset_id is used to assign an ID to the next fontset we create,
AFAIK.

> > A "non-ASCII face" is basically
> > the same face as its "ASCII face" counterpart, it just uses a
> > different font.  An example would be some well-known face, like 'bold'
> > or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
> > character in this face, and the "ASCII face"s font doesn't support the
> > character, we internally create a new face that uses the same fontset
> > as the "ASCII face".  This new face basically shadows the "ASCII face"
> > (and is never exposed to Lisp) and is for every practical purpose an
> > integral part of that "ASCII face" -- they always go together.
> 
> Except they're not freed together?

How do you see that?

> >> I meant "face", sorry!  The non-ASCII face remains in the font cache,
> >> and its fontset is set to the newly freed fontset's ID, which is likely
> >> soon to be reused; only if it isn't, we see a crash.
> >
> > That shouldn't happen, AFAIU, except for very brief periods of time,
> > since we free the cached faces one by one, see free_realized_faces.
> 
> Again, not what I'm seeing, because 'free_realized_faces' isn't where the
> font is actually removed from the cache; it's 'free_realized_face'.

Yes, but free_realized_faces calls free_realized_face, no?





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 15:38                       ` Eli Zaretskii
@ 2024-08-18 16:08                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 17:55                           ` Eli Zaretskii
  2024-08-18 17:56                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 16:08 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Sun, 18 Aug 2024 14:59:51 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> I don't understand yet what underlying assumption is violated, and what
>> precisely happened.
>>
>> But I have just reproduced the crash, I think. It does need this patch,
>> which means we will actually crash when accessing a formerly-valid
>> fontset, rather than accessing random and inappropriate data, so I think
>> we need to first establish that this patch doesn't break things and
>> cause a different crash.
>
> I don't understand: is this patch needed to trigger a crash, or are
> you saying we need it to fix crashes?

It helps trigger the crash, which might take a long time without the
patch.

> next_fontset_id is used to assign an ID to the next fontset we create,
> AFAIK.

Indeed, and if we never reset it to a low value, we won't reuse slots in
Vfontset_table.  So the entries, rather than containing a different and
incorrect fontset for our font, will remain zeroed.

>> > A "non-ASCII face" is basically
>> > the same face as its "ASCII face" counterpart, it just uses a
>> > different font.  An example would be some well-known face, like 'bold'
>> > or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
>> > character in this face, and the "ASCII face"s font doesn't support the
>> > character, we internally create a new face that uses the same fontset
>> > as the "ASCII face".  This new face basically shadows the "ASCII face"
>> > (and is never exposed to Lisp) and is for every practical purpose an
>> > integral part of that "ASCII face" -- they always go together.
>>
>> Except they're not freed together?
>
> How do you see that?

printf debugging.

>> >> I meant "face", sorry!  The non-ASCII face remains in the font cache,
>> >> and its fontset is set to the newly freed fontset's ID, which is likely
>> >> soon to be reused; only if it isn't, we see a crash.
>> >
>> > That shouldn't happen, AFAIU, except for very brief periods of time,
>> > since we free the cached faces one by one, see free_realized_faces.
>>
>> Again, not what I'm seeing, because 'free_realized_faces' isn't where the
>> font is actually removed from the cache; it's 'free_realized_face'.
>
> Yes, but free_realized_faces calls free_realized_face, no?

Yes, it does, but in my case, 'free_realized_face' is called by
'realize_face', and 'free_realized_faces' isn't.

I'll continue debugging this, but if there are any questions or further
helpful information, that would be much appreciated.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 16:08                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 17:55                           ` Eli Zaretskii
  2024-08-18 18:11                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 17:56                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 17:55 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 16:08:39 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > I don't understand: is this patch needed to trigger a crash, or are
> > you saying we need it to fix crashes?
> 
> It helps trigger the crash, which might take a long time without the
> patch.
> 
> > next_fontset_id is used to assign an ID to the next fontset we create,
> > AFAIK.
> 
> Indeed, and if we never reset it to a low value, we won't reuse slots in
> Vfontset_table.  So the entries, rather than containing a different and
> incorrect fontset for our font, will remain zeroed.

How can incorrect fontset in Vfontset_table cause a segfault of the
kind the OP reported?

> >> > A "non-ASCII face" is basically
> >> > the same face as its "ASCII face" counterpart, it just uses a
> >> > different font.  An example would be some well-known face, like 'bold'
> >> > or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
> >> > character in this face, and the "ASCII face"s font doesn't support the
> >> > character, we internally create a new face that uses the same fontset
> >> > as the "ASCII face".  This new face basically shadows the "ASCII face"
> >> > (and is never exposed to Lisp) and is for every practical purpose an
> >> > integral part of that "ASCII face" -- they always go together.
> >>
> >> Except they're not freed together?
> >
> > How do you see that?
> 
> printf debugging.

Which shows what exactly?

> >> >> I meant "face", sorry!  The non-ASCII face remains in the font cache,
> >> >> and its fontset is set to the newly freed fontset's ID, which is likely
> >> >> soon to be reused; only if it isn't, we see a crash.
> >> >
> >> > That shouldn't happen, AFAIU, except for very brief periods of time,
> >> > since we free the cached faces one by one, see free_realized_faces.
> >>
> >> Again, not what I'm seeing, because 'free_realized_faces' isn't where the
> >> font is actually removed from the cache; it's 'free_realized_face'.
> >
> > Yes, but free_realized_faces calls free_realized_face, no?
> 
> Yes, it does, but in my case, 'free_realized_face' is called by
> 'realize_face', and 'free_realized_faces' isn't.

Which face was freed, the ASCII face or not?

> I'll continue debugging this, but if there are any questions or further
> helpful information, that would be much appreciated.

I don't yet understand well what you are seeing because there isn't
enough detailed information.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 16:08                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 17:55                           ` Eli Zaretskii
@ 2024-08-18 17:56                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 18:38                             ` Eli Zaretskii
  1 sibling, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 17:56 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Pip Cet" <pipcet@protonmail.com> writes:

> "Eli Zaretskii" <eliz@gnu.org> writes:
>
>>> Date: Sun, 18 Aug 2024 14:59:51 +0000
>>> From: Pip Cet <pipcet@protonmail.com>
>>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>>
>>> I don't understand yet what underlying assumption is violated, and what
>>> precisely happened.
>>>
>>> But I have just reproduced the crash, I think. It does need this patch,
>>> which means we will actually crash when accessing a formerly-valid
>>> fontset, rather than accessing random and inappropriate data, so I think
>>> we need to first establish that this patch doesn't break things and
>>> cause a different crash.
>>
>> I don't understand: is this patch needed to trigger a crash, or are
>> you saying we need it to fix crashes?
>
> It helps trigger the crash, which might take a long time without the
> patch.

And I understand why it's so rare now: the non-ASCII face contains a
dangling pointer to the (freed!) old ASCII face, and we verify in
'face_for_font' that the pointer matches the new ASCII face, which it
can do only if the new ASCII face happens to be allocated at the same
address the old one had.

But, it happens, and we need to fix it somehow.  The easiest fix would
be to use a refcount in 'struct face' and do the actual freeing (of
fontset and struct face) only when no other 'struct face' refers to our
face through ->ascii_face.

Or is there a simpler solution?

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 17:55                           ` Eli Zaretskii
@ 2024-08-18 18:11                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 18:52                               ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-18 18:11 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Sun, 18 Aug 2024 16:08:39 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > I don't understand: is this patch needed to trigger a crash, or are
>> > you saying we need it to fix crashes?
>>
>> It helps trigger the crash, which might take a long time without the
>> patch.
>>
>> > next_fontset_id is used to assign an ID to the next fontset we create,
>> > AFAIK.
>>
>> Indeed, and if we never reset it to a low value, we won't reuse slots in
>> Vfontset_table.  So the entries, rather than containing a different and
>> incorrect fontset for our font, will remain zeroed.
>
> How can incorrect fontset in Vfontset_table cause a segfault of the
> kind the OP reported?

I said "rather than containing a different and incorrect fontset"; in
the OP's case (and after the patch, on my system), it was Qnil.

>> >> > A "non-ASCII face" is basically
>> >> > the same face as its "ASCII face" counterpart, it just uses a
>> >> > different font.  An example would be some well-known face, like 'bold'
>> >> > or 'variable-pitch' or 'region' -- when we need to display a non-ASCII
>> >> > character in this face, and the "ASCII face"s font doesn't support the
>> >> > character, we internally create a new face that uses the same fontset
>> >> > as the "ASCII face".  This new face basically shadows the "ASCII face"
>> >> > (and is never exposed to Lisp) and is for every practical purpose an
>> >> > integral part of that "ASCII face" -- they always go together.
>> >>
>> >> Except they're not freed together?
>> >
>> > How do you see that?
>>
>> printf debugging.
>
> Which shows what exactly?

See below.

>> >> >> I meant "face", sorry!  The non-ASCII face remains in the font cache,
>> >> >> and its fontset is set to the newly freed fontset's ID, which is likely
>> >> >> soon to be reused; only if it isn't, we see a crash.
>> >> >
>> >> > That shouldn't happen, AFAIU, except for very brief periods of time,
>> >> > since we free the cached faces one by one, see free_realized_faces.
>> >>
>> >> Again, not what I'm seeing, because 'free_realized_faces' isn't where the
>> >> font is actually removed from the cache; it's 'free_realized_face'.
>> >
>> > Yes, but free_realized_faces calls free_realized_face, no?
>>
>> Yes, it does, but in my case, 'free_realized_face' is called by
>> 'realize_face', and 'free_realized_faces' isn't.
>
> Which face was freed, the ASCII face or not?

The ASCII face was freed, the non-ASCII face remained in the cache. In
the log below, the ASCII face is 0x117cca0, the non-ASCII face is
0x2a7a3c0.

>> I'll continue debugging this, but if there are any questions or further
>> helpful information, that would be much appreciated.
>
> I don't yet understand well what you are seeing because there isn't
> enough detailed information.

Okay, maybe this helps.

Here's the patch:

diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..52149ebd6b2 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
   ASET (Vfontset_table, face->fontset, Qnil);
-  if (face->fontset < next_fontset_id)
-    next_fontset_id = face->fontset;
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
@@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
       eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       eassert (f == XFRAME (FONTSET_FRAME (fontset)));
       ASET (Vfontset_table, id, Qnil);
-      if (id < next_fontset_id)
-	next_fontset_id = face->fontset;
     }
   face->fontset = -1;
 }
@@ -1000,6 +996,7 @@ face_for_char (struct frame *f, struct face *face, int c,
      and display it as "glyphless".  That is certainly better than
      violating the assertion below or crashing when assertions are not
      compiled in.  */
+  fprintf (stderr, "fontset %d used for face %p\n", face->fontset, face);
   if (face->fontset < 0 && !face->font)
     return face->id;
 
diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..86ab8e1328a 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4598,7 +4598,25 @@ free_realized_face (struct frame *f, struct face *face)
 	{
 	  /* Free fontset of FACE if it is ASCII face.  */
 	  if (face->fontset >= 0 && face == face->ascii_face)
-	    free_face_fontset (f, face);
+	    {
+	      struct face_cache *cache = FRAME_FACE_CACHE (f);
+	      if (cache)
+		{
+		  for (int i = 0; i < cache->used; i++)
+		    {
+		      struct face *face2 = cache->faces_by_id[i];
+		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
+			{
+			  fprintf (stderr, "Freeing fontset %d that's still in use by %p!\n", face->fontset,
+				   face2);
+			}
+		    }
+		}
+	      free_face_fontset (f, face);
+	    }
+	  else
+	    fprintf (stderr, "fontset %d not freed, used by %p\n", face->fontset, face);
+	dont:
 
 #ifdef HAVE_X_WINDOWS
 	  /* This function might be called with the frame's display



Here's hibiscus.el:

(display-time-mode t)
(setq display-time-interval .1)
(let ((i 0))
  (while t
    (push (concat (make-string 1 (floor (random 132000)))
                  (make-string 1 (floor (random 132000)))
                  (make-string 1 (floor (random 132000)))
                  (make-string 1 (floor (random 132000))))
          mode-line-format)
    (dolist (f (frame-list))
      (set-frame-parameter f 'alpha-background 1.0)
      (sit-for 0)
      (cl-incf i)
      (message "%S" i)
      (set-frame-parameter f 'alpha-background 0.9)
      (sit-for 0)
      (garbage-collect))))



And here's the output of emacs -Q --load hibiscus.el:

fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a7a3c0
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a62860
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2fb0dc0
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a7a3c0
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a62860
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2fb0dc0
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a7a3c0
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2a62860
fontset 103 used for face 0x117cca0
fontset 103 used for face 0x2fb0dc0
Freeing fontset 103 that's still in use by 0x2a7a3c0!
Freeing fontset 103 that's still in use by 0x2a62860!
Freeing fontset 103 that's still in use by 0x2fb0dc0!
Freeing fontset 103 that's still in use by 0x2fdb7a0!
fontset 126 used for face 0x117cca0
fontset 103 used for face 0x2a7a3c0

lisp.h:2126: Emacs fatal error: assertion failed: CHAR_TABLE_P (a)
Fatal error 6: Aborted
Backtrace:
./emacs() [0x60f113]
./emacs() [0x5da076]
./emacs() [0x684c6d]
./emacs() [0x78d649]
./emacs() [0x790239]
./emacs() [0x44b7bd]
./emacs() [0x46933b]
./emacs() [0x4a9aef]
./emacs() [0x4a63af]
./emacs() [0x4a6dc3]
./emacs() [0x4a542f]
./emacs() [0x4a512e]
./emacs() [0x48dce3]
./emacs() [0x483053]
./emacs() [0x6b96a0]
./emacs() [0x482ec5]
./emacs() [0x4816c0]
./emacs() [0x482434]
./emacs() [0x433222]
./emacs() [0x6bd608]
./emacs() [0x718884]
./emacs() [0x6bdc5f]
./emacs() [0x6bdaf6]
./emacs() [0x6bc027]
./emacs() [0x6b6ae6]
./emacs() [0x6b8679]
./emacs() [0x6bbaae]
./emacs() [0x6b6ae6]
./emacs() [0x6b6b16]
./emacs() [0x6b86e1]
./emacs() [0x6bbaae]
./emacs() [0x6b6ae6]
./emacs() [0x6b8679]
./emacs() [0x6bbaae]
./emacs() [0x6b6ae6]
./emacs() [0x6b6b16]
./emacs() [0x6b86e1]
./emacs() [0x6bbaae]
./emacs() [0x6b6ae6]
./emacs() [0x6b8679]
./emacs() [0x6bbaae]
./emacs() [0x6fd2d6]
./emacs() [0x6fdb40]
./emacs() [0x6fde8f]
./emacs() [0x6bd6e6]
./emacs() [0x718884]
./emacs() [0x6bdc5f]
./emacs() [0x6bd059]
./emacs() [0x6bd308]
./emacs() [0x6fb7c7]
./emacs() [0x6bd6e6]
./emacs() [0x718884]
./emacs() [0x6bdc5f]
./emacs() [0x6bdaf6]
./emacs() [0x6bc027]
./emacs() [0x6bb55a]
./emacs() [0x5e1fdd]
./emacs() [0x6b95c9]
./emacs() [0x5e2038]
./emacs() [0x6b8a8d]
./emacs() [0x5e1ec0]
./emacs() [0x5e1327]
./emacs() [0x5e153a]
./emacs() [0x5dd18f]
/lib64/libc.so.6(+0x26200) [0x7ffff5b63200]
/lib64/libc.so.6(__libc_start_main+0x89) [0x7ffff5b632b9]
./emacs() [0x422155]
Aborted


Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 17:56                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 18:38                             ` Eli Zaretskii
  2024-08-19  6:28                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 18:38 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 17:56:12 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Pip Cet" <pipcet@protonmail.com> writes:
> 
> > "Eli Zaretskii" <eliz@gnu.org> writes:
> >
> >>> Date: Sun, 18 Aug 2024 14:59:51 +0000
> >>> From: Pip Cet <pipcet@protonmail.com>
> >>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> >>>
> >>> I don't understand yet what underlying assumption is violated, and what
> >>> precisely happened.
> >>>
> >>> But I have just reproduced the crash, I think. It does need this patch,
> >>> which means we will actually crash when accessing a formerly-valid
> >>> fontset, rather than accessing random and inappropriate data, so I think
> >>> we need to first establish that this patch doesn't break things and
> >>> cause a different crash.
> >>
> >> I don't understand: is this patch needed to trigger a crash, or are
> >> you saying we need it to fix crashes?
> >
> > It helps trigger the crash, which might take a long time without the
> > patch.
> 
> And I understand why it's so rare now: the non-ASCII face contains a
> dangling pointer to the (freed!) old ASCII face, and we verify in
> 'face_for_font' that the pointer matches the new ASCII face, which it
> can do only if the new ASCII face happens to be allocated at the same
> address the old one had.
> 
> But, it happens, and we need to fix it somehow.  The easiest fix would
> be to use a refcount in 'struct face' and do the actual freeing (of
> fontset and struct face) only when no other 'struct face' refers to our
> face through ->ascii_face.
> 
> Or is there a simpler solution?

I don't understand what you are saying, because there isn't enough
details.  How does the "dangling pointer to the freed old ASCII face"
come into existence, by which code and in what situation?  What do you
mean by "the new ASCII face happens to be allocated at the same
address the old one had" -- is that the address of 'struct face', and
if so, are you saying that malloc returns to us the same address in
most cases? how's that possible?

Please, PLEASE describe the issue with enough details and pointers to
the code, and preferably back that up with data from a debugging
session.  That's the only way to conduct this kind of discussion while
making sure all of the participants are on the same page, and can help
each other with ideas and their respective knowledge of Emacs
internals.

Here's one data point: this kind of problem has never, NEVER happened
to me, although I display non-ASCII text in my Emacs sessions quite a
lot.  So if what you describe is so trivially easy to trigger, how
come it didn't happen to me, in all the years I'm using this code?

There has to be more to this than meets the eye, and we can only
figure this out if you provide all the missing details.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 18:11                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-18 18:52                               ` Eli Zaretskii
  2024-08-19  6:17                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 18:52 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 18:11:47 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> >> > Yes, but free_realized_faces calls free_realized_face, no?
> >>
> >> Yes, it does, but in my case, 'free_realized_face' is called by
> >> 'realize_face', and 'free_realized_faces' isn't.
> >
> > Which face was freed, the ASCII face or not?
> 
> The ASCII face was freed, the non-ASCII face remained in the cache. In
> the log below, the ASCII face is 0x117cca0, the non-ASCII face is
> 0x2a7a3c0.

What are the other faces, 0x2a62860 and 0x2fb0dc0?

> >> I'll continue debugging this, but if there are any questions or further
> >> helpful information, that would be much appreciated.
> >
> > I don't yet understand well what you are seeing because there isn't
> > enough detailed information.
> 
> Okay, maybe this helps.

Thanks, it helps some.

> lisp.h:2126: Emacs fatal error: assertion failed: CHAR_TABLE_P (a)
> Fatal error 6: Aborted
> Backtrace:
> ./emacs() [0x60f113]
> ./emacs() [0x5da076]

Can you show this backtrace from GDB, preferably "bt all"?  I'm not
sure I understand the reason just by looking at this.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 14:59                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-18 15:38                       ` Eli Zaretskii
@ 2024-08-18 19:24                       ` Eli Zaretskii
  2024-08-19  6:07                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-18 19:24 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sun, 18 Aug 2024 14:59:51 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> >> I was under the impression two faces could share the same fontset.  That
> >> certainly is what my debugging sessions so far indicate.  Maybe that's
> >> the bug?
> >
> > We are talking about a fontset identified by face->fontset.  AFAIU,
> > face->fontset is only non-negative for so-called "ASCII faces".
> 
> Not what I'm seeing. base_face->fontset is copied into the new face by
> realize_non_ascii_face.

Where do you see this copying in realize_non_ascii_face?





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 19:24                       ` Eli Zaretskii
@ 2024-08-19  6:07                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-19 14:17                           ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19  6:07 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Sun, 18 Aug 2024 14:59:51 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> >> I was under the impression two faces could share the same fontset.  That
>> >> certainly is what my debugging sessions so far indicate.  Maybe that's
>> >> the bug?
>> >
>> > We are talking about a fontset identified by face->fontset.  AFAIU,
>> > face->fontset is only non-negative for so-called "ASCII faces".
>>
>> Not what I'm seeing. base_face->fontset is copied into the new face by
>> realize_non_ascii_face.
>
> Where do you see this copying in realize_non_ascii_face?

static struct face *
realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
			struct face *base_face)
{
  struct face_cache *cache = FRAME_FACE_CACHE (f);
  struct face *face;

  face = xmalloc (sizeof *face);
  *face = *base_face;
        ^____ here

(The entire structure is copied, and fontset isn't explicitly changed
afterwards).

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 18:52                               ` Eli Zaretskii
@ 2024-08-19  6:17                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19  6:17 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Sun, 18 Aug 2024 18:11:47 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> >> > Yes, but free_realized_faces calls free_realized_face, no?
>> >>
>> >> Yes, it does, but in my case, 'free_realized_face' is called by
>> >> 'realize_face', and 'free_realized_faces' isn't.
>> >
>> > Which face was freed, the ASCII face or not?
>>
>> The ASCII face was freed, the non-ASCII face remained in the cache. In
>> the log below, the ASCII face is 0x117cca0, the non-ASCII face is
>> 0x2a7a3c0.
>
> What are the other faces, 0x2a62860 and 0x2fb0dc0?

Other non-ASCII faces for the same ASCII face.  Since I insert four
random Unicode characters into the mode line, it's not unexpected there
is more than one.

>> >> I'll continue debugging this, but if there are any questions or further
>> >> helpful information, that would be much appreciated.
>> >
>> > I don't yet understand well what you are seeing because there isn't
>> > enough detailed information.
>>
>> Okay, maybe this helps.
>
> Thanks, it helps some.

I can still provide a fuller log if it helps.

>> lisp.h:2126: Emacs fatal error: assertion failed: CHAR_TABLE_P (a)
>> Fatal error 6: Aborted
>> Backtrace:
>> ./emacs() [0x60f113]
>> ./emacs() [0x5da076]
>
> Can you show this backtrace from GDB, preferably "bt all"?  I'm not
> sure I understand the reason just by looking at this.

Here's the backtrace. I applied a different patch this time so line
numbers might not match master precisely.  Patch follows afterwards.

(gdb) bt full
#0  terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:432
#1  0x0000000000684caf in die (msg=0x81ee20 "CHAR_TABLE_P (a)", file=0x81ecf0 "lisp.h", line=2126) at alloc.c:8058
#2  0x000000000078d68b in XCHAR_TABLE (a=XIL(0)) at lisp.h:2126
#3  0x000000000079027b in face_for_char (f=0x1235ad8, face=0x2a79d50, c=100206, pos=1, object=XIL(0x1178ab4)) at fontset.c:1005
        fontset = XIL(0)
        rfont_def = XIL(0x532a03)
        charset = XIL(0)
        face_id = 0
        id = 15805504
#4  0x000000000044b7bd in FACE_FOR_CHAR (f=0x1235ad8, face=0x2a79d50, character=100206, pos=1, object=XIL(0x1178ab4))
    at dispextern.h:1962
#5  0x000000000046933b in get_next_display_element (it=0x7fffffff5e80) at xdisp.c:8547
        pos = 1
        c = 100206
        face = 0x2a79d50
        success_p = true
#6  0x00000000004a9aef in display_string
    (string=0x0, lisp_string=XIL(0x1178ab4), face_string=XIL(0), face_string_pos=0, start=0, it=0x7fffffff5e80, field_width=0, precision=2, max_x=1912, multibyte=1) at xdisp.c:29274
        x_before = 0
        i = 1
        nglyphs = 1
        x = 19
        n_glyphs_before = 0
        hpos_at_start = 0
        saved_face_id = 1
        row = 0x2a8e5e0
        it_charpos = 1
#7  0x00000000004a63af in display_mode_element (it=0x7fffffff5e80, depth=2, field_width=0, precision=0, elt=XIL(0x1178ab4), props=XIL(0), risky=false)
    at xdisp.c:27822
        bytepos = 0
        charpos = 0
        nchars = 2
        nbytes = 0
        last_offset = 0
        c = 0 '\000'
        offset = 8
        n = 0
        field = 1696
        prec = 3
        literal = false
#8  0x00000000004a6dc3 in display_mode_element (it=0x7fffffff5e80, depth=1, field_width=0, precision=0, elt=XIL(0x7ffff3385833), props=XIL(0), risky=false)
    at xdisp.c:28070
        li = {
          tortoise = XIL(0x7ffff3385833),
          max = 2,
          n = 0,
          q = 2
        }
        car = XIL(0)
        tem = XIL(0)
        n = 0
        field = 7072844
        prec = 32767
        literal = false
#9  0x00000000004a542f in display_mode_line (w=0x1235d60, face_id=MODE_LINE_ACTIVE_FACE_ID, format=XIL(0x7ffff3385833)) at xdisp.c:27495
        it = {
          window = XIL(0x1235d65),
          w = 0x1235d60,
          f = 0x1235ad8,
          method = GET_FROM_STRING,
          stop_charpos = 2,
          prev_stop = 0,
          base_level_stop = 0,
          end_charpos = 2,
          medium_narrowing_begv = 0,
          medium_narrowing_zv = 0,
          large_narrowing_begv = 0,
          large_narrowing_zv = 0,
          s = 0x0,
          string_nchars = 2,
          multibyte_p = true,
          tab_line_p = false,
          header_line_p = false,
          string_from_display_prop_p = false,
          string_from_prefix_prop_p = false,
          from_disp_prop_p = false,
          ellipsis_p = false,
          avoid_cursor_p = false,
          dp = 0x0,
          dpvec = 0x0,
          dpend = 0x0,
          dpvec_char_len = 0,
          dpvec_face_id = 0,
          saved_face_id = 1,
          ctl_chars = {XIL(0) <repeats 16 times>},
          start = {
            pos = {
              charpos = 0,
              bytepos = 0
            },
            overlay_string_index = 0,
            string_pos = {
              charpos = 0,
              bytepos = 0
            },
            dpvec_index = 0
          },
          current = {
            pos = {
              charpos = 0,
              bytepos = 0
            },
            overlay_string_index = -1,
            string_pos = {
              charpos = 1,
              bytepos = 4
            },
            dpvec_index = -1
          },
          n_overlay_strings = 0,
          overlay_strings_charpos = 0,
          overlay_strings = {XIL(0) <repeats 16 times>},
          string_overlays = {XIL(0) <repeats 16 times>},
          string = XIL(0x1178ab4),
          from_overlay = XIL(0),
          stack = {{
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }},
          sp = 0,
          selective = 0,
          what = IT_CHARACTER,
          face_id = 20,
          selective_display_ellipsis_p = true,
          ctl_arrow_p = true,
          face_box_p = true,
          start_of_box_run_p = false,
          end_of_box_run_p = false,
          overlay_strings_at_end_processed_p = false,
          ignore_overlay_strings_at_pos_p = false,
          glyph_not_available_p = false,
          starts_in_middle_of_char_p = false,
          face_before_selective_p = false,
          constrain_row_ascent_descent_p = false,
          line_number_produced_p = false,
          align_visually_p = false,
          line_wrap = TRUNCATE,
          base_face_id = 1,
          c = 100206,
          len = 4,
          cmp_it = {
            stop_pos = 2,
            id = -1,
            ch = -2,
            rule_idx = 0,
            lookback = 0,
            nglyphs = 0,
            reversed_p = false,
            parent_it = 0x7fffffff5e80,
            charpos = 0,
            nchars = 0,
            nbytes = 0,
            from = 0,
            to = 0,
            width = 0
          },
          char_to_display = 100206,
          glyphless_method = GLYPHLESS_DISPLAY_HEX_CODE,
          image_id = 0,
          xwidget = 0x0,
          slice = {
            x = XIL(0),
            y = XIL(0),
            width = XIL(0),
            height = XIL(0)
          },
          space_width = XIL(0),
          voffset = 0,
          tab_width = 8,
          font_height = XIL(0),
          object = XIL(0x1178ab4),
          position = {
            charpos = 1,
            bytepos = 4
          },
          truncation_pixel_width = 9,
          continuation_pixel_width = 0,
          first_visible_x = 0,
          last_visible_x = 1912,
          last_visible_y = 2250,
          extra_line_spacing = 0,
          max_extra_line_spacing = 0,
          override_ascent = -1,
          override_descent = 0,
          override_boff = 0,
          glyph_row = 0x2a8e5e0,
          area = TEXT_AREA,
          nglyphs = 1,
          pixel_width = 19,
          ascent = 13,
          descent = 5,
          max_ascent = 13,
          max_descent = 5,
          phys_ascent = 13,
          phys_descent = 5,
          max_phys_ascent = 13,
          max_phys_descent = 5,
          current_x = 19,
          wrap_prefix_width = 0,
          continuation_lines_width = 0,
          eol_pos = {
            charpos = 0,
            bytepos = 0
          },
          current_y = 0,
          first_vpos = 0,
          vpos = 0,
          hpos = 1,
          lnum = 0,
          lnum_bytepos = 0,
          lnum_width = 0,
          lnum_pixel_width = 0,
          pt_lnum = 0,
          stretch_adjust = 0,
          left_user_fringe_bitmap = 0,
          right_user_fringe_bitmap = 0,
          left_user_fringe_face_id = 0,
          right_user_fringe_face_id = 0,
          bidi_p = true,
          bidi_it = {
            bytepos = 4,
            charpos = 1,
            ch = 100206,
            nchars = 1,
            ch_len = 4,
            type = STRONG_L,
            type_after_wn = STRONG_L,
            orig_type = STRONG_L,
            resolved_level = 0 '\000',
            isolate_level = 0 '\000',
            invalid_levels = 0,
            invalid_isolates = 0,
            prev = {
              charpos = 0,
              type = STRONG_L,
              orig_type = STRONG_L
            },
            last_strong = {
              charpos = 0,
              type = STRONG_L,
              orig_type = STRONG_L
            },
            next_for_neutral = {
              charpos = -1,
              type = UNKNOWN_BT,
              orig_type = UNKNOWN_BT
            },
            prev_for_neutral = {
              charpos = 0,
              type = STRONG_L,
              orig_type = STRONG_L
            },
            next_for_ws = {
              charpos = -1,
              type = UNKNOWN_BT,
              orig_type = UNKNOWN_BT
            },
            bracket_pairing_pos = -1,
            bracket_enclosed_type = UNKNOWN_BT,
            next_en_pos = 0,
            next_en_type = UNKNOWN_BT,
            sos = L2R,
            scan_dir = 1,
            disp_pos = 2,
            disp_prop = 0,
            stack_idx = 0,
            level_stack = {{
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              } <repeats 128 times>},
            string = {
              lstring = XIL(0x1178ab4),
              s = 0x0,
              schars = 2,
              bufpos = 0,
              from_disp_str = false,
              unibyte = false
            },
            w = 0x1235d60,
            paragraph_dir = L2R,
            separator_limit = -1,
            first_elt = false,
            new_paragraph = false,
            frame_window_p = true
          },
          paragraph_embedding = L2R,
          min_width_property = XIL(0),
          min_width_start = 0
        }
        face = 0x7fffffff7220
        count = {
          bytes = 1664
        }
#10 0x00000000004a512e in display_mode_lines (w=0x1235d60) at xdisp.c:27408
        window_mode_line_format = XIL(0)
        sel_w = 0x1235d60
        old_selected_window = XIL(0x1235d65)
        new_frame = XIL(0x1235add)
        count = {
          bytes = 1600
        }
        n = 0
#11 0x000000000048dce3 in redisplay_window (window=XIL(0x1235d65), just_this_one_p=false) at xdisp.c:20981
        count1 = {
          bytes = 1568
        }
        w = 0x1235d60
        f = 0x1235ad8
        buffer = 0x7ffff261e750
        old = 0x7ffff261e750
        lpoint = {
          charpos = 1,
          bytepos = 1
        }
        opoint = {
          charpos = 1,
          bytepos = 1
        }
        startp = {
          charpos = 1,
          bytepos = 1
        }
        update_mode_line = true
        tem = 0
        it = {
          window = XIL(0),
          w = 0x0,
          f = 0x0,
          method = 4294936480,
          stop_charpos = 140733193388032,
          prev_stop = 1,
          base_level_stop = 1,
          end_charpos = 1,
          medium_narrowing_begv = 1,
          medium_narrowing_zv = 0,
          large_narrowing_begv = 0,
          large_narrowing_zv = 0,
          s = 0x0,
          string_nchars = 0,
          multibyte_p = false,
          tab_line_p = false,
          header_line_p = false,
          string_from_display_prop_p = false,
          string_from_prefix_prop_p = false,
          from_disp_prop_p = false,
          ellipsis_p = false,
          avoid_cursor_p = false,
          dp = 0xffffffff00000000,
          dpvec = 0x0,
          dpend = 0x0,
          dpvec_char_len = 0,
          dpvec_face_id = 0,
          saved_face_id = 1,
          ctl_chars = {XIL(0xfc6b90), XIL(0x1235f80), XIL(0x7fffffff9b70), make_fixnum(1195614), XIL(0x1), XIL(0x1), XIL(0x1235f85), XIL(0x1235f85), XIL(0x1235f85), XIL(0x1235f80), XIL(0x1235ad8), XIL(0), make_fixnum(0), XIL(0x1), XIL(0), make_fixnum(0)},
          start = {
            pos = {
              charpos = 0,
              bytepos = 0
            },
            overlay_string_index = 0,
            string_pos = {
              charpos = 0,
              bytepos = 0
            },
            dpvec_index = 0
          },
          current = {
            pos = {
              charpos = 1,
              bytepos = 0
            },
            overlay_string_index = 0,
            string_pos = {
              charpos = 0,
              bytepos = 0
            },
            dpvec_index = 0
          },
          n_overlay_strings = 0,
          overlay_strings_charpos = 0,
          overlay_strings = {XIL(0) <repeats 14 times>, make_fixnum(0), make_fixnum(0)},
          string_overlays = {XIL(0xffffffffffffffff), XIL(0xffffffffffffffff), XIL(0xffffffffffffffff), XIL(0xffffffff), make_fixnum(0), make_fixnum(0), XIL(0xffffffffffffffff), XIL(0xffffffffffffffff), XIL(0xffffffffffffffff), XIL(0xffffffff), XIL(0), make_fixnum(0), XIL(0), XIL(0), XIL(0), XIL(0)},
          string = XIL(0),
          from_overlay = XIL(0),
          stack = {{
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }, {
              string = XIL(0),
              string_nchars = 0,
              end_charpos = 0,
              stop_charpos = 0,
              prev_stop = 0,
              base_level_stop = 0,
              cmp_it = {
                stop_pos = 0,
                id = 0,
                ch = 0,
                rule_idx = 0,
                lookback = 0,
                nglyphs = 0,
                reversed_p = false,
                parent_it = 0x0,
                charpos = 0,
                nchars = 0,
                nbytes = 0,
                from = 0,
                to = 0,
                width = 0
              },
              face_id = 0,
              u = {
                image = {
                  object = XIL(0),
                  slice = {
                    x = XIL(0),
                    y = XIL(0),
                    width = XIL(0),
                    height = XIL(0)
                  },
                  image_id = 0
                },
                stretch = {
                  object = XIL(0)
                },
                xwidget = {
                  object = XIL(0)
                }
              },
              position = {
                charpos = 0,
                bytepos = 0
              },
              current = {
                pos = {
                  charpos = 0,
                  bytepos = 0
                },
                overlay_string_index = 0,
                string_pos = {
                  charpos = 0,
                  bytepos = 0
                },
                dpvec_index = 0
              },
              from_overlay = XIL(0),
              area = LEFT_MARGIN_AREA,
              method = GET_FROM_BUFFER,
              paragraph_embedding = NEUTRAL_DIR,
              multibyte_p = false,
              string_from_display_prop_p = false,
              string_from_prefix_prop_p = false,
              display_ellipsis_p = false,
              avoid_cursor_p = false,
              bidi_p = false,
              from_disp_prop_p = false,
              line_wrap = TRUNCATE,
              voffset = 0,
              space_width = XIL(0),
              font_height = XIL(0)
            }},
          sp = 0,
          selective = 0,
          what = IT_CHARACTER,
          face_id = 0,
          selective_display_ellipsis_p = false,
          ctl_arrow_p = false,
          face_box_p = false,
          start_of_box_run_p = false,
          end_of_box_run_p = false,
          overlay_strings_at_end_processed_p = false,
          ignore_overlay_strings_at_pos_p = false,
          glyph_not_available_p = false,
          starts_in_middle_of_char_p = false,
          face_before_selective_p = false,
          constrain_row_ascent_descent_p = false,
          line_number_produced_p = false,
          align_visually_p = false,
          line_wrap = TRUNCATE,
          base_face_id = 0,
          c = 0,
          len = 0,
          cmp_it = {
            stop_pos = 0,
            id = 0,
            ch = 0,
            rule_idx = 0,
            lookback = 0,
            nglyphs = 0,
            reversed_p = false,
            parent_it = 0x0,
            charpos = 0,
            nchars = 0,
            nbytes = 0,
            from = 0,
            to = 0,
            width = 0
          },
          char_to_display = 0,
          glyphless_method = GLYPHLESS_DISPLAY_THIN_SPACE,
          image_id = 0,
          xwidget = 0x0,
          slice = {
            x = XIL(0),
            y = XIL(0),
            width = XIL(0),
            height = XIL(0)
          },
          space_width = XIL(0),
          voffset = 0,
          tab_width = 0,
          font_height = XIL(0),
          object = XIL(0),
          position = {
            charpos = 0,
            bytepos = 0
          },
          truncation_pixel_width = 5,
          continuation_pixel_width = 0,
          first_visible_x = 0,
          last_visible_x = 35,
          last_visible_y = 2,
          extra_line_spacing = 0,
          max_extra_line_spacing = 49,
          override_ascent = 1,
          override_descent = 0,
          override_boff = 1,
          glyph_row = 0xffffffffffffffff,
          area = -2,
          nglyphs = 0,
          pixel_width = 0,
          ascent = 0,
          descent = 0,
          max_ascent = 0,
          max_descent = 0,
          phys_ascent = 0,
          phys_descent = -30800,
          max_phys_ascent = 32767,
          max_phys_descent = 0,
          current_x = 0,
          wrap_prefix_width = 0,
          continuation_lines_width = 0,
          eol_pos = {
            charpos = 0,
            bytepos = 0
          },
          current_y = 49,
          first_vpos = 0,
          vpos = 0,
          hpos = 0,
          lnum = 0,
          lnum_bytepos = 0,
          lnum_width = 0,
          lnum_pixel_width = 0,
          pt_lnum = 0,
          stretch_adjust = 0,
          left_user_fringe_bitmap = 0,
          right_user_fringe_bitmap = 0,
          left_user_fringe_face_id = 0,
          right_user_fringe_face_id = 0,
          bidi_p = false,
          bidi_it = {
            bytepos = 524288,
            charpos = 0,
            ch = 19287589,
            nchars = 2,
            ch_len = 2,
            type = 589824,
            type_after_wn = UNKNOWN_BT,
            orig_type = 1881,
            resolved_level = 18 '\022',
            isolate_level = 0 '\000',
            invalid_levels = 0,
            invalid_isolates = 4294967295,
            prev = {
              charpos = 0,
              type = 16542864,
              orig_type = UNKNOWN_BT
            },
            last_strong = {
              charpos = 4294967297,
              type = LRO,
              orig_type = LRI
            },
            next_for_neutral = {
              charpos = 5,
              type = UNKNOWN_BT,
              orig_type = UNKNOWN_BT
            },
            prev_for_neutral = {
              charpos = 0,
              type = UNKNOWN_BT,
              orig_type = UNKNOWN_BT
            },
            next_for_ws = {
              charpos = 0,
              type = UNKNOWN_BT,
              orig_type = UNKNOWN_BT
            },
            bracket_pairing_pos = 0,
            bracket_enclosed_type = WEAK_ET,
            next_en_pos = 1,
            next_en_type = UNKNOWN_BT,
            sos = NEUTRAL_DIR,
            scan_dir = 0,
            disp_pos = 0,
            disp_prop = 0,
            stack_idx = 0,
            level_stack = {{
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 2,
                next_for_neutral_type = 2,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 4294967295,
                next_for_neutral_type = 1,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 1,
                next_for_neutral_type = 6,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 6,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 1,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 12884901888,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 7,
                last_strong_type = 7,
                prev_for_neutral_type = 7,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 2,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 12884901889,
                next_for_neutral_type = 7,
                last_strong_type = 7,
                prev_for_neutral_type = 7,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 7,
                last_strong_type = 7,
                prev_for_neutral_type = 7,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 4294967296,
                next_for_neutral_type = 1,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 2,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              } <repeats 89 times>, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 1,
                prev_for_neutral_type = 6,
                level = 73 'I',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 1,
                prev_for_neutral_type = 6,
                level = 73 'I',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 140737488328832,
                next_for_neutral_type = 0,
                last_strong_type = 2,
                prev_for_neutral_type = 1,
                level = 105 'i',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737258288008,
                next_for_neutral_type = 0,
                last_strong_type = 4,
                prev_for_neutral_type = 2,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 6899898,
                next_for_neutral_type = 4,
                last_strong_type = 7,
                prev_for_neutral_type = 1,
                level = 105 'i',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737258288008,
                next_for_neutral_type = 0,
                last_strong_type = 2,
                prev_for_neutral_type = 7,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 6911646,
                next_for_neutral_type = 4,
                last_strong_type = 7,
                prev_for_neutral_type = 1,
                level = 105 'i',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 6,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737258288008,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 19287584,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737264827720,
                next_for_neutral_type = 0,
                last_strong_type = 3,
                prev_for_neutral_type = 5,
                level = 173 '\255',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 3,
                prev_for_neutral_type = 5,
                level = 173 '\255',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 140737488328992,
                next_for_neutral_type = 7,
                last_strong_type = 1,
                prev_for_neutral_type = 2,
                level = 105 'i',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737264827736,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 5,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 6900093,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737264827736,
                next_for_neutral_type = 0,
                last_strong_type = 6,
                prev_for_neutral_type = 1,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 6911738,
                next_for_neutral_type = 0,
                last_strong_type = 1,
                prev_for_neutral_type = 6,
                level = 73 'I',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 140737259890512,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 0,
                level = 0 '\000',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 140737264827736,
                next_for_neutral_type = 0,
                last_strong_type = 2,
                prev_for_neutral_type = 6,
                level = 255 '\377',
                flags = 255 '\377'
              }, {
                next_for_neutral_pos = 6891084,
                next_for_neutral_type = 0,
                last_strong_type = 0,
                prev_for_neutral_type = 1,
                level = 241 '\361',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 1,
                prev_for_neutral_type = 6,
                level = 73 'I',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 140737259890512,
                next_for_neutral_type = 0,
                last_strong_type = 1,
                prev_for_neutral_type = 6,
                level = 73 'I',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 140737488329152,
                next_for_neutral_type = 0,
                last_strong_type = 6,
                prev_for_neutral_type = 1,
                level = 241 '\361',
                flags = 0 '\000'
              }, {
                next_for_neutral_pos = 48,
                next_for_neutral_type = 0,
                last_strong_type = 3,
                prev_for_neutral_type = 5,
                level = 173 '\255',
                flags = 242 '\362'
              }, {
                next_for_neutral_pos = 0,
                next_for_neutral_type = 0,
                last_strong_type = 3,
                prev_for_neutral_type = 5,
                level = 173 '\255',
                flags = 242 '\362'
              }},
            string = {
              lstring = XIL(0x7fffffff99f0),
              s = 0x69488f <OBJFWDP+24> "\203\370\002\017\224\300\311\303UH\211\345H\203\354\020H\211}\370\017\266\005\276̇",
              schars = 140737264827736,
              bufpos = 140737488329232,
              from_disp_str = true,
              unibyte = false
            },
            w = 0x1264e20,
            paragraph_dir = (unknown: 0xf2ad3d58),
            separator_limit = 140737488329536,
            first_elt = false,
            new_paragraph = true,
            frame_window_p = false
          },
          paragraph_embedding = (unknown: 0xf283bc90),
          min_width_property = XIL(0x7ffff261e750),
          min_width_start = 48
        }
        current_matrix_up_to_date_p = false
        used_current_matrix_p = false
        temp_scroll_step = false
        count = {
          bytes = 1536
        }
        rc = 0
        centering_position = -1
        last_line_misfit = false
        beg_unchanged = 0
        end_unchanged = 0
        frame_line_height = 18
        margin = 0
        use_desired_matrix = false
        itdata = 0x0
        lchars_modiff = 1
        ochars_modiff = 1
#12 0x0000000000483053 in redisplay_window_0 (window=XIL(0x1235d65)) at xdisp.c:18070
#13 0x00000000006b96e2 in internal_condition_case_1
    (bfun=0x483011 <redisplay_window_0>, arg=XIL(0x1235d65), handlers=XIL(0x7ffff274a113), hfun=0x482eef <redisplay_window_error>) at eval.c:1622
        val = XIL(0x44c111)
        c = 0xfcd380
#14 0x0000000000482ec5 in redisplay_windows (window=XIL(0x1235d65)) at xdisp.c:18039
        w = 0x1235d60
#15 0x00000000004816c0 in redisplay_internal () at xdisp.c:17438
        gcscrollbars = true
        f_redisplay_flag = true
        f = 0x1235ad8
        w = 0x1235d60
        sw = 0x1235d60
        fr = 0x1235ad8
        pending = false
        must_finish = true
        match_p = true
        tlbufpos = {
          charpos = 1,
          bytepos = 1
        }
        tlendpos = {
          charpos = 0,
          bytepos = 0
        }
        number_of_visible_frames = 1
        sf = 0x1235ad8
        polling_stopped_here = false
        tail = XIL(0x7ffff33b27b3)
        frame = XIL(0x1235add)
        hscroll_retries = 0
        garbaged_frame_retries = 0
        consider_all_windows_p = true
        update_miniwindow_p = true
        count = {
          bytes = 1440
        }
#16 0x0000000000482434 in redisplay_preserve_echo_area (from_where=2) at xdisp.c:17797
        count = {
          bytes = 1408
        }
#17 0x0000000000433222 in Fredisplay (force=XIL(0)) at dispnew.c:6369
        count = {
          bytes = 1408
        }
#18 0x00000000006bd64a in funcall_subr (subr=0xe88f80 <Sredisplay>, numargs=0, args=0x7fffe3fff2f0) at eval.c:3138
        argbuf = {XIL(0), XIL(0x7fffffffba00), XIL(0xf12ca0), XIL(0x560), XIL(0x7fffffffb260), make_fixnum(19329211838), XIL(0xe88f85), XIL(0x7fffffffb280)}
        a = 0x7fffffffb230
        maxargs = 1
        fun = XIL(0xe88f85)
#19 0x00000000007188c6 in exec_byte_code (fun=XIL(0x7ffff2360e35), args_template=513, nargs=1, args=0x7fffffffb818) at bytecode.c:813
        call_nargs = 0
        call_fun = XIL(0xe88f85)
        count1 = {
          bytes = 1376
        }
        val = XIL(0)
        call_args = 0x7fffe3fff2f0
        original_fun = XIL(0x7ffff173e668)
        op = 0
        type = HANDLER_BIND
        targets = {0x71c0f0 <exec_byte_code+17688>, 0x71c113 <exec_byte_code+17723>, 0x71c115 <exec_byte_code+17725>, 0x71c117 <exec_byte_code+17727>, 0x71c119 <exec_byte_code+17729>, 0x71c119 <exec_byte_code+17729>, 0x71c173 <exec_byte_code+17819>, 0x71c1dc <exec_byte_code+17924>, 0x7180b9 <exec_byte_code+1249>, 0x7180bb <exec_byte_code+1251>, 0x7180bd <exec_byte_code+1253>, 0x7180bf <exec_byte_code+1255>, 0x7180c1 <exec_byte_code+1257>, 0x7180c1 <exec_byte_code+1257>, 0x7180c7 <exec_byte_code+1263>, 0x718088 <exec_byte_code+1200>, 0x718438 <exec_byte_code+2144>, 0x71843a <exec_byte_code+2146>, 0x71843c <exec_byte_code+2148>, 0x71843e <exec_byte_code+2150>, 0x718440 <exec_byte_code+2152>, 0x718440 <exec_byte_code+2152>, 0x718475 <exec_byte_code+2205>, 0x718446 <exec_byte_code+2158>, 0x71860c <exec_byte_code+2612>, 0x71860e <exec_byte_code+2614>, 0x718610 <exec_byte_code+2616>, 0x718612 <exec_byte_code+2618>, 0x718614 <exec_byte_code+2620>, 0x718614 <exec_byte_code+2620>, 0x7185c6 <exec_byte_code+2542>, 0x7185dd <exec_byte_code+2565>, 0x7186b6 <exec_byte_code+2782>, 0x7186b8 <exec_byte_code+2784>, 0x7186ba <exec_byte_code+2786>, 0x7186bc <exec_byte_code+2788>, 0x7186be <exec_byte_code+2790>, 0x7186be <exec_byte_code+2790>, 0x718670 <exec_byte_code+2712>, 0x718687 <exec_byte_code+2735>, 0x7189e0 <exec_byte_code+3592>, 0x7189e2 <exec_byte_code+3594>, 0x7189e4 <exec_byte_code+3596>, 0x7189e6 <exec_byte_code+3598>, 0x7189e8 <exec_byte_code+3600>, 0x7189e8 <exec_byte_code+3600>, 0x71899a <exec_byte_code+3522>, 0x7189b1 <exec_byte_code+3545>, 0x7191c9 <exec_byte_code+5617>, 0x718fdc <exec_byte_code+5124>, 0x718fd3 <exec_byte_code+5115>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7193d3 <exec_byte_code+6139>, 0x71954f <exec_byte_code+6519>, 0x7195a6 <exec_byte_code+6606>, 0x7195fb <exec_byte_code+6691>, 0x719652 <exec_byte_code+6778>, 0x7182ba <exec_byte_code+1762>, 0x718331 <exec_byte_code+1881>, 0x7196c0 <exec_byte_code+6888>, 0x718211 <exec_byte_code+1593>, 0x71838e <exec_byte_code+1974>, 0x71971d <exec_byte_code+6981>, 0x71977a <exec_byte_code+7074>, 0x7197b7 <exec_byte_code+7135>, 0x719814 <exec_byte_code+7228>, 0x71986f <exec_byte_code+7319>, 0x719942 <exec_byte_code+7530>, 0x71997f <exec_byte_code+7591>, 0x719b1f <exec_byte_code+8007>, 0x719cea <exec_byte_code+8466>, 0x719d27 <exec_byte_code+8527>, 0x719d64 <exec_byte_code+8588>, 0x719dc1 <exec_byte_code+8681>, 0x719e1e <exec_byte_code+8774>, 0x719e7b <exec_byte_code+8867>, 0x719ef5 <exec_byte_code+8989>, 0x719f39 <exec_byte_code+9057>, 0x719f7d <exec_byte_code+9125>, 0x71a031 <exec_byte_code+9305>, 0x71a11b <exec_byte_code+9539>, 0x71a205 <exec_byte_code+9773>, 0x71a2e1 <exec_byte_code+9993>, 0x71a3d0 <exec_byte_code+10232>, 0x71a4bf <exec_byte_code+10471>, 0x71a5ae <exec_byte_code+10710>, 0x71a69d <exec_byte_code+10949>, 0x71a813 <exec_byte_code+11323>, 0x71a8fe <exec_byte_code+11558>, 0x71aa71 <exec_byte_code+11929>, 0x71ab2c <exec_byte_code+12116>, 0x71abe7 <exec_byte_code+12303>, 0x71b04e <exec_byte_code+13430>, 0x718e8e <exec_byte_code+4790>, 0x71b09e <exec_byte_code+13510>, 0x71b0db <exec_byte_code+13571>, 0x71b18a <exec_byte_code+13746>, 0x71b1da <exec_byte_code+13826>, 0x71b22a <exec_byte_code+13906>, 0x71b267 <exec_byte_code+13967>, 0x71b29f <exec_byte_code+14023>, 0x71b2d7 <exec_byte_code+14079>, 0x71b317 <exec_byte_code+14143>, 0x71c0f0 <exec_byte_code+17688>, 0x71b364 <exec_byte_code+14220>, 0x71b39c <exec_byte_code+14276>, 0x71b3d4 <exec_byte_code+14332>, 0x71b40c <exec_byte_code+14388>, 0x71b444 <exec_byte_code+14444>, 0x71b47c <exec_byte_code+14500>, 0x718e8e <exec_byte_code+4790>, 0x71c0f0 <exec_byte_code+17688>, 0x71b4b9 <exec_byte_code+14561>, 0x71b4fe <exec_byte_code+14630>, 0x71b53b <exec_byte_code+14691>, 0x71b578 <exec_byte_code+14752>, 0x71b5d5 <exec_byte_code+14845>, 0x71b632 <exec_byte_code+14938>, 0x71b66f <exec_byte_code+14999>, 0x71b6ac <exec_byte_code+15060>, 0x71b709 <exec_byte_code+15153>, 0x71b766 <exec_byte_code+15246>, 0x71b7c3 <exec_byte_code+15339>, 0x71b7fb <exec_byte_code+15395>, 0x71c0f0 <exec_byte_code+17688>, 0x718dee <exec_byte_code+4630>, 0x718a43 <exec_byte_code+3691>, 0x71818a <exec_byte_code+1458>, 0x718add <exec_byte_code+3845>, 0x718b56 <exec_byte_code+3966>, 0x718bcc <exec_byte_code+4084>, 0x718c42 <exec_byte_code+4202>, 0x718dc2 <exec_byte_code+4586>, 0x71857e <exec_byte_code+2470>, 0x718e62 <exec_byte_code+4746>, 0x718eba <exec_byte_code+4834>, 0x718f3b <exec_byte_code+4963>, 0x718f74 <exec_byte_code+5020>, 0x71920a <exec_byte_code+5682>, 0x719278 <exec_byte_code+5792>, 0x7192f2 <exec_byte_code+5914>, 0x71934d <exec_byte_code+6005>, 0x71c0f0 <exec_byte_code+17688>, 0x71b838 <exec_byte_code+15456>, 0x71b8b2 <exec_byte_code+15578>, 0x71b8ef <exec_byte_code+15639>, 0x71b92c <exec_byte_code+15700>, 0x71b969 <exec_byte_code+15761>, 0x71b9a6 <exec_byte_code+15822>, 0x71ba03 <exec_byte_code+15915>, 0x71ba60 <exec_byte_code+16008>, 0x71babd <exec_byte_code+16101>, 0x71bb1a <exec_byte_code+16194>, 0x71bcab <exec_byte_code+16595>, 0x71bd08 <exec_byte_code+16688>, 0x71bd65 <exec_byte_code+16781>, 0x71bda2 <exec_byte_code+16842>, 0x71be93 <exec_byte_code+17083>, 0x71bf84 <exec_byte_code+17324>, 0x71bfc1 <exec_byte_code+17385>, 0x71bffe <exec_byte_code+17446>, 0x71ad71 <exec_byte_code+12697>, 0x71af04 <exec_byte_code+13100>, 0x71c042 <exec_byte_code+17514>, 0x71c099 <exec_byte_code+17601>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7198d2 <exec_byte_code+7418>, 0x719fc1 <exec_byte_code+9193>, 0x71b11a <exec_byte_code+13634>, 0x71c260 <exec_byte_code+18056>, 0x71c2ca <exec_byte_code+18162>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c351 <exec_byte_code+18297>, 0x71c3cd <exec_byte_code+18421>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c580 <exec_byte_code+18856> <repeats 64 times>}
        quitcounter = 1 '\001'
        bc = 0xe87fd0 <main_thread+496>
        top = 0x7fffe3fff2e8
        pc = 0x7ffff2c898df "\207\211\204)"
        bytestr = XIL(0x7ffff26e06cc)
        vector = XIL(0x7ffff2360e85)
        maxdepth = make_fixnum(7)
        const_length = 11
        bytestr_length = 64
        vectorp = 0x7ffff2360e88
        max_stack = 7
        frame_base = 0x7fffe3fff2d8
        fp = 0x7fffe3fff310
        bytestr_data = 0x7ffff2c898be "\b\203\t"
        rest = false
        mandatory = 1
        nonrest = 2
        pushedargs = 1
        saved_quitcounter = 0 '\000'
        saved_vectorp = 0xad70
        saved_bytestr_data = 0x3ff0000000000000 <error: Cannot access memory at address 0x3ff0000000000000>
        result = XIL(0x7fffffffb400)
#20 0x00000000006bdca1 in funcall_lambda (fun=XIL(0x7ffff2360e35), nargs=1, arg_vector=0x7fffffffb810) at eval.c:3229
        syms_left = make_fixnum(513)
        lexenv = XIL(0x7fffffffb800)
        count = {
          bytes = 140737488336832
        }
        i = 1344
        optional = false
        rest = false
        previous_rest = 127
        val = XIL(0x7fffffffb810)
#21 0x00000000006bdb38 in apply_lambda (fun=XIL(0x7ffff2360e35), args=XIL(0x7ffff33a0003), count=...) at eval.c:3192
        arg_vector = 0x7fffffffb810
        tem = make_fixnum(0)
        sa_avail = 16376
        sa_count = {
          bytes = 1376
        }
        numargs = 1
        args_left = XIL(0)
#22 0x00000000006bc069 in eval_sub (form=XIL(0x7ffff33a0053)) at eval.c:2622
        original_fun = XIL(0x7ffff144e1c0)
        original_args = XIL(0x7ffff33a0003)
        count = {
          bytes = 1344
        }
        fun = XIL(0x7ffff2360e35)
        val = XIL(0x1318a54)
        funcar = XIL(0x7f00ffffb900)
        argvals = {XIL(0x69247c), XIL(0x7ffff339fac3), XIL(0x7fffffffb900), make_fixnum(1728400), XIL(0), XIL(0), XIL(0x7ffff3385823), XIL(0)}
#23 0x00000000006b6b28 in Fprogn (body=XIL(0x7ffff339f9c3)) at eval.c:430
        form = XIL(0x7ffff33a0053)
        val = XIL(0)
#24 0x00000000006b86bb in Flet (args=XIL(0x7ffff33858f3)) at eval.c:1100
        temps = 0x7fffffffba00
        tem = XIL(0x1235add)
        lexenv = XIL(0)
        elt = XIL(0x7ffff339faa3)
        count = {
          bytes = 1312
        }
        argnum = 1
        sa_avail = 16376
        sa_count = {
          bytes = 1312
        }
        varlist = XIL(0)
        varlist_len = 1
        nvars = 1
#25 0x00000000006bbaf0 in eval_sub (form=XIL(0x7ffff33858e3)) at eval.c:2526
        args_left = XIL(0x7ffff33858f3)
        numargs = 9
        original_fun = XIL(0xc150)
        original_args = XIL(0x7ffff33858f3)
        count = {
          bytes = 1280
        }
        fun = XIL(0xe97c05)
        val = XIL(0)
        funcar = XIL(0x60)
        argvals = {make_fixnum(1757858), XIL(0x7ffff3385823), XIL(0x7fffffffbc30), make_fixnum(1764833), XIL(0x7000f12c40), XIL(0x324d70), XIL(0x7fffffffbb40), XIL(0x697128)}
#26 0x00000000006b6b28 in Fprogn (body=XIL(0)) at eval.c:430
        form = XIL(0x7ffff33858e3)
        val = XIL(0)
#27 0x00000000006b6b58 in prog_ignore (body=XIL(0x7ffff33858b3)) at eval.c:441
#28 0x00000000006b8723 in Fwhile (args=XIL(0x7ffff33858c3)) at eval.c:1121
        test = XIL(0x324d70)
        body = XIL(0x7ffff33858b3)
#29 0x00000000006bbaf0 in eval_sub (form=XIL(0x7ffff33858d3)) at eval.c:2526
        args_left = XIL(0x7ffff33858c3)
        numargs = 2
        original_fun = XIL(0x7ffff1502160)
        original_args = XIL(0x7ffff33858c3)
        count = {
          bytes = 1248
        }
        fun = XIL(0xe97c45)
        val = XIL(0)
        funcar = XIL(0x7ffff2ad3f70)
        argvals = {XIL(0), XIL(0x7ffff33a0343), XIL(0xd4a0), XIL(0x9), XIL(0), XIL(0), XIL(0x69247c), XIL(0x30)}
#30 0x00000000006b6b28 in Fprogn (body=XIL(0)) at eval.c:430
        form = XIL(0x7ffff33858d3)
        val = XIL(0)
#31 0x00000000006b86bb in Flet (args=XIL(0x7ffff3385893)) at eval.c:1100
        temps = 0x7fffffffbdf0
        tem = XIL(0x7ffff3385823)
        lexenv = XIL(0)
        elt = XIL(0x7ffff339faf3)
        count = {
          bytes = 1216
        }
        argnum = 1
        sa_avail = 16376
        sa_count = {
          bytes = 1216
        }
        varlist = XIL(0)
        varlist_len = 1
        nvars = 1
#32 0x00000000006bbaf0 in eval_sub (form=XIL(0x7ffff3385883)) at eval.c:2526
        args_left = XIL(0x7ffff3385893)
        numargs = 2
        original_fun = XIL(0xc150)
        original_args = XIL(0x7ffff3385893)
        count = {
          bytes = 1184
        }
        fun = XIL(0xe97c05)
        val = XIL(0x7ffff3385833)
        funcar = make_fixnum(29)
        argvals = {make_fixnum(1757858), XIL(0x30), XIL(0x7fffffffc020), make_fixnum(1764833), XIL(0), XIL(0x30), XIL(0x7fff00ffbf20), XIL(0)}
#33 0x00000000006b6b28 in Fprogn (body=XIL(0)) at eval.c:430
        form = XIL(0x7ffff3385883)
        val = XIL(0x7ffff3385833)
#34 0x00000000006b6b58 in prog_ignore (body=XIL(0x7ffff339fba3)) at eval.c:441
#35 0x00000000006b8723 in Fwhile (args=XIL(0x7ffff339fbb3)) at eval.c:1121
        test = XIL(0x30)
        body = XIL(0x7ffff339fba3)
#36 0x00000000006bbaf0 in eval_sub (form=XIL(0x7ffff339fbc3)) at eval.c:2526
        args_left = XIL(0x7ffff339fbb3)
        numargs = 3
        original_fun = XIL(0x7ffff1502160)
        original_args = XIL(0x7ffff339fbb3)
        count = {
          bytes = 1152
        }
        fun = XIL(0xe97c45)
        val = XIL(0)
        funcar = XIL(0x7ffff3385853)
        argvals = {XIL(0x9), make_fixnum(0), XIL(0), XIL(0), XIL(0x7fffffffc200), XIL(0x7ffff33a80a7), XIL(0x7fffffffc210), make_fixnum(1764808)}
#37 0x00000000006b6b28 in Fprogn (body=XIL(0)) at eval.c:430
        form = XIL(0x7ffff339fbc3)
        val = XIL(0)
#38 0x00000000006b86bb in Flet (args=XIL(0x7ffff3385853)) at eval.c:1100
        temps = 0x7fffffffc1e0
        tem = make_fixnum(0)
        lexenv = XIL(0)
        elt = XIL(0x7ffff33a0553)
        count = {
          bytes = 1120
        }
        argnum = 1
        sa_avail = 16376
        sa_count = {
          bytes = 1120
        }
        varlist = XIL(0)
        varlist_len = 1
        nvars = 1
#39 0x00000000006bbaf0 in eval_sub (form=XIL(0x7ffff3385843)) at eval.c:2526
        args_left = XIL(0x7ffff3385853)
        numargs = 2
        original_fun = XIL(0xc150)
        original_args = XIL(0x7ffff3385853)
        count = {
          bytes = 1088
        }
        fun = XIL(0xe97c05)
        val = XIL(0x30)
        funcar = XIL(0x7fffffffc370)
        argvals = {make_fixnum(0), XIL(0x7ffff29ec62d), XIL(0x7fffffffc2f0), XIL(0x6f77a4), XIL(0x6f777f), XIL(0x7ffff283de85), XIL(0x7fffffffc340), XIL(0xb370)}
#40 0x00000000006fd318 in readevalloop_eager_expand_eval (val=XIL(0x7ffff33a0563), macroexpand=XIL(0xb370)) at lread.c:2355
#41 0x00000000006fdb82 in readevalloop
    (readcharfun=XIL(0x174460d), infile0=0x0, sourcename=XIL(0x132d034), printflag=false, unibyte=XIL(0), readfun=XIL(0), start=XIL(0), end=XIL(0))
    at lread.c:2537
        count1 = {
          bytes = 1088
        }
        c = 40
        val = XIL(0x7ffff33a0563)
        count = {
          bytes = 928
        }
        b = 0x1744608
        continue_reading_p = true
        lex_bound = XIL(0)
        whole_buffer = true
        first_sexp = false
        macroexpand = XIL(0xb370)
#42 0x00000000006fded1 in Feval_buffer (buffer=XIL(0x174460d), printflag=XIL(0), filename=XIL(0x132d034), unibyte=XIL(0), do_allow_print=XIL(0x30))
    at lread.c:2612
        count = {
          bytes = 800
        }
        tem = XIL(0)
        buf = XIL(0x174460d)
#43 0x00000000006bd728 in funcall_subr (subr=0xe9ae40 <Seval_buffer>, numargs=5, args=0x7fffe3fff290) at eval.c:3146
        argbuf = {XIL(0x1f2300f08), XIL(0xffffffffffffffff), XIL(0xf12ca0), XIL(0x300), XIL(0x7fffffffc6c0), make_fixnum(19329211838), XIL(0xe9ae45), XIL(0x7fffffffc6e0)}
        a = 0x7fffe3fff290
        maxargs = 5
        fun = XIL(0xe9ae45)
#44 0x00000000007188c6 in exec_byte_code (fun=XIL(0x7ffff23a51fd), args_template=257, nargs=1, args=0x7fffe3fff298) at bytecode.c:813
        call_nargs = 5
        call_fun = XIL(0xe9ae45)
        count1 = {
          bytes = 768
        }
        val = XIL(0)
        call_args = 0x7fffe3fff290
        original_fun = XIL(0x7ffff15069e8)
        op = 5
        type = 1801675106
        targets = {0x71c0f0 <exec_byte_code+17688>, 0x71c113 <exec_byte_code+17723>, 0x71c115 <exec_byte_code+17725>, 0x71c117 <exec_byte_code+17727>, 0x71c119 <exec_byte_code+17729>, 0x71c119 <exec_byte_code+17729>, 0x71c173 <exec_byte_code+17819>, 0x71c1dc <exec_byte_code+17924>, 0x7180b9 <exec_byte_code+1249>, 0x7180bb <exec_byte_code+1251>, 0x7180bd <exec_byte_code+1253>, 0x7180bf <exec_byte_code+1255>, 0x7180c1 <exec_byte_code+1257>, 0x7180c1 <exec_byte_code+1257>, 0x7180c7 <exec_byte_code+1263>, 0x718088 <exec_byte_code+1200>, 0x718438 <exec_byte_code+2144>, 0x71843a <exec_byte_code+2146>, 0x71843c <exec_byte_code+2148>, 0x71843e <exec_byte_code+2150>, 0x718440 <exec_byte_code+2152>, 0x718440 <exec_byte_code+2152>, 0x718475 <exec_byte_code+2205>, 0x718446 <exec_byte_code+2158>, 0x71860c <exec_byte_code+2612>, 0x71860e <exec_byte_code+2614>, 0x718610 <exec_byte_code+2616>, 0x718612 <exec_byte_code+2618>, 0x718614 <exec_byte_code+2620>, 0x718614 <exec_byte_code+2620>, 0x7185c6 <exec_byte_code+2542>, 0x7185dd <exec_byte_code+2565>, 0x7186b6 <exec_byte_code+2782>, 0x7186b8 <exec_byte_code+2784>, 0x7186ba <exec_byte_code+2786>, 0x7186bc <exec_byte_code+2788>, 0x7186be <exec_byte_code+2790>, 0x7186be <exec_byte_code+2790>, 0x718670 <exec_byte_code+2712>, 0x718687 <exec_byte_code+2735>, 0x7189e0 <exec_byte_code+3592>, 0x7189e2 <exec_byte_code+3594>, 0x7189e4 <exec_byte_code+3596>, 0x7189e6 <exec_byte_code+3598>, 0x7189e8 <exec_byte_code+3600>, 0x7189e8 <exec_byte_code+3600>, 0x71899a <exec_byte_code+3522>, 0x7189b1 <exec_byte_code+3545>, 0x7191c9 <exec_byte_code+5617>, 0x718fdc <exec_byte_code+5124>, 0x718fd3 <exec_byte_code+5115>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7193d3 <exec_byte_code+6139>, 0x71954f <exec_byte_code+6519>, 0x7195a6 <exec_byte_code+6606>, 0x7195fb <exec_byte_code+6691>, 0x719652 <exec_byte_code+6778>, 0x7182ba <exec_byte_code+1762>, 0x718331 <exec_byte_code+1881>, 0x7196c0 <exec_byte_code+6888>, 0x718211 <exec_byte_code+1593>, 0x71838e <exec_byte_code+1974>, 0x71971d <exec_byte_code+6981>, 0x71977a <exec_byte_code+7074>, 0x7197b7 <exec_byte_code+7135>, 0x719814 <exec_byte_code+7228>, 0x71986f <exec_byte_code+7319>, 0x719942 <exec_byte_code+7530>, 0x71997f <exec_byte_code+7591>, 0x719b1f <exec_byte_code+8007>, 0x719cea <exec_byte_code+8466>, 0x719d27 <exec_byte_code+8527>, 0x719d64 <exec_byte_code+8588>, 0x719dc1 <exec_byte_code+8681>, 0x719e1e <exec_byte_code+8774>, 0x719e7b <exec_byte_code+8867>, 0x719ef5 <exec_byte_code+8989>, 0x719f39 <exec_byte_code+9057>, 0x719f7d <exec_byte_code+9125>, 0x71a031 <exec_byte_code+9305>, 0x71a11b <exec_byte_code+9539>, 0x71a205 <exec_byte_code+9773>, 0x71a2e1 <exec_byte_code+9993>, 0x71a3d0 <exec_byte_code+10232>, 0x71a4bf <exec_byte_code+10471>, 0x71a5ae <exec_byte_code+10710>, 0x71a69d <exec_byte_code+10949>, 0x71a813 <exec_byte_code+11323>, 0x71a8fe <exec_byte_code+11558>, 0x71aa71 <exec_byte_code+11929>, 0x71ab2c <exec_byte_code+12116>, 0x71abe7 <exec_byte_code+12303>, 0x71b04e <exec_byte_code+13430>, 0x718e8e <exec_byte_code+4790>, 0x71b09e <exec_byte_code+13510>, 0x71b0db <exec_byte_code+13571>, 0x71b18a <exec_byte_code+13746>, 0x71b1da <exec_byte_code+13826>, 0x71b22a <exec_byte_code+13906>, 0x71b267 <exec_byte_code+13967>, 0x71b29f <exec_byte_code+14023>, 0x71b2d7 <exec_byte_code+14079>, 0x71b317 <exec_byte_code+14143>, 0x71c0f0 <exec_byte_code+17688>, 0x71b364 <exec_byte_code+14220>, 0x71b39c <exec_byte_code+14276>, 0x71b3d4 <exec_byte_code+14332>, 0x71b40c <exec_byte_code+14388>, 0x71b444 <exec_byte_code+14444>, 0x71b47c <exec_byte_code+14500>, 0x718e8e <exec_byte_code+4790>, 0x71c0f0 <exec_byte_code+17688>, 0x71b4b9 <exec_byte_code+14561>, 0x71b4fe <exec_byte_code+14630>, 0x71b53b <exec_byte_code+14691>, 0x71b578 <exec_byte_code+14752>, 0x71b5d5 <exec_byte_code+14845>, 0x71b632 <exec_byte_code+14938>, 0x71b66f <exec_byte_code+14999>, 0x71b6ac <exec_byte_code+15060>, 0x71b709 <exec_byte_code+15153>, 0x71b766 <exec_byte_code+15246>, 0x71b7c3 <exec_byte_code+15339>, 0x71b7fb <exec_byte_code+15395>, 0x71c0f0 <exec_byte_code+17688>, 0x718dee <exec_byte_code+4630>, 0x718a43 <exec_byte_code+3691>, 0x71818a <exec_byte_code+1458>, 0x718add <exec_byte_code+3845>, 0x718b56 <exec_byte_code+3966>, 0x718bcc <exec_byte_code+4084>, 0x718c42 <exec_byte_code+4202>, 0x718dc2 <exec_byte_code+4586>, 0x71857e <exec_byte_code+2470>, 0x718e62 <exec_byte_code+4746>, 0x718eba <exec_byte_code+4834>, 0x718f3b <exec_byte_code+4963>, 0x718f74 <exec_byte_code+5020>, 0x71920a <exec_byte_code+5682>, 0x719278 <exec_byte_code+5792>, 0x7192f2 <exec_byte_code+5914>, 0x71934d <exec_byte_code+6005>, 0x71c0f0 <exec_byte_code+17688>, 0x71b838 <exec_byte_code+15456>, 0x71b8b2 <exec_byte_code+15578>, 0x71b8ef <exec_byte_code+15639>, 0x71b92c <exec_byte_code+15700>, 0x71b969 <exec_byte_code+15761>, 0x71b9a6 <exec_byte_code+15822>, 0x71ba03 <exec_byte_code+15915>, 0x71ba60 <exec_byte_code+16008>, 0x71babd <exec_byte_code+16101>, 0x71bb1a <exec_byte_code+16194>, 0x71bcab <exec_byte_code+16595>, 0x71bd08 <exec_byte_code+16688>, 0x71bd65 <exec_byte_code+16781>, 0x71bda2 <exec_byte_code+16842>, 0x71be93 <exec_byte_code+17083>, 0x71bf84 <exec_byte_code+17324>, 0x71bfc1 <exec_byte_code+17385>, 0x71bffe <exec_byte_code+17446>, 0x71ad71 <exec_byte_code+12697>, 0x71af04 <exec_byte_code+13100>, 0x71c042 <exec_byte_code+17514>, 0x71c099 <exec_byte_code+17601>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7198d2 <exec_byte_code+7418>, 0x719fc1 <exec_byte_code+9193>, 0x71b11a <exec_byte_code+13634>, 0x71c260 <exec_byte_code+18056>, 0x71c2ca <exec_byte_code+18162>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c351 <exec_byte_code+18297>, 0x71c3cd <exec_byte_code+18421>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c580 <exec_byte_code+18856> <repeats 64 times>}
        quitcounter = 1 '\001'
        bc = 0xe87fd0 <main_thread+496>
        top = 0x7fffe3fff288
        pc = 0x7ffff2c7b504 "\210.\006\266\005\334\006\b!\210\004\204", <incomplete sequence \335>
        bytestr = XIL(0x7ffff231dd24)
        vector = XIL(0x7ffff23a524d)
        maxdepth = make_fixnum(4)
        const_length = 3
        bytestr_length = 7
        vectorp = 0x7ffff26cf120
        max_stack = 4
        frame_base = 0x7fffe3fff2d8
        fp = 0x7fffe3fff2f8
        bytestr_data = 0x7ffff2c7b44d "\306\005!\204\023"
        rest = false
        mandatory = 1
        nonrest = 1
        pushedargs = 1
        saved_quitcounter = 0 '\000'
        saved_vectorp = 0x30
        saved_bytestr_data = 0xf12c70 <lispsym+48> <incomplete sequence \310>
        result = XIL(0x664698)
#45 0x00000000006bdca1 in funcall_lambda (fun=XIL(0x7ffff26cf0cd), nargs=4, arg_vector=0x7fffffffcdc8) at eval.c:3229
        syms_left = make_fixnum(1282)
        lexenv = XIL(0x7ffff26cf0cd)
        count = {
          bytes = 2891346283121877002
        }
        i = 137195406424
        optional = false
        rest = false
        previous_rest = 127
        val = XIL(0x69488f)
#46 0x00000000006bd09b in funcall_general (fun=XIL(0x7ffff26cf0cd), numargs=4, args=0x7fffffffcdc8) at eval.c:3021
        original_fun = XIL(0x7ffff17bc458)
#47 0x00000000006bd34a in Ffuncall (nargs=5, args=0x7fffffffcdc0) at eval.c:3070
        count = {
          bytes = 512
        }
        val = XIL(0x7fffffffccf0)
#48 0x00000000006fb809 in Fload (file=XIL(0x11e4824), noerror=XIL(0), nomessage=XIL(0x30), nosuffix=XIL(0), must_suffix=XIL(0)) at lread.c:1615
        val = XIL(0x3e8)
        stream = 0x0
        fd = 8
        fd_index = {
          bytes = 352
        }
        count = {
          bytes = 352
        }
        found = XIL(0x132d034)
        efound = XIL(0x3e8000081a4)
        hist_file_name = XIL(0x132d034)
        newer = false
        compiled = false
        handler = XIL(0)
        fmode = 0x810366 "r"
        version = 0
        no_native = false
        is_module = false
        is_native_elisp = false
        found_eff = XIL(0x132d034)
        is_elc = false
        input = {
          stream = 0x0,
          lookahead = 64 '@',
          buf = "\263\361\000"
        }
#49 0x00000000006bd728 in funcall_subr (subr=0xe9adc0 <Sload>, numargs=3, args=0x7fffe3fff1b0) at eval.c:3146
        argbuf = {XIL(0x11e4824), XIL(0), XIL(0x30), XIL(0), XIL(0), make_fixnum(19329211838), XIL(0xe9adc5), XIL(0x7fffffffd010)}
        a = 0x7fffffffcfc0
        maxargs = 5
        fun = XIL(0xe9adc5)
#50 0x00000000007188c6 in exec_byte_code (fun=XIL(0x7ffff28a0895), args_template=769, nargs=3, args=0x7fffe3fff3f0) at bytecode.c:813
        call_nargs = 3
        call_fun = XIL(0xe9adc5)
        count1 = {
          bytes = 320
        }
        val = XIL(0x30)
        call_args = 0x7fffe3fff1b0
        original_fun = XIL(0xc5a0)
        op = 3
        type = CONDITION_CASE
        targets = {0x71c0f0 <exec_byte_code+17688>, 0x71c113 <exec_byte_code+17723>, 0x71c115 <exec_byte_code+17725>, 0x71c117 <exec_byte_code+17727>, 0x71c119 <exec_byte_code+17729>, 0x71c119 <exec_byte_code+17729>, 0x71c173 <exec_byte_code+17819>, 0x71c1dc <exec_byte_code+17924>, 0x7180b9 <exec_byte_code+1249>, 0x7180bb <exec_byte_code+1251>, 0x7180bd <exec_byte_code+1253>, 0x7180bf <exec_byte_code+1255>, 0x7180c1 <exec_byte_code+1257>, 0x7180c1 <exec_byte_code+1257>, 0x7180c7 <exec_byte_code+1263>, 0x718088 <exec_byte_code+1200>, 0x718438 <exec_byte_code+2144>, 0x71843a <exec_byte_code+2146>, 0x71843c <exec_byte_code+2148>, 0x71843e <exec_byte_code+2150>, 0x718440 <exec_byte_code+2152>, 0x718440 <exec_byte_code+2152>, 0x718475 <exec_byte_code+2205>, 0x718446 <exec_byte_code+2158>, 0x71860c <exec_byte_code+2612>, 0x71860e <exec_byte_code+2614>, 0x718610 <exec_byte_code+2616>, 0x718612 <exec_byte_code+2618>, 0x718614 <exec_byte_code+2620>, 0x718614 <exec_byte_code+2620>, 0x7185c6 <exec_byte_code+2542>, 0x7185dd <exec_byte_code+2565>, 0x7186b6 <exec_byte_code+2782>, 0x7186b8 <exec_byte_code+2784>, 0x7186ba <exec_byte_code+2786>, 0x7186bc <exec_byte_code+2788>, 0x7186be <exec_byte_code+2790>, 0x7186be <exec_byte_code+2790>, 0x718670 <exec_byte_code+2712>, 0x718687 <exec_byte_code+2735>, 0x7189e0 <exec_byte_code+3592>, 0x7189e2 <exec_byte_code+3594>, 0x7189e4 <exec_byte_code+3596>, 0x7189e6 <exec_byte_code+3598>, 0x7189e8 <exec_byte_code+3600>, 0x7189e8 <exec_byte_code+3600>, 0x71899a <exec_byte_code+3522>, 0x7189b1 <exec_byte_code+3545>, 0x7191c9 <exec_byte_code+5617>, 0x718fdc <exec_byte_code+5124>, 0x718fd3 <exec_byte_code+5115>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7193d3 <exec_byte_code+6139>, 0x71954f <exec_byte_code+6519>, 0x7195a6 <exec_byte_code+6606>, 0x7195fb <exec_byte_code+6691>, 0x719652 <exec_byte_code+6778>, 0x7182ba <exec_byte_code+1762>, 0x718331 <exec_byte_code+1881>, 0x7196c0 <exec_byte_code+6888>, 0x718211 <exec_byte_code+1593>, 0x71838e <exec_byte_code+1974>, 0x71971d <exec_byte_code+6981>, 0x71977a <exec_byte_code+7074>, 0x7197b7 <exec_byte_code+7135>, 0x719814 <exec_byte_code+7228>, 0x71986f <exec_byte_code+7319>, 0x719942 <exec_byte_code+7530>, 0x71997f <exec_byte_code+7591>, 0x719b1f <exec_byte_code+8007>, 0x719cea <exec_byte_code+8466>, 0x719d27 <exec_byte_code+8527>, 0x719d64 <exec_byte_code+8588>, 0x719dc1 <exec_byte_code+8681>, 0x719e1e <exec_byte_code+8774>, 0x719e7b <exec_byte_code+8867>, 0x719ef5 <exec_byte_code+8989>, 0x719f39 <exec_byte_code+9057>, 0x719f7d <exec_byte_code+9125>, 0x71a031 <exec_byte_code+9305>, 0x71a11b <exec_byte_code+9539>, 0x71a205 <exec_byte_code+9773>, 0x71a2e1 <exec_byte_code+9993>, 0x71a3d0 <exec_byte_code+10232>, 0x71a4bf <exec_byte_code+10471>, 0x71a5ae <exec_byte_code+10710>, 0x71a69d <exec_byte_code+10949>, 0x71a813 <exec_byte_code+11323>, 0x71a8fe <exec_byte_code+11558>, 0x71aa71 <exec_byte_code+11929>, 0x71ab2c <exec_byte_code+12116>, 0x71abe7 <exec_byte_code+12303>, 0x71b04e <exec_byte_code+13430>, 0x718e8e <exec_byte_code+4790>, 0x71b09e <exec_byte_code+13510>, 0x71b0db <exec_byte_code+13571>, 0x71b18a <exec_byte_code+13746>, 0x71b1da <exec_byte_code+13826>, 0x71b22a <exec_byte_code+13906>, 0x71b267 <exec_byte_code+13967>, 0x71b29f <exec_byte_code+14023>, 0x71b2d7 <exec_byte_code+14079>, 0x71b317 <exec_byte_code+14143>, 0x71c0f0 <exec_byte_code+17688>, 0x71b364 <exec_byte_code+14220>, 0x71b39c <exec_byte_code+14276>, 0x71b3d4 <exec_byte_code+14332>, 0x71b40c <exec_byte_code+14388>, 0x71b444 <exec_byte_code+14444>, 0x71b47c <exec_byte_code+14500>, 0x718e8e <exec_byte_code+4790>, 0x71c0f0 <exec_byte_code+17688>, 0x71b4b9 <exec_byte_code+14561>, 0x71b4fe <exec_byte_code+14630>, 0x71b53b <exec_byte_code+14691>, 0x71b578 <exec_byte_code+14752>, 0x71b5d5 <exec_byte_code+14845>, 0x71b632 <exec_byte_code+14938>, 0x71b66f <exec_byte_code+14999>, 0x71b6ac <exec_byte_code+15060>, 0x71b709 <exec_byte_code+15153>, 0x71b766 <exec_byte_code+15246>, 0x71b7c3 <exec_byte_code+15339>, 0x71b7fb <exec_byte_code+15395>, 0x71c0f0 <exec_byte_code+17688>, 0x718dee <exec_byte_code+4630>, 0x718a43 <exec_byte_code+3691>, 0x71818a <exec_byte_code+1458>, 0x718add <exec_byte_code+3845>, 0x718b56 <exec_byte_code+3966>, 0x718bcc <exec_byte_code+4084>, 0x718c42 <exec_byte_code+4202>, 0x718dc2 <exec_byte_code+4586>, 0x71857e <exec_byte_code+2470>, 0x718e62 <exec_byte_code+4746>, 0x718eba <exec_byte_code+4834>, 0x718f3b <exec_byte_code+4963>, 0x718f74 <exec_byte_code+5020>, 0x71920a <exec_byte_code+5682>, 0x719278 <exec_byte_code+5792>, 0x7192f2 <exec_byte_code+5914>, 0x71934d <exec_byte_code+6005>, 0x71c0f0 <exec_byte_code+17688>, 0x71b838 <exec_byte_code+15456>, 0x71b8b2 <exec_byte_code+15578>, 0x71b8ef <exec_byte_code+15639>, 0x71b92c <exec_byte_code+15700>, 0x71b969 <exec_byte_code+15761>, 0x71b9a6 <exec_byte_code+15822>, 0x71ba03 <exec_byte_code+15915>, 0x71ba60 <exec_byte_code+16008>, 0x71babd <exec_byte_code+16101>, 0x71bb1a <exec_byte_code+16194>, 0x71bcab <exec_byte_code+16595>, 0x71bd08 <exec_byte_code+16688>, 0x71bd65 <exec_byte_code+16781>, 0x71bda2 <exec_byte_code+16842>, 0x71be93 <exec_byte_code+17083>, 0x71bf84 <exec_byte_code+17324>, 0x71bfc1 <exec_byte_code+17385>, 0x71bffe <exec_byte_code+17446>, 0x71ad71 <exec_byte_code+12697>, 0x71af04 <exec_byte_code+13100>, 0x71c042 <exec_byte_code+17514>, 0x71c099 <exec_byte_code+17601>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x7198d2 <exec_byte_code+7418>, 0x719fc1 <exec_byte_code+9193>, 0x71b11a <exec_byte_code+13634>, 0x71c260 <exec_byte_code+18056>, 0x71c2ca <exec_byte_code+18162>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c351 <exec_byte_code+18297>, 0x71c3cd <exec_byte_code+18421>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c0f0 <exec_byte_code+17688>, 0x71c580 <exec_byte_code+18856> <repeats 64 times>}
        quitcounter = 126 '~'
        bc = 0xe87fd0 <main_thread+496>
        top = 0x7fffe3fff1a8
        pc = 0x7ffff2d14129 "\266\003\202z\003\353\002\206\n\002\n\211A\022\242!\352\001!\354\001!\357\001!\203\032\002\211\262\002\016A\360\232\203)\002\361\002!\266\004\202z\003\362\002!\266\004\202z\003\334\026B\001\206=\002\n\211A\022\242\262\n\006\t;\204I\002\335\363!\210\364\353\006\v!!\210\202z\003\016A\365\232\204a\002\016A\366\232\203m\002\001\204z\003\n\210\nA\022\202z\003\016A\367\267\202\202\002\370\334!\210\202z\003\371\372!\210\202z\003\324\373\016A\"\203\224\002\005\374\016A!\240\210\202z\003\324\375\016A\"\203\263\002\005\374\330\331\016A\"!\240\210\004\374\330\376\016A\"!\240\210\202z\003\337\003\r\"\211\262\v\203\307\002\006\tA@\n\233"...
        bytestr = XIL(0x7ffff28a0a6c)
        vector = XIL(0x7ffff28a08d5)
        maxdepth = make_fixnum(18)
        const_length = 36
        bytestr_length = 338
        vectorp = 0x7ffff28e9508
        max_stack = 18
        frame_base = 0x7fffe3fff430
        fp = 0x7fffe3fff4c0
        bytestr_data = 0x7ffff2d13f2e "\306 \210\b\203\034"
        rest = false
        mandatory = 1
        nonrest = 3
        pushedargs = 3
        saved_quitcounter = 17 '\021'
        saved_vectorp = 0x7ffff2abf378
        saved_bytestr_data = 0x7ffff2d5342a "\002??\205S\002\b\304p\001\031\305\306\304\"r\211q\210\307\310\002\"\216\006\006c\210eb\210`dW\203N\002`ɉ\211\211g\312U\203\n\002\31317"
        result = XIL(0xf12c40)
#51 0x00000000006bdca1 in funcall_lambda (fun=XIL(0x7ffff28f15ed), nargs=0, arg_vector=0x7fffffffd5a0) at eval.c:3229
        syms_left = make_fixnum(0)
        lexenv = XIL(0x7fffffffd590)
        count = {
          bytes = 140737488344400
        }
        i = 128
        optional = false
        rest = false
        previous_rest = 127
        val = XIL(0x7fffffffd5a0)
#52 0x00000000006bdb38 in apply_lambda (fun=XIL(0x7ffff28f15ed), args=XIL(0), count=...) at eval.c:3192
        arg_vector = 0x7fffffffd5a0
        tem = XIL(0x6b577d)
        sa_avail = 16384
        sa_count = {
          bytes = 160
        }
        numargs = 0
        args_left = XIL(0)
#53 0x00000000006bc069 in eval_sub (form=XIL(0x7ffff2ab1e2b)) at eval.c:2622
        original_fun = XIL(0x7ffff19de978)
        original_args = XIL(0)
        count = {
          bytes = 128
        }
        fun = XIL(0x7ffff28f15ed)
        val = XIL(0)
        funcar = make_fixnum(1757858)
        argvals = {XIL(0x7fffffffd6d0), XIL(0x698440), XIL(0x1f2ad3d68), XIL(0), XIL(0x7ffff283c1bb), XIL(0xb340), XIL(0x69488f), XIL(0x7ffff2ad3d68)}
#54 0x00000000006bb59c in Feval (form=XIL(0x7ffff2ab1e2b), lexical=XIL(0x30)) at eval.c:2439
        count = {
          bytes = 96
        }
#55 0x00000000005e201f in top_level_2 () at keyboard.c:1179
        setup_handler = false
        res = XIL(0x100000000)
#56 0x00000000006b960b in internal_condition_case (bfun=0x5e1fb8 <top_level_2>, handlers=XIL(0x90), hfun=0x5e1890 <cmd_error>) at eval.c:1598
        val = XIL(0x5de865)
        c = 0xfcf530
#57 0x00000000005e207a in top_level_1 (ignore=XIL(0)) at keyboard.c:1191
#58 0x00000000006b8acf in internal_catch (tag=XIL(0x12360), func=0x5e2038 <top_level_1>, arg=XIL(0)) at eval.c:1277
        val = XIL(0x7fffffffd890)
        c = 0xfcf3f0
#59 0x00000000005e1f02 in command_loop () at keyboard.c:1140
#60 0x00000000005e1369 in recursive_edit_1 () at keyboard.c:749
        count = {
          bytes = 32
        }
        val = XIL(0x6bec4c)
#61 0x00000000005e157c in Frecursive_edit () at keyboard.c:832
        count = {
          bytes = 0
        }
        buffer = XIL(0)
#62 0x00000000005dd1d1 in main (argc=4, argv=0x7fffffffdba8) at emacs.c:2624
        stack_bottom_variable = 0x7ffff6219080
        old_argc = 4
        dump_file = 0x0
        no_loadup = false
        junk = 0x0
        dname_arg = 0x0
        ch_to_dir = 0x0
        original_pwd = 0x0
        dump_mode = 0x0
        skip_args = 0
        temacs = 0x0
        attempt_load_pdump = true
        only_version = false
        rlim = {
          rlim_cur = 10022912,
          rlim_max = 18446744073709551615
        }
        lc_all = 0x0
        sockfd = -1
        module_assertions = false

Lisp Backtrace:
"redisplay_internal (C function)" (0x0)
"redisplay" (0xe3fff2f0)
"sit-for" (0xffffb810)
"let" (0xffffbb30)
"while" (0xffffbd00)
"let" (0xffffbf20)
"while" (0xffffc0f0)
"let" (0xffffc310)
"eval-buffer" (0xe3fff290)
"load-with-code-conversion" (0xffffcdc8)
"load" (0xe3fff1b0)
"command-line-1" (0xe3fff0b8)
"command-line" (0xe3fff040)
"normal-top-level" (0xffffd5a0)


diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..52149ebd6b2 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
   ASET (Vfontset_table, face->fontset, Qnil);
-  if (face->fontset < next_fontset_id)
-    next_fontset_id = face->fontset;
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
@@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
       eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       eassert (f == XFRAME (FONTSET_FRAME (fontset)));
       ASET (Vfontset_table, id, Qnil);
-      if (id < next_fontset_id)
-	next_fontset_id = face->fontset;
     }
   face->fontset = -1;
 }
@@ -1000,6 +996,7 @@ face_for_char (struct frame *f, struct face *face, int c,
      and display it as "glyphless".  That is certainly better than
      violating the assertion below or crashing when assertions are not
      compiled in.  */
+  fprintf (stderr, "fontset %d used for face %p\n", face->fontset, face);
   if (face->fontset < 0 && !face->font)
     return face->id;
 
diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..7cab3b9b28c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4576,6 +4576,7 @@ make_realized_face (Lisp_Object *attr)
 {
   enum { off = offsetof (struct face, id) };
   struct face *face = xmalloc (sizeof *face);
+  printf ("allocated %p\n", face);
 
   memcpy (face->lface, attr, sizeof face->lface);
   memset (&face->id, 0, sizeof *face - off);
@@ -4598,7 +4599,24 @@ free_realized_face (struct frame *f, struct face *face)
 	{
 	  /* Free fontset of FACE if it is ASCII face.  */
 	  if (face->fontset >= 0 && face == face->ascii_face)
-	    free_face_fontset (f, face);
+	    {
+	      struct face_cache *cache = FRAME_FACE_CACHE (f);
+	      if (cache)
+		{
+		  for (int i = 0; i < cache->used; i++)
+		    {
+		      struct face *face2 = cache->faces_by_id[i];
+		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
+			{
+			  fprintf (stderr, "Freeing fontset %d that's still in use by %p!\n", face->fontset,
+				   face2);
+			}
+		    }
+		}
+	      free_face_fontset (f, face);
+	    }
+	  else
+	    fprintf (stderr, "fontset %d not freed, used by %p\n", face->fontset, face);
 
 #ifdef HAVE_X_WINDOWS
 	  /* This function might be called with the frame's display
@@ -4627,6 +4645,7 @@ free_realized_face (struct frame *f, struct face *face)
 #ifdef HAVE_X_WINDOWS
     free_face:
 #endif /* HAVE_X_WINDOWS */
+      printf ("freeing %p\n", face);
       xfree (face);
     }
 }

That change, by the way, produces many pairs of lines such as these:

freeing 0x105f020
allocated 0x105f020
freeing 0x10209a0
allocated 0x10209a0
freeing 0x1224350
allocated 0x1224350
freeing 0x1191950
allocated 0x1191950

which indicates that malloc() does indeed return the freed block for the
next allocation.

Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-18 18:38                             ` Eli Zaretskii
@ 2024-08-19  6:28                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-19 11:30                                 ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19  6:28 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

> Here's one data point: this kind of problem has never, NEVER happened
> to me, although I display non-ASCII text in my Emacs sessions quite a
> lot.  So if what you describe is so trivially easy to trigger, how
> come it didn't happen to me, in all the years I'm using this code?

It isn't trivially easy to trigger at all! To trigger it reliably, you
need to:

* apply the patch so we don't reuse fontset table entries, which
  otherwise hides the bug
* modify the mode line to use two new non-ASCII faces, at once, by
  inserting two characters provided by different fonts
* modify the right frame parameter (such as alpha-background) so that
  the basic faces are re-realized ('free_realized_face' is called for
  them), but 'free_realized_faces' is not.
* be unlucky in your choice of malloc implementation

> There has to be more to this than meets the eye, and we can only
> figure this out if you provide all the missing details.

I don't think there is, at this point, but I'm happy to investigate
further to gain some confidence about that.

In particular, I'd like to understand why we need to use two non-ASCII
faces at once.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19  6:28                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-19 11:30                                 ` Eli Zaretskii
  2024-08-19 13:32                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-19 11:30 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Mon, 19 Aug 2024 06:28:32 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > Here's one data point: this kind of problem has never, NEVER happened
> > to me, although I display non-ASCII text in my Emacs sessions quite a
> > lot.  So if what you describe is so trivially easy to trigger, how
> > come it didn't happen to me, in all the years I'm using this code?
> 
> It isn't trivially easy to trigger at all! To trigger it reliably, you
> need to:
> 
> * apply the patch so we don't reuse fontset table entries, which
>   otherwise hides the bug

But the OP didn't use that patch.  And your description sounded like
the problem could happen quite frequently even without that patch.

> * modify the mode line to use two new non-ASCII faces, at once, by
>   inserting two characters provided by different fonts

Why does it have to be the mode line? why not buffer text?  Mixing
different fonts (i.e. non-ASCII faces) in the same buffer is quite
common in Emacs; e.g., try "C-h h".

Also, why do we need more than one non-ASCII face to trigger the
problem?

> * modify the right frame parameter (such as alpha-background) so that
>   the basic faces are re-realized ('free_realized_face' is called for
>   them), but 'free_realized_faces' is not.

Basic faces are routinely freed and re-realized whenever we start the
display iteration, see init_iterator.  AFAIR, all you need to do for
that is to customize some face -- doing so sets the face_change flag,
and init_iterator will then normally free all the faces and realize
them again.

> * be unlucky in your choice of malloc implementation

"Unlucky" in what sense?

And if all the users of GNU/Linux (i.e. glibc) are thus "unlucky",
this still leaves us with many potential victims.

> In particular, I'd like to understand why we need to use two non-ASCII
> faces at once.

Maybe I don't understand the question, but we need a new non-ASCII
face each time we find a character for which existing non-ASCII faces
don't have a glyph.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 11:30                                 ` Eli Zaretskii
@ 2024-08-19 13:32                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-19 14:35                                     ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19 13:32 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 19 Aug 2024 06:28:32 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > Here's one data point: this kind of problem has never, NEVER happened
>> > to me, although I display non-ASCII text in my Emacs sessions quite a
>> > lot.  So if what you describe is so trivially easy to trigger, how
>> > come it didn't happen to me, in all the years I'm using this code?
>>
>> It isn't trivially easy to trigger at all! To trigger it reliably, you
>> need to:
>>
>> * apply the patch so we don't reuse fontset table entries, which
>>   otherwise hides the bug
>
> But the OP didn't use that patch.

Indeed, and got rare (about once a day) crashes, even though they met
all other criteria for them.

> And your description sounded like
> the problem could happen quite frequently even without that patch.

The crashes are infrequent, since we will silently use the wrong fontset
rather than crashing if its ID has been reused.

Using the wrong fontset would be much more common, but lead to very
subtle bugs which I haven't seen (nor am I sure how they would show up).

>> * modify the mode line to use two new non-ASCII faces, at once, by
>>   inserting two characters provided by different fonts
>
> Why does it have to be the mode line?

It doesn't, but that gets us into the murky territory of what is and
isn't the same bug.

> why not buffer text?

Seems to cause the crash as well, via 'realize_default_face'

> Also, why do we need more than one non-ASCII face to trigger the
> problem?

I don't know.  As I said, I'm trying to understand that, but I think
it's a minor detail: we know the crash happens, we can reproduce it
(changing only things that make crashes more likely but shouldn't affect
correctness), we know why it's apparently rare (fontset slot reuse,
malloc() returning a freed face's block, the two non-ASCII-face thing).

>> * modify the right frame parameter (such as alpha-background) so that
>>   the basic faces are re-realized ('free_realized_face' is called for
>>   them), but 'free_realized_faces' is not.
>
> Basic faces are routinely freed and re-realized whenever we start the
> display iteration, see init_iterator.

> AFAIR, all you need to do for
> that is to customize some face -- doing so sets the face_change flag,
> and init_iterator will then normally free all the faces and realize
> them again.

... which won't trigger the bug, because it calls 'free_realized_faces'.
I specifically explained why 'free_realized_face' must be called
directly, not via (or after) 'free_realized_faces', to trigger the bug.

>> * be unlucky in your choice of malloc implementation
>
> "Unlucky" in what sense?

Have a malloc which returns a recently-freed block of appropriate size
for the next allocation.

> And if all the users of GNU/Linux (i.e. glibc) are thus "unlucky",
> this still leaves us with many potential victims.

Indeed, which is why we should fix the bug.

>> In particular, I'd like to understand why we need to use two non-ASCII
>> faces at once.
>
> Maybe I don't understand the question, but we need a new non-ASCII
> face each time we find a character for which existing non-ASCII faces
> don't have a glyph.

I meant why we need at least two non-ASCII faces to trigger the bug.

Here's a reproducer hibiscus.el which uses buffer text:

(while t
  (insert (concat (make-string 1 (floor (random 132000)))))
  (set-frame-parameter nil 'alpha-background 1.0)
  (sit-for 1.0))

It does, however, need at least two characters to crash, so the "why two
non-ASCII faces" problem remains.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19  6:07                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-19 14:17                           ` Eli Zaretskii
  2024-08-19 14:44                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-19 14:17 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Mon, 19 Aug 2024 06:07:35 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > Where do you see this copying in realize_non_ascii_face?
> 
> static struct face *
> realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
> 			struct face *base_face)
> {
>   struct face_cache *cache = FRAME_FACE_CACHE (f);
>   struct face *face;
> 
>   face = xmalloc (sizeof *face);
>   *face = *base_face;
>         ^____ here
> 
> (The entire structure is copied, and fontset isn't explicitly changed
> afterwards).

I need new glasses.

In any case, if you are right, and we free an ASCII face but leave its
non-ASCII variants unchanged, we have a much deeper problem: a
non-ASCII face is meaningless if its ASCII face was freed and
re-realized, because the non-ASCII face needs to be re-realized as
well.  So if this happens, we need to understand how and plug that
much worse problem.

In the cases I was able to reproduce on my system, the call to
realize_basic_faces was followed by setting the frame's 'face_change'
flag, which causes the next redisplay free all the frame's faces and
re-realize all of them.  (But the alpha-background parameter is not
supported here, so I needed to change other attributes.)  As long as
this happens before we try to display anything, the fact that we
uncached the fontset will not cause any harm.  IOW, the fact that the
fontset was freed and uncached in itself is not a catastrophe, as long
as the freed fontset is not accessed before it is regenerated.

So can you show a backtrace from the call to free_realized_faces
(supposedly called by realize_basic_faces?) which causes these
printfs:

> fontset 103 used for face 0x117cca0
> fontset 103 used for face 0x2a7a3c0
> fontset 103 used for face 0x117cca0
> fontset 103 used for face 0x2a62860

Also, could you add to the print-outs the pointer to the face's
ascii_face, so that we see whether there's only one ASCII face
involved here or more than one?





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 13:32                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-19 14:35                                     ` Eli Zaretskii
  2024-08-19 15:03                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-19 14:35 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Mon, 19 Aug 2024 13:32:42 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> >> * modify the right frame parameter (such as alpha-background) so that
> >>   the basic faces are re-realized ('free_realized_face' is called for
> >>   them), but 'free_realized_faces' is not.
> >
> > Basic faces are routinely freed and re-realized whenever we start the
> > display iteration, see init_iterator.
> 
> > AFAIR, all you need to do for
> > that is to customize some face -- doing so sets the face_change flag,
> > and init_iterator will then normally free all the faces and realize
> > them again.
> 
> ... which won't trigger the bug, because it calls 'free_realized_faces'.

Not necessarily.  I show below a backtrace which called
realize_basic_faces and triggered the same freeing of the fontset of
the ASCII face.  This was obtained by changing the color of the
default face via Customize.

> I specifically explained why 'free_realized_face' must be called
> directly, not via (or after) 'free_realized_faces', to trigger the bug.

Any caller of realize_face (and only those, AFAICT) will go that path.
Which is why I asked for a backtrace in your case (since I cannot
reproduce it exactly myself).  As I explained in my other message,
there's potentially a much more serious problem here, if indeed you
are right.

> I meant why we need at least two non-ASCII faces to trigger the bug.

Which bug?  I can trigger freeing the fontset of an ASCII face while
its non-ASCII variants are not freed without having 2 ASCII faces, see
the backtrace below.

> Here's a reproducer hibiscus.el which uses buffer text:
> 
> (while t
>   (insert (concat (make-string 1 (floor (random 132000)))))
>   (set-frame-parameter nil 'alpha-background 1.0)
>   (sit-for 1.0))

Thanks, but this doesn't help me because AFAIK alpha-background is not
supported on Windows.

Here's the backtrace I promised:

#0  realize_face (cache=0x7c73288, attrs=0xbfb8d8, former_face_id=0)
    at xfaces.c:6097
#1  0x00df6b33 in realize_default_face (f=0x7c6bad8) at xfaces.c:6010
#2  0x00df5d73 in realize_basic_faces (f=0x7c6bad8) at xfaces.c:5862
#3  0x00def95a in update_face_from_frame_parameter (f=0x7c6bad8,
    param=XIL(0x8940), new_value=XIL(0x8000000010805bb8)) at xfaces.c:3813
#4  0x00fe70bc in w32_set_foreground_color (f=0x7c6bad8,
    arg=XIL(0x8000000010805bb8), oldval=XIL(0x8000000007c6f740))
    at w32fns.c:1215
#5  0x00cc486a in gui_set_frame_parameters_1 (f=0x7c6bad8, alist=XIL(0),
    default_parameter=false) at frame.c:4400
#6  0x00cc57a2 in gui_set_frame_parameters (f=0x7c6bad8,
    alist=XIL(0xc000000000bfbec0)) at frame.c:4560
#7  0x00cc21fe in Fmodify_frame_parameters (frame=XIL(0xa000000007c6bad8),
    alist=XIL(0xc000000000bfbec0)) at frame.c:3549
#8  0x00def80d in Finternal_set_lisp_face_attribute (face=XIL(0x6480),
    attr=XIL(0x1050), value=XIL(0x8000000010805bb8),
    frame=XIL(0xa000000007c6bad8)) at xfaces.c:3782
#9  0x00effe0e in funcall_subr (
    subr=0x1553600 <Sinternal_set_lisp_face_attribute>, numargs=4,
    args=0x9fa94e8) at eval.c:3167
#10 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa0000000094e7eb0),
    args_template=642, nargs=34, args=0xbfc6e8) at bytecode.c:812
#11 0x00f00623 in funcall_lambda (fun=XIL(0xa0000000094e7eb0), nargs=34,
    arg_vector=0xbfc6d8) at eval.c:3252
#12 0x00eff6e9 in funcall_general (fun=XIL(0xa0000000094e7eb0), numargs=34,
    args=0xbfc6d8) at eval.c:3044
#13 0x00effa12 in Ffuncall (nargs=35, args=0xbfc6d0) at eval.c:3093
#14 0x00efeb75 in Fapply (nargs=4, args=0x9fa9460) at eval.c:2765
#15 0x00f001bb in funcall_subr (subr=0x155c180 <Sapply>, numargs=4,
    args=0x9fa9460) at eval.c:3184
#16 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa0000000095c89f0),
    args_template=771, nargs=3, args=0x9fa9420) at bytecode.c:812
#17 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001062d700), nargs=1,
    arg_vector=0xbfcff8) at eval.c:3252
#18 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001062d700), numargs=1,
    args=0xbfcff8) at eval.c:3044
#19 0x00effa12 in Ffuncall (nargs=2, args=0xbfcff0) at eval.c:3093
#20 0x00efe75a in Fapply (nargs=3, args=0xbfcff0) at eval.c:2718
#21 0x00f17ff9 in Fwidget_apply (nargs=2, args=0x9fa92d0) at fns.c:3847
#22 0x00f001bb in funcall_subr (subr=0x155dd00 <Swidget_apply>, numargs=2,
    args=0x9fa92d0) at eval.c:3184
#23 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001069ff18),
    args_template=257, nargs=1, args=0xbfd860) at bytecode.c:812
#24 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001069ff18), nargs=1,
    arg_vector=0xbfd858) at eval.c:3252
#25 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001069ff18), numargs=1,
    args=0xbfd858) at eval.c:3044
#26 0x00effa12 in Ffuncall (nargs=2, args=0xbfd850) at eval.c:3093
#27 0x00f15ac5 in mapcar1 (leni=1, vals=0x0, fn=XIL(0xa00000001069ff18),
    seq=XIL(0xc00000000ef11220)) at fns.c:3346
#28 0x00f16701 in Fmapc (function=XIL(0xa00000001069ff18),
    sequence=XIL(0xc00000000ef11220)) at fns.c:3483
#29 0x00effd5f in funcall_subr (subr=0x155dac0 <Smapc>, numargs=2,
    args=0x9fa9290) at eval.c:3163
#30 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001069feb8),
    args_template=770, nargs=2, args=0x9fa9258) at bytecode.c:812
#31 0x00f00623 in funcall_lambda (fun=XIL(0xa00000001069ff48), nargs=2,
    arg_vector=0xbfe0b8) at eval.c:3252
#32 0x00eff6e9 in funcall_general (fun=XIL(0xa00000001069ff48), numargs=2,
    args=0xbfe0b8) at eval.c:3044
#33 0x00effa12 in Ffuncall (nargs=3, args=0xbfe0b0) at eval.c:3093
#34 0x00efe7a9 in Fapply (nargs=3, args=0xbfe0b0) at eval.c:2722
#35 0x00f17ff9 in Fwidget_apply (nargs=3, args=0x9fa9208) at fns.c:3847
#36 0x00f001bb in funcall_subr (subr=0x155dd00 <Swidget_apply>, numargs=3,
    args=0x9fa9208) at eval.c:3184
#37 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa00000001061b0d0),
    args_template=513, nargs=2, args=0x9fa91c8) at bytecode.c:812
#38 0x00f00623 in funcall_lambda (fun=XIL(0xa0000000106337b0), nargs=1,
    arg_vector=0xbfea50) at eval.c:3252
#39 0x00eff6e9 in funcall_general (fun=XIL(0xa0000000106337b0), numargs=1,
    args=0xbfea50) at eval.c:3044
#40 0x00effa12 in Ffuncall (nargs=2, args=0xbfea48) at eval.c:3093
#41 0x00ef07ca in Ffuncall_interactively (nargs=2, args=0xbfea48)
    at callint.c:250
#42 0x00f001bb in funcall_subr (subr=0x155b840 <Sfuncall_interactively>,
    numargs=2, args=0xbfea48) at eval.c:3184
#43 0x00eff682 in funcall_general (fun=XIL(0xa00000000155b840), numargs=2,
    args=0xbfea48) at eval.c:3040
#44 0x00effa12 in Ffuncall (nargs=3, args=0xbfea40) at eval.c:3093
#45 0x00ef3838 in Fcall_interactively (function=XIL(0x80f0308),
    record_flag=XIL(0), keys=XIL(0xa000000010706cc8)) at callint.c:789
#46 0x00effda7 in funcall_subr (subr=0x155b880 <Scall_interactively>,
    numargs=3, args=0x9fa9078) at eval.c:3165
#47 0x00f6d4f5 in exec_byte_code (fun=XIL(0xa000000009bd6c38),
    args_template=1025, nargs=1, args=0xbff7a0) at bytecode.c:812
#48 0x00f00623 in funcall_lambda (fun=XIL(0xa000000009bd6c38), nargs=1,
    arg_vector=0xbff798) at eval.c:3252
#49 0x00eff6e9 in funcall_general (fun=XIL(0xa000000009bd6c38), numargs=1,
    args=0xbff798) at eval.c:3044
#50 0x00effa12 in Ffuncall (nargs=2, args=0xbff790) at eval.c:3093
#51 0x00e05691 in command_loop_1 () at keyboard.c:1550
#52 0x00efa701 in internal_condition_case (bfun=0xe04aa1 <command_loop_1>,
    handlers=XIL(0x90), hfun=0xe03afa <cmd_error>) at eval.c:1613
#53 0x00e04506 in command_loop_2 (handlers=XIL(0x90)) at keyboard.c:1168
#54 0x00ef9786 in internal_catch (tag=XIL(0x12720),
    func=0xe044cf <command_loop_2>, arg=XIL(0x90)) at eval.c:1292
#55 0x00e04471 in command_loop () at keyboard.c:1146
#56 0x00e0355a in recursive_edit_1 () at keyboard.c:754
#57 0x00e037f8 in Frecursive_edit () at keyboard.c:837
#58 0x00dfe919 in main (argc=2, argv=0x7ce2570) at emacs.c:2635

Lisp Backtrace:
"internal-set-lisp-face-attribute" (0x9fa94e8)
"set-face-attribute" (0xbfc6d8)
"apply" (0x9fa9460)
"face-spec-set-2" (0x9fa9408)
"face-spec-recalc" (0x9fa9398)
"face-spec-set" (0x9fa9328)
"custom-face-set" (0xbfcff8)
"widget-apply" (0x9fa92d0)
0x1069ff18 PVEC_CLOSURE
"mapc" (0x9fa9290)
"custom-command-apply" (0x9fa9248)
"Custom-set" (0xbfe0b8)
"widget-apply" (0x9fa9208)
"widget-apply-action" (0x9fa91b8)
"widget-button--check-and-call-button" (0x9fa9120)
"widget-button-click" (0xbfea50)
"funcall-interactively" (0xbfea48)
"call-interactively" (0x9fa9078)
"command-execute" (0xbff798)

And I wrote a simple GDB script that loops over the cached faces when
free_realized_face is called under conditions that will cause it to
call free_face_fontset, and got this:

  face 0xbcad118(N), fontset 3, ascii 0x10643628
  face 0x1025a7f0(N), fontset 3, ascii 0x10643628
  face 0x101a0f50(N), fontset 3, ascii 0x10643628
  face 0x1016a328(N), fontset 3, ascii 0x10643628
  face 0xc02ed68(N), fontset 3, ascii 0x10643628
  face 0xb9fb020(N), fontset 3, ascii 0x10643628
  face 0xb98fc38(N), fontset 3, ascii 0x10643628
  face 0xb9b1498(N), fontset 3, ascii 0x10643628
  face 0x7c4cd48(N), fontset 3, ascii 0x10643628
  face 0xbcbb350(N), fontset 3, ascii 0x10643628
  face 0x107e5410(N), fontset 3, ascii 0x10643628
  face 0x105ff8e8(N), fontset 3, ascii 0x10643628
  face 0xbcab9f8(N), fontset 3, ascii 0x10643628
  face 0xb9c8cd0(N), fontset 3, ascii 0x10643628
  face 0xb99e470(N), fontset 3, ascii 0x10643628
  face 0xb998d38(N), fontset 3, ascii 0x10643628
  face 0xb97cbd0(N), fontset 3, ascii 0x10643628
  face 0x104ac2b8(N), fontset 3, ascii 0x10643628
  face 0x10167af0(N), fontset 3, ascii 0x10643628
  face 0x10643d30(N), fontset 3, ascii 0x10643628
  face 0x104d0c48(N), fontset 3, ascii 0x10643628
  face 0x107e31b0(N), fontset 3, ascii 0x10643628
  face 0xb949650(N), fontset 3, ascii 0x10643628
  face 0xb949758(N), fontset 3, ascii 0x10643628
  face 0x105403f0(N), fontset 3, ascii 0x10643628
  face 0x105404f8(N), fontset 3, ascii 0x10643628
  face 0x10540600(N), fontset 3, ascii 0x10643628
  face 0x10540708(N), fontset 3, ascii 0x10643628
  face 0x10540810(N), fontset 3, ascii 0x10643628
  face 0x10540918(N), fontset 3, ascii 0x10643628
  face 0x10540a20(N), fontset 3, ascii 0x10643628
  face 0x10540b28(N), fontset 3, ascii 0x10643628
  face 0x104a4fe8(N), fontset 3, ascii 0x10643628
  face 0x104a50f0(N), fontset 3, ascii 0x10643628
  face 0x104a51f8(N), fontset 3, ascii 0x10643628
  face 0x104a5300(N), fontset 3, ascii 0x10643628

The "(N)" part means that this face is not ASCII face (its ASCII
parent is shown by "ascii 0xNNNNN").

Except that in this case the caller sets the frame's 'face_change'
flag, which then frees and all the non-ASCII faces the first time we
call init_iterator.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 14:17                           ` Eli Zaretskii
@ 2024-08-19 14:44                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19 14:44 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 19 Aug 2024 06:07:35 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > Where do you see this copying in realize_non_ascii_face?
>>
>> static struct face *
>> realize_non_ascii_face (struct frame *f, Lisp_Object font_object,
>> 			struct face *base_face)
>> {
>>   struct face_cache *cache = FRAME_FACE_CACHE (f);
>>   struct face *face;
>>
>>   face = xmalloc (sizeof *face);
>>   *face = *base_face;
>>         ^____ here
>>
>> (The entire structure is copied, and fontset isn't explicitly changed
>> afterwards).
>
> I need new glasses.

:-)

> In any case, if you are right, and we free an ASCII face but leave its
> non-ASCII variants unchanged, we have a much deeper problem: a
> non-ASCII face is meaningless if its ASCII face was freed and
> re-realized, because the non-ASCII face needs to be re-realized as
> well.  So if this happens, we need to understand how and plug that
> much worse problem.

Well, that points to an easy fix: keep a doubly-linked list of linked
non-ASCII faces in the ASCII face, and free all of them in one go.

> In the cases I was able to reproduce on my system, the call to
> realize_basic_faces was followed by setting the frame's 'face_change'
> flag, which causes the next redisplay free all the frame's faces and
> re-realize all of them.

If we free all of them, there's no problem.

> (But the alpha-background parameter is not
> supported here, so I needed to change other attributes.)  As long as
> this happens before we try to display anything, the fact that we
> uncached the fontset will not cause any harm.  IOW, the fact that the
> fontset was freed and uncached in itself is not a catastrophe, as long
> as the freed fontset is not accessed before it is regenerated.

At the very least, that needs a very explicit comment explaining that
->ascii_face may point into freed (or, worse, freed-then-allocated)
memory, and under which specific circumstances.

> So can you show a backtrace from the call to free_realized_faces

I think you mean 'free_realized_face'. No 's'. (Not (just) being pedantic
here, but the problem is that 'realize_basic_faces' does not call
'free_realized_faces' but only 'free_realized_face').

> (supposedly called by realize_basic_faces?) which causes these
> printfs:

>> fontset 103 used for face 0x117cca0
>> fontset 103 used for face 0x2a7a3c0
>> fontset 103 used for face 0x117cca0
>> fontset 103 used for face 0x2a62860

(That printf is currently in face_for_char, but I think I understand
what you mean).

> Also, could you add to the print-outs the pointer to the face's
> ascii_face, so that we see whether there's only one ASCII face
> involved here or more than one?

Good idea.  I was going to respond that of course they must be the same
ASCII face, because they share a fontset, but then that's precisely the
bug we're trying to hunt down...


GDB log:

$ gdb --ar ./emacs -Q --load ../hibiscus.el
GNU gdb (Gentoo 15.1 vanilla) 15.1
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://bugs.gentoo.org/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./emacs...
SIGINT is used by the debugger.
Are you sure you want to change it? (y or n) [answered Y; input not from terminal]
DISPLAY = :0.0
TERM = dumb
Breakpoint 1 at 0x5da023: file emacs.c, line 432.
Breakpoint 2 at 0x593ccd: file xterm.c, line 27102.
(gdb) b xfaces.c:6290 if face->fontset == 83
Breakpoint 3 at 0x55d337: file xfaces.c, line 6290.
(gdb) r
Starting program: /home/pip/emacs/src/emacs -Q --load ../hibiscus.el
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
allocated 0xfc4ac0
allocated 0xfc5010
allocated 0xfc5150
allocated 0xfc5290
allocated 0xfc53d0
allocated 0xfc5510
allocated 0xfc58c0
allocated 0xfc5a00
allocated 0xfc6b90
allocated 0xfc6cd0
allocated 0xfc6e10
allocated 0xfc6f50
allocated 0xfc7090
allocated 0xfc71d0
allocated 0xfc7310
allocated 0xfc7450
allocated 0xfc7590
allocated 0xfc76d0
allocated 0xfc7810
[New Thread 0x7fffe3ffe6c0 (LWP 1467)]
[New Thread 0x7fffdbfff6c0 (LWP 1468)]
[New Thread 0x7fffe366e6c0 (LWP 1469)]
[Detaching after fork from child process 1470]
allocated 0x105f020
fontset 3 allocated for face 0x105f020
allocated 0x10209a0
allocated 0xfdb390
allocated 0xfdb4d0
allocated 0x11c4ad0
allocated 0x11c4c10
allocated 0xfdad30
allocated 0xfdae70
allocated 0xfda8d0
allocated 0xfdaa10
allocated 0x115ac20
allocated 0x115ad60
allocated 0x115aea0
allocated 0x1160180
allocated 0x11602c0
allocated 0x1160400
allocated 0x1160540
allocated 0x1269a30
allocated 0x1269b70
[New Thread 0x7fffe1fff6c0 (LWP 1472)]
freeing 0x105f020
allocated 0x105f020
fontset 22 allocated for face 0x105f020
freeing 0x10209a0
allocated 0x10209a0
freeing 0xfdb390
allocated 0xfdb390
freeing 0xfdb4d0
allocated 0xfdb4d0
freeing 0x11c4ad0
allocated 0x11c4ad0
freeing 0x11c4c10
allocated 0x11c4c10
freeing 0xfdad30
allocated 0xfdad30
freeing 0xfdae70
allocated 0xfdae70
freeing 0xfda8d0
allocated 0xfda8d0
freeing 0xfdaa10
allocated 0xfdaa10
freeing 0x115ac20
allocated 0x115ac20
freeing 0x115ad60
allocated 0x115ad60
freeing 0x115aea0
allocated 0x115aea0
freeing 0x1160180
allocated 0x1160180
freeing 0x11602c0
allocated 0x11602c0
freeing 0x1160400
allocated 0x1160400
freeing 0x1160540
allocated 0x1160540
freeing 0x1269a30
allocated 0x1269a30
freeing 0x1269b70
allocated 0x1269b70
[New Thread 0x7fffe15ef6c0 (LWP 1473)]
freeing 0xfc4ac0
freeing 0xfc5010
freeing 0xfc5150
freeing 0xfc5290
freeing 0xfc53d0
freeing 0xfc5510
freeing 0xfc58c0
freeing 0xfc5a00
freeing 0xfc6b90
freeing 0xfc6cd0
freeing 0xfc6e10
freeing 0xfc6f50
freeing 0xfc7090
freeing 0xfc71d0
freeing 0xfc7310
freeing 0xfc7450
freeing 0xfc7590
freeing 0xfc76d0
freeing 0xfc7810
allocated 0xfc53d0
allocated 0xfc5290
allocated 0xfc5150
allocated 0xfc5010
allocated 0xfc4ac0
allocated 0x13cd5b0
allocated 0x13d3af0
allocated 0xfc5510
allocated 0xfc58c0
allocated 0xfc5a00
allocated 0xfc6b90
allocated 0xfc6cd0
allocated 0xfc6e10
allocated 0xfc6f50
allocated 0xfc7090
allocated 0xfc71d0
allocated 0xfc7310
allocated 0xfc7450
allocated 0xfc7590
freeing 0x105f020
freeing 0x10209a0
freeing 0xfdb390
freeing 0xfdb4d0
freeing 0x11c4ad0
freeing 0x11c4c10
freeing 0xfdad30
freeing 0xfdae70
freeing 0xfda8d0
freeing 0xfdaa10
freeing 0x115ac20
freeing 0x115ad60
freeing 0x115aea0
freeing 0x1160180
freeing 0x11602c0
freeing 0x1160400
freeing 0x1160540
freeing 0x1269a30
freeing 0x1269b70
allocated 0xfdad30
fontset 41 allocated for face 0xfdad30
allocated 0x11c4c10
allocated 0x11c4ad0
allocated 0xfdb4d0
allocated 0xfdb390
allocated 0x10209a0
allocated 0x105f020
allocated 0xfdae70
allocated 0xfc76d0
allocated 0xfc7810
allocated 0xfda8d0
allocated 0xfdaa10
allocated 0x1269a30
allocated 0x1269b70
allocated 0x115ac20
allocated 0x115ad60
allocated 0x115aea0
allocated 0x1160180
allocated 0x11602c0
allocated 0x1160400
fontset 60 allocated for face 0x1160400
freeing 0xfdad30
allocated 0xfdad30
fontset 61 allocated for face 0xfdad30
freeing 0xfdad30
freeing 0x11c4c10
freeing 0x11c4ad0
freeing 0xfdb4d0
freeing 0xfdb390
freeing 0x10209a0
freeing 0x105f020
freeing 0xfdae70
freeing 0xfc76d0
freeing 0xfc7810
freeing 0xfda8d0
freeing 0xfdaa10
freeing 0x1269a30
freeing 0x1269b70
freeing 0x115ac20
freeing 0x115ad60
freeing 0x115aea0
freeing 0x1160180
freeing 0x11602c0
freeing 0x1160400
allocated 0x10209a0
fontset 62 allocated for face 0x10209a0
allocated 0xfdb390
allocated 0xfdb4d0
fontset 64 allocated for face 0xfdb4d0
allocated 0x11c4ad0
allocated 0x11c4c10
allocated 0xfdad30
allocated 0x1733a10
allocated 0xfdae70
allocated 0x1706010
allocated 0x105f020
allocated 0x1706bb0
allocated 0x1725720
allocated 0x17310c0
allocated 0x1269a30
allocated 0xfda8d0
allocated 0xfdaa10
allocated 0xfc76d0
allocated 0xfc7810
fontset 79 allocated for face 0xfc7810
allocated 0x1730940
fontset 80 allocated for face 0x1730940
freeing 0xfc53d0
freeing 0xfc5290
freeing 0xfc5150
freeing 0xfc5010
freeing 0xfc4ac0
freeing 0x13cd5b0
freeing 0x13d3af0
freeing 0xfc5510
freeing 0xfc58c0
freeing 0xfc5a00
freeing 0xfc6b90
freeing 0xfc6cd0
freeing 0xfc6e10
freeing 0xfc6f50
freeing 0xfc7090
freeing 0xfc71d0
freeing 0xfc7310
freeing 0xfc7450
freeing 0xfc7590
allocated 0x13d3af0
fontset 81 allocated for face 0x13d3af0
allocated 0x173cfe0
fontset 82 allocated for face 0x173cfe0
freeing 0x10209a0
allocated 0x10209a0

Thread 1 "emacs" hit Breakpoint 3, realize_gui_face (cache=0x12243a0, attrs=0x7fffffffb600) at xfaces.c:6290
6290		  fprintf (stderr, "fontset %d allocated for face %p\n", face->fontset, face);
(gdb) bt
#0  realize_gui_face (cache=0x12243a0, attrs=0x7fffffffb600) at xfaces.c:6290
#1  0x000000000055cc06 in realize_face (cache=0x12243a0, attrs=0x7fffffffb600, former_face_id=0) at xfaces.c:6121
#2  0x000000000055c863 in realize_default_face (f=0x11c38f8) at xfaces.c:6029
#3  0x000000000055bd9b in realize_basic_faces (f=0x11c38f8) at xfaces.c:5881
#4  0x000000000054e61e in recompute_basic_faces (f=0x11c38f8) at xfaces.c:737
#5  0x00000000004447ff in gui_set_alpha_background (f=0x11c38f8, arg=XIL(0x7ffff33a80b7), oldval=XIL(0)) at frame.c:5237
#6  0x00000000005a1a8b in x_set_alpha_background (f=0x11c38f8, arg=XIL(0x7ffff33a80b7), oldval=XIL(0)) at xfns.c:742
#7  0x0000000000441833 in gui_set_frame_parameters_1 (f=0x11c38f8, alist=XIL(0), default_parameter=false) at frame.c:4400
#8  0x000000000044240e in gui_set_frame_parameters (f=0x11c38f8, alist=XIL(0x7ffff33a79c3)) at frame.c:4560
#9  0x000000000043faca in Fmodify_frame_parameters (frame=XIL(0), alist=XIL(0x7ffff33a79c3)) at frame.c:3549
#10 0x00000000006bd69e in funcall_subr (subr=0xe898c0 <Smodify_frame_parameters>, numargs=2, args=0x7fffe3fff2f8) at eval.c:3140
#11 0x00000000007188f3 in exec_byte_code (fun=XIL(0x7ffff235902d), args_template=771, nargs=3, args=0x7fffffffc048) at bytecode.c:813
#12 0x00000000006bdcce in funcall_lambda (fun=XIL(0x7ffff235902d), nargs=3, arg_vector=0x7fffffffc030) at eval.c:3229
#13 0x00000000006bdb65 in apply_lambda (fun=XIL(0x7ffff235902d), args=XIL(0x7ffff33a7ea3), count=...) at eval.c:3192
#14 0x00000000006bc096 in eval_sub (form=XIL(0x7ffff33a7eb3)) at eval.c:2622
#15 0x00000000006b6b55 in Fprogn (body=XIL(0x7ffff33a7e23)) at eval.c:430
#16 0x00000000006b6b85 in prog_ignore (body=XIL(0x7ffff33a7ec3)) at eval.c:441
#17 0x00000000006b8750 in Fwhile (args=XIL(0x7ffff33b07f3)) at eval.c:1121
#18 0x00000000006bbb1d in eval_sub (form=XIL(0x7ffff33b0803)) at eval.c:2526
#19 0x00000000006fd345 in readevalloop_eager_expand_eval (val=XIL(0x7ffff33b0803), macroexpand=XIL(0xb370)) at lread.c:2355
#20 0x00000000006fdbaf in readevalloop
    (readcharfun=XIL(0x175107d), infile0=0x0, sourcename=XIL(0x1368874), printflag=false, unibyte=XIL(0), readfun=XIL(0), start=XIL(0), end=XIL(0))
    at lread.c:2537
#21 0x00000000006fdefe in Feval_buffer (buffer=XIL(0x175107d), printflag=XIL(0), filename=XIL(0x1368874), unibyte=XIL(0), do_allow_print=XIL(0x30))
    at lread.c:2612
#22 0x00000000006bd755 in funcall_subr (subr=0xe9ae40 <Seval_buffer>, numargs=5, args=0x7fffe3fff290) at eval.c:3146
#23 0x00000000007188f3 in exec_byte_code (fun=XIL(0x7ffff23a51fd), args_template=257, nargs=1, args=0x7fffe3fff298) at bytecode.c:813
#24 0x00000000006bdcce in funcall_lambda (fun=XIL(0x7ffff26cf0cd), nargs=4, arg_vector=0x7fffffffcdc8) at eval.c:3229
#25 0x00000000006bd0c8 in funcall_general (fun=XIL(0x7ffff26cf0cd), numargs=4, args=0x7fffffffcdc8) at eval.c:3021
#26 0x00000000006bd377 in Ffuncall (nargs=5, args=0x7fffffffcdc0) at eval.c:3070
#27 0x00000000006fb836 in Fload (file=XIL(0x1368924), noerror=XIL(0), nomessage=XIL(0x30), nosuffix=XIL(0), must_suffix=XIL(0)) at lread.c:1615
#28 0x00000000006bd755 in funcall_subr (subr=0xe9adc0 <Sload>, numargs=3, args=0x7fffe3fff1b0) at eval.c:3146
#29 0x00000000007188f3 in exec_byte_code (fun=XIL(0x7ffff28a0895), args_template=769, nargs=3, args=0x7fffe3fff3f0) at bytecode.c:813
#30 0x00000000006bdcce in funcall_lambda (fun=XIL(0x7ffff28f15ed), nargs=0, arg_vector=0x7fffffffd5a0) at eval.c:3229
#31 0x00000000006bdb65 in apply_lambda (fun=XIL(0x7ffff28f15ed), args=XIL(0), count=...) at eval.c:3192
#32 0x00000000006bc096 in eval_sub (form=XIL(0x7ffff2ab1e2b)) at eval.c:2622
#33 0x00000000006bb5c9 in Feval (form=XIL(0x7ffff2ab1e2b), lexical=XIL(0x30)) at eval.c:2439
#34 0x00000000005e204c in top_level_2 () at keyboard.c:1179
#35 0x00000000006b9638 in internal_condition_case (bfun=0x5e1fe5 <top_level_2>, handlers=XIL(0x90), hfun=0x5e18bd <cmd_error>) at eval.c:1598
#36 0x00000000005e20a7 in top_level_1 (ignore=XIL(0)) at keyboard.c:1191
#37 0x00000000006b8afc in internal_catch (tag=XIL(0x12360), func=0x5e2065 <top_level_1>, arg=XIL(0)) at eval.c:1277
#38 0x00000000005e1f2f in command_loop () at keyboard.c:1140
#39 0x00000000005e1396 in recursive_edit_1 () at keyboard.c:749
#40 0x00000000005e15a9 in Frecursive_edit () at keyboard.c:832
#41 0x00000000005dd1fe in main (argc=4, argv=0x7fffffffdba8) at emacs.c:2624

Lisp Backtrace:
"modify-frame-parameters" (0xe3fff2f8)
"set-frame-parameter" (0xffffc030)
"while" (0xffffc310)
"eval-buffer" (0xe3fff290)
"load-with-code-conversion" (0xffffcdc8)
"load" (0xe3fff1b0)
"command-line-1" (0xe3fff0b8)
"command-line" (0xe3fff040)
"normal-top-level" (0xffffd5a0)
(gdb) c
Continuing.
fontset 83 allocated for face 0x10209a0
freeing 0xfdb390
allocated 0xfdb390
freeing 0xfdb4d0
allocated 0xfdb4d0
fontset 85 allocated for face 0xfdb4d0
freeing 0x11c4ad0
allocated 0x11c4ad0
freeing 0x11c4c10
allocated 0x11c4c10
freeing 0xfdad30
allocated 0xfdad30
freeing 0x1733a10
allocated 0x1733a10
freeing 0xfdae70
allocated 0xfdae70
freeing 0x1706010
allocated 0x1706010
freeing 0x105f020
allocated 0x105f020
freeing 0x1706bb0
allocated 0x1706bb0
freeing 0x1725720
allocated 0x1725720
freeing 0x17310c0
allocated 0x17310c0
freeing 0x1269a30
allocated 0x1269a30
freeing 0xfda8d0
allocated 0xfda8d0
freeing 0xfdaa10
allocated 0xfdaa10
freeing 0xfc76d0
allocated 0xfc76d0
freeing 0xfc7810
allocated 0xfc7810
fontset 100 allocated for face 0xfc7810
freeing 0x1730940
allocated 0xfc5290
fontset 101 allocated for face 0xfc5290
fontset 83 used for face 0x10209a0
[Thread 0x7fffe1fff6c0 (LWP 1472) exited]
allocated 0x124a140
fontset 103 allocated for face 0x124a140
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x2a2b6c0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x2a2b6c0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x10209a0
fontset 83 used for face 0x2a2b6c0
fontset 83 used for face 0x10209a0
Freeing fontset 83 that's still in use by 0x2a2b6c0 (ASCII face 0x10209a0==0x10209a0)!
freeing 0x10209a0
allocated 0x10209a0
fontset 104 allocated for face 0x10209a0
freeing 0xfdb390
allocated 0xfdb390
freeing 0xfdb4d0
allocated 0xfdb4d0
fontset 106 allocated for face 0xfdb4d0
freeing 0x11c4ad0
allocated 0x11c4ad0
freeing 0x11c4c10
allocated 0x11c4c10
freeing 0xfdad30
allocated 0xfdad30
freeing 0x1733a10
allocated 0x1733a10
freeing 0xfdae70
allocated 0xfdae70
freeing 0x1706010
allocated 0x1706010
freeing 0x105f020
allocated 0x105f020
freeing 0x1706bb0
allocated 0x1706bb0
freeing 0x1725720
allocated 0x1725720
freeing 0x17310c0
allocated 0x17310c0
freeing 0x1269a30
allocated 0x1269a30
freeing 0xfda8d0
allocated 0xfda8d0
freeing 0xfdaa10
allocated 0xfdaa10
freeing 0xfc76d0
allocated 0xfc76d0
freeing 0xfc7810
allocated 0xfc7810
fontset 121 allocated for face 0xfc7810
freeing 0xfc5290
allocated 0xfc5290
fontset 122 allocated for face 0xfc5290
fontset 104 used for face 0x10209a0
fontset 83 used for face 0x2a2b6c0

lisp.h:2126: Emacs fatal error: assertion failed: CHAR_TABLE_P (a)

Thread 1 "emacs" hit Breakpoint 1, terminate_due_to_signal (sig=6, backtrace_limit=2147483647) at emacs.c:432
432	  signal (sig, SIG_DFL);
(gdb) up
#1  0x0000000000684cdc in die (msg=0x81ee60 "CHAR_TABLE_P (a)", file=0x81ed30 "lisp.h", line=2126) at alloc.c:8058
8058	  terminate_due_to_signal (SIGABRT, INT_MAX);
(gdb) 
#2  0x000000000078d6b8 in XCHAR_TABLE (a=XIL(0)) at /home/pip/emacs/src/lisp.h:2126
2126	  eassert (CHAR_TABLE_P (a));
(gdb) 
#3  0x00000000007902a8 in face_for_char (f=0x11c38f8, face=0x2a2b6c0, c=19233, pos=2, object=XIL(0)) at fontset.c:1005
1005	  eassert (!BASE_FONTSET_P (fontset));
(gdb) 
#4  0x000000000044b7bd in FACE_FOR_CHAR (f=0x11c38f8, face=0x2a2b6c0, character=19233, pos=2, object=XIL(0)) at /home/pip/emacs/src/dispextern.h:1962
1962	  return face_for_char (f, face, character, pos, object);
(gdb) p face
$1 = (struct face *) 0x2a2b6c0
(gdb) p face->fontset
$2 = 83
(gdb) p face->ascii_face
$3 = (struct face *) 0x10209a0
(gdb) show args
Argument list to give program being debugged when it is started is "-Q --load ../hibiscus.el".



patch:

diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..0a1e3717eab 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -900,7 +900,7 @@ fontset_ascii (int id)
 {
   Lisp_Object fontset, elt;
 
-  fontset= FONTSET_FROM_ID (id);
+  fontset = FONTSET_FROM_ID (id);
   elt = FONTSET_ASCII (fontset);
   if (CONSP (elt))
     elt = XCAR (elt);
@@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
   ASET (Vfontset_table, face->fontset, Qnil);
-  if (face->fontset < next_fontset_id)
-    next_fontset_id = face->fontset;
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
@@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
       eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       eassert (f == XFRAME (FONTSET_FRAME (fontset)));
       ASET (Vfontset_table, id, Qnil);
-      if (id < next_fontset_id)
-	next_fontset_id = face->fontset;
     }
   face->fontset = -1;
 }
@@ -1000,6 +996,7 @@ face_for_char (struct frame *f, struct face *face, int c,
      and display it as "glyphless".  That is certainly better than
      violating the assertion below or crashing when assertions are not
      compiled in.  */
+  fprintf (stderr, "fontset %d used for face %p\n", face->fontset, face);
   if (face->fontset < 0 && !face->font)
     return face->id;
 
diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..088ad46111f 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4576,6 +4576,7 @@ make_realized_face (Lisp_Object *attr)
 {
   enum { off = offsetof (struct face, id) };
   struct face *face = xmalloc (sizeof *face);
+  printf ("allocated %p\n", face);
 
   memcpy (face->lface, attr, sizeof face->lface);
   memset (&face->id, 0, sizeof *face - off);
@@ -4598,7 +4599,24 @@ free_realized_face (struct frame *f, struct face *face)
 	{
 	  /* Free fontset of FACE if it is ASCII face.  */
 	  if (face->fontset >= 0 && face == face->ascii_face)
-	    free_face_fontset (f, face);
+	    {
+	      struct face_cache *cache = FRAME_FACE_CACHE (f);
+	      if (cache)
+		{
+		  for (int i = 0; i < cache->used; i++)
+		    {
+		      struct face *face2 = cache->faces_by_id[i];
+		      if (face2 != 0 && face2 != face && face2->fontset == face->fontset)
+			{
+			  fprintf (stderr, "Freeing fontset %d that's still in use by %p (ASCII face %p==%p)!\n", face->fontset,
+				   face2, face2->ascii_face, face);
+			}
+		    }
+		}
+	      free_face_fontset (f, face);
+	    }
+	  else
+	    fprintf (stderr, "fontset %d not freed, used by %p\n", face->fontset, face);
 
 #ifdef HAVE_X_WINDOWS
 	  /* This function might be called with the frame's display
@@ -4627,6 +4645,7 @@ free_realized_face (struct frame *f, struct face *face)
 #ifdef HAVE_X_WINDOWS
     free_face:
 #endif /* HAVE_X_WINDOWS */
+      printf ("freeing %p\n", face);
       xfree (face);
     }
 }
@@ -6268,6 +6287,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE]
 	{
 	  face->font = XFONT_OBJECT (attrs[LFACE_FONT_INDEX]);
 	  face->fontset = make_fontset_for_ascii_face (f, fontset, face);
+	  fprintf (stderr, "fontset %d allocated for face %p\n", face->fontset, face);
 	}
       else
 	{


hibiscus.el:

(while t
  (insert (concat (make-string 1 (floor (random 132000)))))
  (set-frame-parameter nil 'alpha-background 1.0)
  (sit-for 1.0))


Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 14:35                                     ` Eli Zaretskii
@ 2024-08-19 15:03                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-19 15:54                                         ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19 15:03 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 19 Aug 2024 13:32:42 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> >> * modify the right frame parameter (such as alpha-background) so that
>> >>   the basic faces are re-realized ('free_realized_face' is called for
>> >>   them), but 'free_realized_faces' is not.
>> >
>> > Basic faces are routinely freed and re-realized whenever we start the
>> > display iteration, see init_iterator.
>>
>> > AFAIR, all you need to do for
>> > that is to customize some face -- doing so sets the face_change flag,
>> > and init_iterator will then normally free all the faces and realize
>> > them again.
>>
>> ... which won't trigger the bug, because it calls 'free_realized_faces'.
>
> Not necessarily.  I show below a backtrace which called
> realize_basic_faces and triggered the same freeing of the fontset of
> the ASCII face.  This was obtained by changing the color of the
> default face via Customize.

But only momentarily, right? Because we set f->face_change = true in
update_face_from_frame_parameter, under this comment:

  /* Changing a named face means that all realized faces depending on
     that face are invalid.  Since we cannot tell which realized faces
     depend on the face, make sure they are all removed.  This is done
     by setting face_change.  The next call to init_iterator will then
     free realized faces.  */

>> I specifically explained why 'free_realized_face' must be called
>> directly, not via (or after) 'free_realized_faces', to trigger the bug.
>
> Any caller of realize_face (and only those, AFAICT) will go that path.

'realize_basic_faces' doesn't call 'free_realized_faces', just
'free_realized_face', via 'realize_face' and its 'former_face_id'.

> Which is why I asked for a backtrace in your case (since I cannot
> reproduce it exactly myself).  As I explained in my other message,
> there's potentially a much more serious problem here, if indeed you
> are right.

I think it's a serious problem either way.  Leaving a pointer to freed
memory in a structure is a bug unless there's a VERY LOUD COMMENT
explaining that this is so.

>> I meant why we need at least two non-ASCII faces to trigger the bug.
>
> Which bug?  I can trigger freeing the fontset of an ASCII face while
> its non-ASCII variants are not freed without having 2 ASCII faces, see
> the backtrace below.

I can trigger that part, but not the crash, using only one non-ASCII
face.

>> Here's a reproducer hibiscus.el which uses buffer text:
>>
>> (while t
>>   (insert (concat (make-string 1 (floor (random 132000)))))
>>   (set-frame-parameter nil 'alpha-background 1.0)
>>   (sit-for 1.0))
>
> Thanks, but this doesn't help me because AFAIK alpha-background is not
> supported on Windows.

w32_frame_parm_handlers includes it by setting the
gui_set_alpha_background slot, though.

> Here's the backtrace I promised:
>
> #0  realize_face (cache=0x7c73288, attrs=0xbfb8d8, former_face_id=0)
>     at xfaces.c:6097
> #1  0x00df6b33 in realize_default_face (f=0x7c6bad8) at xfaces.c:6010
> #2  0x00df5d73 in realize_basic_faces (f=0x7c6bad8) at xfaces.c:5862
> #3  0x00def95a in update_face_from_frame_parameter (f=0x7c6bad8,
>     param=XIL(0x8940), new_value=XIL(0x8000000010805bb8)) at xfaces.c:3813

update_face_from_frame_parameter will set f->face_change = true before
it returns.

> And I wrote a simple GDB script that loops over the cached faces when
> free_realized_face is called under conditions that will cause it to
> call free_face_fontset, and got this:
>
>   face 0xbcad118(N), fontset 3, ascii 0x10643628
>   face 0x1025a7f0(N), fontset 3, ascii 0x10643628
>   face 0x101a0f50(N), fontset 3, ascii 0x10643628
>   face 0x1016a328(N), fontset 3, ascii 0x10643628
>   face 0xc02ed68(N), fontset 3, ascii 0x10643628
>   face 0xb9fb020(N), fontset 3, ascii 0x10643628
>   face 0xb98fc38(N), fontset 3, ascii 0x10643628
>   face 0xb9b1498(N), fontset 3, ascii 0x10643628
>   face 0x7c4cd48(N), fontset 3, ascii 0x10643628
>   face 0xbcbb350(N), fontset 3, ascii 0x10643628
>   face 0x107e5410(N), fontset 3, ascii 0x10643628
>   face 0x105ff8e8(N), fontset 3, ascii 0x10643628
>   face 0xbcab9f8(N), fontset 3, ascii 0x10643628
>   face 0xb9c8cd0(N), fontset 3, ascii 0x10643628
>   face 0xb99e470(N), fontset 3, ascii 0x10643628
>   face 0xb998d38(N), fontset 3, ascii 0x10643628
>   face 0xb97cbd0(N), fontset 3, ascii 0x10643628
>   face 0x104ac2b8(N), fontset 3, ascii 0x10643628
>   face 0x10167af0(N), fontset 3, ascii 0x10643628
>   face 0x10643d30(N), fontset 3, ascii 0x10643628
>   face 0x104d0c48(N), fontset 3, ascii 0x10643628
>   face 0x107e31b0(N), fontset 3, ascii 0x10643628
>   face 0xb949650(N), fontset 3, ascii 0x10643628
>   face 0xb949758(N), fontset 3, ascii 0x10643628
>   face 0x105403f0(N), fontset 3, ascii 0x10643628
>   face 0x105404f8(N), fontset 3, ascii 0x10643628
>   face 0x10540600(N), fontset 3, ascii 0x10643628
>   face 0x10540708(N), fontset 3, ascii 0x10643628
>   face 0x10540810(N), fontset 3, ascii 0x10643628
>   face 0x10540918(N), fontset 3, ascii 0x10643628
>   face 0x10540a20(N), fontset 3, ascii 0x10643628
>   face 0x10540b28(N), fontset 3, ascii 0x10643628
>   face 0x104a4fe8(N), fontset 3, ascii 0x10643628
>   face 0x104a50f0(N), fontset 3, ascii 0x10643628
>   face 0x104a51f8(N), fontset 3, ascii 0x10643628
>   face 0x104a5300(N), fontset 3, ascii 0x10643628
>
> The "(N)" part means that this face is not ASCII face (its ASCII
> parent is shown by "ascii 0xNNNNN").
>
> Except that in this case the caller sets the frame's 'face_change'
> flag, which then frees and all the non-ASCII faces the first time we
> call init_iterator.

I'll check whether setting f->face_change = true in the relevant places
is enough to avoid the bug...

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 15:03                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-19 15:54                                         ` Eli Zaretskii
  2024-08-19 16:34                                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-19 15:54 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Mon, 19 Aug 2024 15:03:13 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> I'll check whether setting f->face_change = true in the relevant places
> is enough to avoid the bug...

Thanks, but I'd also like to see the callers which call
free_realized_face in a way that causes the latter to call
free_face_fontset.  That's why I asked for backtraces from those
calls, but I don't think you sent such backtraces.  What you sent was
a backtrace from realize_gui_face and another one from the abort.  The
former is too early, the latter too late.  I'd like to see the code
which causes the fontset to be freed in a way that avoids re-realizing
all of the faces that use the fontset.  That's where the problem is,
at least at my current level of understanding this issue.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 15:54                                         ` Eli Zaretskii
@ 2024-08-19 16:34                                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-19 16:49                                             ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-19 16:34 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 19 Aug 2024 15:03:13 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> I'll check whether setting f->face_change = true in the relevant places
>> is enough to avoid the bug...
>
> Thanks, but I'd also like to see the callers which call
> free_realized_face in a way that causes the latter to call
> free_face_fontset.  That's why I asked for backtraces from those
> calls, but I don't think you sent such backtraces.  What you sent was

Just for the record, you asked:

> So can you show a backtrace from the call to free_realized_faces
> (supposedly called by realize_basic_faces?) which causes these
> printfs:
> > fontset 103 used for face 0x117cca0
> > fontset 103 used for face 0x2a7a3c0
> > fontset 103 used for face 0x117cca0
> > fontset 103 used for face 0x2a62860

... which I misunderstood.  Sorry.

Is this what you want?

Thread 1 "emacs" hit Breakpoint 3, free_realized_face (f=0x11d1cc8, face=0x11e22b0) at xfaces.c:4612
4612				  fprintf (stderr, "Freeing fontset %d that's still in use by %p (ASCII face %p==%p)!\n", face->fontset,
(gdb) p face->fontset
$1 = 83
(gdb) bt
#0  free_realized_face (f=0x11d1cc8, face=0x11e22b0) at xfaces.c:4612
#1  0x000000000055fe5d in realize_face (cache=0x12731e0, attrs=0x7fffffffb5f0, former_face_id=0) at xfaces.c:6117
#2  0x000000000055faf7 in realize_default_face (f=0x11d1cc8) at xfaces.c:6030
#3  0x000000000055f023 in realize_basic_faces (f=0x11d1cc8) at xfaces.c:5882
#4  0x000000000055084f in recompute_basic_faces (f=0x11d1cc8) at xfaces.c:737
#5  0x0000000000445160 in gui_set_alpha_background (f=0x11d1cc8, arg=XIL(0x7ffff33a80c7), oldval=XIL(0x7ffff33a80c7)) at frame.c:5237
#6  0x00000000005a511e in x_set_alpha_background (f=0x11d1cc8, arg=XIL(0x7ffff33a80c7), oldval=XIL(0x7ffff33a80c7)) at xfns.c:742
#7  0x0000000000442194 in gui_set_frame_parameters_1 (f=0x11d1cc8, alist=XIL(0), default_parameter=false) at frame.c:4400
#8  0x0000000000442d6f in gui_set_frame_parameters (f=0x11d1cc8, alist=XIL(0x7ffff33a3223)) at frame.c:4560
#9  0x000000000044042b in Fmodify_frame_parameters (frame=XIL(0), alist=XIL(0x7ffff33a3223)) at frame.c:3549
#10 0x00000000006c043c in funcall_subr (subr=0xe8d920 <Smodify_frame_parameters>, numargs=2, args=0x7fffe41ff2f8) at eval.c:3140
#11 0x000000000071b3ab in exec_byte_code (fun=XIL(0x7ffff249ab35), args_template=771, nargs=3, args=0x7fffffffc038) at bytecode.c:813
#12 0x00000000006c0a6c in funcall_lambda (fun=XIL(0x7ffff249ab35), nargs=3, arg_vector=0x7fffffffc020) at eval.c:3229
#13 0x00000000006c0903 in apply_lambda (fun=XIL(0x7ffff249ab35), args=XIL(0x7ffff336a2d3), count=...) at eval.c:3192
#14 0x00000000006bee34 in eval_sub (form=XIL(0x7ffff336a2c3)) at eval.c:2622
#15 0x00000000006b98f3 in Fprogn (body=XIL(0x7ffff336a353)) at eval.c:430
#16 0x00000000006b9923 in prog_ignore (body=XIL(0x7ffff336a2b3)) at eval.c:441
#17 0x00000000006bb4ee in Fwhile (args=XIL(0x7ffff336a1f3)) at eval.c:1121
#18 0x00000000006be8bb in eval_sub (form=XIL(0x7ffff336a1e3)) at eval.c:2526
#19 0x00000000006fff09 in readevalloop_eager_expand_eval (val=XIL(0x7ffff336a1e3), macroexpand=XIL(0xb370)) at lread.c:2355
#20 0x0000000000700773 in readevalloop
    (readcharfun=XIL(0x143d9a5), infile0=0x0, sourcename=XIL(0x127a2f4), printflag=false, unibyte=XIL(0), readfun=XIL(0), start=XIL(0), end=XIL(0))
    at lread.c:2537
#21 0x0000000000700ac2 in Feval_buffer (buffer=XIL(0x143d9a5), printflag=XIL(0), filename=XIL(0x127a2f4), unibyte=XIL(0), do_allow_print=XIL(0x30))
    at lread.c:2612
#22 0x00000000006c04f3 in funcall_subr (subr=0xe9f0e0 <Seval_buffer>, numargs=5, args=0x7fffe41ff290) at eval.c:3146
#23 0x000000000071b3ab in exec_byte_code (fun=XIL(0x7ffff25bab55), args_template=257, nargs=1, args=0x7fffe41ff298) at bytecode.c:813
#24 0x00000000006c0a6c in funcall_lambda (fun=XIL(0x7ffff280f18d), nargs=4, arg_vector=0x7fffffffcdb8) at eval.c:3229
#25 0x00000000006bfe66 in funcall_general (fun=XIL(0x7ffff280f18d), numargs=4, args=0x7fffffffcdb8) at eval.c:3021
#26 0x00000000006c0115 in Ffuncall (nargs=5, args=0x7fffffffcdb0) at eval.c:3070
#27 0x00000000006fe3fa in Fload (file=XIL(0x127a614), noerror=XIL(0), nomessage=XIL(0x30), nosuffix=XIL(0), must_suffix=XIL(0)) at lread.c:1615
#28 0x00000000006c04f3 in funcall_subr (subr=0xe9f060 <Sload>, numargs=3, args=0x7fffe41ff1b0) at eval.c:3146
#29 0x000000000071b3ab in exec_byte_code (fun=XIL(0x7ffff2a036c5), args_template=769, nargs=3, args=0x7fffe41ff4a0) at bytecode.c:813
#30 0x00000000006c0a6c in funcall_lambda (fun=XIL(0x7ffff2a529cd), nargs=0, arg_vector=0x7fffffffd590) at eval.c:3229
#31 0x00000000006c0903 in apply_lambda (fun=XIL(0x7ffff2a529cd), args=XIL(0), count=...) at eval.c:3192
#32 0x00000000006bee34 in eval_sub (form=XIL(0x7ffff2c113fb)) at eval.c:2622
#33 0x00000000006be367 in Feval (form=XIL(0x7ffff2c113fb), lexical=XIL(0x30)) at eval.c:2439
#34 0x00000000005e5392 in top_level_2 () at keyboard.c:1179
#35 0x00000000006bc3d6 in internal_condition_case (bfun=0x5e532b <top_level_2>, handlers=XIL(0x90), hfun=0x5e4c03 <cmd_error>) at eval.c:1598
#36 0x00000000005e53ed in top_level_1 (ignore=XIL(0)) at keyboard.c:1191
#37 0x00000000006bb89a in internal_catch (tag=XIL(0x12360), func=0x5e53ab <top_level_1>, arg=XIL(0)) at eval.c:1277
#38 0x00000000005e5275 in command_loop () at keyboard.c:1140
#39 0x00000000005e46dc in recursive_edit_1 () at keyboard.c:749
#40 0x00000000005e48ef in Frecursive_edit () at keyboard.c:832
#41 0x00000000005e05cf in main (argc=4, argv=0x7fffffffdb98) at emacs.c:2624

Lisp Backtrace:
"modify-frame-parameters" (0xe41ff2f8)
"set-frame-parameter" (0xffffc020)
"while" (0xffffc300)
"eval-buffer" (0xe41ff290)
"load-with-code-conversion" (0xffffcdb8)
"load" (0xe41ff1b0)
"command-line-1" (0xe41ff0b8)
"command-line" (0xe41ff040)
"normal-top-level" (0xffffd590)
(gdb) p face->ascii_face
$2 = (struct face *) 0x11e22b0

> a backtrace from realize_gui_face and another one from the abort.  The
> former is too early, the latter too late.  I'd like to see the code
> which causes the fontset to be freed in a way that avoids re-realizing
> all of the faces that use the fontset.  That's where the problem is,
> at least at my current level of understanding this issue.

Indeed, I can report that the bug doesn't seem to occur after this
simple change:

diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..a4ac9c0787a 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -736,6 +736,7 @@ recompute_basic_faces (struct frame *f)
       clear_face_cache (false);
       if (!realize_basic_faces (f))
        emacs_abort ();
+      f->face_change = true;
     }
 }
 

So something like that (though moving the call down into
realize_basic_faces or even further would be good) would probably work
for the OP, and emacs-30?

Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 16:34                                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-19 16:49                                             ` Eli Zaretskii
  2024-08-24  9:09                                               ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-19 16:49 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Mon, 19 Aug 2024 16:34:59 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > Thanks, but I'd also like to see the callers which call
> > free_realized_face in a way that causes the latter to call
> > free_face_fontset.  That's why I asked for backtraces from those
> > calls, but I don't think you sent such backtraces.  What you sent was
> 
> Just for the record, you asked:
> 
> > So can you show a backtrace from the call to free_realized_faces
> > (supposedly called by realize_basic_faces?) which causes these
> > printfs:
> > > fontset 103 used for face 0x117cca0
> > > fontset 103 used for face 0x2a7a3c0
> > > fontset 103 used for face 0x117cca0
> > > fontset 103 used for face 0x2a62860
> 
> ... which I misunderstood.  Sorry.

Sorry for being unclear.

> Is this what you want?

Yes, recompute_basic_faces was the prime suspect.  I think we added
several calls to it over the last years, to fix problems with face
cache being emptied at some unexpected times.

> Indeed, I can report that the bug doesn't seem to occur after this
> simple change:
> 
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 684b6ccfac7..a4ac9c0787a 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -736,6 +736,7 @@ recompute_basic_faces (struct frame *f)
>        clear_face_cache (false);
>        if (!realize_basic_faces (f))
>         emacs_abort ();
> +      f->face_change = true;
>      }
>  }
>  
> 
> So something like that (though moving the call down into
> realize_basic_faces or even further would be good) would probably work
> for the OP, and emacs-30?

I think setting the flag in recompute_basic_faces should be enough.
Let me think about it some more.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-19 16:49                                             ` Eli Zaretskii
@ 2024-08-24  9:09                                               ` Eli Zaretskii
  2024-08-24 10:04                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-24  9:09 UTC (permalink / raw)
  To: pipcet; +Cc: execvy, 72692-done

> Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> Date: Mon, 19 Aug 2024 19:49:03 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> 
> > Date: Mon, 19 Aug 2024 16:34:59 +0000
> > From: Pip Cet <pipcet@protonmail.com>
> > Cc: execvy@gmail.com, 72692@debbugs.gnu.org
> > 
> > "Eli Zaretskii" <eliz@gnu.org> writes:
> > 
> > > Thanks, but I'd also like to see the callers which call
> > > free_realized_face in a way that causes the latter to call
> > > free_face_fontset.  That's why I asked for backtraces from those
> > > calls, but I don't think you sent such backtraces.  What you sent was
> > 
> > Just for the record, you asked:
> > 
> > > So can you show a backtrace from the call to free_realized_faces
> > > (supposedly called by realize_basic_faces?) which causes these
> > > printfs:
> > > > fontset 103 used for face 0x117cca0
> > > > fontset 103 used for face 0x2a7a3c0
> > > > fontset 103 used for face 0x117cca0
> > > > fontset 103 used for face 0x2a62860
> > 
> > ... which I misunderstood.  Sorry.
> 
> Sorry for being unclear.
> 
> > Is this what you want?
> 
> Yes, recompute_basic_faces was the prime suspect.  I think we added
> several calls to it over the last years, to fix problems with face
> cache being emptied at some unexpected times.
> 
> > Indeed, I can report that the bug doesn't seem to occur after this
> > simple change:
> > 
> > diff --git a/src/xfaces.c b/src/xfaces.c
> > index 684b6ccfac7..a4ac9c0787a 100644
> > --- a/src/xfaces.c
> > +++ b/src/xfaces.c
> > @@ -736,6 +736,7 @@ recompute_basic_faces (struct frame *f)
> >        clear_face_cache (false);
> >        if (!realize_basic_faces (f))
> >         emacs_abort ();
> > +      f->face_change = true;
> >      }
> >  }
> >  
> > 
> > So something like that (though moving the call down into
> > realize_basic_faces or even further would be good) would probably work
> > for the OP, and emacs-30?
> 
> I think setting the flag in recompute_basic_faces should be enough.
> Let me think about it some more.

I decided to go with this change only, and installed it on the
emacs-30 release branch.  Let's hope it makes this tricky problem go
away.

I'm closing this bug.  If the problem resurfaces, we can reopen it.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-24  9:09                                               ` Eli Zaretskii
@ 2024-08-24 10:04                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-24 10:13                                                   ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-24 10:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692-done

"Eli Zaretskii" <eliz@gnu.org> writes:

> I decided to go with this change only, and installed it on the
> emacs-30 release branch.  Let's hope it makes this tricky problem go
> away.

Just to be clear on that, we're going with this fix on both emacs-30 and
master, right?  (I'd like that very much.)

> I'm closing this bug.  If the problem resurfaces, we can reopen it.

Let's hope it doesn't :-)

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-24 10:04                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-24 10:13                                                   ` Eli Zaretskii
  2024-08-25 17:58                                                     ` Juri Linkov
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-24 10:13 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692

> Date: Sat, 24 Aug 2024 10:04:01 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692-done@debbugs.gnu.org
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > I decided to go with this change only, and installed it on the
> > emacs-30 release branch.  Let's hope it makes this tricky problem go
> > away.
> 
> Just to be clear on that, we're going with this fix on both emacs-30 and
> master, right?  (I'd like that very much.)

Every change on the release branch gets merged to master, unless
specifically marked otherwise.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-24 10:13                                                   ` Eli Zaretskii
@ 2024-08-25 17:58                                                     ` Juri Linkov
  2024-08-25 18:49                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-25 18:57                                                       ` Eli Zaretskii
  0 siblings, 2 replies; 66+ messages in thread
From: Juri Linkov @ 2024-08-25 17:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Pip Cet, execvy, 72692

>> > I decided to go with this change only, and installed it on the
>> > emacs-30 release branch.  Let's hope it makes this tricky problem go
>> > away.
>>
>> Just to be clear on that, we're going with this fix on both emacs-30 and
>> master, right?  (I'd like that very much.)
>
> Every change on the release branch gets merged to master, unless
> specifically marked otherwise.

Unfortunately, after the release branch was merged to master now,
it's impossible to use Emacs with this change because point motion
is too jumpy and not as smooth as it was before.
Reverting this line fixes the problem:

-      f->face_change = true;





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-25 17:58                                                     ` Juri Linkov
@ 2024-08-25 18:49                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-27 16:31                                                         ` Juri Linkov
  2024-08-25 18:57                                                       ` Eli Zaretskii
  1 sibling, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-25 18:49 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, execvy, 72692

"Juri Linkov" <juri@linkov.net> writes:

>>> > I decided to go with this change only, and installed it on the
>>> > emacs-30 release branch.  Let's hope it makes this tricky problem go
>>> > away.
>>>
>>> Just to be clear on that, we're going with this fix on both emacs-30 and
>>> master, right?  (I'd like that very much.)
>>
>> Every change on the release branch gets merged to master, unless
>> specifically marked otherwise.
>
> Unfortunately, after the release branch was merged to master now,
> it's impossible to use Emacs with this change because point motion
> is too jumpy and not as smooth as it was before.
> Reverting this line fixes the problem:
>
> -      f->face_change = true;

Which OS is this on?  I'm having weird trouble when running the Windows
binary in wine, which I attribute to this change: when menu-bar-mode is
on, the Emacs frame raises itself whenever it loses focus.

I see Eli reverted the change, which makes sense for now.  We'll have to
find another way to fix this, I think.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-25 17:58                                                     ` Juri Linkov
  2024-08-25 18:49                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-25 18:57                                                       ` Eli Zaretskii
  2024-08-26  5:52                                                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-25 18:57 UTC (permalink / raw)
  To: Juri Linkov; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: Pip Cet <pipcet@protonmail.com>,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Sun, 25 Aug 2024 20:58:40 +0300
> 
> Unfortunately, after the release branch was merged to master now,
> it's impossible to use Emacs with this change because point motion
> is too jumpy and not as smooth as it was before.
> Reverting this line fixes the problem:
> 
> -      f->face_change = true;

Sorry about that.  I've now reverted that change; we will have to find
a cheaper solution for the original problem.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-25 18:57                                                       ` Eli Zaretskii
@ 2024-08-26  5:52                                                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-26 12:39                                                           ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-26  5:52 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, Juri Linkov

"Eli Zaretskii" <eliz@gnu.org> writes:

>> From: Juri Linkov <juri@linkov.net>
>> Cc: Pip Cet <pipcet@protonmail.com>,  execvy@gmail.com,  72692@debbugs.gnu.org
>> Date: Sun, 25 Aug 2024 20:58:40 +0300
>>
>> Unfortunately, after the release branch was merged to master now,
>> it's impossible to use Emacs with this change because point motion
>> is too jumpy and not as smooth as it was before.
>> Reverting this line fixes the problem:
>>
>> -      f->face_change = true;
>
> Sorry about that.  I've now reverted that change; we will have to find
> a cheaper solution for the original problem.

This patch, moving down the setting of f->face_change to when we
definitely know it's required, seems to avoid the
always-in-the-foreground problem, but I'm not sure it fixes Juri's
performance issue:

diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..0fe65e9b481 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -920,6 +920,10 @@ free_face_fontset (struct frame *f, struct face *face)
     return;
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
+  /* Force complete face recalculation next time we use the display
+     code, because there might be non-ASCII faces sharing this
+     fontset.  */
+  f->face_change = true;
   ASET (Vfontset_table, face->fontset, Qnil);
   if (face->fontset < next_fontset_id)
     next_fontset_id = face->fontset;
diff --git a/src/xdisp.c b/src/xdisp.c
index f9a10267bad..977495c2802 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -3227,13 +3227,13 @@ init_iterator (struct it *it, struct window *w,
       if (face_change)
        {
          face_change = false;
-         XFRAME (w->frame)->face_change = 0;
          free_all_realized_faces (Qnil);
+         XFRAME (w->frame)->face_change = 0;
        }
       else if (XFRAME (w->frame)->face_change)
        {
-         XFRAME (w->frame)->face_change = 0;
          free_all_realized_faces (w->frame);
+         XFRAME (w->frame)->face_change = 0;
        }
     }
 

However, I would still prefer a solution which doesn't, even for a short
period of time, leave the non-ASCII faces' ->ascii_face pointing to a
face which has been freed, and their ->fontset identifying a fontset
which might be nil.

Is it true that all non-ASCII faces share their ASCII face's hash and
thus live in the same collision chain?  We could walk that and unrealize
them all when the ASCII face is unrealized, then.

Something like this:

diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..bfc6b76d58a 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4585,6 +4585,8 @@ make_realized_face (Lisp_Object *attr)
 }
 
 
+static void uncache_face (struct face_cache *c, struct face *face);
+
 /* Free realized face FACE, including its X resources.  FACE may
    be null.  */
 
@@ -4596,9 +4598,28 @@ free_realized_face (struct frame *f, struct face *face)
 #ifdef HAVE_WINDOW_SYSTEM
       if (FRAME_WINDOW_P (f))
 	{
-	  /* Free fontset of FACE if it is ASCII face.  */
-	  if (face->fontset >= 0 && face == face->ascii_face)
-	    free_face_fontset (f, face);
+	  if (face == face->ascii_face)
+	    {
+	      struct face *next;
+	      /* Because cache_face puts non-ASCII faces last in the
+		 collision chain, we only have to check in one
+		 direction.  */
+	      for (struct face *face_nonascii = face->next; face_nonascii;
+		   face_nonascii = next)
+		{
+		  next = face_nonascii->next;
+
+		  if (face == face_nonascii->ascii_face)
+		    {
+		      uncache_face (FRAME_FACE_CACHE (f), face_nonascii);
+		      free_realized_face (f, face_nonascii);
+		    }
+		}
+
+	      /* Free fontset of FACE if it is ASCII face.  */
+	      if (face->fontset >= 0)
+		free_face_fontset (f, face);
+	    }
 
 #ifdef HAVE_X_WINDOWS
 	  /* This function might be called with the frame's display



Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-26  5:52                                                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-26 12:39                                                           ` Eli Zaretskii
  2024-08-26 19:04                                                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-26 12:39 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Mon, 26 Aug 2024 05:52:11 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: Juri Linkov <juri@linkov.net>, execvy@gmail.com, 72692@debbugs.gnu.org
> 
> >> -      f->face_change = true;
> >
> > Sorry about that.  I've now reverted that change; we will have to find
> > a cheaper solution for the original problem.
> 
> This patch, moving down the setting of f->face_change to when we
> definitely know it's required, seems to avoid the
> always-in-the-foreground problem, but I'm not sure it fixes Juri's
> performance issue:

We should find the correct patch first, and think about performance
only after that, of course.  And in this case, I'm not sure that the
fontset is the only problem, nor that when we free it, we must in all
the cases re-realize all the faces.

If all we want is to set the face_change flag without causing
performance issues, then the patch below does it, and AFAIU should
prevent the segfaults in this bug (please check, as I'm unable to
trigger the segfaults):

diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6cc..1baa364 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -733,9 +733,13 @@ recompute_basic_faces (struct frame *f)
 {
   if (FRAME_FACE_CACHE (f))
     {
+      bool non_basic_faces_cached =
+	FRAME_FACE_CACHE (f)->used >= BASIC_FACE_ID_SENTINEL;
       clear_face_cache (false);
       if (!realize_basic_faces (f))
 	emacs_abort ();
+      if (non_basic_faces_cached)
+	f->face_change = true;
     }
 }
 
The idea here is that if all we have in the frame's face cache are the
basic faces, then they are all ASCII faces, and therefore the issue
with non-ASCII faces still holding the freed fontset ID should not
arise.  The performance problem was caused by init_iterator calling
recompute_basic_faces every time and then shooting itself in the foot
by immediately setting the face_change flag, but this is now avoided
because init_iterator only calls recompute_basic_faces if the frame's
face cache is empty.  Most other places that call
recompute_basic_faces also do that when the cache is empty (in which
case we don't have to worry about non-ASCII faces), but some call it
unconditionally, and the above is for those.

Once again, I'm not yet sure if this is TRT.

Btw, thinking again about the original problem, I don't think I
understand why free_face_fontset could cause a segfault.  All that
function does is remove the fontset from the cache and put nil into
its slot.  Thereafter trying to access the fontset by its ID will
yield nil.  So how can this cause trouble?  The two ways I can think
of are:

  . Some code that calls FONTSET_FROM_ID and does not check that the
    result is nil.  We indeed have a couple of places like that, but
    it should be easy to fix them.  However, can this cause a
    segfault?
  . While some face holds to a (stale) fontset ID, a new fontset is
    created and stored in the cache at the slot corresponding to that
    stale ID.  So accessing this ID will yield a wrong, but still
    valid fontset.  Can this cause a segfault?

Are there any other scenarios?  (And in your reproducer, the second
scenario above was AFAIU disabled by never decreasing next_fontset_id,
so only the first one could cause some trouble?)

> However, I would still prefer a solution which doesn't, even for a short
> period of time, leave the non-ASCII faces' ->ascii_face pointing to a
> face which has been freed, and their ->fontset identifying a fontset
> which might be nil.

This goes against the design of the faces and their interaction with
the display code, I think.

> Is it true that all non-ASCII faces share their ASCII face's hash and
> thus live in the same collision chain?  We could walk that and unrealize
> them all when the ASCII face is unrealized, then.
> 
> Something like this:

If all we want is to free all the faces that belong to a certain frame
and share the same ascii_face, why not simply walk the frame's face
cache looking for such faces, and free each one of them?





^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-26 12:39                                                           ` Eli Zaretskii
@ 2024-08-26 19:04                                                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-26 19:20                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-27 11:44                                                               ` Eli Zaretskii
  0 siblings, 2 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-26 19:04 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 26 Aug 2024 05:52:11 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: Juri Linkov <juri@linkov.net>, execvy@gmail.com, 72692@debbugs.gnu.org
>>
>> >> -      f->face_change = true;
>> >
>> > Sorry about that.  I've now reverted that change; we will have to find
>> > a cheaper solution for the original problem.
>>
>> This patch, moving down the setting of f->face_change to when we
>> definitely know it's required, seems to avoid the
>> always-in-the-foreground problem, but I'm not sure it fixes Juri's
>> performance issue:
>
> If all we want is to set the face_change flag without causing
> performance issues, then the patch below does it, and AFAIU should
> prevent the segfaults in this bug (please check, as I'm unable to
> trigger the segfaults):

Will do.

> diff --git a/src/xfaces.c b/src/xfaces.c
> index 684b6cc..1baa364 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -733,9 +733,13 @@ recompute_basic_faces (struct frame *f)
>  {
>    if (FRAME_FACE_CACHE (f))
>      {
> +      bool non_basic_faces_cached =
> +	FRAME_FACE_CACHE (f)->used >= BASIC_FACE_ID_SENTINEL;

There's an off by one here, I think: FRAME_FACE_CACHE (f)->used is a
count, and it'll usually be equal to BASIC_FACE_ID_SENTINEL after the
basic faces have been realized, greater (never equal) if non-basic faces
have been realized, and 0 if no faces have been realized.

So, in fact, your patch is equivalent to checking that FRAME_FACE_CACHE
(f)->used != 0, and only setting face_change if it was.

That makes sense to me, but it doesn't match the variable names or your
description.

> The idea here is that if all we have in the frame's face cache are the
> basic faces, then they are all ASCII faces, and therefore the issue
> with non-ASCII faces still holding the freed fontset ID should not
> arise.

See above, not what your code actually does.  Good thing, too, because
that would change things only if no non-ASCII face were to be in use.

> The performance problem was caused by init_iterator calling
> recompute_basic_faces every time and then shooting itself in the foot
> by immediately setting the face_change flag,

And it's easily fixed by clearing the face_change flag after
recompute_basic_faces runs, rather than before, which is the more
important part of my first patch.  (The less important part is a mere
performance optimization).

> but this is now avoided
> because init_iterator only calls recompute_basic_faces if the frame's
> face cache is empty.  Most other places that call
> recompute_basic_faces also do that when the cache is empty (in which
> case we don't have to worry about non-ASCII faces), but some call it
> unconditionally, and the above is for those.

??? I don't see any such callers in my backtraces of Emacs with or
without the patch, but I do see significant performance differences, so
this must be wrong.

> Btw, thinking again about the original problem, I don't think I
> understand why free_face_fontset could cause a segfault.  All that
> function does is remove the fontset from the cache and put nil into
> its slot.  Thereafter trying to access the fontset by its ID will
> yield nil.

It's font_for_char that segfaults, or fontset_font, depending on whether
assertions are enabled.

The code path is this, in the case with assertions:

  fontset = FONTSET_FROM_ID (face->fontset);  /* fontset is nil */
  eassert (!BASE_FONTSET_P (fontset));

Since

#define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))

and

#define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[3]

we end up looking at XCHAR_TABLE (Qnil)->extras[3], which segfaults
because nil is not a char table.

The code path without assertions is similar, it just that the
XCHAR_TABLE happens further down the call stack, in fontset_find_font.
See the original backtrace.

> So how can this cause trouble?  The two ways I can think
> of are:
>
>   . Some code that calls FONTSET_FROM_ID and does not check that the
>     result is nil.  We indeed have a couple of places like that, but
>     it should be easy to fix them.  However, can this cause a
>     segfault?

Yes.

>   . While some face holds to a (stale) fontset ID, a new fontset is
>     created and stored in the cache at the slot corresponding to that
>     stale ID.  So accessing this ID will yield a wrong, but still
>     valid fontset.  Can this cause a segfault?

No, just cause us to silently use the wrong fontset, leading to other
bugs.

> Are there any other scenarios?  (And in your reproducer, the second
> scenario above was AFAIU disabled by never decreasing next_fontset_id,
> so only the first one could cause some trouble?)

Correct. The first scenario causes segfaults, the second scenario causes
silently misbehaving code. We need to fix both, of course.

>> However, I would still prefer a solution which doesn't, even for a short
>> period of time, leave the non-ASCII faces' ->ascii_face pointing to a
>> face which has been freed, and their ->fontset identifying a fontset
>> which might be nil.
>
> This goes against the design of the faces and their interaction with
> the display code, I think.

If the design indeed relies on dangling pointers to freed memory
surviving said freeing (it doesn't), that would be a very bad design
indeed, particularly since this fact isn't documented.  The correct
thing to do here is to ensure all references to ascii_face are removed,
by freeing the non-ASCII faces, before we remove the ascii_face itself.

And please, let's document such "design decisions" (actually, bugs) if
you refuse to let anyone fix them.  Having a pointer in a structure
which might point to random memory is a bug unless there is a very loud
comment advising us of this fact.

>> Is it true that all non-ASCII faces share their ASCII face's hash and
>> thus live in the same collision chain?  We could walk that and unrealize
>> them all when the ASCII face is unrealized, then.
>>
>> Something like this:
>
> If all we want is to free all the faces that belong to a certain frame
> and share the same ascii_face, why not simply walk the frame's face
> cache looking for such faces, and free each one of them?

Because there are 1009 buckets, and we only need to walk half of one.
Otherwise the effects are identical.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-26 19:04                                                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-26 19:20                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-27 11:47                                                                 ` Eli Zaretskii
  2024-08-27 11:44                                                               ` Eli Zaretskii
  1 sibling, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-26 19:20 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Pip Cet" <pipcet@protonmail.com> writes:

> "Eli Zaretskii" <eliz@gnu.org> writes:
>
>>> Date: Mon, 26 Aug 2024 05:52:11 +0000
>>> From: Pip Cet <pipcet@protonmail.com>
>>> Cc: Juri Linkov <juri@linkov.net>, execvy@gmail.com, 72692@debbugs.gnu.org
>>>
>>> >> -      f->face_change = true;
>>> >
>>> > Sorry about that.  I've now reverted that change; we will have to find
>>> > a cheaper solution for the original problem.
>>>
>>> This patch, moving down the setting of f->face_change to when we
>>> definitely know it's required, seems to avoid the
>>> always-in-the-foreground problem, but I'm not sure it fixes Juri's
>>> performance issue:
>>
>> If all we want is to set the face_change flag without causing
>> performance issues, then the patch below does it, and AFAIU should
>> prevent the segfaults in this bug (please check, as I'm unable to
>> trigger the segfaults):
>
> Will do.

That was quick.  With this patch:

diff --git a/src/fontset.c b/src/fontset.c
index 16d14669c89..41d845c9bc5 100644
--- a/src/fontset.c
+++ b/src/fontset.c
@@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
   eassert (! BASE_FONTSET_P (fontset));
   eassert (f == XFRAME (FONTSET_FRAME (fontset)));
   ASET (Vfontset_table, face->fontset, Qnil);
-  if (face->fontset < next_fontset_id)
-    next_fontset_id = face->fontset;
   if (! NILP (FONTSET_DEFAULT (fontset)))
     {
       int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
@@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
       eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
       eassert (f == XFRAME (FONTSET_FRAME (fontset)));
       ASET (Vfontset_table, id, Qnil);
-      if (id < next_fontset_id)
-	next_fontset_id = face->fontset;
     }
   face->fontset = -1;
 }
diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6ccfac7..02fc934ee4d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -733,9 +733,12 @@ recompute_basic_faces (struct frame *f)
 {
   if (FRAME_FACE_CACHE (f))
     {
+      bool was_empty = FRAME_FACE_CACHE (f)->used == 0;
       clear_face_cache (false);
       if (!realize_basic_faces (f))
 	emacs_abort ();
+      if (!was_empty)
+	f->face_change = true;
     }
 }
 

and this hibiscus.el:

(while t
  (insert (concat (make-string 1 (floor (random 132000)))))
  (set-frame-parameter nil 'alpha-background 1.0)
  (sit-for 1.0))

emacs -Q --load hibiscus.el works.  Without the last hunk, it segfaults
almost immediately.

And the patch makes sense, too: if the face cache was empty, there's no
need to set f->face_change to true.  Is that case sufficiently common to
result in acceptable performance?

Pip






^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-26 19:04                                                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-26 19:20                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-27 11:44                                                               ` Eli Zaretskii
  2024-08-27 19:23                                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-27 11:44 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Mon, 26 Aug 2024 19:04:13 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > --- a/src/xfaces.c
> > +++ b/src/xfaces.c
> > @@ -733,9 +733,13 @@ recompute_basic_faces (struct frame *f)
> >  {
> >    if (FRAME_FACE_CACHE (f))
> >      {
> > +      bool non_basic_faces_cached =
> > +	FRAME_FACE_CACHE (f)->used >= BASIC_FACE_ID_SENTINEL;
> 
> There's an off by one here, I think

Yes, it should be > instead of >= .

> FRAME_FACE_CACHE (f)->used is a
> count, and it'll usually be equal to BASIC_FACE_ID_SENTINEL after the
> basic faces have been realized, greater (never equal) if non-basic faces
> have been realized, and 0 if no faces have been realized.
> 
> So, in fact, your patch is equivalent to checking that FRAME_FACE_CACHE
> (f)->used != 0, and only setting face_change if it was.

As explained in my previous message, the test for having non-basic
faces in the cache is because when we have only the basic faces, the
problem with sharing the fontsets, and with having non-ASCII faces
that point to released ASCII faces, cannot happen, and therefore
there's no need to do anything.

It is true that 'used != 0' should also do the trick, but I realized
that testing against BASIC_FACE_ID_SENTINEL is stronger, because it
also prevents setting the flag when we have some faces in the cache,
but they are all basic.  Setting the face_change flag when we don't
need that will cause us to unnecessarily re-realize the basic faces,
so refraining from that prevents performance degradation.

> > The idea here is that if all we have in the frame's face cache are the
> > basic faces, then they are all ASCII faces, and therefore the issue
> > with non-ASCII faces still holding the freed fontset ID should not
> > arise.
> 
> See above, not what your code actually does.

Because of the >= thing? that's easily fixed, of course.

> Good thing, too, because
> that would change things only if no non-ASCII face were to be in use.

I don't understand what you are saying with this sentence.

> > The performance problem was caused by init_iterator calling
> > recompute_basic_faces every time and then shooting itself in the foot
> > by immediately setting the face_change flag,
> 
> And it's easily fixed by clearing the face_change flag after
> recompute_basic_faces runs, rather than before

I don't follow: if we clear the flag after recompute_basic_faces
exits, the faces will not be re-realized by next redisplay, and we
might be back at the problem of having non-ASCII faces whose ASCII
parents were removed from the cache and re-realize.  How will this be
useful?  Or what am I missing?

> > but this is now avoided
> > because init_iterator only calls recompute_basic_faces if the frame's
> > face cache is empty.  Most other places that call
> > recompute_basic_faces also do that when the cache is empty (in which
> > case we don't have to worry about non-ASCII faces), but some call it
> > unconditionally, and the above is for those.
> 
> ??? I don't see any such callers in my backtraces of Emacs with or
> without the patch

There are 2 such callers in frame.c, one of them was in the backtrace
you show in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#98,
viz.:

  Thread 1 "emacs" hit Breakpoint 3, free_realized_face (f=0x11d1cc8, face=0x11e22b0) at xfaces.c:4612
  4612				  fprintf (stderr, "Freeing fontset %d that's still in use by %p (ASCII face %p==%p)!\n", face->fontset,
  (gdb) p face->fontset
  $1 = 83
  (gdb) bt
  #0  free_realized_face (f=0x11d1cc8, face=0x11e22b0) at xfaces.c:4612
  #1  0x000000000055fe5d in realize_face (cache=0x12731e0, attrs=0x7fffffffb5f0, former_face_id=0) at xfaces.c:6117
  #2  0x000000000055faf7 in realize_default_face (f=0x11d1cc8) at xfaces.c:6030
  #3  0x000000000055f023 in realize_basic_faces (f=0x11d1cc8) at xfaces.c:5882
  #4  0x000000000055084f in recompute_basic_faces (f=0x11d1cc8) at xfaces.c:737
  #5  0x0000000000445160 in gui_set_alpha_background (f=0x11d1cc8, arg=XIL(0x7ffff33a80c7), oldval=XIL(0x7ffff33a80c7)) at frame.c:5237

There's also one caller in fontset.c (which calls Fclear_face_cache
before recompute_basic_faces, but Fclear_face_cache might decide not
to clear the cache).

> but I do see significant performance differences, so this must be
> wrong.

What performance difference did you see, and what is "this" that you
think must be wrong?

> > Btw, thinking again about the original problem, I don't think I
> > understand why free_face_fontset could cause a segfault.  All that
> > function does is remove the fontset from the cache and put nil into
> > its slot.  Thereafter trying to access the fontset by its ID will
> > yield nil.
> 
> It's font_for_char that segfaults, or fontset_font, depending on whether
> assertions are enabled.
> 
> The code path is this, in the case with assertions:
> 
>   fontset = FONTSET_FROM_ID (face->fontset);  /* fontset is nil */
>   eassert (!BASE_FONTSET_P (fontset));
> 
> Since
> 
> #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
> 
> and
> 
> #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[3]
> 
> we end up looking at XCHAR_TABLE (Qnil)->extras[3], which segfaults
> because nil is not a char table.
> 
> The code path without assertions is similar, it just that the
> XCHAR_TABLE happens further down the call stack, in fontset_find_font.
> See the original backtrace.

OK, so adding protection against fontset being nil, where we currently
lack that, should take care of these cases, right?

> >> However, I would still prefer a solution which doesn't, even for a short
> >> period of time, leave the non-ASCII faces' ->ascii_face pointing to a
> >> face which has been freed, and their ->fontset identifying a fontset
> >> which might be nil.
> >
> > This goes against the design of the faces and their interaction with
> > the display code, I think.
> 
> If the design indeed relies on dangling pointers to freed memory
> surviving said freeing (it doesn't), that would be a very bad design
> indeed, particularly since this fact isn't documented.

Faces on this level (i.e. those cached in the frame's face cache and
referenced by their face ID) don't matter in Emacs until they are used
to display something.  The design, AFAIU it, is to make sure the
cached faces are in good shape when we need them for display.

> The correct thing to do here is to ensure all references to
> ascii_face are removed, by freeing the non-ASCII faces, before we
> remove the ascii_face itself.

Maybe.  I'm not yet sure, primarily because we use the current code
for so many decades.

> And please, let's document such "design decisions" (actually, bugs) if
> you refuse to let anyone fix them.  Having a pointer in a structure
> which might point to random memory is a bug unless there is a very loud
> comment advising us of this fact.

If I come to the conclusion that these are indeed bugs, I will try to
fix them, of course.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-26 19:20                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-27 11:47                                                                 ` Eli Zaretskii
  2024-08-27 19:26                                                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-27 11:47 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Mon, 26 Aug 2024 19:20:59 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
> 
> That was quick.  With this patch:
> 
> diff --git a/src/fontset.c b/src/fontset.c
> index 16d14669c89..41d845c9bc5 100644
> --- a/src/fontset.c
> +++ b/src/fontset.c
> @@ -921,8 +921,6 @@ free_face_fontset (struct frame *f, struct face *face)
>    eassert (! BASE_FONTSET_P (fontset));
>    eassert (f == XFRAME (FONTSET_FRAME (fontset)));
>    ASET (Vfontset_table, face->fontset, Qnil);
> -  if (face->fontset < next_fontset_id)
> -    next_fontset_id = face->fontset;
>    if (! NILP (FONTSET_DEFAULT (fontset)))
>      {
>        int id = XFIXNUM (FONTSET_ID (FONTSET_DEFAULT (fontset)));
> @@ -931,8 +929,6 @@ free_face_fontset (struct frame *f, struct face *face)
>        eassert (!NILP (fontset) && ! BASE_FONTSET_P (fontset));
>        eassert (f == XFRAME (FONTSET_FRAME (fontset)));
>        ASET (Vfontset_table, id, Qnil);
> -      if (id < next_fontset_id)
> -	next_fontset_id = face->fontset;
>      }
>    face->fontset = -1;
>  }
> diff --git a/src/xfaces.c b/src/xfaces.c
> index 684b6ccfac7..02fc934ee4d 100644
> --- a/src/xfaces.c
> +++ b/src/xfaces.c
> @@ -733,9 +733,12 @@ recompute_basic_faces (struct frame *f)
>  {
>    if (FRAME_FACE_CACHE (f))
>      {
> +      bool was_empty = FRAME_FACE_CACHE (f)->used == 0;
>        clear_face_cache (false);
>        if (!realize_basic_faces (f))
>  	emacs_abort ();
> +      if (!was_empty)
> +	f->face_change = true;
>      }
>  }
>  
> 
> and this hibiscus.el:
> 
> (while t
>   (insert (concat (make-string 1 (floor (random 132000)))))
>   (set-frame-parameter nil 'alpha-background 1.0)
>   (sit-for 1.0))
> 
> emacs -Q --load hibiscus.el works.  Without the last hunk, it segfaults
> almost immediately.
> 
> And the patch makes sense, too: if the face cache was empty, there's no
> need to set f->face_change to true.

That was the main idea of the patch I proposed, except that avoiding
to set the face_change flag when all we have in the cache are the
basic faces is a bit stronger, no?

> Is that case sufficiently common to result in acceptable
> performance?

Which case?





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-25 18:49                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-27 16:31                                                         ` Juri Linkov
  2024-08-28 11:50                                                           ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Juri Linkov @ 2024-08-27 16:31 UTC (permalink / raw)
  To: Pip Cet; +Cc: Eli Zaretskii, execvy, 72692

>> Reverting this line fixes the problem:
>>
>> -      f->face_change = true;
>
> Which OS is this on?  I'm having weird trouble when running the Windows
> binary in wine, which I attribute to this change: when menu-bar-mode is
> on, the Emacs frame raises itself whenever it loses focus.

This was on GNU/Linux (x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0),
Windowing system distributor 'The X.Org Foundation', version 11.0.12013000

> I see Eli reverted the change, which makes sense for now.  We'll have to
> find another way to fix this, I think.

I'm ready to test any changes when you'll find another way to fix this.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-27 11:44                                                               ` Eli Zaretskii
@ 2024-08-27 19:23                                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-28 11:41                                                                   ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-27 19:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Mon, 26 Aug 2024 19:04:13 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > --- a/src/xfaces.c
>> > +++ b/src/xfaces.c
>> > @@ -733,9 +733,13 @@ recompute_basic_faces (struct frame *f)
>> >  {
>> >    if (FRAME_FACE_CACHE (f))
>> >      {
>> > +      bool non_basic_faces_cached =
>> > +	FRAME_FACE_CACHE (f)->used >= BASIC_FACE_ID_SENTINEL;
>>
>> There's an off by one here, I think
>
> Yes, it should be > instead of >= .

Ah, okay.  I really wasn't sure.

>> FRAME_FACE_CACHE (f)->used is a
>> count, and it'll usually be equal to BASIC_FACE_ID_SENTINEL after the
>> basic faces have been realized, greater (never equal) if non-basic faces
>> have been realized, and 0 if no faces have been realized.
>>
>> So, in fact, your patch is equivalent to checking that FRAME_FACE_CACHE
>> (f)->used != 0, and only setting face_change if it was.
>
> As explained in my previous message, the test for having non-basic
> faces in the cache is because when we have only the basic faces, the
> problem with sharing the fontsets, and with having non-ASCII faces
> that point to released ASCII faces, cannot happen, and therefore
> there's no need to do anything.

Indeed, but that adds a perilous dependency on whether we only have the
basic faces (no non-ASCII faces in use) or not.

> It is true that 'used != 0' should also do the trick, but I realized

Indeed, it does.

> that testing against BASIC_FACE_ID_SENTINEL is stronger, because it
> also prevents setting the flag when we have some faces in the cache,
> but they are all basic.  Setting the face_change flag when we don't
> need that will cause us to unnecessarily re-realize the basic faces,
> so refraining from that prevents performance degradation.

So it's a performance optimization, and one which helps only users who
don't use non-ASCII during redisplay.

>> > The performance problem was caused by init_iterator calling
>> > recompute_basic_faces every time and then shooting itself in the foot
>> > by immediately setting the face_change flag,
>>
>> And it's easily fixed by clearing the face_change flag after
>> recompute_basic_faces runs, rather than before
>
> I don't follow: if we clear the flag after recompute_basic_faces
> exits, the faces will not be re-realized by next redisplay, and we
> might be back at the problem of having non-ASCII faces whose ASCII
> parents were removed from the cache and re-realize.  How will this be
> useful?  Or what am I missing?

'recompute_basic_faces' never realizes non-ASCII faces, and the face
cache was empty before we called it, so it's safe to leave the flag off.
The performance problem was caused by setting the flag unnecessarily in
these circumstances.

>> > but this is now avoided
>> > because init_iterator only calls recompute_basic_faces if the frame's
>> > face cache is empty.  Most other places that call
>> > recompute_basic_faces also do that when the cache is empty (in which
>> > case we don't have to worry about non-ASCII faces), but some call it
>> > unconditionally, and the above is for those.
>>
>> ??? I don't see any such callers in my backtraces of Emacs with or
>> without the patch
>
> There are 2 such callers in frame.c, one of them was in the backtrace
> you show in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#98,
> viz.:

Yes, but that was the reproducer, not code that ran into performance
issues.  Setting the background alpha is hardly performance critical :-)

> There's also one caller in fontset.c (which calls Fclear_face_cache
> before recompute_basic_faces, but Fclear_face_cache might decide not
> to clear the cache).
>
>> but I do see significant performance differences, so this must be
>> wrong.
>
> What performance difference did you see, and what is "this" that you
> think must be wrong?

"the above is for those".  It's not those callers that cause the
performance issue.

>> > Btw, thinking again about the original problem, I don't think I
>> > understand why free_face_fontset could cause a segfault.  All that
>> > function does is remove the fontset from the cache and put nil into
>> > its slot.  Thereafter trying to access the fontset by its ID will
>> > yield nil.
>>
>> It's font_for_char that segfaults, or fontset_font, depending on whether
>> assertions are enabled.
>>
>> The code path is this, in the case with assertions:
>>
>>   fontset = FONTSET_FROM_ID (face->fontset);  /* fontset is nil */
>>   eassert (!BASE_FONTSET_P (fontset));
>>
>> Since
>>
>> #define BASE_FONTSET_P(fontset) (NILP (FONTSET_BASE (fontset)))
>>
>> and
>>
>> #define FONTSET_BASE(fontset) XCHAR_TABLE (fontset)->extras[3]
>>
>> we end up looking at XCHAR_TABLE (Qnil)->extras[3], which segfaults
>> because nil is not a char table.
>>
>> The code path without assertions is similar, it just that the
>> XCHAR_TABLE happens further down the call stack, in fontset_find_font.
>> See the original backtrace.
>
> OK, so adding protection against fontset being nil, where we currently
> lack that, should take care of these cases, right?

It'll turn a segfaulting bug into a wrong-behavior bug.

>> >> However, I would still prefer a solution which doesn't, even for a short
>> >> period of time, leave the non-ASCII faces' ->ascii_face pointing to a
>> >> face which has been freed, and their ->fontset identifying a fontset
>> >> which might be nil.
>> >
>> > This goes against the design of the faces and their interaction with
>> > the display code, I think.
>>
>> If the design indeed relies on dangling pointers to freed memory
>> surviving said freeing (it doesn't), that would be a very bad design
>> indeed, particularly since this fact isn't documented.
>
> Faces on this level (i.e. those cached in the frame's face cache and
> referenced by their face ID) don't matter in Emacs until they are used
> to display something.  The design, AFAIU it, is to make sure the
> cached faces are in good shape when we need them for display.

Indeed, and dangling pointers hardly qualify as good shape.

>> The correct thing to do here is to ensure all references to
>> ascii_face are removed, by freeing the non-ASCII faces, before we
>> remove the ascii_face itself.
>
> Maybe.  I'm not yet sure, primarily because we use the current code
> for so many decades.

Okay, I can live with "maybe".

>> And please, let's document such "design decisions" (actually, bugs) if
>> you refuse to let anyone fix them.  Having a pointer in a structure
>> which might point to random memory is a bug unless there is a very loud
>> comment advising us of this fact.
>
> If I come to the conclusion that these are indeed bugs, I will try to
> fix them, of course.

I still think #72802 is clearly a bug and you said you didn't want it
fixed, so forgive my confusion on this matter.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-27 11:47                                                                 ` Eli Zaretskii
@ 2024-08-27 19:26                                                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-28 11:48                                                                     ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-27 19:26 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Eli Zaretskii" <eliz@gnu.org> writes:

> That was the main idea of the patch I proposed, except that avoiding
> to set the face_change flag when all we have in the cache are the
> basic faces is a bit stronger, no?

Indeed.  I think your proposed patch is the way to go, with the
off-by-one fixed.  I think there will be some slowdown for people using
non-ASCII faces in the modeline, in particular, but it should still
result in acceptable performance.

>> Is that case sufficiently common to result in acceptable
>> performance?
>
> Which case?

That only basic faces are realized, and we can therefore avoid freeing
any cached faces.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-27 19:23                                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-28 11:41                                                                   ` Eli Zaretskii
  2024-08-28 12:07                                                                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 11:41 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Tue, 27 Aug 2024 19:23:50 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > As explained in my previous message, the test for having non-basic
> > faces in the cache is because when we have only the basic faces, the
> > problem with sharing the fontsets, and with having non-ASCII faces
> > that point to released ASCII faces, cannot happen, and therefore
> > there's no need to do anything.
> 
> Indeed, but that adds a perilous dependency on whether we only have the
> basic faces (no non-ASCII faces in use) or not.

Why is it "perilous"?  It's an optimization, that's all.  (I don't
think there are any situations now where recompute_basic_faces could
be called when only part of the basic faces is realized, but I
couldn't convince myself in that fact, and having code that clearly
follows the idea, instead of simplifying it in a way that depends on
some assumption, sounded like better strategy, let alone more
future-proof.)

> > that testing against BASIC_FACE_ID_SENTINEL is stronger, because it
> > also prevents setting the flag when we have some faces in the cache,
> > but they are all basic.  Setting the face_change flag when we don't
> > need that will cause us to unnecessarily re-realize the basic faces,
> > so refraining from that prevents performance degradation.
> 
> So it's a performance optimization, and one which helps only users who
> don't use non-ASCII during redisplay.

It's a performance optimization, yes.  But the second part
misinterprets the intent, I think.  I would describe this differently:
when recompute_basic_faces is called and there are non-ASCII faces in
the cache, we _must_ set the face_change flag to recompute all the
faces, because otherwise the non-ASCII faces will be in danger of
being incorrect, and so will be their fontsets.  If there are no
non-ASCII faces in the cache, setting the face_change flag is not
needed, and doing so will make us do unnecessary (and potentially
expensive) work at the next call to init_iterator.

> >> > The performance problem was caused by init_iterator calling
> >> > recompute_basic_faces every time and then shooting itself in the foot
> >> > by immediately setting the face_change flag,
> >>
> >> And it's easily fixed by clearing the face_change flag after
> >> recompute_basic_faces runs, rather than before
> >
> > I don't follow: if we clear the flag after recompute_basic_faces
> > exits, the faces will not be re-realized by next redisplay, and we
> > might be back at the problem of having non-ASCII faces whose ASCII
> > parents were removed from the cache and re-realize.  How will this be
> > useful?  Or what am I missing?
> 
> 'recompute_basic_faces' never realizes non-ASCII faces, and the face
> cache was empty before we called it, so it's safe to leave the flag off.
> The performance problem was caused by setting the flag unnecessarily in
> these circumstances.

Well, now we refrain from setting the flag in the first place, so no
need to reset it.

> >> > but this is now avoided
> >> > because init_iterator only calls recompute_basic_faces if the frame's
> >> > face cache is empty.  Most other places that call
> >> > recompute_basic_faces also do that when the cache is empty (in which
> >> > case we don't have to worry about non-ASCII faces), but some call it
> >> > unconditionally, and the above is for those.
> >>
> >> ??? I don't see any such callers in my backtraces of Emacs with or
> >> without the patch
> >
> > There are 2 such callers in frame.c, one of them was in the backtrace
> > you show in https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#98,
> > viz.:
> 
> Yes, but that was the reproducer, not code that ran into performance
> issues.  Setting the background alpha is hardly performance critical :-)

The performance problem was caused by the solution which set the
face_change flag too eagerly.  There was no performance problem before
that.  The original motivation for the change which ended up making
the performance worse was not performance, it was to avoid the bug
which was shown by the reproducer, i.e. to handle the case where
recompute_basic_faces was called in a situation where there were
non-ASCII faces in the cache, as your traces about freeing their
fontset show.

> > There's also one caller in fontset.c (which calls Fclear_face_cache
> > before recompute_basic_faces, but Fclear_face_cache might decide not
> > to clear the cache).
> >
> >> but I do see significant performance differences, so this must be
> >> wrong.
> >
> > What performance difference did you see, and what is "this" that you
> > think must be wrong?
> 
> "the above is for those".  It's not those callers that cause the
> performance issue.

OK, so hopefully the problem will be gone now.

> >> we end up looking at XCHAR_TABLE (Qnil)->extras[3], which segfaults
> >> because nil is not a char table.
> >>
> >> The code path without assertions is similar, it just that the
> >> XCHAR_TABLE happens further down the call stack, in fontset_find_font.
> >> See the original backtrace.
> >
> > OK, so adding protection against fontset being nil, where we currently
> > lack that, should take care of these cases, right?
> 
> It'll turn a segfaulting bug into a wrong-behavior bug.

That depends on what the code we install to handle the nil case will
do, no?  If we do it correctly (assuming there is a correct way of
handling this), there will be no wrong behavior, right?

> >> If the design indeed relies on dangling pointers to freed memory
> >> surviving said freeing (it doesn't), that would be a very bad design
> >> indeed, particularly since this fact isn't documented.
> >
> > Faces on this level (i.e. those cached in the frame's face cache and
> > referenced by their face ID) don't matter in Emacs until they are used
> > to display something.  The design, AFAIU it, is to make sure the
> > cached faces are in good shape when we need them for display.
> 
> Indeed, and dangling pointers hardly qualify as good shape.

There's a misunderstanding here, I think.  The point I was trying to
make is that you will find in our code a lot of situations and paths
whereby faces are released while their cache indices (the FACE_ID
thing) are still stored in places.  A case in point is the current
glyph matrix of every window: it includes arrays of glyphs, where each
glyph stores its face id.  But the current matrix is accessed and if
needed updated only during redisplay, whereas the faces whose cache
indices it stores could be freed due to other reasons between
redisplay cycles.  The design therefore calls for the face_change to
be set whenever the face information cannot be trusted, and that flag
causes the display engine to throw away and recompute all the basic
faces before it does anything else.  As a side effect of this, all the
non-ASCII faces will disappear from the cache, and will be re-realized
and re-cached when they are needed.

It should be possible to change this basic design, so that whenever
faces are released, they are immediately regenerated, but (a) this
will be a very large job, and (b) I expect it to cause performance
degradation (unless we also radically change how faces are realized),
because it will most probably cause us to re-realize faces much more
frequently.  By contrast, the current design strives to do that
lazily, only when faces must be valid, and thus avoids expensive
recomputation of the faces as much as possible.

The case which we are discussing here is simply one more situation
where we must signal that faces are no longer reliable, but weren't
doing that until now.  At least this is how I understand it.

> >> The correct thing to do here is to ensure all references to
> >> ascii_face are removed, by freeing the non-ASCII faces, before we
> >> remove the ascii_face itself.
> >
> > Maybe.  I'm not yet sure, primarily because we use the current code
> > for so many decades.
> 
> Okay, I can live with "maybe".

See above a significant addition to "maybe".

> >> And please, let's document such "design decisions" (actually, bugs) if
> >> you refuse to let anyone fix them.  Having a pointer in a structure
> >> which might point to random memory is a bug unless there is a very loud
> >> comment advising us of this fact.
> >
> > If I come to the conclusion that these are indeed bugs, I will try to
> > fix them, of course.
> 
> I still think #72802 is clearly a bug and you said you didn't want it
> fixed, so forgive my confusion on this matter.

IMO, you over-reacted in that case.  I didn't say I didn't want to
solve that, I said I didn't want to install the solution on master at
this time.  I suggested instead to install it on a feature branch,
which will, I hope, be merged to master some time soon.  This is the
usual policy of not rushing non-trivial changes that could destabilize
Emacs until it either is urgent or we destabilize it for some other
good reason anyway.  We should always keep in mind that quite a few
people use the master branch for production sessions, so keeping it
relatively stable has a lot of merit in my book.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-27 19:26                                                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-28 11:48                                                                     ` Eli Zaretskii
  2024-08-28 11:58                                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 11:48 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Tue, 27 Aug 2024 19:26:21 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
> 
> "Eli Zaretskii" <eliz@gnu.org> writes:
> 
> > That was the main idea of the patch I proposed, except that avoiding
> > to set the face_change flag when all we have in the cache are the
> > basic faces is a bit stronger, no?
> 
> Indeed.  I think your proposed patch is the way to go, with the
> off-by-one fixed.  I think there will be some slowdown for people using
> non-ASCII faces in the modeline, in particular, but it should still
> result in acceptable performance.

Displaying the mode line calls init_iterator exactly once, AFAICT, so
I don't expect any special performance issues due to that.

> >> Is that case sufficiently common to result in acceptable
> >> performance?
> >
> > Which case?
> 
> That only basic faces are realized, and we can therefore avoid freeing
> any cached faces.

If you mean "only basic faces are realized" as opposed to "face cache
is empty", then it's quite possible that they are the same situation,
at least now.  (But in that case we don't lose anything, since the
test of cache->used = 0 is not cheaper than cache->used > SOMETHING.)
But if you mean "face cache is empty", then I think this situation is
quite common, yes.  People nowadays write Lisp code that creates and
modifies a lot of faces, and every change in the faces on the Lisp
level causes us to set the face_change flag, which then causes us to
empty the cache.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-27 16:31                                                         ` Juri Linkov
@ 2024-08-28 11:50                                                           ` Eli Zaretskii
  2024-08-28 16:21                                                             ` Juri Linkov
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 11:50 UTC (permalink / raw)
  To: Juri Linkov; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: Eli Zaretskii <eliz@gnu.org>,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Tue, 27 Aug 2024 19:31:37 +0300
> 
> >> Reverting this line fixes the problem:
> >>
> >> -      f->face_change = true;
> >
> > Which OS is this on?  I'm having weird trouble when running the Windows
> > binary in wine, which I attribute to this change: when menu-bar-mode is
> > on, the Emacs frame raises itself whenever it loses focus.
> 
> This was on GNU/Linux (x86_64-pc-linux-gnu, GTK+ Version 3.24.20, cairo version 1.16.0),
> Windowing system distributor 'The X.Org Foundation', version 11.0.12013000
> 
> > I see Eli reverted the change, which makes sense for now.  We'll have to
> > find another way to fix this, I think.
> 
> I'm ready to test any changes when you'll find another way to fix this.

Thanks, please test the patch below.  If it doesn't adversely affect
performance, I will install it.

diff --git a/src/xfaces.c b/src/xfaces.c
index 684b6cc..94fc59d 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -733,9 +733,13 @@ recompute_basic_faces (struct frame *f)
 {
   if (FRAME_FACE_CACHE (f))
     {
+      bool non_basic_faces_cached =
+	FRAME_FACE_CACHE (f)->used > BASIC_FACE_ID_SENTINEL;
       clear_face_cache (false);
       if (!realize_basic_faces (f))
 	emacs_abort ();
+      if (non_basic_faces_cached)
+	f->face_change = true;
     }
 }
 





^ permalink raw reply related	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 11:48                                                                     ` Eli Zaretskii
@ 2024-08-28 11:58                                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-28 11:58 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Tue, 27 Aug 2024 19:26:21 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > That was the main idea of the patch I proposed, except that avoiding
>> > to set the face_change flag when all we have in the cache are the
>> > basic faces is a bit stronger, no?
>>
>> Indeed.  I think your proposed patch is the way to go, with the
>> off-by-one fixed.  I think there will be some slowdown for people using
>> non-ASCII faces in the modeline, in particular, but it should still
>> result in acceptable performance.
>
> Displaying the mode line calls init_iterator exactly once, AFAICT, so
> I don't expect any special performance issues due to that.

I think you're right, and that I was confused.

>> >> Is that case sufficiently common to result in acceptable
>> >> performance?
>> >
>> > Which case?
>>
>> That only basic faces are realized, and we can therefore avoid freeing
>> any cached faces.
>
> If you mean "only basic faces are realized" as opposed to "face cache
> is empty", then it's quite possible that they are the same situation,
> at least now.

I think I saw a backtrace in which the basic faces were realized, but
I'm not entirely sure and I don't think it matters; your patch should
work and is the way to go.

> (But in that case we don't lose anything, since the
> test of cache->used = 0 is not cheaper than cache->used > SOMETHING.)
> But if you mean "face cache is empty", then I think this situation is
> quite common, yes.  People nowadays write Lisp code that creates and
> modifies a lot of faces, and every change in the faces on the Lisp
> level causes us to set the face_change flag, which then causes us to
> empty the cache.

Correct, but as we don't lose anything by performing your optimization,
let's go with that, assuming it survives testing and you don't come up
with something even better?

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 11:41                                                                   ` Eli Zaretskii
@ 2024-08-28 12:07                                                                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-28 12:51                                                                       ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-28 12:07 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: execvy, 72692, juri

"Eli Zaretskii" <eliz@gnu.org> writes:

>> Date: Tue, 27 Aug 2024 19:23:50 +0000
>> From: Pip Cet <pipcet@protonmail.com>
>> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
>>
>> "Eli Zaretskii" <eliz@gnu.org> writes:
>>
>> > As explained in my previous message, the test for having non-basic
>> > faces in the cache is because when we have only the basic faces, the
>> > problem with sharing the fontsets, and with having non-ASCII faces
>> > that point to released ASCII faces, cannot happen, and therefore
>> > there's no need to do anything.
>>
>> Indeed, but that adds a perilous dependency on whether we only have the
>> basic faces (no non-ASCII faces in use) or not.
>
> Why is it "perilous"?  It's an optimization, that's all.  (I don't

Sorry, my confusion, cleared up now.

>> > There's also one caller in fontset.c (which calls Fclear_face_cache
>> > before recompute_basic_faces, but Fclear_face_cache might decide not
>> > to clear the cache).
>> >
>> >> but I do see significant performance differences, so this must be
>> >> wrong.
>> >
>> > What performance difference did you see, and what is "this" that you
>> > think must be wrong?
>>
>> "the above is for those".  It's not those callers that cause the
>> performance issue.
>
> OK, so hopefully the problem will be gone now.

I agree.

>> >> we end up looking at XCHAR_TABLE (Qnil)->extras[3], which segfaults
>> >> because nil is not a char table.
>> >>
>> >> The code path without assertions is similar, it just that the
>> >> XCHAR_TABLE happens further down the call stack, in fontset_find_font.
>> >> See the original backtrace.
>> >
>> > OK, so adding protection against fontset being nil, where we currently
>> > lack that, should take care of these cases, right?
>>
>> It'll turn a segfaulting bug into a wrong-behavior bug.
>
> That depends on what the code we install to handle the nil case will
> do, no?  If we do it correctly (assuming there is a correct way of
> handling this), there will be no wrong behavior, right?

Yes, but that would require much more than checking for nil, it would
mean checking that the fontset entry is still valid and refers to the
same fontset it did originally, not a new fontset.

>> > Faces on this level (i.e. those cached in the frame's face cache and
>> > referenced by their face ID) don't matter in Emacs until they are used
>> > to display something.  The design, AFAIU it, is to make sure the
>> > cached faces are in good shape when we need them for display.
>>
>> Indeed, and dangling pointers hardly qualify as good shape.
>
> There's a misunderstanding here, I think.  The point I was trying to
> make is that you will find in our code a lot of situations and paths
> whereby faces are released while their cache indices (the FACE_ID
> thing) are still stored in places.  A case in point is the current
> glyph matrix of every window: it includes arrays of glyphs, where each
> glyph stores its face id.  But the current matrix is accessed and if
> needed updated only during redisplay, whereas the faces whose cache
> indices it stores could be freed due to other reasons between
> redisplay cycles.  The design therefore calls for the face_change to
> be set whenever the face information cannot be trusted, and that flag
> causes the display engine to throw away and recompute all the basic
> faces before it does anything else.  As a side effect of this, all the
> non-ASCII faces will disappear from the cache, and will be re-realized
> and re-cached when they are needed.
> It should be possible to change this basic design, so that whenever
> faces are released, they are immediately regenerated, but (a) this
> will be a very large job, and (b) I expect it to cause performance
> degradation (unless we also radically change how faces are realized),
> because it will most probably cause us to re-realize faces much more
> frequently.  By contrast, the current design strives to do that
> lazily, only when faces must be valid, and thus avoids expensive
> recomputation of the faces as much as possible.

Thanks for that explanation, I think it addresses my concerns but should
still be documented.  I shall attempt to come up with a documentation
patch.

> The case which we are discussing here is simply one more situation
> where we must signal that faces are no longer reliable, but weren't
> doing that until now.  At least this is how I understand it.

I agree now.

>> >> And please, let's document such "design decisions" (actually, bugs) if
>> >> you refuse to let anyone fix them.  Having a pointer in a structure
>> >> which might point to random memory is a bug unless there is a very loud
>> >> comment advising us of this fact.
>> >
>> > If I come to the conclusion that these are indeed bugs, I will try to
>> > fix them, of course.
>>
>> I still think #72802 is clearly a bug and you said you didn't want it
>> fixed, so forgive my confusion on this matter.
>
> IMO, you over-reacted in that case.  I didn't say I didn't want to
> solve that, I said I didn't want to install the solution on master at
> this time.  I suggested instead to install it on a feature branch,
> which will, I hope, be merged to master some time soon.  This is the
> usual policy of not rushing non-trivial changes that could destabilize
> Emacs until it either is urgent or we destabilize it for some other
> good reason anyway.  We should always keep in mind that quite a few
> people use the master branch for production sessions, so keeping it
> relatively stable has a lot of merit in my book.

Thank you, that is very helpful.  If you don't mind, I'll think about it
some more before deciding how to proceed there.  Obviously merging the
change only if/when the no-purespace branch is merged is perfectly
acceptable to me.  There is, indeed, no rush to do anything there.

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 12:07                                                                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-28 12:51                                                                       ` Eli Zaretskii
  0 siblings, 0 replies; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 12:51 UTC (permalink / raw)
  To: Pip Cet; +Cc: execvy, 72692, juri

> Date: Wed, 28 Aug 2024 12:07:05 +0000
> From: Pip Cet <pipcet@protonmail.com>
> Cc: execvy@gmail.com, 72692@debbugs.gnu.org, juri@linkov.net
> 
> >> >> The code path without assertions is similar, it just that the
> >> >> XCHAR_TABLE happens further down the call stack, in fontset_find_font.
> >> >> See the original backtrace.
> >> >
> >> > OK, so adding protection against fontset being nil, where we currently
> >> > lack that, should take care of these cases, right?
> >>
> >> It'll turn a segfaulting bug into a wrong-behavior bug.
> >
> > That depends on what the code we install to handle the nil case will
> > do, no?  If we do it correctly (assuming there is a correct way of
> > handling this), there will be no wrong behavior, right?
> 
> Yes, but that would require much more than checking for nil, it would
> mean checking that the fontset entry is still valid and refers to the
> same fontset it did originally, not a new fontset.

Yes, for the case of a non-nil but different fontset we need a
separate fix.  But that is a separate problem; I was talking only
about the case when the fontset was removed from the cache and its
slot set to nil.  We already have tests for this in many cases, but
not in all of them.

I will try to come up with something when I have time.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 11:50                                                           ` Eli Zaretskii
@ 2024-08-28 16:21                                                             ` Juri Linkov
  2024-08-28 17:53                                                               ` Eli Zaretskii
  2024-08-28 17:56                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 66+ messages in thread
From: Juri Linkov @ 2024-08-28 16:21 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pipcet, execvy, 72692

>> > I see Eli reverted the change, which makes sense for now.  We'll have to
>> > find another way to fix this, I think.
>> 
>> I'm ready to test any changes when you'll find another way to fix this.
>
> Thanks, please test the patch below.  If it doesn't adversely affect
> performance, I will install it.

With the previous change, when leaning on an arrow key, cursor motion
was visibly laggy since the cursor skipped 3-4 characters.

Now with this patch, the cursor visits every character without delays.

OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
and it's never visited.  So it seems this change has no effect
in normal circumstances.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 16:21                                                             ` Juri Linkov
@ 2024-08-28 17:53                                                               ` Eli Zaretskii
  2024-08-28 18:35                                                                 ` Juri Linkov
  2024-08-28 17:56                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 17:53 UTC (permalink / raw)
  To: Juri Linkov; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: pipcet@protonmail.com,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Wed, 28 Aug 2024 19:21:08 +0300
> 
> >> > I see Eli reverted the change, which makes sense for now.  We'll have to
> >> > find another way to fix this, I think.
> >> 
> >> I'm ready to test any changes when you'll find another way to fix this.
> >
> > Thanks, please test the patch below.  If it doesn't adversely affect
> > performance, I will install it.
> 
> With the previous change, when leaning on an arrow key, cursor motion
> was visibly laggy since the cursor skipped 3-4 characters.
> 
> Now with this patch, the cursor visits every character without delays.

Thanks, this is good news.

> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
> and it's never visited.  So it seems this change has no effect
> in normal circumstances.

I suggest to try Pip's recipe from

  https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#133

(but without patching the C sources).

But yes, in normal circumstances this is not needed, as AFAIU the
problem happens under rare conditions.  (Otherwise, we'd have
face-related crashes all over the place.)  The challenge was to find a
solution that doesn't make the normal cases more expensive, and still
manages to catch those where this is needed.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 16:21                                                             ` Juri Linkov
  2024-08-28 17:53                                                               ` Eli Zaretskii
@ 2024-08-28 17:56                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 0 replies; 66+ messages in thread
From: Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-28 17:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Eli Zaretskii, execvy, 72692

"Juri Linkov" <juri@linkov.net> writes:

>>> > I see Eli reverted the change, which makes sense for now.  We'll have to
>>> > find another way to fix this, I think.
>>>
>>> I'm ready to test any changes when you'll find another way to fix this.
>>
>> Thanks, please test the patch below.  If it doesn't adversely affect
>> performance, I will install it.
>
> With the previous change, when leaning on an arrow key, cursor motion
> was visibly laggy since the cursor skipped 3-4 characters.
>
> Now with this patch, the cursor visits every character without delays.

Excellent.

> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
> and it's never visited.  So it seems this change has no effect
> in normal circumstances.

I'm not sure that's the right way around: we try to execute the code
inside 'if (non_basic_faces_cached)' as rarely as possible, with Eli's
change, and never executing it at all is the best possible outcome (and
the expected one if no non-standard faces or non-ASCII characters are in
use).

Pip






^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 17:53                                                               ` Eli Zaretskii
@ 2024-08-28 18:35                                                                 ` Juri Linkov
  2024-08-28 18:57                                                                   ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Juri Linkov @ 2024-08-28 18:35 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pipcet, execvy, 72692

>> Now with this patch, the cursor visits every character without delays.
>
> Thanks, this is good news.
>
>> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
>> and it's never visited.  So it seems this change has no effect
>> in normal circumstances.
>
> I suggest to try Pip's recipe from
>
>   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#133
>
> (but without patching the C sources).

I tried Pip's recipe with the while loop, and it doesn't segfault.
But it doesn't segfault without your patch either.
So I couldn't confirm if the patch fixes the crashes.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 18:35                                                                 ` Juri Linkov
@ 2024-08-28 18:57                                                                   ` Eli Zaretskii
  2024-08-28 19:02                                                                     ` Juri Linkov
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-28 18:57 UTC (permalink / raw)
  To: Juri Linkov; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: pipcet@protonmail.com,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Wed, 28 Aug 2024 21:35:56 +0300
> 
> >> Now with this patch, the cursor visits every character without delays.
> >
> > Thanks, this is good news.
> >
> >> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
> >> and it's never visited.  So it seems this change has no effect
> >> in normal circumstances.
> >
> > I suggest to try Pip's recipe from
> >
> >   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#133
> >
> > (but without patching the C sources).
> 
> I tried Pip's recipe with the while loop, and it doesn't segfault.
> But it doesn't segfault without your patch either.
> So I couldn't confirm if the patch fixes the crashes.

I meant to use that recipe to trigger the breakpoint inside
'if (non_basic_faces_cached)'.

But maybe that will also not happen for you.  I think the result
depends on which fonts are installed on your system.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 18:57                                                                   ` Eli Zaretskii
@ 2024-08-28 19:02                                                                     ` Juri Linkov
  2024-08-29  4:36                                                                       ` Eli Zaretskii
  2024-08-29 10:06                                                                       ` Eli Zaretskii
  0 siblings, 2 replies; 66+ messages in thread
From: Juri Linkov @ 2024-08-28 19:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pipcet, execvy, 72692

>> >> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
>> >> and it's never visited.  So it seems this change has no effect
>> >> in normal circumstances.
>> >
>> > I suggest to try Pip's recipe from
>> >
>> >   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#133
>> >
>> > (but without patching the C sources).
>> 
>> I tried Pip's recipe with the while loop, and it doesn't segfault.
>> But it doesn't segfault without your patch either.
>> So I couldn't confirm if the patch fixes the crashes.
>
> I meant to use that recipe to trigger the breakpoint inside
> 'if (non_basic_faces_cached)'.

The breakpoint inside 'if (non_basic_faces_cached)'
is triggered on every character inserted by Pip's recipe.
So the condition in your patch works in this test,
whereas it's never triggered in normal use.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 19:02                                                                     ` Juri Linkov
@ 2024-08-29  4:36                                                                       ` Eli Zaretskii
  2024-08-29 10:06                                                                       ` Eli Zaretskii
  1 sibling, 0 replies; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-29  4:36 UTC (permalink / raw)
  To: Juri Linkov; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: pipcet@protonmail.com,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Wed, 28 Aug 2024 22:02:44 +0300
> 
> >> >> OTOH, I tried to set a breakpoint inside 'if (non_basic_faces_cached)',
> >> >> and it's never visited.  So it seems this change has no effect
> >> >> in normal circumstances.
> >> >
> >> > I suggest to try Pip's recipe from
> >> >
> >> >   https://debbugs.gnu.org/cgi/bugreport.cgi?bug=72692#133
> >> >
> >> > (but without patching the C sources).
> >> 
> >> I tried Pip's recipe with the while loop, and it doesn't segfault.
> >> But it doesn't segfault without your patch either.
> >> So I couldn't confirm if the patch fixes the crashes.
> >
> > I meant to use that recipe to trigger the breakpoint inside
> > 'if (non_basic_faces_cached)'.
> 
> The breakpoint inside 'if (non_basic_faces_cached)'
> is triggered on every character inserted by Pip's recipe.
> So the condition in your patch works in this test,
> whereas it's never triggered in normal use.

Thanks.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-28 19:02                                                                     ` Juri Linkov
  2024-08-29  4:36                                                                       ` Eli Zaretskii
@ 2024-08-29 10:06                                                                       ` Eli Zaretskii
  2024-08-29 12:06                                                                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  1 sibling, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-29 10:06 UTC (permalink / raw)
  To: Juri Linkov, Po Lu; +Cc: pipcet, execvy, 72692

> From: Juri Linkov <juri@linkov.net>
> Cc: pipcet@protonmail.com,  execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Wed, 28 Aug 2024 22:02:44 +0300
> 
> The breakpoint inside 'if (non_basic_faces_cached)'
> is triggered on every character inserted by Pip's recipe.
> So the condition in your patch works in this test,
> whereas it's never triggered in normal use.

Thanks, I've now installed the change in xfaces.c.

The fact that we hit that breakpoint for every character bothered me,
so I looked into it.  It turns out we do that because the test calls
set-frame-parameter inside the loop to set the frame's
alpha-background parameter.  But the value of alpha-background is the
same in all the calls: 1.0.  So this call is basically a no-op, but
gui_set_alpha_background, which is the handler of alpha-background
parameter, doesn't check that the value is the same, and not only sets
the same value, but also recomputes all the basic faces (on the
assumption that alpha-background changed).  It also sets the frame's
garbaged flag.  This is silly, since we are shooting ourselves in the
foot by slowing down the following redisplay cycle: it will need to
re-realize all the faces and also perform a thorough redisplay of all
of the frame's windows.

Then I looked at the other handlers of frame parameters, and it turns
out almost none of them check that the new value is different,
although they all receive the old value as their last argument!

Po Lu, is there any reason why frame-parameter handlers for GUI frames
should ignore the fact that the new value of a parameter is exactly
equal to the old value?  Is there some subtle issue here, and if so,
does it affect all the parameters or only some?

If there's no real reason for this, I think we should teach the
handlers to do nothing if the new value is identical to the old one.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-29 10:06                                                                       ` Eli Zaretskii
@ 2024-08-29 12:06                                                                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  2024-08-29 12:26                                                                           ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-08-29 12:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pipcet, execvy, 72692, Juri Linkov

Eli Zaretskii <eliz@gnu.org> writes:

> Po Lu, is there any reason why frame-parameter handlers for GUI frames
> should ignore the fact that the new value of a parameter is exactly
> equal to the old value?  Is there some subtle issue here, and if so,
> does it affect all the parameters or only some?

No reason occurs to me why redundant changes shouldn't be discarded in
the case of alpha-background, but modifications to other parameters
(e.g. Qfullscreen) always trigger recomputation of various window
manager properties and states, which is not redundant when these
properties change without Emacs's knowledge.





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-29 12:06                                                                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2024-08-29 12:26                                                                           ` Eli Zaretskii
  2024-09-07  7:52                                                                             ` Eli Zaretskii
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-08-29 12:26 UTC (permalink / raw)
  To: Po Lu; +Cc: pipcet, execvy, 72692, juri

> From: Po Lu <luangruo@yahoo.com>
> Cc: Juri Linkov <juri@linkov.net>,  pipcet@protonmail.com,
>   execvy@gmail.com,  72692@debbugs.gnu.org
> Date: Thu, 29 Aug 2024 20:06:17 +0800
> 
> Eli Zaretskii <eliz@gnu.org> writes:
> 
> > Po Lu, is there any reason why frame-parameter handlers for GUI frames
> > should ignore the fact that the new value of a parameter is exactly
> > equal to the old value?  Is there some subtle issue here, and if so,
> > does it affect all the parameters or only some?
> 
> No reason occurs to me why redundant changes shouldn't be discarded in
> the case of alpha-background, but modifications to other parameters
> (e.g. Qfullscreen) always trigger recomputation of various window
> manager properties and states, which is not redundant when these
> properties change without Emacs's knowledge.

OK, I was aware of the issues with Qfullscreen.

But what about the rest?  Would you mind reviewing the other handlers
in frame.c, and telling which ones should do their thing regardless of
whether the old and the new value of the parameter are identical?

TIA





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-08-29 12:26                                                                           ` Eli Zaretskii
@ 2024-09-07  7:52                                                                             ` Eli Zaretskii
  2024-09-08  0:42                                                                               ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 1 reply; 66+ messages in thread
From: Eli Zaretskii @ 2024-09-07  7:52 UTC (permalink / raw)
  To: luangruo; +Cc: pipcet, execvy, 72692, juri

> Cc: pipcet@protonmail.com, execvy@gmail.com, 72692@debbugs.gnu.org,
>  juri@linkov.net
> Date: Thu, 29 Aug 2024 15:26:07 +0300
> From: Eli Zaretskii <eliz@gnu.org>
> 
> > From: Po Lu <luangruo@yahoo.com>
> > Cc: Juri Linkov <juri@linkov.net>,  pipcet@protonmail.com,
> >   execvy@gmail.com,  72692@debbugs.gnu.org
> > Date: Thu, 29 Aug 2024 20:06:17 +0800
> > 
> > Eli Zaretskii <eliz@gnu.org> writes:
> > 
> > > Po Lu, is there any reason why frame-parameter handlers for GUI frames
> > > should ignore the fact that the new value of a parameter is exactly
> > > equal to the old value?  Is there some subtle issue here, and if so,
> > > does it affect all the parameters or only some?
> > 
> > No reason occurs to me why redundant changes shouldn't be discarded in
> > the case of alpha-background, but modifications to other parameters
> > (e.g. Qfullscreen) always trigger recomputation of various window
> > manager properties and states, which is not redundant when these
> > properties change without Emacs's knowledge.
> 
> OK, I was aware of the issues with Qfullscreen.
> 
> But what about the rest?  Would you mind reviewing the other handlers
> in frame.c, and telling which ones should do their thing regardless of
> whether the old and the new value of the parameter are identical?

Ping!





^ permalink raw reply	[flat|nested] 66+ messages in thread

* bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland)
  2024-09-07  7:52                                                                             ` Eli Zaretskii
@ 2024-09-08  0:42                                                                               ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 0 replies; 66+ messages in thread
From: Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2024-09-08  0:42 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: pipcet, execvy, 72692, juri

Eli Zaretskii <eliz@gnu.org> writes:

>> Cc: pipcet@protonmail.com, execvy@gmail.com, 72692@debbugs.gnu.org,
>>  juri@linkov.net
>> Date: Thu, 29 Aug 2024 15:26:07 +0300
>> From: Eli Zaretskii <eliz@gnu.org>
>> 
>> > From: Po Lu <luangruo@yahoo.com>
>> > Cc: Juri Linkov <juri@linkov.net>,  pipcet@protonmail.com,
>> >   execvy@gmail.com,  72692@debbugs.gnu.org
>> > Date: Thu, 29 Aug 2024 20:06:17 +0800
>> > 
>> > Eli Zaretskii <eliz@gnu.org> writes:
>> > 
>> > > Po Lu, is there any reason why frame-parameter handlers for GUI frames
>> > > should ignore the fact that the new value of a parameter is exactly
>> > > equal to the old value?  Is there some subtle issue here, and if so,
>> > > does it affect all the parameters or only some?
>> > 
>> > No reason occurs to me why redundant changes shouldn't be discarded in
>> > the case of alpha-background, but modifications to other parameters
>> > (e.g. Qfullscreen) always trigger recomputation of various window
>> > manager properties and states, which is not redundant when these
>> > properties change without Emacs's knowledge.
>> 
>> OK, I was aware of the issues with Qfullscreen.
>> 
>> But what about the rest?  Would you mind reviewing the other handlers
>> in frame.c, and telling which ones should do their thing regardless of
>> whether the old and the new value of the parameter are identical?
>
> Ping!

I will, but after the release.  I'm a little drained of energy for these
matters at the moment.





^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2024-09-08  0:42 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-18  8:29 bug#72692: Emacs 31.05 (40eecd594ac) get SIGSEGV on Linux (Linux 6.6.45 Kde Wayland) Eval EXEC
2024-08-18  8:58 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18  9:08   ` Eval EXEC
2024-08-18  9:23     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18  9:24       ` execvy
2024-08-18  9:34         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18  9:36           ` execvy
2024-08-18 12:43             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 12:53               ` execvy
2024-08-18 13:35               ` Eli Zaretskii
2024-08-18 13:44                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 14:12                   ` Eli Zaretskii
2024-08-18 14:59                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 15:38                       ` Eli Zaretskii
2024-08-18 16:08                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 17:55                           ` Eli Zaretskii
2024-08-18 18:11                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 18:52                               ` Eli Zaretskii
2024-08-19  6:17                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 17:56                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-18 18:38                             ` Eli Zaretskii
2024-08-19  6:28                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 11:30                                 ` Eli Zaretskii
2024-08-19 13:32                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 14:35                                     ` Eli Zaretskii
2024-08-19 15:03                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 15:54                                         ` Eli Zaretskii
2024-08-19 16:34                                           ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 16:49                                             ` Eli Zaretskii
2024-08-24  9:09                                               ` Eli Zaretskii
2024-08-24 10:04                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-24 10:13                                                   ` Eli Zaretskii
2024-08-25 17:58                                                     ` Juri Linkov
2024-08-25 18:49                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-27 16:31                                                         ` Juri Linkov
2024-08-28 11:50                                                           ` Eli Zaretskii
2024-08-28 16:21                                                             ` Juri Linkov
2024-08-28 17:53                                                               ` Eli Zaretskii
2024-08-28 18:35                                                                 ` Juri Linkov
2024-08-28 18:57                                                                   ` Eli Zaretskii
2024-08-28 19:02                                                                     ` Juri Linkov
2024-08-29  4:36                                                                       ` Eli Zaretskii
2024-08-29 10:06                                                                       ` Eli Zaretskii
2024-08-29 12:06                                                                         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-29 12:26                                                                           ` Eli Zaretskii
2024-09-07  7:52                                                                             ` Eli Zaretskii
2024-09-08  0:42                                                                               ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-28 17:56                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-25 18:57                                                       ` Eli Zaretskii
2024-08-26  5:52                                                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-26 12:39                                                           ` Eli Zaretskii
2024-08-26 19:04                                                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-26 19:20                                                               ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-27 11:47                                                                 ` Eli Zaretskii
2024-08-27 19:26                                                                   ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-28 11:48                                                                     ` Eli Zaretskii
2024-08-28 11:58                                                                       ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-27 11:44                                                               ` Eli Zaretskii
2024-08-27 19:23                                                                 ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-28 11:41                                                                   ` Eli Zaretskii
2024-08-28 12:07                                                                     ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-28 12:51                                                                       ` Eli Zaretskii
2024-08-18 19:24                       ` Eli Zaretskii
2024-08-19  6:07                         ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-08-19 14:17                           ` Eli Zaretskii
2024-08-19 14:44                             ` Pip Cet via Bug reports for GNU Emacs, the Swiss army knife of text editors

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.