在Linux程序中输出函数调用栈

2023-11-09

在Linux程序中输出函数调用栈

  • 12/23. 2013

程序发生异常时,将函数的调用栈打印出来,可以大大提高定位效率。

Linux中提供了三个函数用来获取调用栈:

1
2
3
4
5
6
7
8
/* 获取函数调用栈 */
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 ) ;

示例代码:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
 
/* 打印调用栈的最大深度 */
#define DUMP_STACK_DEPTH_MAX 16
 
/* 打印调用栈函数 */
void dump_trace ( ) {
void * stack_trace [ DUMP_STACK_DEPTH_MAX ] = { 0 } ;
char * * stack_strings = NULL ;
int stack_depth = 0 ;
int i = 0 ;
 
/* 获取栈中各层调用函数地址 */
stack_depth = backtrace ( stack_trace , DUMP_STACK_DEPTH_MAX ) ;
 
/* 查找符号表将函数调用地址转换为函数名称 */
stack_strings = ( char * * ) backtrace_symbols ( stack_trace , stack_depth ) ;
if ( NULL == stack_strings ) {
printf ( " Memory is not enough while dump Stack Trace! \r\n" ) ;
return ;
}
 
/* 打印调用栈 */
printf ( " Stack Trace: \r\n" ) ;
for ( i = 0 ; i < stack_depth ; ++ i ) {
printf ( " [%d] %s \r\n" , i , stack_strings [ i ] ) ;
}
 
/* 获取函数名称时申请的内存需要自行释放 */
free ( stack_strings ) ;
stack_strings = NULL ;
 
return ;
}
 
/* 测试函数 2 */
void test_meloner ( ) {
dump_trace ( ) ;
return ;
}
 
/* 测试函数 1 */
void test_hutaow ( ) {
test_meloner ( ) ;
return ;
}
 
/* 主函数 */
int main ( int argc , char * argv [ ] ) {
test_hutaow ( ) ;
return 0 ;
}

编译时需要加上-rdynamic参数,以得到符号名称,像下面这样:

1
gcc - rdynamic backtrace . c - o backtrace

执行./backtrace运行程序,输出如下:

