* Fri Oct 10 2008 Adam Jackson <ajax@redhat.com> 1.5.2-2
- xserver-1.5.1-global-backtrace.patch: Make backtraces possible from outside the xfree86 DDX. - xserver-1.5.2-mieq-backtrace.patch: bt when we fill the input queue.
This commit is contained in:
parent
861a625c46
commit
5435f0df69
@ -19,7 +19,7 @@
|
||||
Summary: X.Org X11 X server
|
||||
Name: xorg-x11-server
|
||||
Version: 1.5.2
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
URL: http://www.x.org
|
||||
License: MIT
|
||||
Group: User Interface/X
|
||||
@ -82,6 +82,9 @@ Patch6001: xserver-1.5.0-edid-backport.patch
|
||||
# force mode debugging on for randr 1.2 drivers
|
||||
Patch6003: xserver-1.5.1-mode-debug.patch
|
||||
|
||||
Patch6004: xserver-1.5.1-global-backtrace.patch
|
||||
Patch6005: xserver-1.5.2-mieq-backtrace.patch
|
||||
|
||||
%define moduledir %{_libdir}/xorg/modules
|
||||
%define drimoduledir %{_libdir}/dri
|
||||
%define sdkdir %{_includedir}/xorg
|
||||
@ -512,6 +515,11 @@ rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%changelog
|
||||
* Fri Oct 10 2008 Adam Jackson <ajax@redhat.com> 1.5.2-2
|
||||
- xserver-1.5.1-global-backtrace.patch: Make backtraces possible from
|
||||
outside the xfree86 DDX.
|
||||
- xserver-1.5.2-mieq-backtrace.patch: bt when we fill the input queue.
|
||||
|
||||
* Fri Oct 10 2008 Adam Jackson <ajax@redhat.com> 1.5.2-1
|
||||
- xserver 1.5.2
|
||||
- xserver-1.5.0-comment-out-glxdri2.c: Drop, no longer relevant.
|
||||
|
427
xserver-1.5.1-global-backtrace.patch
Normal file
427
xserver-1.5.1-global-backtrace.patch
Normal file
@ -0,0 +1,427 @@
|
||||
From 7a8a31c041b52d87c1522e684cb301b07ea6ad9b Mon Sep 17 00:00:00 2001
|
||||
From: Adam Jackson <ajax@redhat.com>
|
||||
Date: Fri, 10 Oct 2008 15:53:48 -0400
|
||||
Subject: [PATCH] Move xorg_backtrace() up to the OS level so we can call it from DIX.
|
||||
|
||||
---
|
||||
hw/xfree86/common/xf86Events.c | 173 ----------------------------------
|
||||
include/os.h | 2 +
|
||||
os/Makefile.am | 1 +
|
||||
os/backtrace.c | 202 ++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 205 insertions(+), 173 deletions(-)
|
||||
create mode 100644 os/backtrace.c
|
||||
|
||||
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
|
||||
index 6ca0ae7..a2c206e 100644
|
||||
--- a/hw/xfree86/common/xf86Events.c
|
||||
+++ b/hw/xfree86/common/xf86Events.c
|
||||
@@ -358,179 +358,6 @@
|
||||
xf86SigIllHandler = sigillhandler;
|
||||
}
|
||||
|
||||
-#ifdef HAVE_BACKTRACE
|
||||
-#include <execinfo.h>
|
||||
-
|
||||
-static __inline__ void xorg_backtrace(void)
|
||||
-{
|
||||
- void *array[32]; /* deeper nesting than this means something's wrong */
|
||||
- size_t size, i;
|
||||
- char **strings;
|
||||
- ErrorF("\nBacktrace:\n");
|
||||
- size = backtrace(array, 32);
|
||||
- strings = backtrace_symbols(array, size);
|
||||
- for (i = 0; i < size; i++)
|
||||
- ErrorF("%d: %s\n", i, strings[i]);
|
||||
- free(strings);
|
||||
-}
|
||||
-
|
||||
-#else /* not glibc or glibc < 2.1 */
|
||||
-
|
||||
-# if defined(sun) && defined(__SVR4)
|
||||
-# define HAVE_PSTACK
|
||||
-# endif
|
||||
-
|
||||
-# if defined(HAVE_WALKCONTEXT) /* Solaris 9 & later */
|
||||
-
|
||||
-# include <ucontext.h>
|
||||
-# include <signal.h>
|
||||
-# include <dlfcn.h>
|
||||
-# include <sys/elf.h>
|
||||
-
|
||||
-#ifdef _LP64
|
||||
-# define ElfSym Elf64_Sym
|
||||
-#else
|
||||
-# define ElfSym Elf32_Sym
|
||||
-#endif
|
||||
-
|
||||
-/* Called for each frame on the stack to print it's contents */
|
||||
-static int xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
|
||||
-{
|
||||
- Dl_info dlinfo;
|
||||
- ElfSym *dlsym;
|
||||
- char header[32];
|
||||
- int depth = *((int *) arg);
|
||||
-
|
||||
- if (signo) {
|
||||
- char signame[SIG2STR_MAX];
|
||||
-
|
||||
- if (sig2str(signo, signame) != 0) {
|
||||
- strcpy(signame, "unknown");
|
||||
- }
|
||||
-
|
||||
- ErrorF("** Signal %d (%s)\n", signo, signame);
|
||||
- }
|
||||
-
|
||||
- snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
|
||||
- *((int *) arg) = depth + 1;
|
||||
-
|
||||
- /* Ask system dynamic loader for info on the address */
|
||||
- if (dladdr1((void *) pc, &dlinfo, (void **) &dlsym, RTLD_DL_SYMENT)) {
|
||||
- unsigned long offset = pc - (uintptr_t) dlinfo.dli_saddr;
|
||||
- const char *symname;
|
||||
-
|
||||
- if (offset < dlsym->st_size) { /* inside a function */
|
||||
- symname = dlinfo.dli_sname;
|
||||
- } else { /* found which file it was in, but not which function */
|
||||
- symname = "<section start>";
|
||||
- offset = pc - (uintptr_t)dlinfo.dli_fbase;
|
||||
- }
|
||||
- ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname,
|
||||
- symname, offset);
|
||||
-
|
||||
- } else {
|
||||
- /* Couldn't find symbol info from system dynamic loader, should
|
||||
- * probably poke elfloader here, but haven't written that code yet,
|
||||
- * so we just print the pc.
|
||||
- */
|
||||
- ErrorF("%s\n", header);
|
||||
- }
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-# endif /* HAVE_WALKCONTEXT */
|
||||
-
|
||||
-# ifdef HAVE_PSTACK
|
||||
-static int xorg_backtrace_pstack(void) {
|
||||
- pid_t kidpid;
|
||||
- int pipefd[2];
|
||||
-
|
||||
- if (pipe(pipefd) != 0) {
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- kidpid = fork1();
|
||||
-
|
||||
- if (kidpid == -1) {
|
||||
- /* ERROR */
|
||||
- return -1;
|
||||
- } else if (kidpid == 0) {
|
||||
- /* CHILD */
|
||||
- char parent[16];
|
||||
-
|
||||
- seteuid(0);
|
||||
- close(STDIN_FILENO);
|
||||
- close(STDOUT_FILENO);
|
||||
- dup2(pipefd[1],STDOUT_FILENO);
|
||||
- closefrom(STDERR_FILENO);
|
||||
-
|
||||
- snprintf(parent, sizeof(parent), "%d", getppid());
|
||||
- execle("/usr/bin/pstack", "pstack", parent, NULL);
|
||||
- exit(1);
|
||||
- } else {
|
||||
- /* PARENT */
|
||||
- char btline[256];
|
||||
- int kidstat;
|
||||
- int bytesread;
|
||||
- int done = 0;
|
||||
-
|
||||
- close(pipefd[1]);
|
||||
-
|
||||
- while (!done) {
|
||||
- bytesread = read(pipefd[0], btline, sizeof(btline) - 1);
|
||||
-
|
||||
- if (bytesread > 0) {
|
||||
- btline[bytesread] = 0;
|
||||
- ErrorF("%s", btline);
|
||||
- }
|
||||
- else if ((bytesread < 0) ||
|
||||
- ((errno != EINTR) && (errno != EAGAIN)))
|
||||
- done = 1;
|
||||
- }
|
||||
- close(pipefd[0]);
|
||||
- waitpid(kidpid, &kidstat, 0);
|
||||
- if (kidstat != 0)
|
||||
- return -1;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-# endif /* HAVE_PSTACK */
|
||||
-
|
||||
-
|
||||
-# if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
|
||||
-
|
||||
-static __inline__ void xorg_backtrace(void) {
|
||||
-
|
||||
- ErrorF("\nBacktrace:\n");
|
||||
-
|
||||
-# ifdef HAVE_PSTACK
|
||||
-/* First try fork/exec of pstack - otherwise fall back to walkcontext
|
||||
- pstack is preferred since it can print names of non-exported functions */
|
||||
-
|
||||
- if (xorg_backtrace_pstack() < 0)
|
||||
-# endif
|
||||
- {
|
||||
-# ifdef HAVE_WALKCONTEXT
|
||||
- ucontext_t u;
|
||||
- int depth = 1;
|
||||
-
|
||||
- if (getcontext(&u) == 0)
|
||||
- walkcontext(&u, xorg_backtrace_frame, &depth);
|
||||
- else
|
||||
-# endif
|
||||
- Error("Failed to get backtrace info");
|
||||
- }
|
||||
- ErrorF("\n");
|
||||
-}
|
||||
-
|
||||
-# else
|
||||
-
|
||||
-/* Default fallback if we can't find any way to get a backtrace */
|
||||
-static __inline__ void xorg_backtrace(void) { return; }
|
||||
-
|
||||
-# endif
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* xf86SigHandler --
|
||||
* Catch unexpected signals and exit or continue cleanly.
|
||||
diff --git a/include/os.h b/include/os.h
|
||||
--- a/include/os.h
|
||||
+++ b/include/os.h
|
||||
@@ -517,4 +517,6 @@
|
||||
extern void Error(char *str);
|
||||
extern void LogPrintMarkers(void);
|
||||
|
||||
+extern void xorg_backtrace(void);
|
||||
+
|
||||
#endif /* OS_H */
|
||||
diff --git a/os/Makefile.am b/os/Makefile.am
|
||||
--- a/os/Makefile.am
|
||||
+++ b/os/Makefile.am
|
||||
@@ -11,6 +11,7 @@
|
||||
WaitFor.c \
|
||||
access.c \
|
||||
auth.c \
|
||||
+ backtrace.c \
|
||||
connection.c \
|
||||
io.c \
|
||||
mitauth.c \
|
||||
diff --git a/os/backtrace.c b/os/backtrace.c
|
||||
new file mode 100644
|
||||
--- /dev/null
|
||||
+++ b/os/backtrace.c
|
||||
@@ -0,0 +1,201 @@
|
||||
+/*
|
||||
+ * Copyright 2008 Red Hat, Inc.
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining a
|
||||
+ * copy of this software and associated documentation files (the "Software")
|
||||
+ * to deal in the software without restriction, including without limitation
|
||||
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
|
||||
+ * license, and/or sell copies of the Software, and to permit persons to whom
|
||||
+ * them Software is furnished to do so, subject to the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice (including the next
|
||||
+ * paragraph) shall be included in all copies or substantial portions of the
|
||||
+ * Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY,
|
||||
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
||||
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER
|
||||
+ * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+#ifdef HAVE_DIX_CONFIG_H
|
||||
+#include <dix-config.h>
|
||||
+#endif
|
||||
+
|
||||
+#include "os.h"
|
||||
+#include "misc.h"
|
||||
+
|
||||
+#ifdef HAVE_BACKTRACE
|
||||
+#include <execinfo.h>
|
||||
+
|
||||
+void xorg_backtrace(void)
|
||||
+{
|
||||
+ void *array[32]; /* deeper nesting than this means something's wrong */
|
||||
+ size_t size, i;
|
||||
+ char **strings;
|
||||
+ ErrorF("\nBacktrace:\n");
|
||||
+ size = backtrace(array, 32);
|
||||
+ strings = backtrace_symbols(array, size);
|
||||
+ for (i = 0; i < size; i++)
|
||||
+ ErrorF("%d: %s\n", i, strings[i]);
|
||||
+ free(strings);
|
||||
+}
|
||||
+
|
||||
+#else /* not glibc or glibc < 2.1 */
|
||||
+
|
||||
+# if defined(sun) && defined(__SVR4)
|
||||
+# define HAVE_PSTACK
|
||||
+# endif
|
||||
+
|
||||
+# if defined(HAVE_WALKCONTEXT) /* Solaris 9 & later */
|
||||
+
|
||||
+# include <ucontext.h>
|
||||
+# include <signal.h>
|
||||
+# include <dlfcn.h>
|
||||
+# include <sys/elf.h>
|
||||
+
|
||||
+#ifdef _LP64
|
||||
+# define ElfSym Elf64_Sym
|
||||
+#else
|
||||
+# define ElfSym Elf32_Sym
|
||||
+#endif
|
||||
+
|
||||
+/* Called for each frame on the stack to print it's contents */
|
||||
+static int xorg_backtrace_frame(uintptr_t pc, int signo, void *arg)
|
||||
+{
|
||||
+ Dl_info dlinfo;
|
||||
+ ElfSym *dlsym;
|
||||
+ char header[32];
|
||||
+ int depth = *((int *) arg);
|
||||
+
|
||||
+ if (signo) {
|
||||
+ char signame[SIG2STR_MAX];
|
||||
+
|
||||
+ if (sig2str(signo, signame) != 0) {
|
||||
+ strcpy(signame, "unknown");
|
||||
+ }
|
||||
+
|
||||
+ ErrorF("** Signal %d (%s)\n", signo, signame);
|
||||
+ }
|
||||
+
|
||||
+ snprintf(header, sizeof(header), "%d: 0x%lx", depth, pc);
|
||||
+ *((int *) arg) = depth + 1;
|
||||
+
|
||||
+ /* Ask system dynamic loader for info on the address */
|
||||
+ if (dladdr1((void *) pc, &dlinfo, (void **) &dlsym, RTLD_DL_SYMENT)) {
|
||||
+ unsigned long offset = pc - (uintptr_t) dlinfo.dli_saddr;
|
||||
+ const char *symname;
|
||||
+
|
||||
+ if (offset < dlsym->st_size) { /* inside a function */
|
||||
+ symname = dlinfo.dli_sname;
|
||||
+ } else { /* found which file it was in, but not which function */
|
||||
+ symname = "<section start>";
|
||||
+ offset = pc - (uintptr_t)dlinfo.dli_fbase;
|
||||
+ }
|
||||
+ ErrorF("%s: %s:%s+0x%lx\n", header, dlinfo.dli_fname,
|
||||
+ symname, offset);
|
||||
+
|
||||
+ } else {
|
||||
+ /* Couldn't find symbol info from system dynamic loader, should
|
||||
+ * probably poke elfloader here, but haven't written that code yet,
|
||||
+ * so we just print the pc.
|
||||
+ */
|
||||
+ ErrorF("%s\n", header);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+# endif /* HAVE_WALKCONTEXT */
|
||||
+
|
||||
+# ifdef HAVE_PSTACK
|
||||
+static int xorg_backtrace_pstack(void) {
|
||||
+ pid_t kidpid;
|
||||
+ int pipefd[2];
|
||||
+
|
||||
+ if (pipe(pipefd) != 0) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ kidpid = fork1();
|
||||
+
|
||||
+ if (kidpid == -1) {
|
||||
+ /* ERROR */
|
||||
+ return -1;
|
||||
+ } else if (kidpid == 0) {
|
||||
+ /* CHILD */
|
||||
+ char parent[16];
|
||||
+
|
||||
+ seteuid(0);
|
||||
+ close(STDIN_FILENO);
|
||||
+ close(STDOUT_FILENO);
|
||||
+ dup2(pipefd[1],STDOUT_FILENO);
|
||||
+ closefrom(STDERR_FILENO);
|
||||
+
|
||||
+ snprintf(parent, sizeof(parent), "%d", getppid());
|
||||
+ execle("/usr/bin/pstack", "pstack", parent, NULL);
|
||||
+ exit(1);
|
||||
+ } else {
|
||||
+ /* PARENT */
|
||||
+ char btline[256];
|
||||
+ int kidstat;
|
||||
+ int bytesread;
|
||||
+ int done = 0;
|
||||
+
|
||||
+ close(pipefd[1]);
|
||||
+
|
||||
+ while (!done) {
|
||||
+ bytesread = read(pipefd[0], btline, sizeof(btline) - 1);
|
||||
+
|
||||
+ if (bytesread > 0) {
|
||||
+ btline[bytesread] = 0;
|
||||
+ ErrorF("%s", btline);
|
||||
+ }
|
||||
+ else if ((bytesread < 0) ||
|
||||
+ ((errno != EINTR) && (errno != EAGAIN)))
|
||||
+ done = 1;
|
||||
+ }
|
||||
+ close(pipefd[0]);
|
||||
+ waitpid(kidpid, &kidstat, 0);
|
||||
+ if (kidstat != 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+# endif /* HAVE_PSTACK */
|
||||
+
|
||||
+
|
||||
+# if defined(HAVE_PSTACK) || defined(HAVE_WALKCONTEXT)
|
||||
+
|
||||
+void xorg_backtrace(void) {
|
||||
+
|
||||
+ ErrorF("\nBacktrace:\n");
|
||||
+
|
||||
+# ifdef HAVE_PSTACK
|
||||
+/* First try fork/exec of pstack - otherwise fall back to walkcontext
|
||||
+ pstack is preferred since it can print names of non-exported functions */
|
||||
+
|
||||
+ if (xorg_backtrace_pstack() < 0)
|
||||
+# endif
|
||||
+ {
|
||||
+# ifdef HAVE_WALKCONTEXT
|
||||
+ ucontext_t u;
|
||||
+ int depth = 1;
|
||||
+
|
||||
+ if (getcontext(&u) == 0)
|
||||
+ walkcontext(&u, xorg_backtrace_frame, &depth);
|
||||
+ else
|
||||
+# endif
|
||||
+ Error("Failed to get backtrace info");
|
||||
+ }
|
||||
+ ErrorF("\n");
|
||||
+}
|
||||
+
|
||||
+# else
|
||||
+
|
||||
+/* Default fallback if we can't find any way to get a backtrace */
|
||||
+void xorg_backtrace(void) { return; }
|
||||
+
|
||||
+# endif
|
||||
+#endif
|
||||
--
|
||||
1.6.0.1
|
||||
|
41
xserver-1.5.2-mieq-backtrace.patch
Normal file
41
xserver-1.5.2-mieq-backtrace.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From b736f477f5324f79af30fc0f941ba0714a34ccda Mon Sep 17 00:00:00 2001
|
||||
From: Adam Jackson <ajax@redhat.com>
|
||||
Date: Fri, 10 Oct 2008 16:33:24 -0400
|
||||
Subject: [PATCH] mieq: Backtrace when the queue overflows.
|
||||
|
||||
Since we're probably stuck down in a driver somewhere, let's at least
|
||||
try to point out where. This will need to be rethought when the input
|
||||
thread work lands though.
|
||||
---
|
||||
mi/mieq.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/mi/mieq.c b/mi/mieq.c
|
||||
index 0a1b740..062dede 100644
|
||||
--- a/mi/mieq.c
|
||||
+++ b/mi/mieq.c
|
||||
@@ -169,6 +169,7 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
|
||||
oldtail = (oldtail - 1) % QUEUE_SIZE;
|
||||
}
|
||||
else {
|
||||
+ static int stuck = 0;
|
||||
newtail = (oldtail + 1) % QUEUE_SIZE;
|
||||
/* Toss events which come in late. Usually this means your server's
|
||||
* stuck in an infinite loop somewhere, but SIGIO is still getting
|
||||
@@ -176,8 +177,13 @@ mieqEnqueue(DeviceIntPtr pDev, xEvent *e)
|
||||
if (newtail == miEventQueue.head) {
|
||||
ErrorF("[mi] EQ overflowing. The server is probably stuck "
|
||||
"in an infinite loop.\n");
|
||||
+ if (!stuck) {
|
||||
+ xorg_backtrace();
|
||||
+ stuck = 1;
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
+ stuck = 0;
|
||||
miEventQueue.tail = newtail;
|
||||
}
|
||||
|
||||
--
|
||||
1.6.0.1
|
||||
|
Loading…
Reference in New Issue
Block a user