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

    文章

    3019

    浏览量

    74001
  • 调试
    +关注

    关注

    7

    文章

    578

    浏览量

    33923
  • 文件
    +关注

    关注

    1

    文章

    565

    浏览量

    24727
  • 编译
    +关注

    关注

    0

    文章

    657

    浏览量

    32851
  • gdb
    gdb
    +关注

    关注

    0

    文章

    60

    浏览量

    13295

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

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

收藏 人收藏

    评论

    相关推荐

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

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

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

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

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

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

    网管配置通道环和复用方法

      网管配置方法   通道保护调试步骤   复用保护调试步骤   复用保护配置注意事项
    发表于 09-10 16:19 0次下载

    mplab icd3错误消息及解决方法

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

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

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

    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 2347次阅读

    linux C用户态调试追踪函数调用堆栈以及定位错误

    一般察看函数运行时堆栈的方法是使用GDB(bt命令)之类的外部调试器,但是,有些时候为了分析程序的BUG,(主要针对长时间运行程序的分析),在程序出错时打印出函数的调用堆栈是非常有用的。
    发表于 05-16 17:36 869次阅读
    linux C用户态<b class='flag-5'>调试</b>追踪函数调用堆栈<b class='flag-5'>以及</b>定位<b class='flag-5'>段</b><b class='flag-5'>错误</b>

    错误调试神器 - Core Dump详解

    一、前言: 有的程序可以通过编译, 但在运行时会出现Segment fault(错误). 这通常都是指针错误引起的. 但这不像编译错误一样会提示到文件某一行, 而是没
    发表于 04-02 14:34 1163次阅读

    Linux环境下段错误的产生原因及调试方法小结

    dmesg可以在应用程序crash掉时,显示内核中保存的相关信息。如下所示,通过dmesg命令可以查看发生错误的程序名称、引起错误发生的内存地址、指令指针地址、堆栈指针地址、
    的头像 发表于 04-30 15:23 2536次阅读

    什么是错误

    来源:聚优致成 一、什么是错误?一旦一个程序发生了越界访问,cpu 就会产生相应的保护,于是 segmentation fault 就出现了,通过上面的解释,错误应该就是访问了不可
    的头像 发表于 09-11 14:04 1.7w次阅读

    单片机硬错误排查方法

    HardFault 错误调试定位方法1、首先更改 startup.s 的启动文件,把里面的 HardFault_Handler 代码换成下面的代码:HardFault_Handler
    发表于 12-16 16:54 0次下载
    单片机硬<b class='flag-5'>错误</b>排查<b class='flag-5'>方法</b>

    错误是什么意思?是何原因引起的?

    刚接触指针的时候,经常会遇到错误。所谓错误,就是访问了不能访问的内存。
    的头像 发表于 02-13 09:41 3309次阅读

    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>