C/C++ 调试工具

众所周知,计算机程序在开发过程中不出现 Bugs 是困难的,随着程序设计的日益复杂,「Bug Free」也才成为了一种可贵的能力.「Bug Free」通常是困难的,也离不开长期努力的学习和练习.期待先达成「Bug Free」,再开始写程序是不切实际的幻想,Bugs 又必须修复,故此才体现了调试的价值.

Lint

静态分析工具是开发时的良师,静态分析工具常常能在开发过程中发现许多错误或疑似错误问题,并给出 errorwarning

有很多自由且功能强大的工具能提供 C/C++ 代码静态分析(按照名称升序排列):

当然,编译器在编译代码时,也能提供有关代码错误和警告信息.

静态分析工具常常可通过插件或扩展等方式与 IDE 整合,在开发过程中,自动分析代码错误,并及时修改.静态分析工具不仅能分析代码中的错误,还能给出有关可读性的建议,能促使开发者规范的编码.

需要注意的是:不必「过分的讨好」静态分析工具,只要开发者确认静态分析工具给出了错误的信息,那么请坚持自己的做法,并在静态分析工具中禁用相关 checks.

动态分析

Sanitizers

Google 与 LLVM 为开发者提供了一套内置于 clang 内的动态分析工具用于检测众多代码问题.

Thread Safety Analysis

线程安全的问题时常让人苦恼,虽然编写线程安全的 C/C++ 程序算是 C/C++ 开发者的一项基本功,但时常出现的线程不安全与条件竞争也让人防不胜防.

ThreadSafetyAnalysis

Clang Thread Safety Analysis is a C++ language extension which warns about potential race conditions in code. The analysis is completely static (i.e. compile-time); there is no run-time overhead. The analysis is still under active development, but it is mature enough to be deployed in an industrial setting. It is being developed by Google, in collaboration with CERT/SEI, and is used extensively in Google’s internal code base.

Thread safety analysis works very much like a type system for multi-threaded programs. In addition to declaring the type of data (e.g. int, float, etc.), the programmer can (optionally) declare how access to that data is controlled in a multi-threaded environment. For example, if foo is guarded by the mutex mu, then the analysis will issue a warning whenever a piece of code reads or writes to foo without first locking mu. Similarly, if there are particular routines that should only be called by the GUI thread, then the analysis will warn if other threads call those routines.[3]

Valgrind

valgrind

Valgrind is an instrumentation framework for building dynamic analysis tools. There are Valgrind tools that can automatically detect many memory management and threading bugs, and profile your programs in detail. You can also use Valgrind to build new tools.

The Valgrind distribution currently includes seven production-quality tools: a memory error detector, two thread error detectors, a cache and branch-prediction profiler, a call-graph generating cache and branch-prediction profiler, and two different heap profilers. It also includes an experimental SimPoint basic block vector generator. It runs on the following platforms: X86/Linux, AMD64/Linux, ARM/Linux, ARM64/Linux, PPC32/Linux, PPC64/Linux, PPC64LE/Linux, S390X/Linux, MIPS32/Linux, MIPS64/Linux, X86/Solaris, AMD64/Solaris, ARM/Android (2.3.x and later), ARM64/Android, X86/Android (4.0 and later), MIPS32/Android, X86/Darwin and AMD64/Darwin (Mac OS X 10.12).

  • memcheck:内存错误检查
  • cachegrind:缓存使用
  • callgrind:函数调用
  • dhat
  • drd
  • exp-bbv
  • getoff
  • helgrind
  • lackey:资源泄漏
  • massif

网络分析

网络相关的错误常常可以使用 Wireshark 进行调试,Wireshark能直观的查看程序发送或接受的数据,能够为调试带来很多的便利.
Netcat 则是常见的测试工具,方便在终端下直接操作 socket.

单元测试

单元测试是一种良好的测试 API 的方式,在编码阶段即可通过单元测试检查 API 是否满足预期.

C:

C++:

日志

对于一个复杂的软件系统,常常需要在长期在后台静默的运行,那么日志的输出就十分重要,日志也常常被用来定位系统中的 Bugs,高效的记录日志对调试有很大的帮助.

  • spdlog:Very fast, header-only/compiled, C++ logging library.
  • Google Logging Library:Google Logging (glog) is a C++98 library that implements application-level logging. The library provides logging APIs based on C++-style streams and various helper macros.

Debuger

有时面对的问题是复杂的,调试器也是解决问题的利器.

参考资料

1. google/sanitizers:AddressSanitizer, ThreadSanitizer, MemorySanitizer [G/OL]. https://github.com/google/sanitizers.
2. Clang 13 documentation [G/OL]. https://clang.llvm.org/docs/.
3. Thread Safety Analysis [G/OL]. https://clang.llvm.org/docs/ThreadSafetyAnalysis.html.