[转帖]GDB调试core文件

gdb,调试,core,文件 · 浏览次数 : 0

小编点评

**什么是core文件?** core文件是分析内存错误的有用的文件,它包含程序运行时的内存状态信息,包括寄存器信息、内存管理信息、处理器和操作系统状态和信息等。 core dump 文件可以用于编程人员诊断和调试程序,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序出错时的情景。 **在Ubuntu20中开启core dump功能** 1. 打开终端 2. 使用命令 `ulimit -c unlimited` 设置 core dump 文件的大小不限制 3. 更改 core 文件生成目录 4. 使用 `cat /proc/sys/kernel/core_pattern` 命令查看 core 文件保存路径 5. 可以将 core 文件生成在当前目录下:`echo core-%e-%p-%t > /proc/sys/kernel/core_pattern` **测试** 1. 创建一个名为 `test.c` 的文件,并在其中编写以下代码: ```c int p = NULL; p = 2; printf("\"%d\\",*p); ``` 2. 在当前目录下运行编译和执行程序: ```bash gcc -o learn_gdb -g learn_gdb.c ./learn_gdb -q ``` 3. 在 `learn_gdb` 中设置断点并运行程序: ```bash gdb learn_gdb -q break 5 ``` 4. 在断点处设置 `next` 命令,然后运行程序继续执行: ```bash next ``` 5. 使用 `step` 命令跟踪程序执行的代码行号。 6. 使用 `print` 命令打印变量的值。

正文

在Linux环境下C程序经常会出现A segmentation fault(段错误),如果我们的程序只有几十行,那么我们可以通过printf输出调试来找到哪个地方出现了异常,但如果是在项目中,如果我们还是通过print找查找错误,那么效率会很低。那么我们来学习一下Linux环境下通过core文件来找到发生段错误的位置。

1. 什么是core文件?

​ 对于c程序员来说,core文件是分析内存错误的有用的文件,结合gdb命令,一般情况下(有时候代码编译的时候没有包含debug信息或者栈空间被破坏,会看不到具体的位置信息),可以知道导致core的具体的代码位置。当程序运行的过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做Core Dump(中文有的翻译成“核心转储”)。我们可以认为 core dump 是“内存快照”,但实际上,除了内存信息之外,还有些关键的程序运行状态也会同时 dump 下来,例如寄存器信息(包括程序指针、栈指针等)、内存管理信息、其他处理器和操作系统状态和信息。core dump 对于编程人员诊断和调试程序是非常有帮助的,因为对于有些程序错误是很难重现的,例如指针异常,而 core dump 文件可以再现程序 出错时的情景。

2. 在Ubuntu20中怎么开启core dump功能

在终端输入命令:ulimit -c
在这里插入图片描述
输出结果为0,说明默认是关闭core dump的。
使用命令 ulimit -c unlimited 来开启core dump功能,并且不限制core dump文件的大小;如果需要限制文件的大小,将unlimited改成core文件最大的大小,单位为blocks(KB)
在这里插入图片描述

用上面的命令只会对当前的终端环境有效,如果想要永久生效,可以参考以下方法:
法一:
修改/etc/security/limits.conf参考以下代码:
在这里插入图片描述

法二:

编辑 .bashrc 文件:

