Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 如何将核心文件与其关联的可执行文件捆绑在一起?_Linux_Debugging_Gdb_Core - Fatal编程技术网

Linux 如何将核心文件与其关联的可执行文件捆绑在一起?

Linux 如何将核心文件与其关联的可执行文件捆绑在一起?,linux,debugging,gdb,core,Linux,Debugging,Gdb,Core,如何将核心文件与其关联的可执行文件和共享库捆绑在一起 当一个程序崩溃时,它会生成一个核心文件,我可以用它来调试gdb。但是如果有人跟在我后面,在开启额外调试的情况下“有益地”重新编译程序,或者升级软件包,或者以任何方式破坏系统,那么核心文件将变得毫无用处 所以我想要的是一种将核心文件和它引用的所有其他二进制文件捆绑到一个大文件中的方法 当然,我还需要一种在gdb中打开这个文件的方法。我不想将文件“提取”回原始位置,并覆盖升级或更改的二进制文件。我正在想象一个shell脚本,它将二进制文件提取到一

如何将核心文件与其关联的可执行文件和共享库捆绑在一起

当一个程序崩溃时,它会生成一个核心文件,我可以用它来调试gdb。但是如果有人跟在我后面,在开启额外调试的情况下“有益地”重新编译程序,或者升级软件包,或者以任何方式破坏系统,那么核心文件将变得毫无用处

所以我想要的是一种将核心文件和它引用的所有其他二进制文件捆绑到一个大文件中的方法


当然,我还需要一种在gdb中打开这个文件的方法。我不想将文件“提取”回原始位置,并覆盖升级或更改的二进制文件。我正在想象一个shell脚本,它将二进制文件提取到一个临时目录中,然后告诉gdb查看那里。

您可以捕获SIGSEGV,然后编写一个子进程,将相关的进程文件(使用lsof)复制到临时目录中。

首先找到与核心相关的二进制文件。您有几个选择:

  • 将系统配置为根据导致核心的二进制文件命名核心,并将二进制文件安装在脚本可以从中获取它们的标准位置。有关核心命名的说明,另请参见核心(5)

  • 如果您无法配置系统,我想到的最好方法是在内核上运行字符串,然后对每个字符串运行一个有效路径“file”,并对“ELF”和“executable”进行grepping。这可能会让您得到错误的答案,特别是如果二进制文件被另一个实用程序(如make)调用,它们可能会出现在内核中,因此您可以添加额外的过滤器,如排除/bin和/usr/bin中的路径(如果您知道二进制文件始终位于say/opt中),并选择具有最新mtime的二进制文件(较新的软件更可能是取芯软件,也更可能是您的,而不是系统附带的软件)

  • 另一个补充技巧是在字符串输出中查找“=/your/binary/here”——“”是一个特殊的环境变量,由一些Shell/WMs/apps设置为它们正在调用的二进制文件。但它也可能会产生误导(例如,当make调用二进制文件时,它将是/usr/bin/make)

  • 其次,收集二进制文件的依赖项:

  • 再次Grep从核心输出的字符串,以获取LD_PRELOAD和LD_LIBRARY_PATH的值。这些值可能会影响二进制文件实际链接的库
  • 在二进制文件上运行“ldd”,将这些变量设置为相同的值,并在“=>”上拆分以查找每个库的文件名

  • 然后将其全部复制到一个目录中并在其上运行tar。将日志文件复制到该目录中通常也很有帮助。

    gdb已经有了您想要的信息(
    info sharedlib
    ):

    因此,您自然可以要求gdb提供这个列表,然后从中可以创建一个“gdb bundle”tarball,其中包含可执行文件和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
    
    !/bin/sh
    me=$(基本名称$0)
    用法(){
    “回声”用法:
    $me-p
    $me
    描述
    $me-创建一个包含可执行文件的tarball,它的核心转储和
    gdb说它加载的所有共享库。
    选择权
    -p要绑定的进程的运行进程id。
    -h显示此帮助消息“
    }
    pid=
    而getopts hp:opt
    做
    案例“$opt”加入
    (p)
    pid=“$OPTARG”
    ;;
    h)
    使用
    出口
    ;;
    \?)
    回声未知选项
    出口
    ;;
    以撒
    完成
    班次$($OPTIND-1))
    可执行文件=$1
    corename=$2
    如果[-n“$pid”];然后
    测试“$pid”-gt 0 |{echo”pid必须为数字;退出1;}
    proc=/proc/$pid/exe
    可执行文件=`readlink-e$proc`||
    {echo“无法读取链接$proc;退出1;}
    corename=${basename}.$pid.core
    其他的
    测试-z“$executable”&&usage&&exit 1;
    测试-z“$corename”&使用和退出1;
    fi
    basename=$(basename$可执行文件)
    如果[-n“$pid”];然后
    sharedlibs=$(gdb-ex“附加$pid”-ex“设置高度0”\
    -ex“设置确认关闭”-ex“生成核心文件$corename”\
    -ex'info sharedlib'-ex退出|
    sed-n'/sharedobjectlibrary/,/^(/p'| grep-E'(Yes | No)'|
    sed-e's,[^/]\+,')| |退出1
    dir=“gdb-${basename}.$pid.$(日期+%F-%H%M%S)”
    其他的
    sharedlibs=$(gdb-ex'设置高度0'-ex'设置确认关闭'\
    -ex“文件$executable”-ex“核心文件$corename”\
    -ex'info sharedlib'-ex退出|
    sed-n'/sharedobjectlibrary/,/^(/p'| grep-E'(Yes | No)'|
    sed-e's,[^/]\+,')| |退出1
    dir=“gdb-${basename}.$(日期+%F-%H%M%S)”
    fi
    mkdir“$dir”和&cp“$corename”“$dir”&&
    tar chf-$sharedlibs$可执行文件| tar-C$dir-xf-&&
    echo-e“gdb:\n\tgdb-ex'设置solib绝对前缀。/”\
    “-ex'文件。$executable'-ex'核心文件。/$corename'”\
    >$dir/makefile&&
    echo tar czf$dir.tar.gz$dir&&
    焦油czf$dir.tar.gz$dir
    
    #!/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