From aa548b0a9b4999f21630273261a8f5880dd24a7f Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 14 Oct 2008 14:04:01 -0400 Subject: [PATCH 1/7] EDID: Catch even more cases of encoding aspect as size. Very cute, Samsung, not only do you claim to be 16cm by 9cm in the global size record, you also claim to be 160mm by 90mm in the detailed timings. Grrr. (cherry picked from commit bd9c6b3a4d726a3f83ac6d8cf7211eddbc28f25a) --- hw/xfree86/ddc/interpret_edid.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hw/xfree86/ddc/interpret_edid.c b/hw/xfree86/ddc/interpret_edid.c index 958247c95..879308520 100644 --- a/hw/xfree86/ddc/interpret_edid.c +++ b/hw/xfree86/ddc/interpret_edid.c @@ -115,12 +115,16 @@ handle_edid_quirks(xf86MonPtr m) } } - if (real_hsize && real_vsize) { + if (!real_hsize || !real_vsize) { + m->features.hsize = m->features.vsize = 0; + } else if ((m->features.hsize * 10 == real_hsize) && + (m->features.vsize * 10 == real_vsize)) { + /* exact match is just unlikely, should do a better check though */ + m->features.hsize = m->features.vsize = 0; + } else { /* convert mm to cm */ m->features.hsize = (real_hsize + 5) / 10; m->features.vsize = (real_vsize + 5) / 10; - } else { - m->features.hsize = m->features.vsize = 0; } xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n", From 7df5e93cf52aad35509be9e6d8c25e399fba0c60 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 10 Oct 2008 15:53:48 -0400 Subject: [PATCH 2/7] Move xorg_backtrace() up to the OS level so we can call it from DIX. (cherry picked from commit 94ed0ba1b5043ad9fc33b42756af447d5ab15bbd) --- hw/xfree86/common/xf86Events.c | 173 ---------------------------- include/os.h | 2 + os/Makefile.am | 1 + os/backtrace.c | 201 +++++++++++++++++++++++++++++++++ 4 files changed, 204 insertions(+), 173 deletions(-) create mode 100644 os/backtrace.c diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c index 2b7cb121d..76c207a13 100644 --- a/hw/xfree86/common/xf86Events.c +++ b/hw/xfree86/common/xf86Events.c @@ -561,179 +561,6 @@ xf86InterceptSigIll(void (*sigillhandler)(void)) xf86SigIllHandler = sigillhandler; } -#ifdef HAVE_BACKTRACE -#include - -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 -# include -# include -# include - -#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 = "
"; - 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 index 4be6b8010..c67821967 100644 --- a/include/os.h +++ b/include/os.h @@ -524,4 +524,6 @@ extern void ErrorF(const char *f, ...) _printf_attribute(1,2); 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 index ce6058538..d6d748577 100644 --- a/os/Makefile.am +++ b/os/Makefile.am @@ -11,6 +11,7 @@ libos_la_SOURCES = \ 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 index 000000000..b52dcded8 --- /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 +#endif + +#include "os.h" +#include "misc.h" + +#ifdef HAVE_BACKTRACE +#include + +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 +# include +# include +# include + +#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 = "
"; + 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 From 483fb847b4363d09ff3347f61ad51bba1dd00602 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 10 Oct 2008 16:33:24 -0400 Subject: [PATCH 3/7] 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. (cherry picked from commit b736f477f5324f79af30fc0f941ba0714a34ccda) --- mi/mieq.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mi/mieq.c b/mi/mieq.c index aaa247d6c..803724708 100644 --- a/mi/mieq.c +++ b/mi/mieq.c @@ -145,6 +145,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 @@ -152,8 +153,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; } From 19776ede8f10e0f59dbc50d93e51facbc4071877 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 14 Oct 2008 13:00:50 -0400 Subject: [PATCH 4/7] Add backtrace definitions to dix-config.h.in (cherry picked from commit ad677238bc96a8578113bbe76d605d7a87aca44c) --- include/dix-config.h.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/dix-config.h.in b/include/dix-config.h.in index b038c0e93..afd82a145 100644 --- a/include/dix-config.h.in +++ b/include/dix-config.h.in @@ -102,6 +102,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ASM_MTRR_H +/* Has backtrace support */ +#undef HAVE_BACKTRACE + /* Define to 1 if you have the header file. */ #undef HAVE_BYTESWAP_H @@ -121,6 +124,9 @@ /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT +/* Have execinfo.h */ +#undef HAVE_EXECINFO_H + /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H From b468eacf511de3c3f8b6a1abd9e38680947b464e Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 14 Oct 2008 09:45:19 -0400 Subject: [PATCH 5/7] kdrive: Hardcode a different wrong value for number of mouse buttons This should really come from the input driver directly, but, kdrive. (cherry picked from commit 3eb52de7f28b0050582f9ac4c28bc894d3f06f4b) --- hw/kdrive/src/kinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 80fcdde5a..9ba11661c 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -1295,7 +1295,7 @@ KdParsePointer (char *arg) return NULL; pi->emulateMiddleButton = kdEmulateMiddleButton; pi->transformCoordinates = !kdRawPointerCoordinates; - pi->nButtons = 3; + pi->nButtons = 5; /* XXX should not be hardcoded */ pi->inputClass = KD_MOUSE; if (!arg) From f75163e5f6fc6dd63ac4eb97e403086031230250 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 21 Oct 2008 16:00:32 -0400 Subject: [PATCH 6/7] Bug #18159: Spell "anisotropic" correctly (cherry picked from commit 81e197b2a5457bb9f7ed72f82c2d33fd8dbfc202) --- glx/glxscreens.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glx/glxscreens.c b/glx/glxscreens.c index cc7054a64..f4839b32c 100644 --- a/glx/glxscreens.c +++ b/glx/glxscreens.c @@ -110,7 +110,7 @@ static const char GLServerExtensions[] = "GL_EXT_texture_env_add " "GL_EXT_texture_env_combine " "GL_EXT_texture_env_dot3 " - "GL_EXT_texture_filter_ansiotropic " + "GL_EXT_texture_filter_anisotropic " "GL_EXT_texture_lod " "GL_EXT_texture_lod_bias " "GL_EXT_texture_mirror_clamp " From ec5046ca7565e2364f42606b26159520a73dd207 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 10 Oct 2008 23:23:02 +0200 Subject: [PATCH 7/7] dri: don't set the dixPrivate key to NULL, as this is a staticly set variable. - This breaks on the 2nd server generation. - No other subsystem seems to NULL their key. - This should fix bug 17982. (cherry picked from commit 5b336585a4cdf11d20831a9536ad581e959ea7f1) --- hw/xfree86/dri/dri.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c index b736c6ae0..79934a1c5 100644 --- a/hw/xfree86/dri/dri.c +++ b/hw/xfree86/dri/dri.c @@ -349,7 +349,6 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD) pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec)); if (!pDRIPriv) { dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); - DRIScreenPrivKey = NULL; return FALSE; } @@ -742,7 +741,6 @@ DRICloseScreen(ScreenPtr pScreen) xfree(pDRIPriv); dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL); - DRIScreenPrivKey = NULL; } }