C++

C++ 开发碎片笔记

C++ 开发工作中积累的零散指令与技巧:性能分析、编译选项、ASAN、反汇编、动态链接调试等

3 分钟阅读1300 字

C++ 开发碎片笔记

日常开发中常用的命令和技巧,持续更新中。


编译相关

常用编译选项

1
2
3
4
5
# 输出 C++ 虚函数表(vtable)布局信息
-Xclang -fdump-vtable-layouts

# 代码覆盖率插桩
-fprofile-instr-generate -fcoverage-mapping

代码覆盖率完整流程(clang/llvm)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
rm *.profraw *.profdata -rf

SRC_FILES=main.cpp
CXX=clang++
LLVM_PROFDATA=llvm-profdata
LLVM_COV=llvm-cov
CXX_PROFILE_INSTR_FLAGS="-fprofile-instr-generate -fcoverage-mapping"

echo "-------------------------------------------------------"
$CXX -O2 -std=c++17 $SRC_FILES -o program_nomal -g && ./program_nomal

echo "-------------------------------------------------------"
$CXX -O2 -std=c++17 $CXX_PROFILE_INSTR_FLAGS $SRC_FILES -o program_instr -g && ./program_instr

echo "-------------------------------------------------------"
echo "merge profraw"
$LLVM_PROFDATA merge -output=program.profdata *.profraw

echo "-------------------------------------------------------"
echo "show testPattern count"
$LLVM_PROFDATA show --function=testPattern --counts --detailed-summary program.profdata

echo "-------------------------------------------------------"
echo "show source"
$LLVM_COV show ./program_instr -instr-profile=./program.profdata main.cpp

echo "-------------------------------------------------------"

代码格式化批量检查

ClangFormat Style Options.clang-format 所有配置项说明

run-clang-format — clang-format 的封装脚本,支持批量检查多个文件/目录,适合 CI 集成。

1
2
3
4
5
# 递归检查 src 和 include 目录
./run-clang-format.py -r src include

# 排除指定路径
./run-clang-format.py -r --exclude src/third_party --exclude '*_test.cpp' src include

也可以在 .clang-format-ignore 文件中配置排除规则:

1
2
# ignore third_party code from clang-format checks
src/third_party/*

ASAN (AddressSanitizer)

CMake 启用 ASAN

1
-DADDRESS_SANITIZER=TRUE

运行时配置

1
2
3
4
5
6
7
# 搭配 LD_PRELOAD 使用(适用于 ROCm/HIP 环境)
LD_PRELOAD=$ROCM_PATH/llvm/lib/clang/17.0.0/lib/linux/libclang_rt.asan-x86_64.so::/opt/hyhal/lib/libhsa-runtime64.so \
  ASAN_OPTIONS=halt_on_error=0,detect_odr_violation=0,log_path=./log_asan.txt \
  ./demo

# 完整 ASAN 选项示例
export ASAN_OPTIONS=halt_on_error=0:detect_odr_violation=0:log_path=./log_asan.txt:verbosity=2:alloc_dealloc_mismatch=1:fast_unwind_on_malloc=0:malloc_context_size=50

反汇编

1
2
3
4
5
6
7
8
# 通用(默认 CPU 架构)
llvm-objdump -d <binary>

# DCU(海光 DCU)
extractkernel -i <binary>

# AMDGPU / DCCobjdump
llvm-amdgpu-objdump --inputs=<binary>

构建与调试

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看 make 详细构建指令
make VERBOSE=1

# 解析 C++ mangled 符号
c++filt <mangled_name>

# 显示动态符号表
nm -D <library>

# 查看动态库依赖并搜索符号
ldd demo | awk '{print $3}' | grep -v '^$' | xargs -I {} nm -A {} | grep _ZTINSt6thread6_StateE

# 动态链接器调试(查看符号解析过程)
LD_DEBUG=libs,symbols,bindings ./demo 2>&1 | grep -A5 -B5 "func"

性能分析

1
2
3
4
5
# 统计指令数、周期数等基础硬件事件
perf stat -e instructions,cycles ls

# 后台运行 ctest,日志带时间戳
nohup ctest > ./ctest_$(date +%m%d%H%M).log 2>&1 &

Trace 可视化

导出 Google Doc 为 PDF:

  1. Ctrl + P → 另存为 PDF
  2. 直接修改 URL 触发下载:
    1
    2
    3
    4
    5
    
    # 原始 URL(预览模式)
    https://docs.google.com/document/d/<DOC_ID>/preview...
    
    # 改为导出 URL
    https://docs.google.com/document/d/<DOC_ID>/export?format=pdf

系统诊断

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 查看进程
ps -ef | grep demo
ps aux | grep demo

# 重定向标准错误到标准输出
./program > log.txt 2>&1

# 系统调用跟踪(输出到 vim)
strace -f ./MatrixTranspose |& vim -

# 查看命名管道
ls -l /tmp/ | grep "^p"

# 查看 PCI 设备(显卡等)
lspci | grep -i Display

# 乌镇平台(海光 DCU)驱动版本
cat /sys/module/hydcu/version
rpm -qa | grep rock
hy-smi --showdriverversion

# 昆山平台(AMD GPU)驱动版本
cat /sys/module/amdgpu/version

# 解压 RPM 文件(不安装)
rpm2cpio package.rpm | cpio -idmv
# 安装 / 卸载 RPM 包
rpm -i package.rpm && rpm -e package_name
# 查看 RPM 包内的安装脚本
rpm -qp --scripts ./package.rpm

# 在指定目录中搜索包含某字符串的头文件
find /opt/hpc/software/mpi/hpcx/v2.11.0 -name "*.h" -exec grep -il "MPI_SEND" {} \;

文本处理

Windows 换行符为 \r\n,在 Linux 下显示为 ^M,需转换为 Unix 格式 \n

1
2
3
4
5
6
dos2unix filename                    # 方法1:dos2unix 工具
sed -i "s/\r//" filename             # 方法2:sed 直接替换
# 方法3:vim 内执行 :set ff=unix 后 :wq

# 以十六进制查看文件原始字节(排查换行符、不可见字符等)
hexdump -C ./simple

参考规范


在线工具

  • Compiler Explorer (Godbolt) — 在线编译查看汇编输出,支持多编译器多语言
  • Quick Bench — 在线 C++ 性能基准测试(基于 Google Benchmark)
  • CppInsights — 展示编译器对 C++ 代码的实际展开(模板、lambda、range-for 等)
  • CppMem — 交互式 C/C++ 内存模型分析,用于理解多线程内存序行为

工具链与源码


学习资源

  • MVIDIA — 在线可视化硬件基础课程

0%