128 lines
2.6 KiB
Plaintext
128 lines
2.6 KiB
Plaintext
|
#!/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 <pid>\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";
|
||
|
|
||
|
$_=<R>; # GNU gdb version
|
||
|
print;
|
||
|
|
||
|
while (<R>) {
|
||
|
last if /^===info/;
|
||
|
print if /^This GDB was configured as/;
|
||
|
}
|
||
|
|
||
|
#print "\n==================== Files ====================\n\n";
|
||
|
#while (<R>) {
|
||
|
# last if /^===files/;
|
||
|
# print;
|
||
|
#}
|
||
|
|
||
|
|
||
|
print "\n==================== Backtrace ================\n";
|
||
|
$fno = "";
|
||
|
$fls = 0;
|
||
|
$o = "";
|
||
|
$use = 0;
|
||
|
while (<R>) {
|
||
|
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 (<R>) {
|
||
|
last if /^===fs$i\b/;
|
||
|
}
|
||
|
$r = "";
|
||
|
while (<R>) {
|
||
|
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 (<R>) {
|
||
|
last if /^===cmds/;
|
||
|
print unless /^\+echo ===cmds/;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
print "\n==================== Backtrace End ============\n\n";
|
||
|
close R;
|
||
|
close W;
|
||
|
|
||
|
exit 0;
|
||
|
|