aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2024-04-13 19:43:40 +0800
committerPo Lu2024-04-13 19:44:34 +0800
commit9fc698479feef6fa660ff13e21619ea50bd404df (patch)
tree89af5b1e136fd6273db592a61e2255bb3a4ea717
parentadbcf268bc81c439f90b1016700d8a0a234e12b7 (diff)
downloademacs-9fc698479feef6fa660ff13e21619ea50bd404df.tar.gz
emacs-9fc698479feef6fa660ff13e21619ea50bd404df.zip
Fix crash upon call to Fset_fontset_font after X server disconnect
* src/image.c (free_image): * src/xfaces.c (free_realized_face): Handle scenarios where free_frame_faces is called with the display connection cut. * src/xterm.c (x_free_frame_resources): Call free_frame_faces unconditionally, lest fontsets for this dead frame contaminate Vfontset_list and produce crashes afterwards. (bug#66151)
-rw-r--r--src/image.c26
-rw-r--r--src/xfaces.c9
-rw-r--r--src/xterm.c15
3 files changed, 39 insertions, 11 deletions
diff --git a/src/image.c b/src/image.c
index 216bdc1ee66..3968145728f 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1699,14 +1699,26 @@ free_image (struct frame *f, struct image *img)
1699 c->images[img->id] = NULL; 1699 c->images[img->id] = NULL;
1700 1700
1701#if !defined USE_CAIRO && defined HAVE_XRENDER 1701#if !defined USE_CAIRO && defined HAVE_XRENDER
1702 if (img->picture) 1702 /* FRAME_X_DISPLAY (f) could be NULL if this is being called from
1703 XRenderFreePicture (FRAME_X_DISPLAY (f), img->picture); 1703 the display IO error handler.*/
1704 if (img->mask_picture) 1704
1705 XRenderFreePicture (FRAME_X_DISPLAY (f), img->mask_picture); 1705 if (FRAME_X_DISPLAY (f))
1706#endif 1706 {
1707 if (img->picture)
1708 XRenderFreePicture (FRAME_X_DISPLAY (f),
1709 img->picture);
1710 if (img->mask_picture)
1711 XRenderFreePicture (FRAME_X_DISPLAY (f),
1712 img->mask_picture);
1713 }
1714#endif /* !USE_CAIRO && HAVE_XRENDER */
1715
1716#ifdef HAVE_X_WINDOWS
1717 if (FRAME_X_DISPLAY (f))
1718#endif /* HAVE_X_WINDOWS */
1719 /* Free resources, then free IMG. */
1720 img->type->free_img (f, img);
1707 1721
1708 /* Free resources, then free IMG. */
1709 img->type->free_img (f, img);
1710 xfree (img->face_font_family); 1722 xfree (img->face_font_family);
1711 xfree (img); 1723 xfree (img);
1712 } 1724 }
diff --git a/src/xfaces.c b/src/xfaces.c
index a558e7328c0..d4583e1a78f 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4569,6 +4569,15 @@ free_realized_face (struct frame *f, struct face *face)
4569 /* Free fontset of FACE if it is ASCII face. */ 4569 /* Free fontset of FACE if it is ASCII face. */
4570 if (face->fontset >= 0 && face == face->ascii_face) 4570 if (face->fontset >= 0 && face == face->ascii_face)
4571 free_face_fontset (f, face); 4571 free_face_fontset (f, face);
4572
4573#ifdef HAVE_X_WINDOWS
4574 /* This function might be called with the frame's display
4575 connection deleted, in which event the callbacks below
4576 should not be executed, as they generate X requests. */
4577 if (FRAME_X_DISPLAY (f))
4578 return;
4579#endif /* HAVE_X_WINDOWS */
4580
4572 if (face->gc) 4581 if (face->gc)
4573 { 4582 {
4574 block_input (); 4583 block_input ();
diff --git a/src/xterm.c b/src/xterm.c
index 5e5eb6269e4..e08ffd15b18 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -29428,6 +29428,17 @@ x_free_frame_resources (struct frame *f)
29428 xi_unlink_touch_points (f); 29428 xi_unlink_touch_points (f);
29429#endif 29429#endif
29430 29430
29431 /* We must free faces before destroying windows because some
29432 font-driver (e.g. xft) access a window while finishing a face.
29433
29434 This function must be called to remove this frame's fontsets from
29435 Vfontset_list, and is itself responsible for not issuing X requests
29436 if the connection has already been terminated. Otherwise, a future
29437 call to a function that iterates over all existing fontsets might
29438 crash, as they are not prepared to receive dead frames.
29439 (bug#66151) */
29440 free_frame_faces (f);
29441
29431 /* If a display connection is dead, don't try sending more 29442 /* If a display connection is dead, don't try sending more
29432 commands to the X server. */ 29443 commands to the X server. */
29433 if (dpyinfo->display) 29444 if (dpyinfo->display)
@@ -29437,10 +29448,6 @@ x_free_frame_resources (struct frame *f)
29437 if (f->pointer_invisible) 29448 if (f->pointer_invisible)
29438 XTtoggle_invisible_pointer (f, 0); 29449 XTtoggle_invisible_pointer (f, 0);
29439 29450
29440 /* We must free faces before destroying windows because some
29441 font-driver (e.g. xft) access a window while finishing a
29442 face. */
29443 free_frame_faces (f);
29444 tear_down_x_back_buffer (f); 29451 tear_down_x_back_buffer (f);
29445 29452
29446 if (f->output_data.x->icon_desc) 29453 if (f->output_data.x->icon_desc)