#!/usr/bin/perl use strict; my %result; sgetopt( [ 'h', 'e:', 'c:', 'o:', 'n' ], \%result); print_usage() if (exists $result{'h'}); print_usage("Missing -c option") if (! exists $result{'c'}); print_usage("Missing -e option") if (! exists $result{'e'}); print_usage("Missing -o option") if (! exists $result{'o'}); my $exe_file = $result{'e'}; my $core_file = $result{'c'}; my $tar_file = $result{'o'}; my $copy_exe = ! defined $result{'n'}; if (! -f $exe_file ) { print_usage(" file does not exist"); } if (defined $core_file && ! -f $core_file) { print_usage(" file does not exist"); } my $VERBOSE = 0; my @libs = get_dependent_libs( $exe_file ); my @dynlibs = get_dyn_libs($exe_file, $core_file); make_tar(); sub make_tar { my ($basedir,$tmp_dir,@dep_files,$f,$dir,@dynlibs); my $tmp_dir = "/tmp/tmp-dir-$$"; @dep_files =get_dependent_libs($exe_file); @dynlibs = get_dyn_libs($exe_file, $core_file); run("mkdir -p $tmp_dir"); foreach $f (@dep_files) { $dir = "$tmp_dir/".get_base_dir($f); run("mkdir -p $dir"); run("cp -Lf $f $dir"); } foreach $f (@dynlibs) { $dir = "$tmp_dir/".get_base_dir($f); run("mkdir -p $dir"); run("cp -Lf $f $dir"); } copy_core($tmp_dir); run("tar cvfj $tar_file -C $tmp_dir ."); run("rm -rf $tmp_dir"); } sub copy_core { my $tmp_dir = shift; my ($cfile,$efile); if (defined $core_file) { run("cp -f $core_file $tmp_dir"); $cfile = get_base_name($core_file); } if ($copy_exe) { run("cp -f $exe_file $tmp_dir"); $efile = get_base_name($exe_file); } my $sf = "$tmp_dir/run.sh"; open(OF,">$sf") || die "Can't create $sf"; print OF <gdb_script <") != -1) { $file = $tokens[2]; } else { $file = $tokens[1]; } if (-f $file) { push(@ret,$file); } } return @ret; } sub get_dyn_libs { my $exe_file = shift; my $core_file = shift; my (@ret,$line,$txt, $start); $txt = `gdb --batch $exe_file $core_file -ex "info sharedlibrary"`; $start = 0; foreach $line (split('\n',$txt)) { my $file; if(!$start) { if (index($line,"From") != -1) { $start = 1; } } else { $line =~ s/^\s+//; $line =~ s/\s+$//; if (($line =~ /^No/)) { #ignore .. } else { my @tokens = split(' ',$line, 4); $tokens[3] =~ s/^\s+//; $tokens[3] =~ s/\s+$//; print "$tokens[3]\n"; if (-f $tokens[3]) { push(@ret,$tokens[3]); } } } } return @ret; } sub run { my $args = shift; print "Running: $args\n" if ($VERBOSE); my $f = `$args`; if ($? != 0) { print "Error: running $args failed."; exit(1); } return $f; } sub get_base_dir { my $f = shift; my $idx = rindex($f,"/"); return $idx != -1 ? substr($f,0,$idx) : $f; } sub get_base_name { my $f = shift; my $idx = rindex($f,"/"); return $idx != -1 ? substr($f,$idx+1) : $f; } sub print_usage { my $msg = shift; if ($msg ne "") { print "Error: $msg\n\n"; } print < [-c ] [-n] -o Parameters -c - core file (optional) -e - path of executable that produced core file -o - output archive file. -n - don't copy executable, only shared libs (optional) the will contain following data - copy of (unless -n is specified) - copy of all dependent shared libraries of - copy of (if specified by -c option) - script that runs gdb so that gdb is looking at copied shared libraries + using the copied cores/executables. The tar file is compressed with bz2 compression, so in order to extract the archive run tar xvfj This program is useful if we want to examine a core file of an executable on a remote machine. It is assumed that the core file has been caused by running EOF ; exit(1); } # ---------------------------------------------------------------------------- sub sgetopt { my $opts = shift; my $resref = shift; my ($i,$argval,$optval,$has_value); for($i=0; $i < scalar(@ARGV) ; ) { $argval = $ARGV[ $i++ ]; next if (! substr($argval,0,1) eq "-" && length($argval) == 2); $argval = substr($argval,1); $has_value = 0; foreach $optval (@{ $opts }) { if ($argval eq substr($optval,0,1)) { $has_value = 1; if (index($optval,':') != -1) { if ($i >= scalar(@ARGV)) { print "ERROR: option -$argval must have a value\n"; exit(1); } $has_value = 1; ${ $resref } { $argval } = $ARGV[ $i ++ ]; } else { ${ $resref } { $argval } = 1; } } } if (! $has_value) { print "ERROR: Command line option -$argval is not defined\n"; exit(1); } } }