当前位置: 首页 > news >正文

扩展addr2line程序的功能,group_add2line() 脚本的实现

------------------------------------------------------------
author: hjjdebug
date: 2024年 08月 05日 星期一 16:19:07 CST
descrition:  扩展addr2line程序的功能,group_add2line() 脚本的实现
------------------------------------------------------------
扩展addr2line程序的功能,group_add2line() 脚本的实现
addr2line 程序简单介绍一下:
addr2line 是binutils 工具包中的一个工具,用法如下.
addr2line -e <file> -f <addr>
要求输入带调试信息的文件名称, 偏移地址
将会输出该地址对应到文件的函数名称及行号

group_addr2line要求:
在debug 时,我可以得到一组调用栈地址, 但这组地址对应着很多so文件
而且,记录的地址是内存中的绝对地址,而不是相对于so起始点的偏移地址.
这不能直接满足addr2line 的要求
给个例子吧:
index      time       addr            size     type     stc stacklist
9019992    10:09:48   0x7f5b41ee49b0  2580552  malloc   6   0:0x7f5bb01ca550 1:0x7f5bacb3be14 2:0x7f5baccb9a58 3:0x7f5baccb987a 4:0x4bc6ec 5:0x7f5ba8aac185 

我们只关注stacklist部分,即第7列,它可能由10几层20几层调用
过程:
第1. 由执行文件,找到pid值. 你可以用ps -ef <执行文件> |grep 一类命令来找到
第2. 从调用栈中提取出地址列表信息,即0x开头的地址, 这需要单词匹配,单词分割.
第3. 转换为偏移地址
步骤2得到的地址是绝对内存地址,要找到偏移地址,需要找到这个地址对应着哪个模块,模块的基地址是多少,才能知道偏移地址
这可以通过 /proc/pid/maps 文件来找到.

这种大规模的劳动人工无法胜任,只能交给电脑去完成!!

这里就设计到几个编程的要点. 都在代码里了,总之,用多了就熟了.
1. 字符串匹配 ,字符串分割, awk 强项
2. bash 和 awk 如何交互信息, awk print, bash的命令替换, here文档, read readarray
3. 用数组保留数据,用循环处理数据, 编程之强项
4. bash中16进制数据与字符串变换 $(())

5. 再体会一下here文档<<< 与重定向到进程输出的差别< <(cmd). 
   在ubuntu下跑的好好的程序, 在centos上必需要把here 文档改成重定向到进程输出.
   否则,readarray 读到的就不是一个array 而是一个元素, 可见代码还要结合具体的环境.
   ubuntu20 的bash 是5.0, centos7的bash 是4.2, 写代码还应该尽量适应早期版本
 

以下设计我们的group_addr2line 脚本
shell 脚本请看附件完整的代码
半自动,半手工化的操作过程.
------------------------------------------------------------
1. 提取执行命令对应的pid 信息:
------------------------------------------------------------
命令行脚本
$ ps -ef |grep multiview_compare|grep -v "grep"|awk '{print $2}'
结果
16517

------------------------------------------------------------
2. 提取调用栈地址信息到数组
------------------------------------------------------------
命令行脚本
$ cat 1.txt |awk '{for(i=7;i<NF;i++){split($i,a,":");print a[2]}}'
得到结果:
0:0x7f5bb01ca550
1:0x7f5bacb3be14
2:0x7f5baccb9a58
3:0x7f5baccb987a
4:0x4bc6ec
5:0x7f5ba8aac185 

------------------------------------------------------------
3.  获取 /proc/pid/maps 中有用的信息
------------------------------------------------------------
$ cat /proc/16517/maps |awk '{if( NF>=6 && !a[$6]){split($1,a2,"-");a[$6]=a2[1];print a[$6],$6}}'
会列出所有模块的起始地址
举例:
00400000 /home/hjj/multiview_compare/multiview_compare
01f48000 [heap]
7f5b6649c000 /usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc
7f5b67893000 /SYSV00000000
7f5b6cdfe000 /usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf
....

------------------------------------------------------------
4. 对每一个地址,执行查询起始地址和模块名称的操作
------------------------------------------------------------
前期准备工作完成,根据输入地址,找到模块偏移地址和模块名称,用穷举法即可.
这是电脑的长处,写个函数吧,
 look_baseaddr_name()

