0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

段错误以及调试方法

技术让梦想更伟大 来源:CSDN-文曲尽墨琛乃缺 2023-02-21 09:12 次阅读

一.段错误产生的原因

段错误就是访问了不可访问的内存,出现了运行时出现了segmentation fault的报错

产生的原因:访问不存在的内存地址、访问系统保护的内存地址 、访问只读的内存地址、空指针废弃(eg:malloc与free释放后,继续使用)、堆栈溢出、内存越界(数组越界,变量类型不一致等)

二. 使用GDB逐步查找段错误

首先加上命令行得先加上-g -rdynamic的参数进行编译,eg:gcc -g rdynamic xxx.c 随着gdb ./a.out

eg:70750666-b17b-11ed-bfe3-dac502259ad0.png

运行结果

70cd1e32-b17b-11ed-bfe3-dac502259ad0.png很明显,都不用一步步的调试,后面几行就显示了出错位置。 并且进程还收到了SIGSEGV信号而结束,而SIGSEGV默认的handler的动作是打印“段错误”的出错信息,并产生core文件。

三. 分析core文件

什么是core文件 Core文件其实就是内存的映像,当程序崩溃时,存储内存的相应信息,主用用于对程序进行调试。 当程序崩溃时便会产生core文件,其实准确的应该说是core dump 文件,默认生成位置与可执行程序位于同一目录下,文件名为core. Core的意思是内存, Dump的意思是扔出来;core dump又叫核心转储, 当程序运行过程中发生异常, 程序异常退出时, 由操作系统把程序当前的内存状况存储在一个core文件中, 叫core dump.

如何使用

gdb-ccore文件路径[应用程序的路径]
1

进去后输入where回车, 就可以显示程序在哪一行当掉的, 在哪个函数中。
但是core文件的生成跟你当前系统的环境设置有关系, 可以用下面的语句设置一下, 然后再运行程序便成生成core文件ulimit -c ulimited; 输入命令

ulimit-c//查是否为0,是0就不生成core文件
ulimit-c1000//ulimit-culimited,改变数值,限制系统的core文件大小
12

eg 70fe1ab4-b17b-11ed-bfe3-dac502259ad0.png

四.段错误时启动调试

(gdb)bt71216cd0-b17b-11ed-bfe3-dac502259ad0.png二,三,四都是在基于系统上的gdb的前提进行的。如果没有,glibc为我们提供了此类能够dump栈内容的函数簇,详见/usr/include/execinfo.h

五. 利用backtrace和objdump进行分析

eg714f51e0-b17b-11ed-bfe3-dac502259ad0.png71afb7ec-b17b-11ed-bfe3-dac502259ad0.png

运行结果

71ee1f78-b17b-11ed-bfe3-dac502259ad0.png

这里得提一下,需要用到库

运行结果似乎没上面几种方式的信息多,清晰;但是还没完,我们再用objdump反汇编程序,找到上面地址对应的代码位置。

objdump -d a.out找到对应main 0x5601a75e0b0f对应的代码位置

72108a54-b17b-11ed-bfe3-dac502259ad0.png

backtrace函数
backtrace函数的作用:当程序出现异常,段错误,崩溃的情况下,会收到内核发送给进程的异常信号,会把程序的堆栈信息打印出来。

intbacktrace(void**buffer,intsize)
//该函数获取当前线程的调用堆栈,获取的信息将会被存放在buffer中,它是一个指针数组,参数size用来指定buffer中可以保存多少个void*元素。函数的返回值是实际返回的void*元素个数。buffer中的void*元素实际是从堆栈中获取的返回地址。
char**backtrace_symbols(void*const*buffer,intsize)
//该函数将backtrace函数获取的信息转化为一个字符串数组,参数buffer是backtrace获取的堆栈指针,size是backtrace返回值。函数返回值是一个指向字符串数组的指针,它包含char*元素个数为size。每个字符串包含了一个相对于buffer中对应元素的可打印信息,包括函数名、函数偏移地址和实际返回地址。
//backtrace_symbols生成的字符串占用的内存是malloc出来的,但是是一次性malloc出来的,释放是只需要一次性释放返回的二级指针即可。
voidbacktrace_symbols_fd(void*const*buffer,intsize,intfd)
//该函数与backtrace_symbols函数功能相同,只是它不会malloc内存,而是将结果写入文件描述符为fd的文件中,每个函数对应一行;该函数可重入。
1234567

注意事项:backtrace_symbols的实现需要符号名称的支持,在gcc编译过程中需要加入-rdynamic参数;

objdump反汇编码

objdump-ftest//显示test的文件头信息

objdump-dtest//反汇编test中的需要执行指令的那些section

objdump-Dtest//与-d类似,但反汇编test中的所有section

objdump-htest//显示test的SectionHeader信息

objdump-xtest//显示test的全部Header信息

objdump-stest//除了显示test的全部Header信息,还显示他们对应的十六进制文件代码
1234567891011

六.段错误信息的获取

当我们运行的时候,发先有段错误segmentation fault时,我们可以通过一些命令进行段错误信息获取。

-g gcc -g 主要适用于gdb调试

dmesg 直接输入命令dmesgdmesg 可以在应用程序崩溃时,显示内存中保存的相关信息。 dmesg 可以查看发生段错误的程序名称、引起段错误发生的内存地址、指令指针地址、堆栈指针地址、错误代码、错误原因等等。

