段错误(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调试的更多相关文章

  1. 在Linux上利用core dump和GDB调试segfault

    时常会遇到段错误(segfault),调试非常费劲,除了单元测试和基本测试外,有些时候是在在线环境下,没有基本开发和测试工具,这就需要调试的技能.以前介绍过使用strace进行系统调试和追踪<l ...

  2. linux下生成core dump文件方法及设置

    linux下生成core dump文件方法及设置    from:http://www.cppblog.com/kongque/archive/2011/03/07/141262.html core ...

  3. 发布项目到 Linux 上运行 Core 项目

    发布项目到 Linux 上运行 Core 项目 目录索引 [无私分享:ASP.NET CORE 项目实战]目录索引 简介 ASP.Net Core 给我们带来的最大的亮点就是跨平台,我在我电脑(win ...

  4. Visual Studio 2017 通过SSH 调试Linux 上.NET Core

    Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Studio 2017 部署环境:Ubuntu ...

  5. Linux系统打开core dump的配置【转】

    什么是core dump core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.core du ...

  6. Linux中生成Core Dump系统异常信息记录文件的教程

    Linux中生成Core Dump系统异常信息记录文件的教程 http://www.jb51.net/LINUXjishu/473351.html

  7. VS2017 Linux 上.NET Core调试

    调试Linux 上.NET Core Visual Studio 2017 通过SSH 调试Linux 上.NET Core 应用程序. 本文环境 开发环境:Win10 x64 Visual Stud ...

  8. linux core dump 文件 gdb分析

    core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump. (linux中如果内存越界会收到SIG ...

  9. linux下生成core dump文件方法及设置【转】

    转自:http://blog.csdn.net/mrjy1475726263/article/details/44116289 源自:http://andyniu.iteye.com/blog/196 ...

随机推荐

  1. (转)Python中集合(set)的基本操作以及一些常见的用法

    原文:http://blog.51cto.com/10616534/1944841 Python除了List.Tuple.Dict等常用数据类型外,还有一种数据类型叫做集合(set),集合的最大特点是 ...

  2. 第6章—渲染web视图—使用Thymeleaf

    使用Thymeleaf 长期以来,jsp在视图领域有非常重要的地位,随着时间的变迁,出现了一位新的挑战者:Thymeleaf,Thymeleaf是原生的,不依赖于标签库.它能够在接受原始HTML的地方 ...

  3. Dubbo-Centos7管控台安装

    1.下载Tomcat7: $ wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-7/v7.0.57/bin/apache-tomcat-7.0. ...

  4. Go语言学习笔记八: 数组

    Go语言学习笔记八: 数组 数组地球人都知道.所以只说说Go语言的特殊(奇葩)写法. 我一直在想一个人参与了两种语言的设计,但是最后两种语言的语法差异这么大.这是自己否定自己么,为什么不与之前统一一下 ...

  5. centos 关闭selinux 临时关闭selinux 报错 setenforce: setenforce() failed

    关闭selinux的方法有两种:临时关闭和永久关闭. 查看selinux的状态:estatus [root@--- ~]# sestatus SELinux status: enabled SELin ...

  6. 01-python基础

    前几天, 觉得python简单的不行, 没有仔细做笔记, 然后今天翻了下前几天看的东西, 还是记下来吧 对于python2.7 和 python3 , 建议使用python3 的模式编程, 然后使用p ...

  7. 文件触发式实时同步 Rsync+Sersync Rsync+Inotify-tools

    一.概述 1.Rsync+Sersync 是什么? 1)Sersync使用c++编写基于inotify开发的触发机制: 2)Sersync可以监控所监听的目录发生的变化(包括新建.修改.删除),具体到 ...

  8. funny alphabet

    1.A Boy Can Do Everything For Girl 2. He Is Just Kidding 3. Love Must Need Our Patience

  9. nginx学习笔记(8)虚拟主机名---转载

    通配符名字正则表达式名字其他类型的名字优化兼容性 虚拟主机名使用server_name指令定义,用于决定由某台虚拟主机来处理请求.具体请参考<nginx如何处理一个请求>.虚拟主机名可以使 ...

  10. nginx学习笔记(7)Nginx如何处理一个请求---转载

    如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...