dump_stack_with_backtrace

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Linux程序中输出函数调用栈 的相关文章

  • 用于 RHEL 的 gdb-multiarch

    我正在尝试寻找方法来运行gdb 多架构RHEL 中的命令 我已经安装了用于 ARM 处理的 QEMU 模拟器 我想安装GDB进行调试 我能够安装GDB 多体系结构在 Ubuntu 中运行命令成功 sudo apt get GDB multi
  • pthread_cond_broadcast 被 dlsym 破坏了?

    我正在尝试使用 LD PRELOAD 机制插入对 pthread cond broadcast 的调用 我插入的 pthread cond broadcast 函数只是调用原始的 pthread cond broadcast 然而 对于一个
  • 挂钩 Win32 窗口创建/调整大小/查询大小

    我正在尝试 扩展 现有的应用程序 The goal就是在不更改应用程序代码的情况下使现有应用程序变得更大 一个约束拉伸的应用程序不会 注意到 它 因此 如果应用程序查询创建的窗口大小 它将看到原始大小 而不是调整后的大小 我设法使用调整窗口
  • 在 MacOS 上从源代码构建 gdb

    我正在尝试在 Apple M1 MacBook 上安装交叉编译的 gdb 我下载了 gdb 11 1 并执行了以下操作 tmp src gdb 11 1 configure enable targets all make sudo make
  • 如何在 gdb 中打印长字符串的完整值?

    我想在 GDB 中打印 C 字符串的完整长度 默认情况下它是缩写的 如何强制 GDB 打印整个字符串 set print elements 0 来自GDB手册 https sourceware org gdb onlinedocs gdb
  • 如何在 gdb 上进行 grep 打印

    有没有办法在 gdb 中 grep 打印命令的输出 就我而言 我正在使用 gdb 调试核心转储 并且我正在调试的对象包含大量元素 我发现很难寻找匹配的属性 即 gdb print this grep
  • 如何在GDB中运行记录指令历史记录和函数调用历史记录?

    编辑 根据下面的第一个答案 当前的 技巧 似乎正在使用 Atom 处理器 但我希望一些 gdb 专家可以回答这是否是一个基本限制 或者路线图上是否添加了对其他处理器的支持 反向执行似乎在我的环境中起作用 我可以反向继续 查看合理的记录日志
  • 在 gdb 中设置应用程序关联

    有没有一种简单的方法可以设置我正在调试的应用程序的亲和力 而无需将 gdb 锁定到同一核心 我问的原因是应用程序以实时优先级运行 并且需要在单核上运行 目前我使用这个命令行 taskset c 3 gdbserver 1234 app ou
  • 有什么方法可以判断我的 iPhone 应用程序在运行时是否在调试器下运行?

    如果我的错误处理代码在调试器下运行 我希望它的行为有所不同 具体来说 如果我在手机上运行 未连接到调试器并且断言失败 我想将错误发送到我的服务器 当我在gdb下时 我想闯入调试器 虽然我可以想象苹果将如何编写代码 但我找不到任何关于测试调试
  • 测试是否定义了 gdb 便利变量

    有没有办法测试 gdb 中是否设置了便利变量 例如 gdb if exitcode 0 gt quit gt end Invalid type combination in equality test gdb p exitcode 1 vo
  • 全局键盘挂钩的合法用途是什么?

    除了仅应由操作系统提供的应用程序启动快捷方式之外 Windows 键盘挂钩等东西的合法用途是什么 在我看来 我们只在键盘记录器之类的事情上遇到问题 因为操作系统提供了钩子来执行除操作系统内核本身之外的任何情况下任何人都不允许执行的操作 编辑
  • 缺少单独的调试信息,请使用: debuginfo-install glibc-2.12-1.47.el6_2.9.i686 libgcc-4.4.6-3.el6.i686 libstdc++-4.4.6-3.el6.i686

    CentOS 6 2 GNU gdb GDB 红帽企业 Linux 7 2 50 el6 当我使用 GDB 调试简单的 C 代码时 我看到以下警告 Missing separate debuginfos use debuginfo inst
  • 错误:“std::this_thread”尚未声明

    我尝试使用 std this thread sleep for 函数但收到错误 error std this thread has not been declared 包括标志 GLIBCXX USE NANOSLEEP 还需要什么来强制它
  • 为什么 GDB 启动一个新的 shell 以及如何禁用此行为?

    我正在解决一个问题 即从 GDB 启动应用程序会导致符号查找错误 但从 shell 启动它却可以 事实证明 每当你从 GDB 中启动一个程序时 它都会启动一个新的 shell 从而覆盖我在启动 GDB 之前设置的所有环境变量 例如LD LI
  • C# - 挂钩现有 COM 对象

    假设我们有一个现有进程 或应用程序 它从 ocx 文件 例如 MyCOMLibrary ocx 调用 COM 对象 有没有办法编写一个 C 库来精确复制 ocx 文件 这样原始应用程序就可以调用您的 C 代码而不是原始 COM 对象 当然
  • 低级键盘钩子不在 UI 线程上

    我想为键盘挂钩创建一个好的库 我使用 SetWindowsHookEx 方法 我注意到如果我的应用程序的主线程繁忙 则应在任何系统 KeyDown 事件中调用的方法 hookProc 不会执行 我认为钩子应该这样制作 以便另一个线程负责它
  • getaddrinfo在程序中调用assert

    我正在使用 libcurl 开发一个程序 该程序创建一个线程 该线程又使用 libcurl 发出 HTTP 请求 但有时程序会因错误而崩溃 netlink 描述符上出现意外错误 9 在curl中关闭AsynchDNS之后 但问题依然存在 据
  • 在 C 程序中追踪数组越界访问/写入的推荐方法

    考虑用 C 语言编写一些不太明显的算法的实现 例如 让它成为递归快速排序 我在 K N King 的 C 编程 现代方法 第二版 书中找到了它 可以从here http knking com books c2 programs qsort
  • 如何将整个 GDB 会话转储到文件中,包括我输入的命令及其输出?

    在 bash 中 我可以使用script命令 它将 shell 上显示的所有内容转储到文件中 包括 键入的命令 PS1 line 命令的 stdout 和 stderr gdb 中的等效项是什么 我试着跑shell script从 GDB
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动