vim ~/.bashrc

    添加:

    ulimit -c unlimited
    

      保存,退出。

      source ~/.bashrc
      

        source命令使修改立即生效。就可以了。

        更改core文件生成目录
        通过cat /proc/sys/kernel/core_pattern命令查看core文件保存路径。

        如果想要把core文件生成在当前目录下,可以通过以下命令进行修改。

        echo core-%e-%p-%t > /proc/sys/kernel/core_pattern
        

          将更改core文件生成路径,自动放在这个当前目录下。
          core文件参数详情:

          %p - insert pid into filename 添加pid
          %u - insert current uid into filename 添加当前uid
          %g - insert current gid into filename 添加当前gid
          %s - insert signal that caused the coredump into the filename 添加导致产生core的信号
          %t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
          %h - insert hostname where the coredump happened into filename 添加主机名
          %e - insert coredumping executable name into filename 添加程序名

          3. 测试

          #include <stdio.h>
          

          int main() {
          int p = NULL;
          p = 2;
          printf("%d\n",*p);
          return 0;
          }

            //编译,编译时需要加上-g参数
            gcc -o test -g test.c
            //执行
            ./test
            

              在这里插入图片描述

              当前目录下生成了一个core文件,文件名中的test表示添加程序名、2057表示添加pid、11表示添加core文件生成时的unix时间。

              //调试文件
              gdb test core-test-2057-11
              

                在这里插入图片描述
                通过调试文件可以看到段错误发生在test.c:5的*p=2处。

                发生段错误可能的原因

                4. 常见的GDB调试命令

                在使用gcc/g++编译文件时,要加上-g参数
                例如:

                gcc -o learn_gdb -g learn_gdb.c
                

                  进入gdb:

                  gdb learn_gdb -q
                  

                    常用命令:

                    调试命令 (缩写) 作用
                    (gdb) break (b) 在源代码指定的某一行设置断点,其中xxx用于指定具体打断点位置
                    (gdb) run (r) 执行被调试的程序,其会自动在第一个断点处暂停执行。
                    (gdb) continue (c) 当程序在某一断点处停止后,用该指令可以继续执行,直至遇到断点或者程序结束。
                    (gdb) next (n) 令程序一行代码一行代码的执行。
                    (gdb) step(s) 如果有调用函数,进入调用的函数内部;否则,和 next 命令的功能一样。
                    (gdb) until (u)
                    (gdb) until (u) location 当你厌倦了在一个循环体内单步跟踪时,单纯使用 until 命令,可以运行程序直到退出循环体。
                    until n 命令中,n 为某一行代码的行号,该命令会使程序运行至第 n 行代码处停止。
                    (gdb) print (p) 打印指定变量的值,其中 xxx 指的就是某一变量名。
                    (gdb) list (l) 显示源程序代码的内容,包括各行代码所在的行号。
                    (gdb) finish(fi) 结束当前正在执行的函数,并在跳出函数后暂停程序的执行。
                    (gdb) return(return) 结束当前调用函数并返回指定值,到上一层函数调用处停止程序执行。
                    (gdb) jump(j) 使程序从当前要执行的代码处,直接跳转到指定位置处继续执行后续的代码。
                    (gdb) quit (q) 终止调试。
                    (gdb) Backtrace(bt) 查看堆栈。
                    (gdb) info threads 显示当前可调试的所有线程
                    (gdb) thread ID 切换当前调试的线程为指定ID的线程
                    (gdb) attach process-id 在gdb状态下,开始调试一个正在运行的进程
                    (gdb) thread apply all command 所有线程执行command

                    参考链接
                    参考资料1
                    参考资料2

                    与[转帖]GDB调试core文件相似的内容:

                    [转帖]GDB调试core文件

                    在Linux环境下C程序经常会出现A segmentation fault(段错误),如果我们的程序只有几十行,那么我们可以通过printf输出调试来找到哪个地方出现了异常,但如果是在项目中,如果我们还是通过print找查找错误,那么效率会很低。那么我们来学习一下Linux环境下通过core文件来找

                    [转帖]gdb调试

                    https://zhuanlan.zhihu.com/p/395115890?utm_id=0 写这个文档的目的,是让有一定软件开发基础的同学,可以较为快速地入门gdb的使用。gdb的命令非常多,在做了简短的介绍后,我挑选了最高频使用的命令/场景,希望能够让读者一个小时拥有即战力。 为了让读者对gd

                    [转帖]gdb调试常见命令详细总结(附示例操作)

                    一、简介 通过gdb调试我们可以监控程序执行的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码,程序的调试过程主要有:单步执行,跳入函数,跳出函数,设置断点,设置观察点,查看变量。 本文将主要介绍linux下的gdb调试工具常用的命令和具体的使用实

                    [转帖]gdb进阶调试技巧

                    https://www.jianshu.com/p/9bdaa0644dba 整理一下在linux下C/C++用gdb工具debug一些提高效率的操作。基本的gdb操作就不在这里赘述了。 打印各种变量x 命令在gdb中可以使用x命令,来打印内存中的值。具体的格式是x/nfu addr。 含义为以f格

                    [转帖]gdb 常用命令

                    https://www.cnblogs.com/xvic/p/15997498.html 栈信息 不管是操作转储文件还是用GDB设置断点进行调试,都可以输入 (gdb)bt 打印栈内容进行查看。一般的宕机BUG,看下宕机的位置,然后看下源代码基本就可以解决了。但是很多情况下简单的 (gdb)bt 还

                    [转帖]如何快速查看进程/子线程堆栈

                    背景:分析现网问题时,有时需要快速查看某个进程/子线程堆栈调用,便于进一步分析问题,现提供几种不同获取进程堆栈方法。 实现方法: 1.使用gdb attach 调试进程,使用gdb相关cmd调试进程 # gdb -p pid 进入gdb后,可通过 (gdb)bt 查看主进程堆栈 (gdb)info

                    [转帖]关于gdb相关的几个工具的说明

                    https://phpor.net/blog/post/846 使用rpm命名查看gdb的rpm包,主要由下面几个程序:/usr/bin/gcore/usr/bin/gdb/usr/bin/gdbserver/usr/bin/gdbtui/usr/bin/gstack 其中:gcore 是生成cor

                    [转帖]记一次使用gdb诊断gc问题全过程

                    https://www.cnblogs.com/codelogs/p/17092141.html 简介# 上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下:从这个图中可以发现,我们GC有

                    [转帖] 记一次使用gdb诊断gc问题全过程

                    记一次使用gdb诊断gc问题全过程 原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。 简介# 上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》然而,过了一段时间,我检查GC日志时,又发现了一个GC问题,如下:从这个图中可

                    [转帖]程序运行崩溃(segfault)的排查方法

                    这篇博文记录的非常详细:https://blog.csdn.net/zhaohaijie600/article/details/45246569 我的笔记: 写的C++程序老是运行两三天就挂了,关键是挂的时候连“segment fault”都不显示。动用了gdb、valgrind还是没办法,最后还是