Understand在完成源码分析后,会根据函数调用、变量引用、类型使用、文件引用等关系建立代码依赖数据。查看一个文件依赖了哪些模块、某个函数被谁调用,或者修改一个公共模块可能影响哪些文件,都可以从项目数据库里继续追踪。依赖图出现缺少调用、关系数量异常、同一个对象被识别成多个实体时,往往和项目分析配置有关,尤其是C/C++工程里的头文件目录、宏定义和实际编译参数没有配置完整时,依赖结果很容易跟源码实际情况对不上。
一、Understand怎么查看代码依赖关系
Understand提供Information Browser、Dependency Browser和多种关系图。函数调用更适合从Calls、Called By查看,分析文件或类之间的整体关系时,可以直接使用Dependency Browser。
1、查看函数的调用和被调用关系
①在源码编辑器中打开目标函数。
②把光标放到函数名称上,右键选择【View Information】。
③打开【Information Browser】,找到当前函数对应的信息。
④展开【Calls】,查看这个函数直接调用了哪些函数。
⑤展开【Called By】,查看哪些函数调用了当前函数。
⑥继续展开Calls或Called By下面的节点,可以向下追踪多层调用关系。
⑦想用图形查看时,右键函数选择【Graphical Views】。
⑧打开【Calls】查看向外调用,或者选择【Called By】反向查找调用来源。
⑨既想看上游又想看下游时,选择对应的双向调用关系图。
C++项目中存在虚函数或函数指针时,运行时可能对应多个目标。Understand会按照静态分析得到的可能关系显示候选调用,所以图里出现多条边不一定代表重复分析。
2、查看文件之间的依赖关系
①在【Project Browser】中找到准备分析的.c、.cpp或其他源码文件。
②右键目标文件,选择【View Dependencies】。
③也可以通过【View】→【Dependency Browser】打开依赖浏览器。
④把方向切换到【Depends On】,查看当前文件依赖了哪些文件。
⑤切换到【Depended On By】,查看哪些文件依赖当前文件。
⑥展开某条依赖,在右侧继续查看产生这条关系的具体References。
⑦根据引用记录找到对应源码行,判断依赖来自函数调用、变量使用还是类型引用。
⑧点击Dependency Browser中的图形按钮,把当前结果切换成依赖关系图。
例如fileA中的函数调用了fileB中定义的函数,Understand会把这条引用继续映射成fileA对fileB的依赖。文件依赖不只统计#include,函数调用、对象使用、赋值和类型引用等关系也可能参与依赖计算。
3、查看类和架构层级的依赖图
工程规模较大时,文件级结果可能比较密,可以提高一个层级再看。
①在项目中选中目标Class或Architecture。
②右键选择【Graphical Views】。
③选择【Dependencies】或对应依赖图。
④查看节点之间的连线和引用数量。
⑤图中节点较多时切换不同Graph Variant,减少当前画面中的关系。
⑥需要继续定位时,选中某个节点,再进入【Dependency Browser】查看具体References。
⑦项目已经建立Architecture分组时,可以直接从【Graphs】→【Dependency Graphs】查看模块之间的关系。
这种方式更适合分析模块耦合,例如底层驱动有没有反向依赖业务模块、公共模块被哪些组件使用,而不是在大量函数节点中逐个查找。
二、Understand代码依赖分析结果不准确如何调整
依赖关系来自项目数据库里的实体和引用数据,所以依赖图不准时,先检查源码有没有被正确解析。C/C++工程里最常见的是Include、Macro或实际构建参数缺失。
1、检查Missing Includes和未解析对象
①打开当前Understand项目。
②进入【Project】→【Improve Project Accuracy】。
③打开【Missing Includes】,查看没有找到的头文件。
④找到这些头文件在原工程中的实际目录。
⑤进入【Project】→【Configure Project】。
⑥打开【C++】相关配置,把缺少的Include目录补进去。
⑦保存设置后重新分析工程。
⑧再次打开原来的【Calls】【Called By】或Dependency Browser,对比之前缺失的关系是否已经出现。
头文件找不到时,其中声明的函数、类和类型可能无法和真实定义正确关联,调用图里就容易出现断开的实体。
2、补齐条件编译使用的宏定义
同一份源码在不同宏配置下,实际参与编译的代码可能完全不同。
①进入【Project】→【Improve Project Accuracy】。
②查看【Undefined Macros】。
③对照原项目的编译参数,确认当前目标使用了哪些-D宏定义。
④打开【Project】→【Configure Project】→【C++】。
⑤把缺少的预处理宏加入项目配置。
⑥检查DEBUG、目标平台、芯片型号、功能开关等宏值是否和实际构建一致。
⑦保存配置并重新执行Analyze。
⑧打开之前显示异常的函数,重新查看调用关系。
例如源码通过宏在两个不同实现之间切换,Understand分析时使用了错误宏值,依赖图显示出来的就可能是另一套代码路径。
3、重新导入真实构建参数
手工补Include和Macro仍然缺很多内容时,可以让Understand读取原工程的构建信息。
①确认原项目能够正常完成编译。
②使用CMake项目时生成【compile_commands.json】。
③打开Understand的项目配置或重新执行构建信息导入。
④选择对应【compile_commands.json】或当前开发环境支持的工程文件。
⑤检查导入后的编译器、Include Paths和Macros。
⑥确认使用的是当前准备分析的构建配置。
⑦重新Analyze项目。
⑧再从【Dependency Browser】检查文件和类之间的依赖关系。
对于编译参数较复杂的C/C++项目,导入实际构建信息通常比手工补几十个目录和宏更容易保持一致。
三、配置修改后怎么检查依赖结果
修改项目参数以后,不用直接相信新生成的图,可以选几处源码中已经明确知道的关系做交叉检查。这样能很快看出项目数据库是否恢复正常。
1、拿一组已知函数调用做验证
①在源码中找到一个明确存在的函数调用,例如A函数直接调用B函数。
②打开A函数的【Information Browser】。
③展开【Calls】,检查B是否已经出现。
④再打开B函数。
⑤展开【Called By】,确认A能够反向查到。
⑥右键B打开【Called By】关系图,检查上下游关系。
⑦如果源码里明确存在调用但图中仍然没有,继续检查函数声明、宏条件和编译配置。
2、重新分析发生变化的源码
①源码只改动少量文件时执行【Analyze Changed Files】。
②项目配置、宏或Include路径改动较多时,重新执行完整Analyze。
③等待分析结束后查看Analysis Log。
④检查Missing Includes和Undefined Entities是否已经减少。
⑤重新打开【Dependency Browser】,查看引用数量。
⑥再检查几个主要模块的依赖方向。
⑦项目包含多种语言时,分别确认各语言所需的Class Path、搜索路径或编译环境是否已经配置。
跨语言项目里,如果某一种语言没有解析完整,跨模块关系也可能出现缺口。此时要修对应语言的项目配置,而不是只在依赖图里调整显示选项。
总结
Understand代码依赖关系来自源码分析后的实体和引用数据,结果出现缺失或方向异常时,通常要回到项目解析配置查原因。头文件目录、宏定义、编译参数和源码版本保持一致后,函数调用、文件依赖以及类之间的关系才更容易和实际工程对应。调整完成后,再拿源码里已经确认的调用关系做一次验证,比单看一张复杂的依赖图更容易判断分析是否正常。如需进一步了解Understand代码依赖分析、调用关系查看与项目解析配置方法,欢迎联系咨询。