在Linux上利用core dump和GDB调试
段错误(segfault)
"段错误"是程序试图操作不允许访问或试图访问的不允许内存的情况。可能导致段错误的原因主要有:
1、试图解引用空指针(你不允许访问内存地址0)
2、试图解引用不在你内存中的其他指针
3、一个C++ vtable虚表指针被破坏并指向错误的地方,这导致程序试图去执行一些不可执行的内存。
4、其他情况,比如未对齐的内存访问也可能会出现段错误。
core dump 文件
在linux下当应用程序发生异常中止退出或者发生崩溃的时候,linux内核会将应用程序在这段运行期间的内存状态等相关信息转存到磁盘,以供系统故障排查或者调试。这个转存的文件叫core dump文件。core dump文件中会记录程序当时的内存调用、堆栈引用、进程和线程调用等信息,可以帮助开发人员和维护人员了解异常发生当时的环境参数和信息,所以core dump对故障排查和bug调试具有重大的意义。
要深入探究还得利用得core dump文件,下面我们就对其进一步探究:
如何获得core dump
我们前面说了core dump是程序发生异常时候,其内存使用副本的转存文件,当你需要调试程具体序出错时的信息时候,它非常有用。
当程序发生段错误时,Linux内核有时会向磁盘写入一个core dump文件。很多人可能疑惑按照教程一步一步来做了,但是最后没有获得所需的core dump。一般情况下系统设置不输出core dump,所以没有生成core dump文件。
如果没有生成core dump文件,请按照以下步骤做设置:
1.在linux终端执行以下命令 ulimit -c unlimited
2.运行sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t
ulimit:
在linux下 通过ulimit -c设置core dump的最大值。它默认设置为0,这时候内核就不会生成core dump。它以KB为单位。 ulimit是按进程为单位进行设置的。我们可以通过运行cat /proc/PID/limit来查看具体某个进程的大小限制。
例如,这些是我的系统随便一个nginx进程的大小限制:
cat /proc/8854/limits (PID换成你系统中具体的进程号,此处我的系统中进程号位8854)
内核通过soft limit值决定写入core文件的大小 (例如上图中我们的nginx"max core file size = 0")。我们使用使用ulimit -c unlimited将软限制无限制,core dump文件就可以无限增大。我们也可以用具体文件大小来替代umlimited的值。
kernel.core_pattern
kernel.core_pattern是内核参数,通过 sysctl命令来配置,用于控制Linux内核将core dump写入磁盘的位置和文件名格式。
我们可以通过运行sysctl -a来获取当前系统的所有内核参数和设置值得列表。或者使用sysctl kernel.core_pattern仅查看kernel.core_pattern的设置值。
sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t设置下core dump文件将被写入/tmp/core-(标识进程的参数值)。具体关于%e.%p.%h参数的表示内容,请参阅man core。
Ubuntu下kernel.core_pattern设置
默认情况下,Ubuntu上, kernel.core_pattern设置的内容为:
sysctl kernel.core_pattern
kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P
这曾让我很困惑,这是什么东西,它是怎么处理我的core dump的。所以我搜索相关资料了解到:
Ubuntu使用称为"apport"的系统来记录apt包管理器中的崩溃
设置kernel.core_pattern = |/usr/share/apport/apport %p %s %c %d %P
表示core dump内容被重定向到apport,其日志为/var/log/apport.log
默认情况下,apport将忽略来非Ubuntu软件包的二进制文件的那部分的崩溃日志。所以默认apport.log中默认也是不会记录core dump信息的。为了得到core dump具体做法就是重新设置kernel.core_pattern的值,将其设为sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t。
用gdb进行追踪
core dump中信息是支持用gdb做调试的,关于gdb是linux下一个强大的debug调试程序,不熟悉的同学,先搜索一下。
用下面的gdb命令打开一个core dump文件:
gdb -c my_core_file
接下来,我们想知道程序崩溃时的堆栈是什么。在gdb提示符下运行bt会给你一个堆栈追踪。默认情况下,编译时候没有做符号调试,gdb无法加载二进制符号,所以追踪结果中会都是??。如下图所示:
这种情况下,我们需要加载符号符号表,使得显示正常。可通过在gdb命令下执行:
symbol-file 应用的执行程序(绝对路径)
sharedlibrary
这会从二进制程序文件及其引入的共享库中加载符号。执行后,再次输入bt,gdb就会返回带有行号堆栈跟踪信息。
如果你想让其工作正常,在做程序做调试时候应该启用哦调试符号编译(gcc -g)。在试图找出程序崩溃的原因时,在堆栈跟踪中有行号非常有用。
在gdb也可以查看每个线程的堆栈,具体方法如下: thread apply all bt full
在Linux上利用core dump和GDB调试的更多相关文章
- 在Linux上利用core dump和GDB调试segfault
时常会遇到段错误(segfault),调试非常费劲,除了单元测试和基本测试外,有些时候是在在线环境下,没有基本开发和测试工具,这就需要调试的技能.以前介绍过使用strace进行系统调试和追踪<l ...
- linux下生成core dump文件方法及设置
linux下生成core dump文件方法及设置 from:http://www.cppblog.com/kongque/archive/2011/03/07/141262.html core ...
- 发布项目到 Linux 上运行 Core 项目
发布项目到 Linux 上运行 Core 项目 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 ASP.Net Core 给我们带来的最大的亮点就是跨平台,我在我电脑(win ...
- Visual Studio 2017 通过SSH 调试Linux 上.NET Core
Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Studio 2017 部署环境:Ubuntu ...
- Linux系统打开core dump的配置【转】
什么是core dump core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.core du ...
- Linux中生成Core Dump系统异常信息记录文件的教程
Linux中生成Core Dump系统异常信息记录文件的教程 http://www.jb51.net/LINUXjishu/473351.html
- VS2017 Linux 上.NET Core调试
调试Linux 上.NET Core Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Stud ...
- linux core dump 文件 gdb分析
core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIG ...
- linux下生成core dump文件方法及设置【转】
转自:http://blog.csdn.net/mrjy1475726263/article/details/44116289 源自:http://andyniu.iteye.com/blog/196 ...
随机推荐
- PHP相关异常
1. Maximum execution time of 30 seconds exceeded 报错一:内存超限,具体报错语句忘了,简单说一下解决办法 1> 利用循环分批导入: 2> 每 ...
- 简单shell expect程序
1 expect程序 用的Ubuntu,本身没带expect,安装. sudo apt-get install expect (关于expect,参见http://www.tclchina.com/a ...
- 使用seek()方法报错:“io.UnsupportedOperation: can't do nonzero cur-relative seeks”错误的原因
在使用seek()函数时,有时候会报错为 “io.UnsupportedOperation: can't do nonzero cur-relative seeks”,代码如下: >>& ...
- database lock
USE masterEXEC sp_lock select * from sys.sysprocesses where blocked<>0 DBCC INPUTBUFFER(120) k ...
- Go 单元测试、基准测试、并发基准测试
一.单元测试 要开始一个单元测试,需要准备一个 go 源码文件,在命名文件时需要让文件必须以_test结尾. 单元测试源码文件可以由多个测试用例组成,每个测试用例函数需要以Test为前缀,例如: fu ...
- Hive导入数据的四种方法
Hive的几种常见的数据导入方式这里介绍四种:(1).从本地文件系统中导入数据到Hive表:(2).从HDFS上导入数据到Hive表:(3).从别的表中查询出相应的数据并导入到Hive表中:(4).在 ...
- [HNOI 2018]寻宝游戏
Description 题库链接 给出 \(n\) 个 \(m\) 位的二进制数,在每一个二进制数间插入一个 & 或 | ,第 \(0\) 个数为 \(0\) , \(0,1\) 间也要插入符 ...
- Linux man C++ 库函数
默认情况下,linux是的man是不能查阅C++的标准库函数的,这个很不方便,那有没有办法可以直接man C++标准库函数呢? 当然有,不过要自己动手,自己动手,才能丰衣足食! 1. 下载安装manp ...
- msdn 中MethodBase.Invoke 方法 介绍中的坑
模块开发总结: c#动态调用webservices 来自网络及使用心得. msdn: MethodBase.Invoke 方法 (Object, Object[]) 使用指定的参数调用当前实例所表示的 ...
- linux中echo命令详解
linux的echo命令, 在shell编程中极为常用, 在终端下打印变量value的时候也是常常用到的, 因此有必要了解下echo的用法 echo命令的功能是在显示器上显示一段文字,一般起到一个提示 ...