CN115543294A - 一种Linux系统上动态链接库可视化依赖树的生成方法 - Google Patents
一种Linux系统上动态链接库可视化依赖树的生成方法 Download PDFInfo
- Publication number
- CN115543294A CN115543294A CN202211552765.7A CN202211552765A CN115543294A CN 115543294 A CN115543294 A CN 115543294A CN 202211552765 A CN202211552765 A CN 202211552765A CN 115543294 A CN115543294 A CN 115543294A
- Authority
- CN
- China
- Prior art keywords
- library
- dependency
- file
- program
- dependent
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Granted
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/30—Creation or generation of source code
- G06F8/34—Graphical or visual programming
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/42—Syntactic analysis
- G06F8/427—Parsing
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F8/00—Arrangements for software engineering
- G06F8/40—Transformation of program code
- G06F8/41—Compilation
- G06F8/43—Checking; Contextual analysis
- G06F8/433—Dependency analysis; Data or control flow analysis
-
- Y—GENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
- Y02—TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
- Y02D—CLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
- Y02D10/00—Energy efficient computing, e.g. low power processors, power management or thermal management
Landscapes
- Engineering & Computer Science (AREA)
- General Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Software Systems (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Stored Programmes (AREA)
Abstract
本发明涉及一种Linux系统上动态链接库可视化依赖树的生成方法,步骤为:S1、执行脚本程序generate_input函数,生成C程序的输入文件result.output;S2、将result.output输入二进制执行程序elf_parser进行分析,生成C程序的输出文件library.dot;S3、执行脚本程序handle_output函数,解析library.dot,最终画出依赖树结构图。本发明通过程序解析elf文件,将依赖层次关系保存到dot格式文件中,并结合脚本的方式,将引用次数加到数据节点中,从而实现了可视化树形结构的生成。
Description
技术领域
本专利申请属于依赖树生成技术领域,更具体地说,是涉及一种Linux系统上动态链接库可视化依赖树的生成方法。
背景技术
应用兼容性是国内外操作系统厂商重点攻克的难题之一,是影响应用生态的关键因素。红帽、欧拉等服务器操作系统通过包的依赖关系划分,给出了系统上一些核心组件的重要性定义。麒麟桌面操作系统在统型工作中,为了能全面准确的定义系统中依赖库与应用程序的影响关系,除了借鉴红帽等发行版的核心组件定义思想外,还从依赖库的被依赖层次、被引用计数、ABI兼容率等多个维度去分析操作系统重要核心组件。
本发明开发的工具就是统型依赖库工作中的一个重要参考维度,我们考虑应用程序的依赖关系通常包括编译依赖和运行时依赖,应用程序的兼容主要从 API 和 ABI 的维度去进行分析。本发明开发了一套操作系统依赖库树形结构生成工具,可视化的标示出所有动态库的依赖层级关系与引用频次。
考虑到需要解析的库文件数量很大,使用 mmap 将磁盘文件映射到虚拟内存,程序可以采用指针的方式读写操作内存,完成对于依赖库文件的解析操作,避免频繁的 I/O操作。
与本专利申请最接近的现有技术是:一种软件包依赖关系检测方法,专利号:CN114327473A。
该技术指出,在软件安装过程中,常常会面临软件依赖的问题。通常情况下,安装时检测某版本软件依赖,会单独去检索这个版本的软件依赖包,如果还有依赖,就继续往下检索。当检索到没有依赖后,倒着把软件包进行安装,即可顺利完成所有软件和依赖的安装。这种做法存在一个无法解决的问题,即当往下检索时,可能会出现后面的软件包依赖前面的软件包的情况,从而形成死锁。
软件包依赖分析的现有方法包括基于集合分析的方法、基于分层图分析的方法等,其中效果较好的分层图分析方法的大致思路为:针对指定操作系统构建分层图,针对用户给定的某个软件,在图中查找依赖关系,最后将依赖关系进行导出。
该专利虽然也是分析操作系统中的依赖关系,但是它分析的维度是软件包,在生成的有向图中标示出包的依赖关系,无法计算动态库的被引用次数。这个专利接收输入是一组软件包,根据生成的有向关系依次安装各个软件包,与本发明的想要解决的问题场景不符。
为了能全面准确的定义系统中依赖库与应用程序的影响关系,在统型工作中提供新的维度去分析操作系统重要核心组件。本发明开发了一套操作系统依赖库树形结构生成工具,可视化的标示出所有动态库的依赖层级关系与引用频次。
发明内容
本发明需要解决的技术问题是提供一种Linux系统上动态链接库可视化依赖树的生成方法,可以可视化地标示出所有动态库的依赖层级关系与引用频次,直观性更好。
为了解决上述问题,本发明所采用的技术方案是:
一种Linux系统上动态链接库可视化依赖树的生成方法,包括如下步骤:
S1、编写脚本程序,执行脚本程序中的generate_input函数,生成C程序的输入文件result.output,输入文件result.output存储有应用程序的依赖库合集;
S2、将输入文件result.output输入二进制执行程序elf_parser进行分析,生成C程序的输出文件library.dot;
S3、执行脚本程序中的 handle_output 函数,解析输出文件library.dot,从而给树状图加上各个依赖库的引用计数,生成可视化图像,最终得以画出依赖树结构图。
本发明技术方案的进一步改进在于:步骤S1中,脚本程序为shell脚本程序。
本发明技术方案的进一步改进在于:步骤S2中,二进制执行程序elf_parser执行如下分析:
S21、解析并检测输入文件result.output合法后,将输入文件result.output中所有依赖库的库名、初始绝对路径 libpath、当前层级level存入consumed队列;否则执行步骤S28;
S22、循环解析consumed队列:遍历consumed队列中的内容,判断consumed队列是否为空,若consumed队列不为空,执行步骤S23,否则执行步骤S27;
S23、当前依赖库的初始绝对路径libpath存在的情况下,加载该依赖库,并判断该依赖库是否为64位的elf文件,若是64位的elf文件,执行步骤S24,否则返回步骤S22;
S24、解析elf文件中的DT_NEEDED字段,DT_NEEDED字段用以表示依赖库上声明的依赖项,在初始绝对路径libpath的基础上,找到这个依赖库在系统中的最终绝对路径newpath,将该依赖库的当前层级level的数值加一,表示依赖库加深了一个层次,层次越深表明依赖库越重要;并将该依赖库的最终绝对路径newpath与新的当前层级level 一起存入consumed队列;同时记录该依赖库的被引用次数,将被引用次数加一,存入counthash哈希表;
libpath和newpath都是变量名,libpath和newpath都是指绝对路径,只不过是名称不一样,实际操作中,先判断libpath是否存在,若libpath存在,newpath是在libpath存在情况下找到的最终绝对路径结果。
S25、调取用于保存依赖库的层次信息的levelhash表,判断是否需要将初始绝对路径 libpath和新的当前层级level插入levelhash表中,若需要,执行步骤S26,否则执行步骤S27;这里需要补充说明:
levelhash表中保存的是层次信息,层次越深表明这个库越重要;counthash哈希保存的是对这个依赖库的引用计数,也就是被引用次数,两张表记录不同的信息。
S26、将初始绝对路径 libpath和新的当前层级level存入levelhash表,并保存.dot结构的文件(也就是将缓存中的数据写到输出文件library.dot予以保存),然后返回步骤S22;
S27、遍历counthash哈希表,将库名与被引用次数写到输出文件count.record;
S28、结束程序。
本发明技术方案的进一步改进在于:步骤S23中,当前依赖库的绝对路径libpath存在,加载该依赖库,是指:调用 mmap 映射到内存空间以弹出consumed队列;
判断该依赖库是否为64位的elf文件,是指:解析 elf文件头结构 e_ident[16]的数据,若e_ident[16]的第五个字节等于2,则该依赖库是64位的elf文件,反之则不是。
本发明技术方案的进一步改进在于:步骤S24中,二进制执行程序elf_parser还可以解析单个依赖库。
本发明技术方案的进一步改进在于:对于单个依赖库,通过-l参数添加一个elf文件(比如解析绝对路径)来解析单个依赖库。这里需要补充说明:-l参数只是为了解析单个库,跟S24的newpath类型其实是一样的,但不是一个内容。举例说明,如果这个程序加 -l参数,就表示只解析一个库;如果这个程序后面接的是文件名,解析的就是文件中保存的所有依赖库的信息,算是单个库与多个库的不同解析方式,当然如果文件中只保存一个库的路径信息,其实效果跟 -l 参数加库名是一样的。
本发明技术方案的进一步改进在于:步骤S25中,判断是否需要将初始绝对路径libpath 和新的当前层级level插入levelhash表,是指:如果levelhash表中不存在依赖库的层级记录或者levelhash表中该依赖库保存的层级低于待插入的依赖库的层级level,则将初始绝对路径libpath 和新的当前层级level存入levelhash表中,否则忽略这个待插入的依赖库。
本发明技术方案的进一步改进在于:步骤S3中,执行脚本程序中的 handle_output 函数,通过去重、替换操作,将依赖库的引用计数加到 .dot 结构的文件中,最后利用 dot 工具生成树状图结构。
本发明技术方案的进一步改进在于:去重为awk去重,替换为sed替换。
由于采用了上述技术方案,本发明取得的有益效果是:
该发明在操作系统统型依赖库中得以应用,可以绘画出操作系统出所有应用程序依赖库的层级关系,结合该可视化树以及引用关系记录文件,引用次数记录文件,引用层级记录文件等,为操作系统依赖库的统型提供了有效的参考依据。
本专利特点如下:
(1)shell 脚本与 C 程序协同工作,创造性的将操作系统的依赖库关系生成 dot格式文件,从而生成可视化的结构树。
(2)通过 mmap 映射到内存文件,glob机制与可执行文件elf 库实现对系统中所有库的解析,以内存访问的形式解析 ELF 格式信息,获取依赖库清单,避免了大量的 I/O操作。
当前的工具如 readelf、libtree 等,只能通过文本方式显示出某一个应用或者动态库的所有依赖关系,这种方式无法直观地看出依赖层次关系,而且得到的信息很有局限性。本发明则不然,根据输入参数的不同,本发明可以解析某一个库的依赖树,也可以绘画出操作系统中所有应用程序的依赖树,更加直观清晰。
本发明提出的一种Linux系统上动态链接库的可视化依赖树生成方法,通过程序解析 ELF 文件,将依赖关系保存到 dot 格式文件中,并结合脚本的方式,将引用次数加到数据节点中,从而实现了可视化树形结构的生成。
附图说明
图1为本发明的方案框架图;
图2为本发明生成的依赖结构图;
图3为本发明的方案实施流程图;
图4为本发明生成的操作系统中所有依赖树结构的局部图。
具体实施方式
下面结合实施例对本发明做进一步详细说明。
首先介绍一下缩略语和关键术语定义。
统型依赖库:操作系统为了引导外部生态建立,最大程度帮助应用程序提高兼容性,提出的对操作系统上依赖库的层次划分思想。最核心的一级库在操作系统主版本间接口保持稳定,二级库在操作系统主版本内接口保持稳定。应用程序通过对自身依赖库的分析与统型组件分级对照,可以明确应用程序在操作系统上的兼容性。
ELF:目标文件常常按照特定格式来组织,在Linux下,它是ELF格式(ExecutableLinkable Format,可执行可链接格式),可执行二进制文件、目标代码文件、共享库文件和core dump文件都属于ELF文件。
静态库与动态库:Linux操作系统上的库有两种:静态库(.a)和动态库(.so)。所谓静态、动态是指链接。在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中。因此对应的链接方式称为静态链接。 动态库在程序编译时并不会被连接到目标代码中,而是在程序运行时被载入。不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例,规避了空间浪费问题。
虚拟内存:一种性能优越的内存管理技术。它为程序提供了看似巨大的内存空间,使得一个较大的程序能够运行在较小的内存空间中;同时又为每个进程提供了独立的虚拟地址空间,既简化了内存管理,也保护了每个进程的地址空间。
mmap:本质是一种进程虚拟内存的映射方法,可以将一个文件、一段物理内存或者其它对象映射到进程的虚拟内存地址空间。实现这样的映射关系后,进程就可以采用指针的方式来读写操作这一段内存,进而完成对文件的操作。
引用频次:通过本次发明程序,计算操作系统上动态库被其他库的直接与间接引用次数。
引用层次:通过本次发明程序,计算各个动态库在操作系统上被其他库依赖的最深层次。
ABI 兼容率:通过 abi-dumper 等开源工具分析某个库包在不同版本的接口、参数等信息,生成的兼容率百分比。
绝对路径:绝对路径就是文件的真正存在的路径,是指从硬盘的根目录开始,进行一级级目录指向文件。比如 “/usr/lib/x86_64-linux-gnu/libc.so.6”;或者/home/xunli/test/desktop-qt像这样的 从/ 开始,没有 . 或者 .. 这样的路径,就是绝对路径。本发明的申请文件里面强调绝对路径,是为了强调使用方法,让用户勿使用相对路径。
本发明中涉及到初始绝对路径、最终绝对路径以及解析绝对路径,分别是绝对路径的三种表现形式,其中初始绝对路径是基础,在初始绝对路径存在的基础上,找到最终绝对路径。解析绝对路径是区别于初始绝对路径、最终绝对路径的存在,属于现有技术。
下面详细说明。
本发明是一种Linux系统上动态链接库可视化依赖树的生成方法,包括如下步骤:
S1、编写脚本程序,执行脚本程序中的generate_input函数,生成C程序的输入文件result.output,输入文件result.output存储有应用程序的依赖库合集;
S2、将输入文件result.output输入二进制执行程序elf_parser进行分析,生成C程序的输出文件library.dot;
S3、执行脚本程序中的 handle_output 函数,解析输出文件library.dot,给树状图加上各个依赖库的引用计数,生成可视化图像,最终画出依赖树结构图。
结合图1的方案框架图,简单介绍本发明的运行流程:
(1)首先./check_list.sh input
这条命令执行了脚本程序中的 generate_input ,目的是为了生成 C 程序的输入文件。
(2)执行 ./elf_parser result.output
elf_parser 是个二进制执行程序,接受 result.output 这个文件名作为输入参数,该文件就是 (1) 生成的。
(3)最后执行 ./check_list.sh output
这条命令执行脚本程序中的 handle_output 函数,目的是为了处理 (2) 中生成的文件,最终画出依赖树结构图。
代码组成结构包括:
(1)一个 shell 脚本,名为 check_list.sh,该脚本主要有两个函数 generate_input 和 handle_output。
(2)一个 C 程序,名为 elf_parser.c,编译生成的二进制程序名为 elf_parser。
具体说,本发明分为shell脚本和C程序两个部分,流程如下:
(1)首先为C程序准备输入文件,采集系统中所有应用程序,结合 ldd 工具,生成所有这些应用程序的依赖库合集,保存到文件 result.output。
(2)编写 C 程序,接收两种参数
a、直接接受一个保存了依赖库路径名的文件名作为参数,比如上面说的result.output,遍历该文件中的内容,挨个解析。
b、-l参数添加一个elf 文件的解析绝对路径,表示解析单个依赖库,执行方式如下:$elf_parser -l /opt/sogouimebs/files/lib/libcurl.so.4。
或者我们只想解析 libxcb.so.1 的依赖树结构, 终端输入命令 ./elf_parser-l /usr/lib/x86_64-linux-gnu/libxcb.so.1 就可以只解析这一个库。
(3)最后用脚本解析 C 程序的输出文件,给树状图加上各个依赖库的引用计数,生成可视化图像。如图2是生成 ./elf_parser -l /usr/lib/x86_64-linux-gnu/libxcb.so.1 命令生成的 libxcb.so.1 的依赖结构图。
结合图3的流程图,开发依赖树生成工具的前提条件
1.编写脚本生成解析程序的输入文件,采集系统中所有应用程序,结合 ldd 工具,生成所有这些应用程序的依赖库合集,经过排序去重等处理,保存到文件result.output。
2.重要部件是解析依赖库并生成依赖关系层次的C程序,该程序的 -l 参数是单个库的测试验证场景,上面已经给过说明,不再赘述。下面重点描述接收文件名作为传入参数的场景:
2.1 elf_parser 程序检测输入文件result.output是否合法,合法后,遍历输入文件result.output中所有依赖库,如果确实为 elf 格式的文件,将输入文件result.output中所有依赖库保存到队列 consumed中,consumed中包括各依赖库的库名、初始绝对路径 libpath、当前层级level等,作为初始化第一层级的依赖库,接下来会执行步骤2.2中循环解析consumed 队列的过程,直到 consumed 队列清空,循环终止,结束循环,执行2.7;
2.2循环解析consumed队列:遍历consumed队列中的内容,如果 consumed 队列不为空,进入步骤2.3-步骤2.6中的循环。
2.3调用函数 parse_lib_link 解析这些输入文件result.output。
(1)函数 parse_lib_link 接受两个参数,第一个参数是依赖库在系统中的初始绝对路径 libpath,第二个参数是当前层级level。
(2)首先判断当前依赖库的初始绝对路径libpath是否存在,如果初始绝对路径libpath存在,加载该依赖库,调用 mmap 映射到内存空间以弹出consumed队列,解析 elf头结构 e_ident[16]的数据,以判断该依赖库是否为64位的elf文件,如果是有效的 64 位elf 文件,进入下一步解析,否则的话跳过这个依赖库回到循环开头,继续解析文件中后面的依赖库。
简单介绍一下 elf 头结构:
typedef struct {
unsigned char e_ident[EI_NIDENT];
uint16_t e_type;
uint16_t e_machine;
uint32_t e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
uint32_t e_flags;
uint16_t e_ehsize;
uint16_t e_phentsize;
uint16_t e_phnum;
uint16_t e_shentsize;
uint16_t e_shnum;
uint16_t e_shstrndx;
} Elf64_Ehdr;
结构体最开头是16个字节的e_ident, 其中包含用以表示ELF文件的字符,以及其他一些与机器无关的信息。本发明主要解析前五个字节,开头的4个字节值固定不变,为0x7f和ELF三个字符。第五个字节表示当前这个 elf 文件是 32位字节还是 64 位字节,本发明只处理 64 位字节的格式,如果检测到e_ident[16]的第五个字节不等于2, 也就是e_ident[4] 不等于 2,自动退出程序。若e_ident[4] 等于 2,则证明该依赖库是64位的elf文件,继续执行下面的步骤。
这个数据结构还包含了许多其他信息,能告诉人们节头表 (section headertable) 在文件中什么位置。通过节头表可知,e_shoff 表示 section header table 的偏移量,e_shstrndx 表示 section header string table index,节头字符串表索引,有这些信息就能读取节头表了。
2.4
本发明的重点是找到 elf 文件依赖的依赖库的名称,也就是节头表中 section名称为 .dynamic 和 .dynstr的节点, 如果 d_tag 为 DT_NEEDED ,表明就是我们需要找的动态依赖库。不过这时候获取的还只是简单的名称,比如 libxcb.so.1,为了能进一步检测这些依赖库所依赖的库,我们需要根据名称来找到它在系统中的最终绝对路径newpath,也就是 “/usr/lib/x86_64-linux-gnu/libxcb.so.1”这样的信息。本发明通过 glob 模式匹配机制,找到该依赖库在系统中的最终绝对路径 newpath,将当前层级level数值加一,表示依赖库加深了一个层次,后续需要进一步解析的。并将依赖库的最终绝对路径newpath 与新的当前层级 level 一起加入 consumed 队列,等待后续解析。
需要说明的是,libpath和newpath都是绝对路径的变量名,libpath和newpath都代表的是绝对路径,只不过是名称不一样, newpath是在libpath存在情况下找到的最终绝对路径的结果,所以需要先判断libpath是否存在。
libpath 比如:/usr/lib/x86_64-linux-gnu/ 。
newpath 比如:/lib/x86_64-linux-gnu/libgraphite2.so.3 。
这里需要结合上文的-l参数继续补充说明:-l参数是小写的数字l,不是字母I。这个-l参数只是为了解析单个库,跟上文的newpath类型其实是一样的,但不是一个内容。如果这个程序加 -l ,就表示只解析一个库;如果这个程序后面接的是文件名,解析的就是文件中保存的所有依赖库的信息,这样算是单个库与多个库的不同解析方式,当然如果文件中只保存一个库的路径信息,其实效果跟 -l 参数加库名是一样的。
通过-l参数添加一个elf 文件的解析绝对路径来解析单个依赖库,此处的解析绝对路径既不是libpath 也不是 newpath,而是本发明可以接受的一个参数,这个参数是指向一个可执行程序或者动态库的用于解析的绝对路径,可以称之为解析绝对路径。
还需要记录正在解析的这个库的被引用次数,解析到这个库,就说明有其他库依赖到它,所以将该库的被引用次数(也可以叫引用计数)加一,存入counthash哈希表。
2.5
同时调取用于保存依赖库的层次信息的levelhash表,判断是否需要将初始绝对路径libpath 和新的当前层级level的信息插入levelhash表,如果 levelhash表中不存在库或者 levelhash 表中保存的层级低于待插入的层级level,将初始绝对路径 libpath和新的当前层级level存入levelhash表,这是为了避免引用层级最深的记录被冲掉。
对于每个依赖库,只保留层级最深的记录。在程序初始运行时,所有依赖库的初始层级都为1,所以如果不存在初始层级的记录就直接插入;如果发现这个记录已经存在了,就需要对比两个依赖库的 level 大小,如果levelhash表中该依赖库的层级低于待插入的依赖库的层级level,则将初始绝对路径libpath 和新的当前层级level存入levelhash表中,否则忽略这个待插入的依赖库。
补充说明:levelhash表中保存的是层次信息,层次越深表明这个库越重要;counthash哈希表保存的是对这个依赖库的引用计数,也就是被引用次数,两张表levelhash表、counthash哈希表记录的信息不同。
2.6
在插入levelhash表时,说明当前依赖库的调用层级在当前时间节点是最深的,所以这里的predepend 是最靠近根部的依赖,此时生成 “lib1” -> “lib2” 格式的记录,保存到缓存中,待写入 dot 格式文件,完成将缓存中的数据写到输出文件library.dot予以保存这一步骤。
完成一个依赖库的操作,接下来继续下一个依赖库,直到consumed队列为空,结束循环。
2.7遍历 counthash哈希表,将库名与被引用次数(也可以叫引用计数)写到文件count.record,并将缓存中的数据写到文件 library.dot。
2.8至此,程序结束。
在步骤S3中,脚本处理解析程序的输出文件,通过 awk 去重、sed 替换等操作,将依赖库的被引用次数(也叫引用计数)加到 .dot 文件中,最后利用 dot 工具生成树状图结构。
本发明的实施场景是在操作系统统型依赖库中得以应用,由于整个系统生成树结构很庞大,截取其中一个片段,如图4。图4是生成的操作系统中所有依赖树结构的局部图,表现的是 samba 这一模块依赖树以及对应各个库的引用频次。Graphviz是一个画图软件,其中的dot工具可以用于绘制流程图。dot工具可以根据dot语言代码生成GIF、PNG、SVG、PDF、PostScript格式的图片文件。结合该可视化树以及引用关系记录文件,引用次数记录文件,引用层级记录文件等,为操作系统依赖库的统型提供了有效的参考依据。
本发明的优势是:
1.结合shell脚本,C程序解析与 dot 工具实现可视化依赖树结构的生成。
2.通过 mmap映射、glob机制与elf 库实现对系统中所有库的解析。
因此,本发明通过程序解析 elf 文件,将依赖层次关系保存到 dot 格式文件中,并结合脚本的方式,将引用次数加到数据节点中,从而实现了可视化树形结构的生成。
Claims (9)
1.一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,包括如下步骤:
S1、编写脚本程序,执行脚本程序中的generate_input函数,生成C程序的输入文件result.output,输入文件result.output存储有应用程序的依赖库合集;
S2、将输入文件result.output输入二进制执行程序elf_parser进行分析,生成C程序的输出文件library.dot;
S3、执行脚本程序中的 handle_output 函数,解析输出文件library.dot,最终画出依赖树结构图。
2.根据权利要求1所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S1中,脚本程序为shell脚本程序。
3.根据权利要求1所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S2中,二进制执行程序elf_parser执行如下分析:
S21、解析并检测输入文件result.output合法后,将输入文件result.output中所有依赖库的库名、初始绝对路径 libpath、当前层级level存入consumed队列;
S22、循环解析consumed队列:遍历consumed队列中的内容,判断consumed队列是否为空,若consumed队列不为空,执行步骤S23,否则执行步骤S27;
S23、当前依赖库的初始绝对路径libpath存在的情况下,加载该依赖库,并判断该依赖库是否为64位的elf文件,若是64位的elf文件,执行步骤S24,否则返回步骤S22;
S24、解析elf文件中的DT_NEEDED字段,DT_NEEDED字段用以表示依赖库上声明的依赖项,在初始绝对路径libpath的基础上,找到这个依赖库在系统中的最终绝对路径newpath,将该依赖库的当前层级level的数值加一,表示依赖库加深了一个层次;并将该依赖库的最终绝对路径newpath与新的当前层级level 一起存入consumed队列;同时记录该依赖库的被引用次数,将被引用次数加一,存入counthash哈希表;
S25、调取用于保存依赖库的层次信息的levelhash表,判断是否需要将初始绝对路径libpath和新的当前层级level插入levelhash表中,若需要,执行步骤S26,否则执行步骤S27;
S26、将初始绝对路径 libpath和新的当前层级level存入levelhash表,并保存.dot结构的文件,然后返回步骤S22;
S27、遍历counthash哈希表,将库名与被引用次数写到输出文件count.record;
S28、结束程序。
4.根据权利要求3所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S23中,当前依赖库的初始绝对路径libpath存在,加载该依赖库,是指:调用mmap 映射到内存空间以弹出consumed队列;
判断该依赖库是否为64位的elf文件,是指:解析 elf文件头结构 e_ident[16]的数据,若e_ident[16]的第五个字节等于2,则该依赖库是64位的elf文件,反之则不是。
5.根据权利要求3所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S24中,二进制执行程序elf_parser还可以解析单个依赖库。
6.根据权利要求5所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,对于单个依赖库,通过-l参数来解析单个依赖库。
7.根据权利要求3所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S25中,判断是否需要将初始绝对路径libpath 和新的当前层级level插入levelhash表,是指:
如果levelhash表中不存在该依赖库的层级记录或者该依赖库的层级低于待插入的依赖库的层级level,则将初始绝对路径libpath 和新的当前层级level存入levelhash表中,否则忽略这个待插入的依赖库。
8.根据权利要求1所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,步骤S3中,执行脚本程序中的 handle_output 函数,通过去重、替换操作,将依赖库的被引用次数加到 .dot 结构的文件中,最后利用 dot 工具生成树状图结构。
9.根据权利要求8所述的一种Linux系统上动态链接库可视化依赖树的生成方法,其特征在于,去重为awk去重,替换为sed替换。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211552765.7A CN115543294B (zh) | 2022-12-06 | 2022-12-06 | 一种Linux系统上动态链接库可视化依赖树的生成方法 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN202211552765.7A CN115543294B (zh) | 2022-12-06 | 2022-12-06 | 一种Linux系统上动态链接库可视化依赖树的生成方法 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN115543294A true CN115543294A (zh) | 2022-12-30 |
CN115543294B CN115543294B (zh) | 2023-03-17 |
Family
ID=84721639
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN202211552765.7A Active CN115543294B (zh) | 2022-12-06 | 2022-12-06 | 一种Linux系统上动态链接库可视化依赖树的生成方法 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN115543294B (zh) |
Cited By (2)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117369865A (zh) * | 2023-12-07 | 2024-01-09 | 麒麟软件有限公司 | 一种GNU linux通用的应用程序打包方法及图形化应用打包器 |
CN117407047A (zh) * | 2023-12-13 | 2024-01-16 | 麒麟软件有限公司 | 一种基于图数据库的linux生态依赖关系图谱构建方法及应用 |
Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102646035A (zh) * | 2012-02-17 | 2012-08-22 | 南京南瑞继保电气有限公司 | 基于api接口和脚本定义相结合的可视化代码生成方法 |
CN109241035A (zh) * | 2018-08-28 | 2019-01-18 | 福建南威软件有限公司 | 一种自定义脚本实现数据库的自动部署方法 |
CN111399830A (zh) * | 2020-03-16 | 2020-07-10 | 北京五八信息技术有限公司 | 一种应用程序容量监控方法、装置、电子设备及存储介质 |
CN113391812A (zh) * | 2020-03-13 | 2021-09-14 | 阿里巴巴集团控股有限公司 | 应用程序模块的分析方法、装置以及分析工具 |
WO2022077222A1 (zh) * | 2020-10-13 | 2022-04-21 | 深圳晶泰科技有限公司 | 一种有向无环图式自动任务流的通用描述语言数据系统 |
CN114780109A (zh) * | 2022-05-20 | 2022-07-22 | 厦门大学 | Python项目第三方库依赖自动化解析与安装方法 |
-
2022
- 2022-12-06 CN CN202211552765.7A patent/CN115543294B/zh active Active
Patent Citations (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN102646035A (zh) * | 2012-02-17 | 2012-08-22 | 南京南瑞继保电气有限公司 | 基于api接口和脚本定义相结合的可视化代码生成方法 |
CN109241035A (zh) * | 2018-08-28 | 2019-01-18 | 福建南威软件有限公司 | 一种自定义脚本实现数据库的自动部署方法 |
CN113391812A (zh) * | 2020-03-13 | 2021-09-14 | 阿里巴巴集团控股有限公司 | 应用程序模块的分析方法、装置以及分析工具 |
CN111399830A (zh) * | 2020-03-16 | 2020-07-10 | 北京五八信息技术有限公司 | 一种应用程序容量监控方法、装置、电子设备及存储介质 |
WO2022077222A1 (zh) * | 2020-10-13 | 2022-04-21 | 深圳晶泰科技有限公司 | 一种有向无环图式自动任务流的通用描述语言数据系统 |
CN114780109A (zh) * | 2022-05-20 | 2022-07-22 | 厦门大学 | Python项目第三方库依赖自动化解析与安装方法 |
Cited By (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN117369865A (zh) * | 2023-12-07 | 2024-01-09 | 麒麟软件有限公司 | 一种GNU linux通用的应用程序打包方法及图形化应用打包器 |
CN117369865B (zh) * | 2023-12-07 | 2024-04-05 | 麒麟软件有限公司 | 一种GNU linux通用的应用程序打包方法及图形化应用打包器 |
CN117407047A (zh) * | 2023-12-13 | 2024-01-16 | 麒麟软件有限公司 | 一种基于图数据库的linux生态依赖关系图谱构建方法及应用 |
CN117407047B (zh) * | 2023-12-13 | 2024-04-05 | 麒麟软件有限公司 | 一种基于图数据库的linux生态依赖关系图谱构建方法及应用 |
Also Published As
Publication number | Publication date |
---|---|
CN115543294B (zh) | 2023-03-17 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN115543294B (zh) | 一种Linux系统上动态链接库可视化依赖树的生成方法 | |
US6836883B1 (en) | Method and system for compiling multiple languages | |
US8464207B2 (en) | System and method for tracking software changes | |
US8819649B2 (en) | Profile guided just-in-time (JIT) compiler and byte code generation | |
US8091075B2 (en) | Method and apparatus for breakpoint analysis of computer programming code using unexpected code path conditions | |
US5854932A (en) | Compiler and method for avoiding unnecessary recompilation | |
US5905892A (en) | Error correcting compiler | |
KR100311585B1 (ko) | 템플릿오브젝트파일들을최적화하기위한시스템과방법 | |
US7937692B2 (en) | Methods and systems for complete static analysis of software for building a system | |
US6993753B2 (en) | Compiler for parallel computer | |
US7406684B2 (en) | Compiler, dynamic compiler, and replay compiler | |
US5960197A (en) | Compiler dispatch function for object-oriented C | |
JP2019053729A (ja) | スマートコントラクトのテスト方法及びテスト装置 | |
US7624390B2 (en) | Optimizing compiling of object oriented source code | |
US7458071B2 (en) | Compilation method, compiler apparatus and compiler | |
US7624381B1 (en) | Portable detection of start and completion of object construction | |
MXPA03004411A (es) | Sistema y metodo para definir y utilizar subclases declarativamente por marcas. | |
CN111475150B (zh) | 一种跨语言绑定方法、装置、设备及存储介质 | |
CN111857681B (zh) | 一种c++系统的软件定义化关键函数定位与提取方法 | |
CN113419960B (zh) | 用于可信操作系统内核模糊测试的种子生成方法及系统 | |
CN115292203A (zh) | 一种源代码分析方法及装置 | |
CN114610364A (zh) | 应用程序更新、应用程序开发方法、装置及计算机设备 | |
US9720660B2 (en) | Binary interface instrumentation | |
JPH07182179A (ja) | オブジェクト指向データベース管理装置 | |
US7555708B2 (en) | Mechanism for converting text output into objects |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |