unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
To: Shannon Jones <cz2s20d02@sneakemail.com>,
	3399@emacsbugs.donarmstrong.com
Subject: bug#3399: Crash in multi-TTY mode
Date: Wed, 27 May 2009 17:27:05 +0900	[thread overview]
Message-ID: <wleiub54ti.wl%mituharu@math.s.chiba-u.ac.jp> (raw)
In-Reply-To: <8369-76746@sneakemail.com>

>>>>> On 27 May 2009 02:44:23 -0000, "Shannon Jones" <cz2s20d02@sneakemail.com> said:

> I'm almost embarrassed to report this, since it's rather strange and
> most likely unique to my setup.  Still, it involves a crash so I
> thought it would be worthwhile to see if anyone else can reproduce
> it.

I could reproduce it on GTK+/Mac OS X with the following steps.

  $ emacs -nw -Q
  M-x server-start RET
  $ emacsclient -c
  C-x 5 0 (on the X11 frame)

The problematic scenario is:

  1. XGetDefault is called in several GTK+ initialization steps.  It
     sets the XlibDisplayDfltRMDB bit in dpy->flags but dpy->db
     remains to be NULL in some cases (InitDefaults may return NULL).

    GetDflt.c (libX11-1.2.1):

    char *
    XGetDefault(
	    Display *dpy,			/* display for defaults.... */
	    char _Xconst *prog,		/* name of program for option	*/
	    register _Xconst char *name)	/* name of option program wants */
    {					/* to get, for example, "font"  */

	:

	    /*
	     * see if database has ever been initialized.  Lookups can be done
	     * without locks held.
	     */
	    LockDisplay(dpy);
	    if (dpy->db == NULL) {
		dpy->db = InitDefaults(dpy);
		dpy->flags |= XlibDisplayDfltRMDB;
	    }
	    UnlockDisplay(dpy);

	:

    }
  2. x_term_init calls XrmSetDatabase, but it doesn't reset the
     XlibDisplayDfltRMDB bit if display->db is NULL.  As a result,
     display->db holds a new database but XlibDisplayDfltRMDB is still
     set.

    Xrm.c (libX11-1.2.1):

    void XrmSetDatabase(
	Display *display,
	XrmDatabase database)
    {
	LockDisplay(display);
	/* destroy database if set up imlicitely by XGetDefault() */
	if (display->db && (display->flags & XlibDisplayDfltRMDB)) {
	    XrmDestroyDatabase(display->db);
	    display->flags &= ~XlibDisplayDfltRMDB;
	}
	display->db = database;
	UnlockDisplay(display);
    }

  3. x_delete_terminal does XrmSetDatabase(dpyinfo->display, NULL) to
     dissociate the database from the display.  Because
     XlibDisplayDfltRMDB is set, it destroys the database to be
     dissociated.

  4. x_delete_terminal then calls XrmSetDatabase and destroys the
     dissociated database again.  This causes crash.

I think this a bug in libX11.  It should either 1) not set
XlibDisplayDfltRMDB in XGetDefault unless dpy->db becomes non-NULL or
2) reset XlibDisplayDfltRMDB in XrmSetDatabase even if the previous
database is NULL.

Below is a possible workaround.  Unfortunately, we need to touch some
X11 internal data structures.

				     YAMAMOTO Mitsuharu
				mituharu@math.s.chiba-u.ac.jp

Index: src/xterm.c
===================================================================
RCS file: /sources/emacs/emacs/src/xterm.c,v
retrieving revision 1.1026
diff -c -p -r1.1026 xterm.c
*** src/xterm.c	19 May 2009 00:26:46 -0000	1.1026
--- src/xterm.c	27 May 2009 07:59:20 -0000
*************** along with GNU Emacs.  If not, see <http
*** 31,36 ****
--- 31,40 ----
  
  #ifdef HAVE_X_WINDOWS
  
+ /* This makes the fields of a Display accessible, in Xlib header files.  */
+ 
+ #define XLIB_ILLEGAL_ACCESS
+ 
  #include "lisp.h"
  #include "blockinput.h"
  
*************** x_term_init (display_name, xrm_option, r
*** 10285,10290 ****
--- 10289,10304 ----
  
    xrdb = x_load_resources (dpyinfo->display, xrm_option,
  			   resource_name, EMACS_CLASS);
+   /* This is a workaround for a bug in some versions of libX11.
+      XGetDefault may set XlibDisplayDfltRMDB (1L << 7) in dpy->flags
+      (dpyinfo->display->private16) even when dpy->db
+      (dpyinfo->display->db) remains to be NULL, and XrmSetDatabase
+      doesn't clear the flag if dpy->db is NULL.  This causes crash in
+      the XrmDestroyDatabase call from x_delete_terminal because the
+      preceding XrmSetDatabase call destroys the associated database
+      because of the XlibDisplayDfltRMDB flag.  */
+   if (dpyinfo->display->db == NULL)
+     dpyinfo->display->private16 &= ~(1L << 7);
  #ifdef HAVE_XRMSETDATABASE
    XrmSetDatabase (dpyinfo->display, xrdb);
  #else





  reply	other threads:[~2009-05-27  8:27 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-05-27  2:44 bug#3399: Crash in multi-TTY mode Shannon Jones
2009-05-27  8:27 ` YAMAMOTO Mitsuharu [this message]
2009-05-27 14:31   ` Stefan Monnier
2009-05-28  0:47     ` YAMAMOTO Mitsuharu
2009-05-28  1:25       ` YAMAMOTO Mitsuharu
2009-05-28 13:14       ` Stefan Monnier
2009-05-29  3:58         ` YAMAMOTO Mitsuharu
2009-05-29 14:30           ` Stefan Monnier
2009-05-30  2:25             ` YAMAMOTO Mitsuharu
2009-05-30 20:37               ` Stefan Monnier
2009-05-31  7:05                 ` YAMAMOTO Mitsuharu
2009-06-01 14:37                   ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=wleiub54ti.wl%mituharu@math.s.chiba-u.ac.jp \
    --to=mituharu@math.s.chiba-u.ac.jp \
    --cc=3399@emacsbugs.donarmstrong.com \
    --cc=cz2s20d02@sneakemail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).