Linux perf在宏代码行插入多探针:如何避免或删除冗余探针?
在perf中避免宏展开生成多个探针的解决方法
问题场景
我尝试用perf在宏所在代码行插入探针,比如在CPython实现中,想在ceval_gil.h第164行每次GIL解锁时生成记录,执行了以下命令:
sudo perf probe -f -x `which python3-dbg` python:take_lock=ceval_gil.h:164
但第164行包含一个三行宏MUTEX_LOCK(gil->mutex),导致perf插入了三个完全相同的探针:
执行命令后的输出:
sudo perf probe -f -x `which python3-dbg` python:take_lock=ceval_gil.h:164 gil Added new events: python:take_lock (on @ceval_gil.h:164 in /usr/bin/python3.10d with gil) python:take_lock (on @ceval_gil.h:164 in /usr/bin/python3.10d with gil) python:take_lock (on @ceval_gil.h:164 in /usr/bin/python3.10d with gil) You can now use it in all perf tools, such as: perf record -e python:take_lock -aR sleep 1
用perf probe --list查看也显示三个重复探针:
sudo perf probe --list python:take_lock (on drop_gil:20@../Python/ceval_gil.h in /usr/bin/python3.10d with gil) python:take_lock (on drop_gil:20@../Python/ceval_gil.h in /usr/bin/python3.10d with gil) python:take_lock (on drop_gil:20@../Python/ceval_gil.h in /usr/bin/python3.10d with gil)
解决方法
1. 精准指定宏内的目标行
perf支持直接定位宏展开后的具体行,无需针对整个宏所在的代码行插入探针。步骤如下:
- 先通过预处理查看宏
MUTEX_LOCK的展开内容:
gcc -E /path/to/ceval_gil.h | grep -A 10 -B 5 MUTEX_LOCK
- 找到宏内你真正需要插探针的语句行,用
头文件:宏名:行号的格式指定。比如如果宏展开后第2行是实际执行锁操作的代码,执行:
sudo perf probe -f -x `which python3-dbg` python:take_lock=ceval_gil.h:MUTEX_LOCK:2 gil
这样只会在宏内的指定行生成一个探针。
2. 删除已生成的多余探针
如果已经生成了多个重复探针,可以通过以下方式删除:
- 先查看探针的详细信息(包含ID):
sudo perf probe -v --list
- 根据ID删除指定探针,比如删除ID为1和2的探针:
sudo perf probe -d python:take_lock:1 python:take_lock:2
注意:如果三个探针名称和位置完全一致,直接通过名称删除会删掉所有,因此用ID删除是更精准的方式。
3. 直接定位函数内的指令偏移
如果知道目标操作在drop_gil函数内的大致位置,可以用函数+指令偏移的方式指定探针:
sudo perf probe -f -x `which python3-dbg` python:take_lock=drop_gil:+10 gil
这里+10表示从drop_gil函数起始位置往后数第10条指令,需要根据实际汇编代码调整偏移量。
内容的提问来源于stack exchange,提问作者Olumide
相关产品推荐
相关产品推荐

