Clang调试deadcode思路

本文深入探讨了Clang中死代码分析的实现细节,解析了功能开关P.enableCheckUnreachable的作用,以及如何通过修改源码开启此功能。文章详细描述了从lib/Analysis/reachableCode.cpp到lib/Sema/AnalysisBasedWarnings.cpp的调用流程,为读者提供了理解并启用Clang死代码分析的完整路径。

首先描述下我的环境:Ubuntu16.04 llvm4.0 clang4.0全部使用源码安装方式

Clang的根目录,位于llvm-src下边的tools目录下。

因为需要找到真正的开关,下边我描述下我的思路:

clang/lib/Analysis/reachableCode.cpp,存着DeadCodeScan::findDeadCode的实现,如果功能开关打开的话,那个一定存在着这个类的初始化,然后进行调用,查找初始化这个类的地方

reachableCode.cpp:683(代表reachableCode.cpp文件的第683行,以后不再进行赘述),存在以下代码:

DeadCodeScan DS(reachable, PP);

numReachable += DS.scanBackwards(block, CB);

if (numReachable == cfg->getNumBlockIDs())

      return;

这段代码属于FindUnreachableCode()函数中。查看这个函数,发现并没有明显的开关,如果你愿意的话,可以调试下,断点肯定进不了这里。

继续向上查找,发现整个clangproject中仅有一次这个函数的调用在

clang/lib/Sema/AnalysisBasedWarnings.cpp文件中的CheckUnreachable()函数中对这个函数进行了调用,这个函数中也没有可能的开关。继续向上查找,发现在该文件的2050行中存在着CheckUnreachable的调用,粘一下这个块的代码:

if (P.enableCheckUnreachable) {

    // Only check for unreachable code on non-template instantiations.

    // Different template instantiations can effectively change the control-flow

    // and it is very difficult to prove that a snippet of code in a template

    // is unreachable for all instantiations.

    bool isTemplateInstantiation = false;

    if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D))

      isTemplateInstantiation = Function->isTemplateInstantiation();

    if (!isTemplateInstantiation)

      CheckUnreachable(S, AC);

  }

这次终于找到了一个明确的开关P.enableCheckUnreachable,查看一下enableCheckUnreachable,发现了这样一段代码

clang::sema::AnalysisBasedWarnings::Policy::Policy() {

  enableCheckFallThrough = 1;

  enableCheckUnreachable = 0;

  enableThreadSafetyAnalysis = 0;

  enableConsumedAnalysis = 0;

}

这里是比较明显的,默认初始化的话,enableCheckUnreachable 0,是不会执行的,看看在执行过程中是否会有对这个值的更改,找到以下代码:

//AnalysisBasedWarnings.cpp1995

if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||

      P.enableConsumedAnalysis) {

    // Unreachable code analysis and thread safety require a linearized CFG.

    AC.getCFGBuildOptions().setAllAlwaysAdd();

  }

在这里下断点,进行调试,

1955 if (P.enableCheckUnreachable || P.enableThreadSafetyAnalysis ||

(gdb) p P.enableCheckUnreachable

$1 = 0

(gdb) p P.enableThreadSafetyAnalysis

$2 = 0

(gdb) p P.enableConsumedAnalysis

$3 = 0

所以,结果就比较明显了,默认情况下,这个开关是没有打开的,需要的是修改这里的源码,重新编译。

转载于:https://www.cnblogs.com/jourluohua/p/9735868.html

### 使用 CMake 进行 Clang 调试的方法 为了有效地使用 CMake 对 Clang 进行调试,可以遵循以下方法: #### 设置合适的编译选项 当配置项目时,在 `CMakeLists.txt` 文件中指定所需的调试标志。通常情况下,这涉及到设置 `-g` 编译器标记来启用调试信息的生成。 ```cmake set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") ``` 此命令会向所有的 C++ 编译操作添加 `-g` 参数[^4]。 #### 配置构建类型 通过设定 `CMAKE_BUILD_TYPE` 变量为 `Debug` 来确保优化被禁用并且启用了额外的运行时检查。这样可以帮助发现潜在的问题并简化追踪错误的过程。 ```bash cmake -DCMAKE_BUILD_TYPE=Debug .. ``` 这条指令告诉 CMake 创建一个适合于开发和调试环境下的目标文件结构[^3]。 #### 构建与测试 完成上述配置之后,执行常规的构建过程即可获得带有完整符号表和其他辅助数据的对象文件以及可执行程序。对于基于 LLVM 的工具链来说,这意味着能够利用像 LLDB 或者 GDB 这样的强大调试器来进行交互式的故障排除工作。 一旦遇到问题,则可以在源码编辑器内启动调试会话,并逐步分析代码逻辑直至定位到具体位置为止;也可以直接附加至正在运行的应用进程上进行实时监控。 #### 头文件处理注意事项 如果项目中有仅由头文件构成的库组件存在的话,那么需要注意这些资源不会重复包含不必要的路径前缀,以免引起链接阶段可能出现的相关警告或报错情况发生[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值