首页 > 其他分享 >针对段错误排查

针对段错误排查

时间:2022-11-28 20:45:56浏览次数:56  
标签:10 00 针对 48 错误 core mov rbp 排查

一、 发生段错误情况分类

  1. 访问不存在的内存
  2. 访问系统保护的内存
  3. 指针操作越界(包括数组)

二、GDB调试出现Core dump 出现的汇编代码

GDB 显示汇编

GDB 如何通过 layout asm/src 显示汇编、源代码窗口

vscode配置gdb显示汇编

vscode 虽然集成了,但是不能显示汇编窗口那么方便, 需要在调试控制台使用 -exec 指令执行查看汇编, -exec disassemble /m

三、 三种场景,三种用法

  1. 在编写过程中,程序启动就出现 core dump, 直接使用 gdb 调试即可
  2. 代码写完之后运行一段时间之后, 或者是一些不确定条件导致的 core dump, 编译加 -g
  3. 同2, 生产环境 不加 -g, 特定条件触发 core dump

四、 测试代码如下

#include <stdio.h>
void test(int *ptr, int val) {
    //对空指针指向的内存区域写,会发生段错误
    ptr[10] = val;
}
int main()
{
    int *null_ptr = NULL;
    //*null_ptr = 10;
    int val = 10;
    test(null_ptr, val);
    return 0;
}

gdb 调试 core 文件

代码写完之后运行一段时间之后, 或者是一些不确定条件导致的 core dump

# 1. 首先, 在编译代码的时候需要加上 `-g` 参数;
# 2. ulimit -c #查看是否开启core文件, 0则不会生成core文件
# 3. ulimit -c [size] #生成限制core文件大小
ulimit -c unlimited #生成core文件不受大小限制, 临时设置, 永久设置在 /etc/security/limits.conf 填写以下两行
@root soft core unlimited
@root hard core unlimited

# 4. 指定core文件保存位置和文件命名方式
`echo "/corefile/core-%e-%p-%t" > /proc/sys/kernel/core_pattern`
# 5. 指定core文件生成是否添加pid作为扩展
`echo 1 > /proc/sys/kernel/core_uses_pid`
# 6. mkdir /corefile 目录
# 7. gcc -g xx.c && a.out
# 8. 会在/corefile 下看生成的 .core 文件
# 9. gdb -core /corefile/xxx.core
# 10 进入gdb之后, 执行 file a.out
# 11. where/bt
# 10. 分析, 可以查看到对应的栈, 参数传递信息等

image

objdump 排查 core dump

在 报错core dump的时候, 内核中会提示如下错误

[ 6629.248711] a.out[2891]: segfault at 28 ip 000000000040054c sp 00007fffd1e9ee20 error 6 in a.out[400000+1000]
[ 6629.248716] Code: 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 f3 0f 1e fa eb 8a 55 48 89 e5 48 89 7d f8 89 75 f4 48 8b 45 f8 48 8d 50 28 8b 45 f4 <89> 02 90 5d c3 55 48 89 e5 48 83 ec 10 48 c7 45 f8 00 00 00 00 c7

其中 打印出来的二进制code就是 编译过后的 二进制执行文件, 即a.out中的内容, objdump 就是将 a.out 二进制文件反汇编成汇编语言, 然后通过汇编语言定位问题
X86汇编代码说明链接:https://www.cnblogs.com/han-guang-xue/p/16525292.html