随机推荐

  • Python爬虫—手机销量

    介绍 最近在学习Python的一些相关知识 爬虫是其中有趣的一项 现在把学习的过程整理出来 给自己留个印记 Selenium爬取天猫手机数据 淘宝的反爬虫有点厉害 光是登陆就研究了小一天 先是尝试模拟输入用户名和密码 但是会出现让拖动滑块
  • Python 模块的概念和基本使用

    视频版教程 Python3零基础7天入门实战视频教程 模块和包 在Python的标准安装中 包含了一组自带的模块 这些模块被成为 标准库 比如常用的math random datetime os json等等 此外 还有很多的第三方模块 比
  • MIPI_DSI协议简要介绍

    MIPI DSI是一种应用于显示技术的串行接口 兼容DPI 显示像素接口 Display Pixel Interface DBI 显示总线接口 Display Bus Interface 和DCS 显示命令集 Display Command
  • tomcat配置400404500类型的错误页面,修改项目默认路径,修改默认项目

    修改项目默认路径 修改默认项目 http xxx xxxxxx xxx 直接访问 找到tomcat路径中conf文件夹下server xml文件找到 修改成 说明 xxx xxx xxx xxx webapps修改的项目默认路径 xxx x
  • 云服务器子系统,Linux子系统使用云服务器

    Linux子系统使用云服务器 内容精选 换一换 用户使用创建弹性云服务器时使用的密钥文件登录Linux弹性云服务器时 登录失败 根据Linux弹性云服务器使用的镜像不同 可能会存在如下原因 原因一 Linux弹性云服务器的镜像为用户自己制作
  • MATLAB生成M序列和Gold序列

    M序列 最长线性移位寄存器序列又称为m序列 他是一种伪随机序列 在硬件电路中 m序列可以通过反馈移位寄存器产生 寄存器的反馈连接有生成m序列的本源多项式确定 m序列的 0 0 0映射成 1 1
  • CentOS 7.9 安装Docker

    Docker简单介绍 Docker的应用场景 Web 应用的自动化打包和发布 自动化测试和持续集成 发布 在服务型环境中部署和调整数据库或其他的后台应用 Docker 的优点 Docker 是一个用于开发 交付和运行应用程序的开放平台 Do
  • 《oracle大型数据库系统在AIX/unix上的实战详解》讨论十二:关于读书

    感谢大家对这本书的热情和踊跃来信 这段日子有几位朋友都提出了类似于下面问题的问题 我在找这方面的工作 想学习您这本书进这一行 您看看怎么看合适 太厚了 我想开始阅读 oracle大型数据库系统在AIX unix上的实战详解 这本书 请问您有
  • Merge into的使用详解-你Merge了没有

    Merge是一个非常有用的功能 类似于Mysql里的insert into on duplicate key Oracle在9i引入了merge命令 通过这个merge你能够在一个SQL语句中对一个表同时执行inserts和updates操
  • Mysql忘记root密码的解决方法(亲测有效)

    首先搜索找到mysql exe的目录 一般是在你安装mysql的bin目录下 右键打开cmd 以管理员权限进入命令行窗口 打开任务管理器 结束掉mysqld exe进程 确保sql没有在运行中 在cmd下 cd切换目录到mysql exe所
  • c++ fbxsdk安装配置_Linux上安装软件 - coydone

    安装JDK 1 下载JDK http www oracle com technetwork java javase downloads jdk8 downloads 2133151 html 2 使用XFTP工具导入linux 3 解压到
  • C++中如何调用C里面的函数

    经验证 下机制可行 Here is a setup that allows C to call C Maybe this method is appropriate for your need 1 use the not using pre
  • OpenLDAP配置TLS加密传输

    原文发表于cu 2016 07 04 参考文档 基于OpenSSL自建CA与颁发SSL证书 http seanlook com 2015 01 18 openssl self sign ca OpenLDAP with TLS http m
  • 计算机网络——TCP四次挥手过程详解

    上次写了TCP的三次握手 这次总结一下TCP的四次挥手的过程 理清楚为什么握手是三次 挥手需要四次 TCP是面向连接的 连接的建立过程被称为 三次握手 天下没有不散的宴席 有了连接的建立 就会有连接的断开 TCP断开的过程通常被称为 四次挥
  • 【安装arch+win11双系统老按不上

    最近安装arch win11双系统老按不上换了debain也不行 网上了查了下 换Ubuntu总算装上了 Linux和windows双系统 安装Win11要求计算机支持TPM2 0 还有安全启动 https www microsoft co
  • mybatis-plus实现自动填充数据如:数据库中createTime和updateTime

    关于数据库中每个表中 或者会有需要记录表中数据修改的时间 这个时候应该怎么做呢 当然我们的常规做法就是 首先在数据库中添加两个字段 然后在实体类中添加两个属性 private Date createTime private Date upd
  • 人工智能是怎么用在人脸识别上的?

    相信大家都有这样的生活经历 小区的门禁不知道从什么时候开始可以 刷脸 进入了 支付宝账号登录不知道从什么时候开始只需要扫脸了等等 这一切都是人脸识别技术在改变我们的生活 那么人脸识别技术究竟是什么 它是如何工作的呢 人工智能是怎么用在人脸识
  • 学习傅里叶变换的心得

    为什么要进行傅立叶变换 傅立叶变换究竟有何意义 如何用Matlab实现快速傅立叶变换 写在最前面 本文是我阅读了多篇相关文章后对它们进行分析重组整合而得 绝大部分内容非我所原创 在此向多位原创作者致敬 一 傅立叶变换的由来 关于傅立叶变换
  • UV 自动化展开

    采用ABF Angle Based Flattening 方法进行UV的展开 具体原版内容见 ABF plus plus Fast and Robust Angle Based Flattening UV展开可看为3d到2d的映射 而ABF
  • 在Linux程序中输出函数调用栈

    在Linux程序中输出函数调用栈 12 23 2013 程序发生异常时 将函数的调用栈打印出来 可以大大提高定位效率 Linux中提供了三个函数用来获取调用栈 1 2 3 4 5 6