ldd 命令
查看二进制程序的共享链接库依赖,包括库的名称、起始地址,这样可以确定段错误到底是发生在了自己的程序中还是依赖的共享库中。

723dedfa-b17b-11ed-bfe3-dac502259ad0.png

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 内存
    +关注

    关注

    8

    文章

    2767

    浏览量

    72777
  • 调试
    +关注

    关注

    7

    文章

    527

    浏览量

    33625
  • 文件
    +关注

    关注

    1

    文章

    540

    浏览量

    24402
  • 编译
    +关注

    关注

    0

    文章

    615

    浏览量

    32397
  • gdb
    gdb
    +关注

    关注

    0

    文章

    60

    浏览量

    13162

原文标题:段错误以及调试方法

文章出处:【微信号:技术让梦想更伟大,微信公众号:技术让梦想更伟大】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式C开发中段错误的3种调试方法

    相信大家在嵌入式C开发中,或多或少都会遇到段错误(segmentation fault )。昨天分享了一个总线错误的例子:嵌入式软件中,关于总线错误,我帮你们踩了这些坑!相比总线错误
    发表于 07-11 09:42 139次阅读
    嵌入式C开发中段<b class='flag-5'>错误</b>的3种<b class='flag-5'>调试</b><b class='flag-5'>方法</b>

    MDK调试时出现MEMORY MISMATCH错误的原因及解决方法

    MDK调试时出现MEMORY MISMATCH错误的原因及解决方法 一、问题    在用RealView MDK + ULink仿真器进行调试
    发表于 08-02 09:28

    请问多核和单核调试区别和方法,有无操作系统(DSP/BIOS)的调试区别以及方法

    本帖最后由 一只耳朵怪 于 2018-6-19 14:39 编辑 具体说明下多核和单核调试区别和方法,有无操作系统(DSP/BIOS)的调试区别以及
    发表于 06-19 01:29

    dbg:M0051错误,无法再调试

    我一直在与BLE先锋工具包和PROC模块一起工作。我有一个低功耗的项目已经工作了一时间。在调试开始时,我成功调试了几次调试模式。然后,我的调试
    发表于 09-17 09:19

    CoreDump应用调试时出现错误的情况该怎么办呢

    应用调试时出现错误的情况。程序运行过程中异常终止或崩溃,操作系统会将程序当时的内存状态记录下来,保存在一个文件中,这种行为就叫做CoreDump。可以认为CoreDump是内存快照,但实际上,除了
    发表于 12-29 06:09

    LCD屏幕的调试方法以及遇到的问题是什么?

    LCD屏幕的调试方法以及遇到的问题是什么?
    发表于 01-19 07:02

    HardFault错误调试的定位方法是什么

    HardFault 错误调试定位方法1、首先更改 startup.s 的启动文件,把里面的 HardFault_Handler 代码换成下面的代码:HardFault_Handler
    发表于 02-15 07:22

    符号模拟电路中的错误诊断设计方法

    符号模拟电路中的错误诊断设计方法  错误诊断是集成电路验证后期一个非常重要的阶段,它帮助设计者在一个错误芯片中预测错误点,因此可以减轻整个
    发表于 04-12 16:21 1330次阅读
    符号模拟电路中的<b class='flag-5'>错误</b>诊断设计<b class='flag-5'>方法</b>

    【LabVIEW从入门到精通】VI调试(找出语法错误

    【LabVIEW从入门到精通】2.4.1 VI调试(找出语法错误)
    发表于 01-04 09:41 0次下载

    mplab icd3错误消息及解决方法

    MPLAB ICD 3在线调试器会产生许多不同的错误消息;其中一些错误消息比较特殊而其他的都可以用常规纠正措施解决。MPLAB ICD 3在线调试器会产生许多不同的
    发表于 10-22 11:52 2w次阅读

    chipscope使用教程以及FPGA在线调试方法

    本文档内容介绍了基于chipscope使用教程以及FPGA在线调试方法,供参考
    发表于 03-02 14:09 9次下载

    嵌入式C语言程序有什么常见错误?C语言程序调试技巧方法资料免费下载

    程序设计很少能够没有错误一次完成,在编程的过程中由于种种原因,总会出现这样或那样的错误,这些程序的错误也就是常说的“Bug”,而检测并修正这些错误就是“Debug”(
    发表于 09-12 11:37 3次下载

    keil中常见的各种错误警告以及相应的解决方法资料说明

    本文档的主要内容详细介绍的是简单整理的keil中常见的各种错误警告以及相应的解决方法
    发表于 03-08 08:00 14次下载
    keil中常见的各种<b class='flag-5'>错误</b>警告<b class='flag-5'>以及</b>相应的解决<b class='flag-5'>方法</b>资料说明

    Labview编程错误调试与处理工具的使用说明

    Labview编程错误调试与处理工具
    的头像 发表于 08-05 06:04 2071次阅读

    AN028 Cortex-M3内核HardFault错误调试定位方法

    AN028 Cortex-M3内核HardFault错误调试定位方法
    发表于 02-27 18:32 0次下载
    AN028 Cortex-M3内核HardFault<b class='flag-5'>错误</b><b class='flag-5'>调试</b>定位<b class='flag-5'>方法</b>