emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

New Issue following up on Issue #221 Emacs disconnects


From: Madhu
Subject: New Issue following up on Issue #221 Emacs disconnects
Date: Tue, 17 Dec 2019 05:28:50 +0530 (IST)

[BCC'd to open a new issue on gnome.gitlab.org. Re."That old GTK bug"]

Attached is a reduced test case which was requested in the now closed
issue #221 - quickly sloppily hacked up from simple.c from gtk+-demos.

gtk_main is replaced by a loop which calls g_main_context_iteration.
X errors are handled via XSetIOErrorHandler and XSetErrorHandler to
handle a closed display and continue with the next
g_main_context_iteration.

To Run the test case:
gcc simple.c -Wno-deprecated -Wno-deprecated-declarations -g3 $(pkg-config 
gtk+-3.0 --cflags --libs ) -lX11
$ DISPLAY=:0 Xephyr :1
$ DISPLAY=:1 G_DEBUG=fatal-warnings ./a.out
kill Xephyr

The stack trace which you get from killing Xephyr is attached.

[Also featured in the code but not relevant to this bug report is the
"closed" signal which is expected from when GdkDisplay connection is
lost. This signal does not seem to fire]


/* simple.c
 * Copyright (C) 1997  Red Hat, Inc
 * Author: Elliot Lee
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
 */
#include <gtk/gtk.h>
#include <gtk/gtkx.h>
#include <setjmp.h>

jmp_buf jmp_ret;


void
gdk_display_closed_callback(GdkDisplay *display, gboolean is_error, gpointer 
data)
{
  fprintf(stderr, "gdk_display_closed_callback %p is_error=%d data=%p\n",
          display, is_error, data);
}

void
register_closed_callback()
{
  Display *dpy = gdk_x11_display_get_xdisplay (gdk_display_get_default ());
  GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (dpy);
  int closed_callback_tag = g_signal_connect
    (G_OBJECT (gdpy),
     "closed",
     G_CALLBACK (gdk_display_closed_callback),
     NULL);
  if (!closed_callback_tag) {
    fprintf(stderr, "failed to register a callback on gdk display ::closed\n");
  } else {
    fprintf(stderr, "registered \"closed\" callback on gdk display %p dpy 
%s\n", gdpy, DisplayString(dpy));
  }
}

void
hello (void)
{
  g_print ("hello world\n");
}

void
x_error_quitter (Display *display, XErrorEvent *event)
{
  if (event->error_code == BadName)
    return;
  char buf[256];
  XGetErrorText (display, event->error_code, buf, sizeof (buf));
  fprintf(stderr, "x_error_quitter on %s: error %s on protocol request %d\n",
          DisplayString(display), buf, event->request_code);
  longjmp(jmp_ret, 1);
}


static  int
x_io_error_quitter (Display *display)
{
  fprintf(stderr, "Connection lost to X Server%s\n", DisplayString (display));
  longjmp(jmp_ret, 2);
}

static int
x_error_handler (Display *display, XErrorEvent *event)
{
  fprintf(stderr, "x_error_handler %p %p\n", display, event);
  if ((event->error_code == BadMatch || event->error_code == BadWindow)
      /* && event->request_code == X_SetInputFocus */)
    {
      return 0;
    }
  x_error_quitter (display, event);
  return 0;
}

void my_gtk_main_quit(GtkWidget *window, gboolean *kill_switch)
{
  fprintf(stderr, "my_gtk_main_quit()\n");
  *kill_switch = True;
}

int
main (int argc, char *argv[])
{
  GtkWidget *window;

  gtk_init (&argc, &argv);
  register_closed_callback();
  XSetErrorHandler (x_error_handler);
  XSetIOErrorHandler (x_io_error_quitter);
  gboolean kill_switch = False;
  window = g_object_connect (g_object_new (gtk_window_get_type (),
                                           "type", GTK_WINDOW_TOPLEVEL,
                                           "title", "hello world",
                                           "resizable", FALSE,
                                           "border_width", 10,
                                           NULL),
                             "signal::destroy", my_gtk_main_quit, &kill_switch,
                             NULL);
  g_object_connect (g_object_new (gtk_button_get_type (),
                                  "GtkButton::label", "hello world",
                                  "GtkWidget::parent", window,
                                  "GtkWidget::visible", TRUE,
                                  NULL),
                    "signal::clicked", hello, NULL,
                    NULL);
  gtk_widget_show (window);
  GMainContext *default_context = g_main_context_default();
  guint64 n_iter = 0;

  int ret;
  if ((ret = setjmp(jmp_ret)) != 0) {
    fprintf(stderr, "handled longjmp from %squitter\n",
            (ret == 2) ? "io" : "");
  }

  while(1) {
    if (kill_switch) break;
    gboolean ret = g_main_context_iteration(default_context, True);
    n_iter++;
    if (n_iter % 10 == 0) fprintf(stderr, ".");
    if (n_iter % 1000 == 0) { fprintf(stderr, "\n"); n_iter = 0; }

  }

  fprintf(stderr, "\nquitting: %d\n", kill_switch);
  return 0;
}

/*
gcc simple.c -Wno-deprecated -Wno-deprecated-declarations -g3 $(pkg-config 
gtk+-3.0 --cflags --libs ) -lX11

$ DISPLAY=:0 Xephyr :1
$ DISPLAY=:1 G_DEBUG=fatal-warnings ./a.out
*/
registered "closed" callback on gdk display 0x42e0e0 dpy :1
[New Thread 0x7ffff194b700 (LWP 28948)]
[New Thread 0x7ffff0fba700 (LWP 28949)]
.Connection lost to X Server:1
handled longjmp from ioquitter

(a.out:28942): GLib-WARNING **: 04:52:00.994: g_main_context_prepare() called 
recursively from within a source's check() or prepare() member.

Thread 1 "a.out" received signal SIGTRAP, Trace/breakpoint trap.
0x00007ffff72909c5 in _g_log_abort (breakpoint=1)
    at ../glib-2.63.0/glib/gmessages.c:554
554         G_BREAKPOINT ();
(gdb) back
#0  0x00007ffff72909c5 in _g_log_abort (breakpoint=1)
    at ../glib-2.63.0/glib/gmessages.c:554
#1  0x00007ffff7291bb6 in g_logv (log_domain=0x7ffff72f93ee "GLib", 
    log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, 
    args=args@entry=0x7fffffffdf98) at ../glib-2.63.0/glib/gmessages.c:1373
#2  0x00007ffff7291d72 in g_log (
    log_domain=log_domain@entry=0x7ffff72f93ee "GLib", 
    log_level=log_level@entry=G_LOG_LEVEL_WARNING, 
    format=format@entry=0x7ffff73004e8 "g_main_context_prepare() called 
recursively from within a source's check() or prepare() member.")
    at ../glib-2.63.0/glib/gmessages.c:1415
#3  0x00007ffff728a5fa in g_main_context_prepare (
    context=context@entry=0x44fb40, priority=priority@entry=0x7fffffffe108)
    at ../glib-2.63.0/glib/gmain.c:3434
#4  0x00007ffff728ada3 in g_main_context_iterate (
    context=context@entry=0x44fb40, block=block@entry=1, 
    dispatch=dispatch@entry=1, self=<optimized out>)
    at ../glib-2.63.0/glib/gmain.c:3898
#5  0x00007ffff728af8f in g_main_context_iteration (context=0x44fb40, 
    may_block=1) at ../glib-2.63.0/glib/gmain.c:3979
#6  0x00000000004011b6 in main (argc=1, argv=0x7fffffffe298) at simple.c:131

reply via email to

[Prev in Thread] Current Thread [Next in Thread]