其他面经

设计模式

设计模式详解

C++性能检测用过什么工具

gdb看backtrace和切换线程

以下是一些常用的多线程调试方法:

1. 查看线程
  • 显示所有线程
    info threads
    

    这个命令会显示当前所有线程的编号、线程ID(TID)、状态以及当前的执行位置。每个线程都有一个 gdb 编号,可以用来切换到指定线程。

2. 切换线程
  • 切换到指定线程
    thread THREAD_NUM
    

    这里的 THREAD_NUMinfo threads 命令输出中线程的编号。切换到指定线程后,可以使用正常的调试命令,比如 backtrace 查看调用栈,print 查看变量等。

3. 设置线程断点
  • 对特定线程设置断点
    break function_name thread THREAD_NUM
    

    在指定线程上设置断点。这样只有当指定线程执行到该断点时,程序才会暂停。

  • 对所有线程设置断点: 正常的断点会影响所有线程,因此可以直接使用 break 命令,而无需特别指定线程。
4. 控制线程
  • 暂停/继续特定线程
    • continue: 继续当前线程的执行。
    • thread THREAD_NUM: 切换到特定线程后,可以继续执行该线程的调试流程。

    注意continue 命令会让所有线程继续运行,想要单步调试特定线程时可以结合 nextstep 命令操作。

5. 锁和竞态调试
  • 设置断点和观察变量: 可以在临界区或共享资源访问代码处设置断点,使用 watch 命令观察共享变量的值变化,帮助发现竞争条件或死锁情况。
    watch var
    
  • 死锁调试: 使用 thread apply all backtrace 查看所有线程的调用栈,确定是否有线程卡在锁等待或死锁状态。

6. 常用命令总结

  • 列出所有线程
    info threads
    
  • 切换线程
    thread THREAD_NUM
    
  • 对指定线程设置断点
    break func_name thread THREAD_NUM
    
  • 查看所有线程的调用栈
    thread apply all backtrace
    
  • 查看特定线程的调用栈
    backtrace
    
  • 继续执行所有线程
    continue
    

检测内存泄漏

Valgrind 是 Linux 下功能非常强大的内存分析工具,常用于检测 C/C++ 程序的内存泄漏、非法访问、内存越界等问题。它的核心工具是 memcheck,用于检测内存泄漏和内存访问错误。以下是对 Valgrind 的详细介绍以及使用方法。

Valgrind 的功能

Valgrind 提供了一系列的子工具来检测和分析程序的各种问题,包括:

  • Memcheck:检测内存泄漏、无效访问、非法读写、未初始化内存使用等。
  • Cachegrind:模拟 CPU 的缓存行为,分析缓存命中率。
  • Massif:内存使用分析工具,帮助优化程序的内存使用。
  • Helgrind:检测多线程程序中的数据竞争和锁定错误。
  • DRD:另一个数据竞争检测工具,类似于 Helgrind。

在检测内存泄漏和非法访问时,通常使用 Memcheck 子工具。

基本使用方法

假设你的可执行文件是 your_program,你可以通过以下命令使用 Valgrind 来检测内存问题:

valgrind --leak-check=full ./your_program

这个命令将启动 Valgrindmemcheck 工具,并运行 your_program--leak-check=full 参数会提供详细的内存泄漏报告。

常用参数选项

Valgrind 提供了很多选项来控制内存检测的精度和输出的信息量。以下是一些常用选项:

  • --leak-check=<yes|no|summary|full>:设置泄漏检查的详细程度。
    • yes:显示简单的内存泄漏摘要。
    • summary:显示泄漏摘要。
    • full:显示每个泄漏的详细信息,包括堆栈回溯。
  • --show-leak-kinds=<kind>:设置报告的泄漏类型,可以选择 all(所有)、definite(确定泄漏)、possible(可能泄漏)、reachable(可达但未释放)、indirect(间接泄漏)。
  • --track-origins=yes:显示未初始化值的来源,适合调试复杂内存问题。
  • --log-file=<filename>:将 Valgrind 输出重定向到文件,方便分析。
  • --num-callers=<n>:设置堆栈回溯的深度,默认是 12。
  • --tool=<toolname>:选择 Valgrind 子工具(如 memcheckmassif 等),默认使用 memcheck
Valgrind 的输出解释

当运行程序出现内存错误或泄漏时,Valgrind 会输出详细的报告,包括:

  • Invalid read/write:表示程序尝试读取或写入无效内存地址,可能是越界或释放后访问。
  • Use of uninitialized value:表示程序使用了未初始化的变量。
  • Conditional jump or move depends on uninitialized value(s):指条件语句使用了未初始化的变量。
  • Memory leaks:报告程序未释放的内存,给出每个泄漏的堆栈信息。

例如,一个典型的内存泄漏报告如下:

==12345== 8 bytes in 1 blocks are definitely lost in loss record 1 of 2
==12345==    at 0x4C2B8F6: malloc (vg_replace_malloc.c:299)
==12345==    by 0x4005F4: main (example.c:10)

解释:

  • 12345Valgrind 为该进程分配的 ID。
  • 8 bytes:泄漏的内存大小为 8 字节。
  • malloc:内存分配的函数来源。
  • main (example.c:10):泄漏发生的代码位置(文件和行号)。

全部加载到内存太大了怎么办

数据迁移怎么保证一致性

新旧数据不兼容怎么办

有哪些加速计算的方法