#!/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;