跳转到内容

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 条件变量的线程也可能被唤醒。唤醒后,应显式检查条件,如果条件不满足,则返回等待。


代码审查清单

[编辑 | 编辑源代码]
  1. 功能影响
    1. 哪些模块受到影响;哪些功能受到影响。
    2. 更改的代码使用哪些模块和功能。
    3. 哪些模块/功能正在使用它。
    4. 副作用。
  2. 架构
    1. 可扩展性
    2. 稳定性
    3. 功能
    4. 鲁棒性
  3. 技术细节
    1. 通用
      1. 第一遍:逻辑。正确性。它(试图)做什么。
        1. 副作用。
        2. 为什么代码在那里?
      2. 第二遍:错误处理和奇异情况。
        1. 副作用。
        2. 是否检查了返回值。代码能否处理它们。
        3. 参数
          1. 是否处理边界/越界/奇怪的值。
          2. 参数类型:方便?
          3. 数据来自哪里?上游三个层级。
          4. 输出将去哪里?下游三个层级。
            1. 可能的/允许的输出是什么?是否所有输出在下游都已处理?
        4. 变量:是否初始化?
        5. (过/下)溢出
          1. 缓冲区。
          2. 整数类型。
        6. 断言的不变性和假设。
        7. 循环:是否少一?是否无限?
        8. 递归:是否存在基本情况?
      3. 第三遍:线程安全性。
      4. 本地化?
      5. 重复信息?
      6. 数学
        1. 是否先处理较小的值?
        2. NaN 检查/std::isnan 及其朋友。
        3. 被零除。
    2. C
      1. return:资源处理。
      2. 使用 N 函数(例如 s'n'printf vs. sprintf)。
      3. printf 及其朋友:格式化程序是否与类型和参数数量匹配?
      4. 不可重入/非线程安全的 API
      5. 不安全/存在竞争条件的 API (mktemp())
      6. 枚举
        1. 是否处理了所有情况?
        2. 默认返回/日志/抛出错误
      7. 未指定/未定义/实现定义/非标准行为或扩展
    3. C++
      1. 第四遍:异常处理
        1. 在析构函数中。
        2. 异常捕获边界?
        3. 资源是否受到 RAII 保护。
      2. 第五遍:性能。
        1. C++11:完美转发和临时对象。
        2. 它如何扩展?
      3. 初始化的数据成员。
      4. 六大要素(默认构造函数、析构函数、复制/移动构造函数/运算符)。
      5. 虚析构函数?
      6. 资源处理:RAII。
      7. 创建和销毁的位置在哪里?生命周期管理?
      8. 彻底的 const 和 volatile。
      9. 谓词是否无状态。
      10. 对 std::string 位置使用 size_t。
      11. 为什么要进行强制转换?
      12. 不要在锁下进行跟踪
      13. 不要在锁下销毁对象
  4. 平台特定
    1. POSIX/SUS
      1. 中断调用。
      2. 虚假唤醒。
      3. 已知存在竞争条件的调用。


一个伪文件系统,公开有关正在运行的进程的信息

# 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
...
参考文献
[编辑 | 编辑源代码]
sysstat, sar
[编辑 | 编辑源代码]


其他工具

[编辑 | 编辑源代码]
addr2line
[编辑 | 编辑源代码]

给定可执行文件中的地址或可重定位对象的某个部分中的偏移量,addr2line将其转换为文件名和行号。

一个用于反解符号名称的工具。

  • 反汇编二进制文件,包括源代码objdump -C -S -r -R -l <binary>
  • HLE:硬件锁省略
  • HT:超线程
  • RTM:受限事务内存
  • TSX: 英特尔事务同步扩展([1][2]
华夏公益教科书