}
static void
+drm_restore(struct weston_compositor *ec)
+{
+ struct drm_compositor *d = (struct drm_compositor *) ec;
+
+ if (weston_launcher_drm_set_master(&d->base, d->drm.fd, 0) < 0)
+ weston_log("failed to drop master: %m\n");
+ tty_reset(d->tty);
+}
+
+static void
drm_destroy(struct weston_compositor *ec)
{
struct drm_compositor *d = (struct drm_compositor *) ec;
}
ec->base.destroy = drm_destroy;
+ ec->base.restore = drm_restore;
ec->base.focus = 1;
#include "git-version.h"
static struct wl_list child_process_list;
-static jmp_buf segv_jmp_buf;
+static struct weston_compositor *segv_compositor;
static int
sigchld_handler(int signal_number, void *data)
int i, count;
Dl_info info;
+ /* This SIGSEGV handler will do a best-effort backtrace, and
+ * then call the backend restore function, which will switch
+ * back to the vt we launched from or ungrab X etc and then
+ * raise SIGTRAP. If we run weston under gdb from X or a
+ * different vt, and tell gdb "handle SIGSEGV nostop", this
+ * will allow weston to switch back to gdb on crash and then
+ * gdb will catch the crash with SIGTRAP. */
+
weston_log("caught segv\n");
count = backtrace(buffer, ARRAY_LENGTH(buffer));
info.dli_fname);
}
- longjmp(segv_jmp_buf, 1);
+ segv_compositor->restore(segv_compositor);
+
+ raise(SIGTRAP);
}
signals[3] = wl_event_loop_add_signal(loop, SIGCHLD, sigchld_handler,
NULL);
- segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
- segv_action.sa_sigaction = on_segv_signal;
- sigemptyset(&segv_action.sa_mask);
- sigaction(SIGSEGV, &segv_action, NULL);
-
if (!backend) {
if (getenv("WAYLAND_DISPLAY"))
backend = "wayland-backend.so";
exit(EXIT_FAILURE);
}
+ segv_action.sa_flags = SA_SIGINFO | SA_RESETHAND;
+ segv_action.sa_sigaction = on_segv_signal;
+ sigemptyset(&segv_action.sa_mask);
+ sigaction(SIGSEGV, &segv_action, NULL);
+ segv_compositor = ec;
+
for (i = 1; argv[i]; i++)
weston_log("fatal: unhandled option: %s\n", argv[i]);
if (argv[1]) {
weston_compositor_dpms_on(ec);
weston_compositor_wake(ec);
- if (setjmp(segv_jmp_buf) == 0)
- wl_display_run(display);
- else
- ret = EXIT_FAILURE;
-out:
+ wl_display_run(display);
+
+ out:
/* prevent further rendering while shutting down */
ec->state = WESTON_COMPOSITOR_SLEEPING;
int has_bind_display;
void (*destroy)(struct weston_compositor *ec);
+ void (*restore)(struct weston_compositor *ec);
int (*authenticate)(struct weston_compositor *c, uint32_t id);
void (*ping_handler)(struct weston_surface *surface, uint32_t serial);
void
tty_destroy(struct tty *tty);
+void
+tty_reset(struct tty *tty);
+
int
tty_activate_vt(struct tty *tty, int vt);
return NULL;
}
-void
-tty_destroy(struct tty *tty)
+void tty_reset(struct tty *tty)
{
struct vt_mode mode = { 0 };
- if (tty->input_source)
- wl_event_source_remove(tty->input_source);
-
if (ioctl(tty->fd, KDSKBMODE, tty->kb_mode))
weston_log("failed to restore keyboard mode: %m\n");
ioctl(tty->fd, VT_ACTIVATE, tty->starting_vt);
ioctl(tty->fd, VT_WAITACTIVE, tty->starting_vt);
}
+}
+
+void
+tty_destroy(struct tty *tty)
+{
+ if (tty->input_source)
+ wl_event_source_remove(tty->input_source);
wl_event_source_remove(tty->vt_source);
+ tty_reset(tty);
+
close(tty->fd);
free(tty);