2012-06-20 57 views
3

如何將核心文件與相關的可執行文件和共享庫捆綁在一起?如何將核心文件與相關的可執行文件打包在一起?

當程序崩潰時,它會生成一個核心文件,我可以用它來用gdb進行調試。但是如果有人出現在我身後,並且「打開」或「升級軟件包」或以任何方式混淆系統,「幫助」重新編譯程序時,該核心文件就變得毫無用處。

所以我想要的是將核心文件與其引用的所有其他二進制文件捆綁到一個大文件中的方法。

然後,當然,我也需要一種方法來在gdb中打開這個文件。我不想將文件「提取」回原始位置,並覆蓋升級或更改的二進制文件。我在想象一個shell腳本,它將二進制文件提取到一個臨時目錄,然後告訴gdb看看那裏。

回答

2

GDB已經擁有你想要的信息(info sharedlib):

$ gdb -ex 'set height 0' -ex 'set confirm off' \ 
    -ex 'file /path/to/exe' -ex 'core-file core.pid' \ 
    -ex 'info sharedlib' -ex quit 

所以很自然的,你可以要求GDB給你這個名單,並從那裏你可以創建一個包含「GDB-捆綁」壓縮包gdb報告的可執行文件和所有共享庫。

我寫了一個腳本來自動完成:

#!/bin/sh 
me=$(basename $0) 

usage() { 
    echo "Usage: 
    $me -p <pid> 
    $me <executable> <core> 

DESCRIPTION 
    $me - Creates a tarball containing the executable, it's core dump and 
     all the shared libraries that gdb said it loads. 

OPTIONS 
    -p <pid> A running process id of a process to be bundled. 
    -h  Show this help message" 
} 

pid= 
while getopts hp: opt 
do 
    case "$opt" in 
     p) 
      pid="$OPTARG" 
      ;; 
     h) 
      usage 
      exit 
      ;; 
     \?) 
      echo Unknown option 
      exit 
      ;; 
    esac 
done 
shift $(($OPTIND -1)) 
executable=$1 
corename=$2 

if [ -n "$pid" ]; then 
    test "$pid" -gt 0 || { echo "pid must be numeric"; exit 1; } 
    proc=/proc/$pid/exe 
    executable=`readlink -e $proc` || 
     { echo "Could not readlink $proc"; exit 1; } 
    corename=${basename}.$pid.core 
else 
    test -z "$executable" && usage && exit 1; 
    test -z "$corename" && usage && exit 1; 
fi 

basename=$(basename $executable) 
if [ -n "$pid" ]; then 
    sharedlibs=$(gdb -ex "attach $pid" -ex 'set height 0' \ 
     -ex 'set confirm off' -ex "generate-core-file $corename" \ 
     -ex 'info sharedlib' -ex quit| 
     sed -n '/Shared Object Library/,/^(/p'|grep -E '(Yes|No)'| 
     sed -e 's,[^/]\+,,') || exit 1 
    dir="gdb-${basename}.$pid.$(date +%F-%H%M%S)" 
else 
    sharedlibs=$(gdb -ex 'set height 0' -ex 'set confirm off' \ 
     -ex "file $executable" -ex "core-file $corename" \ 
     -ex 'info sharedlib' -ex quit| 
     sed -n '/Shared Object Library/,/^(/p'|grep -E '(Yes|No)'| 
     sed -e 's,[^/]\+,,') || exit 1 
    dir="gdb-${basename}.$(date +%F-%H%M%S)" 
fi 

mkdir "$dir" && cp "$corename" "$dir" && 
tar chf - $sharedlibs $executable|tar -C $dir -xf - && 
echo -e "gdb:\n\tgdb -ex 'set solib-absolute-prefix ./'" \ 
    "-ex 'file .$executable' -ex 'core-file ./$corename' " \ 
    > $dir/makefile && 
echo tar czf $dir.tar.gz $dir && 
tar czf $dir.tar.gz $dir 
0

您可以捕獲SIGSEGV,然後編寫一個子進程以將相關進程文件(使用lsof)複製到臨時目錄中。

0

首先找到與核心關聯的二進制文件。您有幾種選擇:

  1. 配置系統名稱內核使他們二進制後,和你的二進制文件被安裝在你的腳本可以抓住他們,一個標準的位置。有關命名核心are here的說明,另請參閱核心(5)。

  2. 如果你不能配置系統,我想到的最好的方法是在覈心上運行字符串,然後爲每個字符串提供一個運行「文件」的有效路徑,併爲「ELF」和「可執行」。這可以讓你得到錯誤的答案,特別是如果二進制文件被另一個實用程序(如make)調用時它們可能會出現在覈心文件中,所以如果你知道的話,你可以添加額外的過濾器,例如排除/ bin和/ usr/bin中的路徑你的二進制文件總是說/ opt,並選擇具有最近mtime的二進制文件(較新的軟件更可能是取心,更可能是你的,而不是系統附帶的軟件)。

  3. 補充技巧是在字符串輸出中查找「_ =/your/binary/here」 - 「_」是一些由shell/WMs/apps設置爲二進制文件的特殊環境變量,調用。它也可能會引起誤解(例如,當調用二進制文件時它將成爲/ usr/bin/make)。

其次,收集依賴於二進制:

  1. grep的再次核心進行LD_PRELOAD和LD_LIBRARY_PATH的值輸出字符串。這些可以影響二進制實際鏈接的庫。
  2. 在二進制文件上運行「ldd」,並將這些變量設置爲相同的值,並在「=>」上分割以查找每個庫的文件名。

然後將其全部複製到一個目錄中並在其上運行tar。將日誌文件複製到目錄通常也很有幫助。

相關問題