当前位置: 首页 > 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…...

C#TreeView控件应用

1、代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace TestApp…...

计算机网络-数据链路层

基本概念 数据链路和链路 链路&#xff1a;指的是从一个节点到相邻节点的一段物理线路&#xff0c;且中间没有任何其他的交换节点 数据链路&#xff1a;传输数据时&#xff0c;除了一条物理线路&#xff0c;还需要一些必要通信协议来控制这些传输。 数据链路层的三个基本问…...

农场游戏中的时间管理实例

一、准备工作 在Unity中创建承载日期和时间的文本 二、设置游戏的时间戳 using System.Collections; using System.Collections.Generic; using UnityEngine; //标识这个类可以被序列化 [System.Serializable] public class GameTimestamp {// 游戏时间戳的成员变量public in…...

css 数字平铺布局

效果图 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>活动中心</title><meta name"viewport" content"maximum-scale1.0,minimum-scale1.0,user-scalable0,widthdevice-width,initial-scale1.0…...

【开源】嵌入式Linux(IMX6U)应用层综合项目(2)--智能家居APP

目录 1.简介 1.1功能介绍 1.2技术栈介绍 1.3演示视频 1.4硬件介绍 2.软件设计 2.1智能家居UI设计 2.2.main函数 3.结尾&#xff08;附网盘链接&#xff09; 1.简介 此文章并不是教程&#xff0c;只能当作笔者的学习分享&#xff0c;只会做一些简单的介绍&#xff0c;其…...

CUDA常见编译器配置问题一览

CUDA常见编译器配置问题一览 关注TechLead&#xff0c;复旦博士&#xff0c;分享云服务领域全维度开发技术。拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;复旦机器人智能实验室成员&#xff0c;国家级大学生赛事评审专家&#xff0c;发表多篇SCI核心期刊…...

【Android】系统级应用升级后的安装位置

系统级应用的安装位置一般在codePath/system 下面&#xff0c; 如果手动的去进行adb install覆盖安装&#xff0c;通过dumpsys package可以发现是安装在/data/app/里&#xff0c; 如果是通过标准的系统升级方式呢&#xff1f; 这里我们来通过升级查看一下&#xff0c; 升级…...

uniapp 使用renderjs通信

一、 server层向renderjs传值&#xff0c;并初始化renderjs prop&#xff1a;可以随便定义 renderTaskDetail&#xff1a;是传往renderjs的数据 change:prop&#xff1a;prop和必须上面prop字段一样 renderScript.initAmap&#xff1a;【 renderScript】需要renderjs 中scr…...

PostgreSQL 15

一、安装前的准备 1、版本信息 操作系统CentOS 7.9.2009PostgreSQL 版本PostgreSQL 15-15.7 2、下载安装包 RPM Chart - PostgreSQL YUM Repositoryhttps://yum.postgresql.org/rpmchart/进入官网&#xff0c;找到相应版本 点击框选内容 依次进入下载页面&#xff0c;下载相…...

给本地设备搭建一个云端语音助手

概述 本语音助手实现了从关键词唤醒 (KWS) 到语音识别 (ASR) 再到自然语言理解 (NLU) 的完整流程。该系统可以通过监听用户的音频输入,检测指定的关键词,并将用户的语音转换为文本,最后与预设的命令进行匹配,执行相应的操作(具体实现请参考main.py),为你的设备配置远程…...