From f195276fb5ae0eb444d7bfba607d03e1c8d94becd6ebf986c6e9a87dc6f3779e Mon Sep 17 00:00:00 2001 From: Stefan Dirsch Date: Wed, 25 Aug 2010 13:37:12 +0000 Subject: [PATCH] Accepting request 46213 from home:mhopf:branches:X11:XOrg Copy from home:mhopf:branches:X11:XOrg/xorg-x11-server via accept of submit request 46213 revision 2. Request was accepted with message: reviewed ok. OBS-URL: https://build.opensuse.org/request/show/46213 OBS-URL: https://build.opensuse.org/package/show/X11:XOrg/xorg-x11-server?expand=0&rev=283 --- ...l-for-creating-backtraces-on-crashes.patch | 123 +++++++++++++++++ xorg-backtrace | 127 ++++++++++++++++++ xorg-x11-server.changes | 8 ++ xorg-x11-server.spec | 5 + 4 files changed, 263 insertions(+) create mode 100644 Use-external-tool-for-creating-backtraces-on-crashes.patch create mode 100644 xorg-backtrace diff --git a/Use-external-tool-for-creating-backtraces-on-crashes.patch b/Use-external-tool-for-creating-backtraces-on-crashes.patch new file mode 100644 index 0000000..5ca0922 --- /dev/null +++ b/Use-external-tool-for-creating-backtraces-on-crashes.patch @@ -0,0 +1,123 @@ +From bb4e768eaf8025d3ccf369cbad9a9b8be721e7ac Mon Sep 17 00:00:00 2001 +From: Matthias Hopf +Date: Wed, 25 Aug 2010 14:12:48 +0200 +Subject: [PATCH] Use external tool for creating backtraces on crashes if available. + +This calls /usr/bin/xorg-backtrace to create reasonable commented backtraces +with gdb. On errors it falls back to the generic method. + +Signed-off-by: Matthias Hopf +--- + os/backtrace.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 82 insertions(+), 0 deletions(-) + +diff --git a/os/backtrace.c b/os/backtrace.c +index 7ca6dab..1e3201a 100644 +--- a/os/backtrace.c ++++ b/os/backtrace.c +@@ -28,6 +28,81 @@ + #include "os.h" + #include "misc.h" + ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define XORG_BACKTRACE "/usr/bin/xorg-backtrace" ++ ++/* Call gdb to create reasonable(!) backtrace. Returns 0 if successfull. */ ++static int xorg_backtrace_gdb(void) ++{ ++ static const char *xorg_backtrace = XORG_BACKTRACE; ++ char pidstr[12]; ++ char fdname[] = "/tmp/xorg.XXXXXX"; ++ char buf[256]; ++ pid_t pid; ++ int fd, status = -1, ret; ++ FILE *f; ++ ++ if (access (xorg_backtrace, R_OK | X_OK) != 0) { ++ ErrorF ("%s not found, using internal backtrace system\n", xorg_backtrace); ++ return 1; ++ } ++ if ( (fd = mkstemp (fdname)) == -1) { ++ ErrorF ("xorg_backtrace_gdb internal error 1\n"); ++ return 1; ++ } ++ unlink (fdname); ++ snprintf (pidstr, 12, "%d", getpid()); ++ ++ switch ( (pid = fork()) ) { ++ case 0: ++ close (0); ++ close (1); ++ close (2); ++ dup2 (fd, 1); ++ dup2 (fd, 2); ++ close (fd); ++ execl (xorg_backtrace, xorg_backtrace, pidstr, NULL); ++ exit (-1); ++ case -1: ++ close (fd); ++ return 1; ++ } ++ ++ while (waitpid (pid, &status, 0) == -1 && errno == EINTR) ++ ; ++ if (WIFEXITED (status) && WEXITSTATUS (status) == 0) ++ ret = 0; ++ else { ++ ErrorF ("%s failed with returncode %d\n", xorg_backtrace, WEXITSTATUS (status)); ++ ret = 1; ++ } ++ ++ lseek (fd, 0, SEEK_SET); ++ if (! (f = fdopen (fd, "r"))) { ++ ErrorF ("xorg_backtrace_gdb internal error 2\n"); ++ close (fd); ++ return 1; ++ } ++ status = 0; ++ while (fgets (buf, 256, f)) { ++ status++; ++ ErrorF("%s", buf); ++ } ++ fclose (f); ++ if (status < 10 && ret == 0) { ++ ErrorF ("%s only produced %d lines of output\n", xorg_backtrace, status); ++ return 1; ++ } ++ ++ return ret; ++} ++ + #ifdef HAVE_BACKTRACE + #ifndef _GNU_SOURCE + #define _GNU_SOURCE +@@ -41,6 +116,10 @@ void xorg_backtrace(void) + const char *mod; + int size, i; + Dl_info info; ++ ++ if (xorg_backtrace_gdb () == 0) ++ return; ++ + ErrorF("\nBacktrace:\n"); + size = backtrace(array, 64); + for (i = 0; i < size; i++) { +@@ -182,6 +261,9 @@ static int xorg_backtrace_pstack(void) { + + void xorg_backtrace(void) { + ++ if (xorg_backtrace_gdb () == 0) ++ return; ++ + ErrorF("\nBacktrace:\n"); + + # ifdef HAVE_PSTACK +-- +1.6.0.2 + diff --git a/xorg-backtrace b/xorg-backtrace new file mode 100644 index 0000000..0bc76eb --- /dev/null +++ b/xorg-backtrace @@ -0,0 +1,127 @@ +#!/usr/bin/perl + +$version = "1.0"; +$timeout = 5; +@pkgs = ( "xorg-x11-server", "xorg-x11-driver-video", "xorg-x11-driver-input", + "libpixman-1-0", "libpciaccess0" ); +$xtracmds= "/etc/X11/xorg-backtrace-cmds"; + + +$pid=$ARGV[0]; +if ($pid == 0) { + print "Usage: $0 \n"; + exit 1; +} + + +if (! -e "/usr/bin/gdb") { + print "Install gdb to get reasonable backtraces\n"; + exit 2; +} + +$SIG{ALRM} = sub { die "timeout starting gdb" }; +alarm $timeout; + +open STDERR, ">&STDOUT"; + +use FileHandle; +use IPC::Open2; +$gdb = open2 (*R, *W, "/usr/bin/gdb -n -p $pid"); + +$SIG{ALRM} = sub { kill QUIT, $gdb; sleep 1; kill KILL, $gdb; die "timeout using gdb" }; +alarm $timeout; + + +print "\n==================== GDB Backtrace ============\n\n"; +print "Done by $0 V$version\n\n"; + +$needpkgs=0; +for $p (@pkgs) { + next if system ("rpm", "-q", "--quiet", "$p-debuginfo") == 0 && + system ("rpm", "-q", "--quiet", "$p-debugsource") == 0; + print "Install following debug packages to improve backtrace:\n" unless $needpkgs; + $needpkgs++; + print "\t$p-debug*\n"; +} +print "\n" if $needpkgs; + +print W "set prompt\necho \\n===info\\n\n"; +#print W "info files\necho ===files\\n\n"; +print W "thread apply all bt full\necho ===btend\\n\n"; + +$_=; # GNU gdb version +print; + +while () { + last if /^===info/; + print if /^This GDB was configured as/; +} + +#print "\n==================== Files ====================\n\n"; +#while () { +# last if /^===files/; +# print; +#} + + +print "\n==================== Backtrace ================\n"; +$fno = ""; +$fls = 0; +$o = ""; +$use = 0; +while () { + last if /^===btend/; + if (/^#(\d+)\s/) { + $fno = $1; + $o .= "\n"; + $o .= "===l".($fno-1)."\n" if $use; + $o .= "\n"; + $fls = $fno+1 if /\bxorg_backtrace \(/ || /\bOsSigHandler \(/; + $use = 1; + } + $line{$fno} = $1 if $line{$fno} == 0 && /:(\d+)\s*$/; + $o .= $_; + $use = 0 if /^No symbol table info available/; +} +$o .="\n===l$fno"; + +for $i ($fls..$fno) { + print W "frame $i\necho ===fs$i\\n\nlist\necho ===fe$i\\n\n"; + while () { + last if /^===fs$i\b/; + } + $r = ""; + while () { + last if /^===fe$i\b/; + $r .= $_; + } + if ($line{$i} > 0) { + $r =~ s/^$line{$i}\b/$line{$i} */m; + } + $o =~ s/^===l$i$/$r/m; +} + +if ($fls > 0) { + for $i (0..$fls-1) { + $o =~ s/^(#$i\s.*?)\n.*?\n#/$1\n\n#/ms; + } +} +$o =~ s/^===l.*$//mg; + +print "$o"; + +if (-e $xtracmds) { + print W "source -v $xtracmds\necho ===cmds\\n\n"; + print "\n==================== Extra Commands ===========\n\n"; + while () { + last if /^===cmds/; + print unless /^\+echo ===cmds/; + } +} + +print "\n==================== Backtrace End ============\n\n"; +close R; +close W; + +exit 0; + diff --git a/xorg-x11-server.changes b/xorg-x11-server.changes index c1d01b9..8fc58c2 100644 --- a/xorg-x11-server.changes +++ b/xorg-x11-server.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Wed Aug 25 13:32:09 UTC 2010 - mhopf@novell.com + +- Use-external-tool-for-creating-backtraces-on-crashes.patch, + xorg-backtrace: + Use external script /usr/bin/xorg-backtrace for creating reasonable + backtraces upon crashes. + ------------------------------------------------------------------- Mon Aug 23 19:28:20 CEST 2010 - sndirsch@suse.de diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 057cda7..733dbac 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -54,6 +54,7 @@ Source3: README.updates Source4: xorgcfg.tar.bz2 Source5: modprobe.nvidia Source7: xorg-docs-1.4.tar.bz2 +Source8: xorg-backtrace Patch1: fpic.diff Patch2: p_default-module-path.diff Patch6: pu_fixes.diff @@ -114,6 +115,7 @@ Patch213: xorg-server-xdmcp.patch Patch217: CVE-2010-2240-address_space_limit.patch Patch218: CVE-2010-2240-tree_depth_limit.patch Patch219: vbe-bufferoverflow.diff +Patch220: Use-external-tool-for-creating-backtraces-on-crashes.patch %if %moblin Patch300: moblin-use_preferred_mode_for_all_outputs.diff %endif @@ -238,6 +240,7 @@ popd %patch217 -p1 %patch218 -p1 %patch219 -p1 +%patch220 -p1 %if %moblin %patch300 -p1 %endif @@ -330,6 +333,7 @@ mkdir -p %buildroot/var/adm/fillup-templates install -m 644 %_sourcedir/sysconfig.displaymanager.template \ %buildroot/var/adm/fillup-templates/sysconfig.displaymanager-%name %endif +install -m 755 $RPM_SOURCE_DIR/xorg-backtrace $RPM_BUILD_ROOT/usr/bin/xorg-backtrace %clean rm -rf "$RPM_BUILD_ROOT" @@ -398,6 +402,7 @@ exit 0 /var/adm/fillup-templates/sysconfig.displaymanager-%name /var/lib/X11/X %endif +/usr/bin/xorg-backtrace %files extra %defattr(-,root,root)