zoukankan      html  css  js  c++  java
  • core文件与gdb调试

      1、核心转储文件(core dump file),下文简称core文件。

      1)简介:某些信号(如SIGQUIT、SIGABRT和SIGSEGV)的默认动作就是引起进程终止并产生core文件。该文件包含进程终止时的内存镜像,用于在调试时探测程序终止时的状态,以随时重现错误。

      coredump的开启和关闭:用ulimit -a查看若core file size这一项为0,说明coredump没开启。ulimit -c可以开启coredump并指定最大能产生的core文件(0表示关闭coredump)。默认不产生core文件,因为它可能包含敏感信息。

      默认的core文件名为core,且在当前目录产生。/proc/sys/kernel/core_pattern定义了core文件的存放目录和命名方式(如/data/coredump/core_%e_%t。其中,%e表示可执行文件名、%t表示coredump的时间、%p表示PID、%s表示引发coredump的信号值等)。另外,若/proc/sys/kernel/core_uses_pid的内容是非0值,则core文件名会把进程ID作为扩展(***.pid)。

      2)使用core文件进行调试。例子:

    int main()
    {   
        int *p = 0;
        cout << *p << endl;
    }

      步骤:(1)开启coredump:ulimit -c unlimited;(2)编译:g++ test.cpp -g;(3)执行:./a.out,出现错误Segmentation fault (core dumped)并产生文件core;(4)调试:gdb ./a.out core

      3)通过管道将核心转储信息重定向给一个进程,而不是写入到磁盘文件。

      Linux从内核2.6.19开始,若/proc/sys/kernel/core_pattern的首字符是'|'(管道),则该行剩下部分将被解析为一个程序及其命令行参数,并在某个进程发生coredump时被执行。coredump的核心转储信息被重定向到该程序的标准输入。

      注意:core_pattern中的程序名必须是绝对路径,且紧跟在'|'后面;该程序以root用户/组运行;可指定命令行参数(从Linux 2.6.24开始),如%p表示发生coredump的进程ID,但行的最大长度为128字节。以下是man core中的例子:

    // core_pattern_pipe_test.c
    //
    忽略错误处理逻辑 #define BUF_SIZE 1024 int main(int argc, char *argv[]) { // 将目录切换到发生coredump的进程的工作目录。argv[1]即core_pattern文件的%p char cwd[PATH_MAX]; snprintf(cwd, PATH_MAX, "/proc/%s/cwd", argv[1]); chdir(cwd); FILE *fp = fopen("core.info", "w+"); // 在core.info中写入发生coredump的进程的信息 int j = 0; fprintf(fp, "argc=%d ", argc); for (j = 0; j < argc; j++) { fprintf(fp, "argc[%d]=<%s> ", j, argv[j]); } // 核心转储信息的字节数 int tot = 0; ssize_t nread; char buf[BUF_SIZE]; while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) { tot += nread; } fprintf(fp, "Total bytes in core dump: %d ", tot); exit(EXIT_SUCCESS); }

      编译得到core_pattern_pipe_test(在/home/hanerfan/programming目录) -> 将/proc/sys/kernel/core_pattern的内容改为"|/home/hanerfan/programming/core_pattern_pipe_test %p UID=%u GID=%g sig=%s"

      执行sleep 100,然后按Ctrl+,则sleep进程被SIGQUIT信号终止并产生核心转储信息 -> 因为core_pattern首字符为'|',因此执行/home/hanerfan/programming/core_pattern_pipe_test %p...。core.info中写入了一些核心转储信息,如下:

    ~/programming$ sudo cat core.info 
    argc=5
    argc[0]=</home/hanerfan/programming/core_pattern_pipe_test>
    argc[1]=<5314>
    argc[2]=<UID=1000>
    argc[3]=<GID=1000>
    argc[4]=<sig=3>
    Total bytes in core dump: 356352

      2、gdb调试

      1)gdbserver:Remote Server for the GNU Debugger。远程调试。

      (1)安装

    yum install gdb-gdbserver.x86_64 # 可先用yum search gdbserver搜索到对应的安装包

      (2)运行

      I、服务器:执行gdbserver localhost:2345 ./a.out(在2345端口上监听远程gdb请求,a.out为被调试的程序)。

      II、客户端:

    [root@localhost siosvr]# gdb
    (gdb) file a.out 
    (gdb) target remote 192.168.32.101:2345 # 客户端和服务器建立了连接(101为服务器地址)。
    (gdb) b 10 # 设置断点
    (gdb) continue # 服务器端的a.out开始运行,并在该断点处“暂停”
    (gdb) continue # 服务器端的a.out正常退出,GDBserver退出

     

    不断学习中。。。

  • 相关阅读:
    Goldbach's Conjecture
    查找素数
    最大公约数和最小公倍数
    迭代求立方根
    计算两个矩阵的乘积
    随机选择算法
    有几个PAT
    python3学习笔记之安装
    Ubuntu 16.04卸载一些不必要的预装软件
    Xshell连接不上虚拟机提示ssh服务器拒绝了密码,请再试一次
  • 原文地址:https://www.cnblogs.com/hanerfan/p/3380938.html
Copyright © 2011-2022 走看看