# 1. 生成汇编, objdump -d a.out > a.outDump
# 2. 查看发生的错误位置 grep -n -A 10 -B 10 "40054c" a.outDump
# 3. 根据以下代码能很明确的定位到代码出现的位置:40054c, 就是 *ptr[10] = 10; 报错
# 4. 问题1: 无法查看参数传递
# 5. 问题2: 如果优化编译的话,看汇编对比源码会比较困难
97-0000000000400536 <test>:
98-  400536:   55                       push   %rbp                  ; 将地址 0x400536 压栈并记录到寄存器 rbp 中
99-  400537:   48 89 e5                 mov    %rsp,%rbp              
100-  40053a:  48 89 7d f8              mov    %rdi,-0x8(%rbp)       ; 将 0x400536 - 0x08 地址指向 rdi寄存器中的值 *ptr = NULL;
101-  40053e:  89 75 f4                 mov    %esi,-0xc(%rbp)       ; 将 0x400536 - 0x0c 地址指向 esi寄存器中的值 val = 10;
102-  400541:  48 8b 45 f8              mov    -0x8(%rbp),%rax       ; 设置rax地址指向 rdi寄存器地址指向的值
103-  400545:  48 8d 50 28              lea    0x28(%rax),%rdx       ; 计算器偏移地址, 就是 0x28 = 40 = 10*4; 也就是 rdx = rax+40, 既ptr[10];
104-  400549:  8b 45 f4                 mov    -0xc(%rbp),%eax       ; 将esi寄存器地址指向的值,10,保存到寄存器eax中
105:  40054c:  89 02                    mov    %eax,(%rdx)           ; 设置 rdx 寄存器的地址指向值 eax, 既 ptr[10] = val;
106-  40054e:  90                       nop                          ; 无操作
107-  40054f:  5d                       pop    %rbp                  ; 将rbp 出栈
108-  400550:  c3                       retq                         ; 将方法test推出栈, 并跳回原来执行的地方
109-
110-0000000000400551 <main>:
111-  400551:  55                       push   %rbp                  ; 将地址 0x400551 压栈并记录到寄存器 rbp 中
112-  400552:  48 89 e5                 mov    %rsp,%rbp             ; 将 0x400551 记录到 rsp(用于堆栈指针) 中
113-  400555:  48 83 ec 10              sub    $0x10,%rsp            ; 暂时没搞明白
114-  400559:  48 c7 45 f8 00 00 00     movq   $0x0,-0x8(%rbp)       ; 设置 0x400551 - 0x08 值为 0x0, *null_ptr = NULL;
115-  400560:  00                                                    
116-  400561:  c7 45 f4 0a 00 00 00     movl   $0xa,-0xc(%rbp)       ; 设置 0x400551 - 0x0c 值为 0xa, val = 10;
117-  400568:  8b 55 f4                 mov    -0xc(%rbp),%edx       ; 设置 edx 指向地址 0x400551 - 0x0c, 该地址指向值 10
118-  40056b:  48 8b 45 f8              mov    -0x8(%rbp),%rax       ; 设置 rax 指向地址 0x400551 - 0x08, 该地址指向值 0
119-  40056f:  89 d6                    mov    %edx,%esi             ; 将edx地址保存到esi中
120-  400571:  48 89 c7                 mov    %rax,%rdi             ; 将rax地址保存到rdi中
121-  400574:  e8 bd ff ff ff           callq  400536 <test>         ; callq 跳到指定地址执行

https://blog.csdn.net/qq_29350001/article/details/53780697

标签:10,00,针对,48,错误,core,mov,rbp,排查
From: https://www.cnblogs.com/han-guang-xue/p/16932168.html

相关文章

  • 错误解决:附加SQL Server 2000数据库 5118错误
    错误解决:附加SQLServer2000数据库5118错误一、错误信息:附加数据库对于服务器“192.168.0.121”失败。 (Microsoft.SqlServer.Smo)有关帮助信息,请单击:http://go.m......
  • Ext 错误:0x80070057
    使用EXt2.0在做项目是遇到了这么个问题。在window里面修改完内容,提交的时候出现的。不知道是FF的错误还是EXt的错误。寻找解决方法中…… uncaughtexception:[Exceptio......
  • Xcode编译错误__NSCFConstantString
    __NSCFConstantString:主要错误就是数据类型造成的,然后就是检查哪个地方造成的数据类型调用错误错误一:'-[__NSCFConstantString_imageThatSuppressesAccessibilityHairlineT......
  • 针对图谱超级节点的一种优化解决方案
    分享一个最近研究的课题:现实中网络结构的度分布往往呈现幂律性,意即存在这么一类节点,其拥有的边数对整个网络的边数占比显著非0,我们称这类节点为超级节点。中证中小投资者......
  • 08.错误处理
    Rust将错误分为两大类:可恢复错误与不可恢复错误。其他大部分变成语言都没有可以区分这两种错误,而是通过异常之类的机制来统一处理它们。虽然Rust没有类似的异常处理机制,但......
  • 【JS】121-重温基础:流程控制和错误处理
    本文是 重温基础 系列文章的第二篇,需要让自己静下心来,学习,养成好习惯。本章节复习的是JS中的控制流语句,让我们能实现更多的交互功能。注意一点:在ES6之前,JS是没有块作用域......
  • 0119-Go-错误恢复
    环境Time2022-08-25Go1.19前言说明参考:https://gobyexample.com/recover目标使用Go语言的recover。示例packagemainimport"fmt"funcmayPanic(){......
  • 错误日志记录类
    项目中经常需要使用到对软件发生错误的日志记录,关于此,很多公司及组织已经做了很多工作,比如可以使用Microsoft提供的MicrosoftEnterpriseLibraryJanuary2006(最新版......
  • 解决fastjson内存对象相互应用导入json字符串出现错误问题
        日常在使用FastJson的时候可能很少会遇到这种问题。比如:我们在一个对象中存在一个集合属性对象这个集合属性对象元素属性也同样存在集合属性那么在使用toJSONSt......