Linux 应用程序调试技术/附录
外观
如果调用被信号中断,许多 API 函数会返回错误代码。通常这本身不是错误,应该重新启动调用。例如
int raccept( int s, struct sockaddr *addr, socklen_t *addrlen )
{
int rc;
do {
rc = accept( s, addr, addrlen );
} while ( rc == -1 && errno == EINTR );
return rc;
}
可中断函数列表在类 Unix 平台之间有所不同。对于 Linux,请参阅 signal(7)。请注意sem_wait()& co. 在列表中。
即使条件尚未满足,等待 pthreads 条件变量的线程也可能被唤醒。唤醒后,应显式检查条件,如果条件不满足,则返回等待。
- 功能影响
- 哪些模块受到影响;哪些功能受到影响。
- 更改的代码使用哪些模块和功能。
- 哪些模块/功能正在使用它。
- 副作用。
- 架构
- 可扩展性
- 稳定性
- 功能
- 鲁棒性
- 技术细节
- 通用
- 第一遍:逻辑。正确性。它(试图)做什么。
- 副作用。
- 为什么代码在那里?
- 第二遍:错误处理和奇异情况。
- 副作用。
- 是否检查了返回值。代码能否处理它们。
- 参数
- 是否处理边界/越界/奇怪的值。
- 参数类型:方便?
- 数据来自哪里?上游三个层级。
- 输出将去哪里?下游三个层级。
- 可能的/允许的输出是什么?是否所有输出在下游都已处理?
- 变量:是否初始化?
- (过/下)溢出
- 缓冲区。
- 整数类型。
- 断言的不变性和假设。
- 循环:是否少一?是否无限?
- 递归:是否存在基本情况?
- 第三遍:线程安全性。
- 本地化?
- 重复信息?
- 数学
- 是否先处理较小的值?
- NaN 检查/std::isnan 及其朋友。
- 被零除。
- 第一遍:逻辑。正确性。它(试图)做什么。
- C
- return:资源处理。
- 使用 N 函数(例如 s'n'printf vs. sprintf)。
- printf 及其朋友:格式化程序是否与类型和参数数量匹配?
- 不可重入/非线程安全的 API
- 不安全/存在竞争条件的 API (mktemp())
- 枚举
- 是否处理了所有情况?
- 默认返回/日志/抛出错误
- 未指定/未定义/实现定义/非标准行为或扩展
- C++
- 第四遍:异常处理
- 在析构函数中。
- 异常捕获边界?
- 资源是否受到 RAII 保护。
- 第五遍:性能。
- C++11:完美转发和临时对象。
- 它如何扩展?
- 初始化的数据成员。
- 六大要素(默认构造函数、析构函数、复制/移动构造函数/运算符)。
- 虚析构函数?
- 资源处理:RAII。
- 创建和销毁的位置在哪里?生命周期管理?
- 彻底的 const 和 volatile。
- 谓词是否无状态。
- 对 std::string 位置使用 size_t。
- 为什么要进行强制转换?
- 不要在锁下进行跟踪
- 不要在锁下销毁对象
- 第四遍:异常处理
- 通用
- 平台特定
- POSIX/SUS
- 中断调用。
- 虚假唤醒。
- 已知存在竞争条件的调用。
- POSIX/SUS
一个伪文件系统,公开有关正在运行的进程的信息
# tree /proc/26041
/proc/26041
...
|-- cmdline # Command line
|-- cwd -> /current/working/folder/for/PID
|-- environ # Program environment variables
|-- exe -> /bin/su
|-- fd # Open files descriptors
| |-- 0 -> /dev/pts/21
| |-- 1 -> /dev/pts/21
| |-- 2 -> /dev/pts/21
| `-- 3 -> socket:[113497835]
|-- fdinfo
| |-- 0
| |-- 1
| |-- 2
| `-- 3
|-- latency
|-- limits
|-- maps
|-- mem
|-- mountinfo
|-- mounts
|-- mountstats
...
# cat /proc/26041/status
...
VmPeak: 103276 kB # Max virtual memory reached
VmSize: 103196 kB # Current VM
VmLck: 0 kB
VmHWM: 1492 kB
VmRSS: 1488 kB # Live memory used
...
Threads: 1
...
给定可执行文件中的地址或可重定位对象的某个部分中的偏移量,addr2line将其转换为文件名和行号。
一个用于反解符号名称的工具。
- 反汇编二进制文件,包括源代码objdump -C -S -r -R -l <binary>