扩展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中修改项目名称
公司最近有个小项目新加了很多功能,在叫原先的项目名有点不合适了。所以在网上查了下资料,发现步骤都比较复杂。自己研究了一下找到了一个相对简单的方法,只需要两步,特此记录一下。 1.修改项目文件夹名称 关闭当前项目ÿ…...
Flink开发语言使用Java还是Scala合适?
目录 1. Flink简介 1.1 什么是Apache Flink? 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底层实现
目录 一, 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的静态库(换root)5. git6. sudo给普通用户提权7. 更新git版本(centos默认安装1.8.x,我们更新到2.x)8. getch9. json10. 升级gcc版本11. 跨系统…...
oracle库PASSWORD_VERSIONS 对应的加密方式
oracle库PASSWORD_VERSIONS 对应的加密方式 10G DES 11G SHA-1 12C SHA-2-based SHA-512官方文档: https://docs.oracle.com/database/121/DBSEG/authentication.htm#DBSEG487...

分享一个基于微信小程序的乡村医疗上门服务预约平台(源码、调试、LW、开题、PPT)
💕💕作者:计算机源码社 💕💕个人简介:本人 八年开发经验,擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等,大家有这一块的问题可以一起交流&…...
切香肠(Sausage)
题目描述 有 n 条香肠,每条香肠的长度相等。我们打算将这些香肠切开后分给 k 名客人,且要求每名客人获得一样多的香肠,且要将所有的香肠分配完,不做保留。 请问最少需要切几刀才能完成?一刀只能切断一条香肠…...
Session与Cookie以及Cache区别,及应用场景
Session、Cookie和Cache是Web开发中常用的数据存储方式,它们在功能、存储位置和应用场景上有所不同。 一、Session、Cookie和Cache的区别 Session 存储位置:服务器端。功能:通过在服务器上存储唯一的标识符(Session IDÿ…...

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

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

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

不同专业方向如何在ChatGPT的帮助下完成选题
学境思源,一键生成论文初稿: AcademicIdeas - 学境思源AI论文写作 选择一个合适的论文题目是每个论文写作同学必须面对的重要任务。无论是历史专业、计算机科学专业,还是其他各个领域,找到一个既有研究价值又符合个人兴趣的选题往…...

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

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

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.项目背景 在线信息查询系统是一种可用于检索和展示各种信息的计算机程序或平台。主要特点包括: 用户接口:通常提供友好的界面,用户可以方便地输入查询条件。 数据存储:系统往往连接到数据库,存储大量信息…...
P1032 [NOIP2002 提高组] 字串变换
[NOIP2002 提高组] 字串变换 题目背景 本题不保证存在靠谱的多项式复杂度的做法。测试数据非常的水,各种做法都可以通过,不代表算法正确。因此本题题目和数据仅供参考。 本题为搜索题,本题不接受 hack 数据。关于此类题目的详细内容 题目…...

Android 12系统源码_多屏幕(一)多屏幕设备显示Activity
前言 分屏:是指一个屏幕分出多个窗口,分别显示不同应用的界面,这在当前的手机设备中很常见。多屏:是指一个设备存在多个屏幕,这些可能是虚拟屏幕或者实体硬件屏幕,不同的应用同时显示在不同的屏幕中&#…...

如何判断IP地址属于住宅IP还是机房IP
在数字化时代,IP地址作为互联网通信的基础标识,扮演着重要的角色。无论是网络管理、数据分析还是安全监控,正确识别IP地址的类型——尤其是区分是住宅IP还是机房IP,对于确保网络安全、优化网络性能以及合法合规运营具有重要意义。IPIDEA代理I…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...