使用 backtrace 调测 SIGSEGV 信号 ---- 打印寄存器值

server/2024/10/21 20:41:59/

#define _GNU_SOURCE

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <execinfo.h>
#include <ucontext.h>

/*
 * backtrace和bacetrace_symbols打印出回溯信息
 */
 
#if 0
#include <execinfo.h>

int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

#endif


static void signal_handler(int sig, siginfo_t *info, void *ctx)
{
    ucontext_t *context = (ucontext_t *)ctx;

    /* dump registers, x64 CPU specific */
    printf( "Signal = %d  Memory location = %p\n"
            "RIP = %016X  RSP = %016X  RBP = %016X\n"
            "RAX = %016X  RBX = %016X  RCX = %016X\n"
            "RDX = %016X  RSI = %016X  RDI = %016X\n"
            "R8  = %016X  R9  = %016X  R10 = %016X\n"
            "R11 = %016X  R12 = %016X  R13 = %016X\n"
            "R14 = %016X  R15 = %016X  RFLAGS = %016X\n\n",
            sig, info->si_addr,
            context->uc_mcontext.gregs[REG_RIP],
            context->uc_mcontext.gregs[REG_RSP],
            context->uc_mcontext.gregs[REG_RBP],
            context->uc_mcontext.gregs[REG_RAX],
            context->uc_mcontext.gregs[REG_RBX],
            context->uc_mcontext.gregs[REG_RCX],
            context->uc_mcontext.gregs[REG_RDX],
            context->uc_mcontext.gregs[REG_RSI],
            context->uc_mcontext.gregs[REG_RDI],
            context->uc_mcontext.gregs[REG_R8],
            context->uc_mcontext.gregs[REG_R9],
            context->uc_mcontext.gregs[REG_R10],
            context->uc_mcontext.gregs[REG_R11],
            context->uc_mcontext.gregs[REG_R12],
            context->uc_mcontext.gregs[REG_R13],
            context->uc_mcontext.gregs[REG_R14],
            context->uc_mcontext.gregs[REG_R15],
            context->uc_mcontext.gregs[REG_EFL]);

    /* get call stack and write to stdout */
    void *buf[256] = {0};
    int size = backtrace(buf, 256);
    backtrace_symbols_fd(buf, size, fileno(stdout));
    exit(-1);
}

void test_3(int *p)
{
    *p = 1;
}

void test_2(int *p)
{
    test_3(p);
}

void test_1(int *p)
{
    test_2(p);
}

int main(int argc, char *argv[])
{
    int *p = 0x12345678;

    struct sigaction action;
    sigemptyset(&action.sa_mask);
    action.sa_sigaction = signal_handler;
    action.sa_flags = SA_SIGINFO;

    sigaction(SIGSEGV, &action, NULL);

    test_1(p);
    return 0;
}

// gcc -rdynamic backtrace2.c -o backtrace2


#if 0

000000000000143f <test_3>:
    143f:    f3 0f 1e fa              endbr64
    1443:    55                       push   %rbp
    1444:    48 89 e5                 mov    %rsp,%rbp
    1447:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
    144b:    48 8b 45 f8              mov    -0x8(%rbp),%rax
    144f:    c7 00 01 00 00 00        movl   $0x1,(%rax)                 // SIGSEGV
    1455:    90                       nop
    1456:    5d                       pop    %rbp
    1457:    c3                       retq   

0000000000001458 <test_2>:
    1458:    f3 0f 1e fa              endbr64
    145c:    55                       push   %rbp
    145d:    48 89 e5                 mov    %rsp,%rbp
    1460:    48 83 ec 08              sub    $0x8,%rsp
    1464:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
    1468:    48 8b 45 f8              mov    -0x8(%rbp),%rax
    146c:    48 89 c7                 mov    %rax,%rdi
    146f:    e8 cb ff ff ff           callq  143f <test_3>
    1474:    90                       nop
    1475:    c9                       leaveq
    1476:    c3                       retq   

0000000000001477 <test_1>:
    1477:    f3 0f 1e fa              endbr64
    147b:    55                       push   %rbp
    147c:    48 89 e5                 mov    %rsp,%rbp
    147f:    48 83 ec 08              sub    $0x8,%rsp
    1483:    48 89 7d f8              mov    %rdi,-0x8(%rbp)
    1487:    48 8b 45 f8              mov    -0x8(%rbp),%rax
    148b:    48 89 c7                 mov    %rax,%rdi
    148e:    e8 c5 ff ff ff           callq  1458 <test_2>
    1493:    90                       nop
    1494:    c9                       leaveq
    1495:    c3                       retq   