------------------------------------------------------------
5. 对每一个地址,执行addr2line xxx 命令调用,输出结果.
------------------------------------------------------------
对于少量的地址, 用手工的方法也是可以得到结果的, 但大量的,完整的就有点麻烦了.

花了我不少时间编写调试,收获也不小,让电脑听自己的话,还是很惬意的,留存吧!
附件: bash 代码

#!/bin/bash
if [ $# -lt 1 ] || [ "$1" = "-h" ] 
#if [ $# -lt 1 ]
thenecho "Usage $0 <prog> <addr>"echo "Example $0 multiview_compare 1.txt"exit 1
fi#提取pid , read 从一行取
read pid < <(ps -ef|awk -v file=$1 '{if(match($8,file))print $2}')
declare -p pid
path="/proc/$pid/maps"
echo $path# 让程序支持管道操作
if [ $# -lt 2 ]
theninput="/dev/stdin"
elseinput=$2
fi#文件$1中 提取地址信息到数组 addrs[] , readarray 可以从多行中提取信息到数组
readarray -t addrs < <(awk '{for(i=7;i<NF;i++){split($i,a,":");print substr(a[2],3)}}' $input)
#declare -p addrs
#echo "addrs[0] is:" ${addrs[0]}
#echo "addrs[1] is:" ${addrs[1]}#提取maps 信息
readarray -t maps < <(awk '{if( NF>=6 && !a[$6]){split($1,a2,"-");a[$6]=a2[1];print a[$6],$6}}' $path)
#declare -p maps#将maps 信息提取为so_addr[] 和 so_name[], read 从单行取, 一次可以取多列
echo "number: ${#maps[@]}"
for(( i=0; i<${#maps[@]}; i++))
doread so_addr[$i] so_name[$i] <<< ${maps[$i]}
done
#declare -p so_addr
#declare -p so_name
#echo ${so_addr[0]}
#echo ${so_name[0]}
#echo ${so_addr[1]}
#echo ${so_name[1]}#根据地址查找模块名称及基地址,写了一个函数
look_baseaddr_name()
{local i addrlet addr=$((16#$1))for((i=0;i<${#so_addr[@]};i++))dolet next_val=$((16#${so_addr[$i+1]}))if [ $((16#${so_addr[$i]})) -lt $addr  -a $addr -lt $next_val ]thenbreak;fidoneif [ $i -ne ${#so_addr[@]} ]thenecho "${so_addr[$i]} ${so_name[$i]}" #输出结果fi}# 循环使用addr2line 输出信息
for((i=0;i<${#addrs[@]};i++))
doread base_addr fnd_name <<< $(look_baseaddr_name ${addrs[$i]})if [ $base_addr ]thenaddr=$((16#${addrs[$i]}))if [ $addr -gt 10000000 ]thenlet offset=$addr-$((16#$base_addr))elselet offset=$addr # 非so文件不用计算偏移ficmd="addr2line -e $fnd_name -f $(printf "%x" $offset)"echo "$i $cmd"$cmd | c++filtecho ""fi
done

执行结果演示:

$ group_addr2line.sh  multiview_compare 1.txt 
0 addr2line -e /home/hjj/gitSource/ld_preload/libpreload/libpreload_udpsend.so -f 1cc0
posix_memalign
/home/hjj/gitSource/ld_preload/libpreload/ld_preload_udpsend.c:294

1 addr2line -e /opt/ffmpeg_build/lib/libavutil.so.56.70.100 -f 3b660
av_malloc
/storage/source/FFmpeg-n4.4/libavutil/mem.c:86

2 addr2line -e /opt/ffmpeg_build/lib/libavutil.so.56.70.100 -f 19723
av_buffer_alloc
/storage/source/FFmpeg-n4.4/libavutil/buffer.c:72

...... 太长了,忽略18项.

20 addr2line -e /opt/ffmpeg_build/lib/libavcodec.so.58.134.100 -f 28ed94
avcodec_send_packet
/storage/source/FFmpeg-n4.4/libavcodec/decode.c:608

21 addr2line -e /home/hjj/multiview_compare/multiview_compare -f 4a891c
FFmpegThread::decode_packet(AVCodecContext*, AVPacket*)
/home/hjj/multiview_compare/myffmpeg/myffmpeg.cpp:1817

22 addr2line -e /home/hjj/multiview_compare/multiview_compare -f 49f9ac
FFmpegThread::run()
/home/hjj/multiview_compare/myffmpeg/myffmpeg.cpp:330

相关文章:

扩展addr2line程序的功能,group_add2line() 脚本的实现

------------------------------------------------------------ author: hjjdebug date: 2024年 08月 05日 星期一 16:19:07 CST descrition: 扩展addr2line程序的功能,group_add2line() 脚本的实现 ------------------------------------------------------------ 扩展addr2…...

idea中修改项目名称

公司最近有个小项目新加了很多功能&#xff0c;在叫原先的项目名有点不合适了。所以在网上查了下资料&#xff0c;发现步骤都比较复杂。自己研究了一下找到了一个相对简单的方法&#xff0c;只需要两步&#xff0c;特此记录一下。 1.修改项目文件夹名称 关闭当前项目&#xff…...

Flink开发语言使用Java还是Scala合适?

目录 1. Flink简介 1.1 什么是Apache Flink&#xff1f; 1.2 Flink的核心组件 2. Java与Scala在Flink开发中的比较 2.1 语言特性对比 2.2 开发体验对比 3. 实际开发中的应用 3.1 使用Java进行Flink开发 3.2 使用Scala进行Flink开发 4. 关键性能和优化 4.1 性能对比 …...

C++STL专题 vector底层实现

目录 一&#xff0c; vector的手搓 1.构造函数 2. 拷贝构造的实现 3.析构函数 4.begin() end() 的实现 5.reserve的实现 6.size和capacity的实现 7.push_back的实现 8.pop_back的实现 9.empty的实现 10.insert的实现 11.erase的实现 12.resize的实现 13.clear的实…...

【Linux】装机常用配置

文章目录 1. 下载常用软件包2. 更新yum源3. vim编辑器配置4. 安装C语言和C的静态库&#xff08;换root&#xff09;5. git6. sudo给普通用户提权7. 更新git版本&#xff08;centos默认安装1.8.x&#xff0c;我们更新到2.x&#xff09;8. getch9. json10. 升级gcc版本11. 跨系统…...

oracle库PASSWORD_VERSIONS 对应的加密方式

oracle库PASSWORD_VERSIONS 对应的加密方式 10G DES 11G SHA-1 12C SHA-2-based SHA-512官方文档&#xff1a; https://docs.oracle.com/database/121/DBSEG/authentication.htm#DBSEG487...

分享一个基于微信小程序的乡村医疗上门服务预约平台(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…...

切香肠(Sausage)

题目描述 有 n 条香肠&#xff0c;每条香肠的长度相等。我们打算将这些香肠切开后分给 k 名客人&#xff0c;且要求每名客人获得一样多的香肠&#xff0c;且要将所有的香肠分配完&#xff0c;不做保留。 请问最少需要切几刀才能完成&#xff1f;一刀只能切断一条香肠&#xf…...

Session与Cookie以及Cache区别,及应用场景

Session、Cookie和Cache是Web开发中常用的数据存储方式&#xff0c;它们在功能、存储位置和应用场景上有所不同。 一、Session、Cookie和Cache的区别 Session 存储位置&#xff1a;服务器端。功能&#xff1a;通过在服务器上存储唯一的标识符&#xff08;Session ID&#xff…...

Debian | 更换 Gnome 至 Xfce4

Debian | 更换 Gnome 至 Xfce4 更新源 sudo apt update && sudo apt upgrade安装 xfce4 sudo apt install xfce4我选择 lightdm&#xff0c;回车 切换桌面 sudo update-alternatives --config x-session-manager输入 xfce 所在序号&#xff0c;我这里是 3 卸载 …...

在使用JSON过程中遇到的一个空间释放问题

在对完成的模块进行空间访问检查中发现了这个问题&#xff0c;这刚开始接触JSON的使用&#xff0c;也不知道他的内部实现&#xff0c;因此该问题找了好久&#xff0c;终于发现是每个节点创建都会自动开辟空间&#xff0c;因此造成空间未成功释放的错误。 JSON未成功替换节点空间…...

基于ThinkPHP开发的校园跑腿社区小程序系统源码,包含前后端代码

基于ThinkPHP开发的校园跑腿社区小程序系统源码&#xff0c;包含前后端代码 最新独立版校园跑腿校园社区小程序系统源码 | 附教程 测试环境&#xff1a;NginxPHP7.2MySQL5.6 多校版本&#xff0c;多模块&#xff0c;适合跑腿&#xff0c;外卖&#xff0c;表白&#xff0c;二…...

不同专业方向如何在ChatGPT的帮助下完成选题

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 选择一个合适的论文题目是每个论文写作同学必须面对的重要任务。无论是历史专业、计算机科学专业&#xff0c;还是其他各个领域&#xff0c;找到一个既有研究价值又符合个人兴趣的选题往…...

MathType7.4中文版本功能详解!你的数学公式编辑神器

嘿&#xff0c;亲爱的小伙伴们&#xff0c;今天我要跟大家分享一个超实用的工具——MathType7中文版。作为一个自媒体人&#xff0c;我常常需要编辑各种复杂的数学公式&#xff0c;而这款软件简直就是我的救星&#xff01;接下来&#xff0c;就让我带你们领略一下它的神奇之处吧…...

在 PhpStorm 中为 .java 文件启用语法高亮,需要正确配置文件类型和关联语言。

点击访问我的技术博客https://ai.weoknow.comhttps://ai.weoknow.com 因为我同时使用java和php混编所以在一个项目中如果同时打开IntelliJ IDEA和PhpStorm不符合我完美主义的本性。 捣鼓了一下搞定了 1. 添加文件类型关联 将 .java 文件与 Java 语言支持关联&#xff1a; …...

2024年8月1日(前端服务器的配置以及tomcat环境的配置)

[rootstatic ~]# cd eleme_web/ [rootstatic eleme_web]# cd src/ [rootstatic src]# ls views/ AboutView.vue HomeView.vue [rootstatic src]# vim views/HomeView.vue [rootstatic src]# nohup npm run serve nohup: 忽略输入并把输出追加到"nohup.out" 构建项目…...

基于tcp,html,数据库的在线信息查询系统项目总结

1.项目背景 在线信息查询系统是一种可用于检索和展示各种信息的计算机程序或平台。主要特点包括&#xff1a; 用户接口&#xff1a;通常提供友好的界面&#xff0c;用户可以方便地输入查询条件。 数据存储&#xff1a;系统往往连接到数据库&#xff0c;存储大量信息&#xf…...

P1032 [NOIP2002 提高组] 字串变换

[NOIP2002 提高组] 字串变换 题目背景 本题不保证存在靠谱的多项式复杂度的做法。测试数据非常的水&#xff0c;各种做法都可以通过&#xff0c;不代表算法正确。因此本题题目和数据仅供参考。 本题为搜索题&#xff0c;本题不接受 hack 数据。关于此类题目的详细内容 题目…...

Android 12系统源码_多屏幕(一)多屏幕设备显示Activity

前言 分屏&#xff1a;是指一个屏幕分出多个窗口&#xff0c;分别显示不同应用的界面&#xff0c;这在当前的手机设备中很常见。多屏&#xff1a;是指一个设备存在多个屏幕&#xff0c;这些可能是虚拟屏幕或者实体硬件屏幕&#xff0c;不同的应用同时显示在不同的屏幕中&#…...

如何判断IP地址属于住宅IP还是机房IP

在数字化时代,IP地址作为互联网通信的基础标识&#xff0c;扮演着重要的角色。无论是网络管理、数据分析还是安全监控&#xff0c;正确识别IP地址的类型——尤其是区分是住宅IP还是机房IP&#xff0c;对于确保网络安全、优化网络性能以及合法合规运营具有重要意义。IPIDEA代理I…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务

通过akshare库&#xff0c;获取股票数据&#xff0c;并生成TabPFN这个模型 可以识别、处理的格式&#xff0c;写一个完整的预处理示例&#xff0c;并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务&#xff0c;进行预测并输…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

Go 语言并发编程基础:无缓冲与有缓冲通道

在上一章节中&#xff0c;我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道&#xff0c;它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好&#xff0…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...