Signal = 11  Memory location = 0x12345678
RIP = 000000000C0E744F  RSP = 00000000029CAB30  RBP = 00000000029CAB30
RAX = 0000000012345678  RBX = 000000000C0E7540  RCX = 00000000317BE166
RDX = 0000000000000000  RSI = 00000000029CAA20  RDI = 0000000012345678
R8  = 0000000000000000  R9  = 0000000000000000  R10 = 0000000000000008
R11 = 0000000000000246  R12 = 000000000C0E7140  R13 = 00000000029CAD20
R14 = 0000000000000000  R15 = 0000000000000000  RFLAGS = 0000000000010202

./backtrace2(+0x1407)[0x56150c0e7407]           // backtrace
/lib/x86_64-linux-gnu/libc.so.6(+0x43090)[0x7f38317be090]
./backtrace2(test_3+0x10)[0x56150c0e744f]       // SIGSEGV
./backtrace2(test_2+0x1c)[0x56150c0e7474]       // test_2 -> test3
./backtrace2(test_1+0x1c)[0x56150c0e7493]       // test_1 -> test2
./backtrace2(main+0x86)[0x56150c0e751c]         // main -> test_1
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0x7f383179f083]
./backtrace2(_start+0x2e)[0x56150c0e716e]

#endif


http://www.ppmy.cn/server/39273.html

相关文章

学习javascript,实现一个简易售卖机的功能

有同学提问&#xff0c;说想实现一个JS售卖机的功能&#xff0c;我觉得这个挺有意思的&#xff0c;正是初学者学习JS&#xff0c;锻炼软件开发思维的一个好题目&#xff0c;所以就实现了一下&#xff0c;希望可以有帮助。 目录 1 需求分析 2 开发实现 2.1 商家端录入 2.2…

全面了解俄罗斯的VK开户和Yandex投放及内容运营

俄罗斯的VKontakte&#xff08;简称VK&#xff09;和Yandex是两个重要的在线平台&#xff0c;对于希望在俄罗斯市场进行推广的企业来说&#xff0c;了解如何在这些平台上开户和投放广告以及内容运营是非常关键的。 俄罗斯vk广告如何开户&#xff1f; 通过上海上弦进行俄罗斯V…

智能量化交易系统开发自动炒币机器人系统开发原理解析

Q&#xff1a;什么是量化交易&#xff1f;数字资产量化交易第三方辅助软件。其具备以下三个特点:1、资产安全资产在用户自己的交易所账户&#xff0c;软件只能通过API帮用户下单。2、操作简单用户只需要选择自己喜欢的操作风格&#xff0c;即可启动量化&#xff0c;通过API接口…

如何更好地导入Scrum?

前面写了一系列极限编程的分享&#xff0c;目前这系列先告一段落&#xff0c;后面等我们禅道20系列版本重构完再和大家分享TDD方面的经验体会。极限编程聊完了&#xff0c;接下来和大家聊聊Scrum。Scrum市面上相关的书籍、视频和分享比极限编程要多很多&#xff0c;我不做赘述。…

这是一关于DSC相关的文档

这是一关于DSC相关的文档 上面这幅图清晰的展示了somewhat flat的像素图示

校友录系统的设计与开发

**中文摘要&#xff1a;**随着互联网技术的不断发展和普及&#xff0c;人们对于信息化、数字化的需求也越来越高。在此背景下&#xff0c;校友录系统的设计与开发显得尤为重要。本文旨在设计和开发一款方便实用的校友录系统&#xff0c;为学校提供一个联系和管理校友的平台&…

如何用爬虫解决问题

一、介绍 爬虫指的是一种自动访问互联网上网页的程序,通过自动化的方式获取网页上的数据并进行处理。它可以从互联网的各个网站上抓取信息,如新闻、商品信息、图片等,并将这些数据存储或用于其他用途,如数据分析、搜索引擎索引等。爬虫可以模拟人的行为,通过访问网页上的…

太速科技-FMC377_双AD9361 射频收发模块

FMC377_双AD9361 射频收发模块 FEATURES&#xff1a; ◆ Coverage from 70M ~ 6GHz RF ◆ Flexible rate 12 bit ADC/DAC ◆ Fully-coherent 4x4 MIMO capability, TDD/FDD ◆ RF ports: 50Ω Matched ◆ support both internal reference and exter…