Arm平台下如何通过Perf获取Load/Store指令的内存地址?
问题解决:Arm Perf采样Load/Store地址时addr为0的修复
核心原因
直接使用0x13作为pe.config只指定了事件的基础编码,缺少事件类型掩码(UMASK),导致Perf无法正确捕获带地址的Load/Store事件,最终采样到的addr为0。
正确的pe.config取值
对于Arm Cortex-A57的DATA_MEM_ACCESS事件,需要结合UMASK指定要采样的访问类型,完整的config格式为:(UMASK << 16) | 0x13
其中UMASK对应取值:
- 0x01:仅采样Load指令
- 0x02:仅采样Store指令
- 0x03:同时采样Load和Store指令
对应完整的config值:
- Load事件:
0x010013 - Store事件:
0x020013 - 全部访问:
0x030013
修改后的代码示例
struct perf_event_attr pe; memset(&pe, 0, sizeof(struct perf_event_attr)); pe.type = PERF_TYPE_RAW; pe.size = sizeof(struct perf_event_attr); // 示例:采样所有Load事件 pe.config = 0x010013; pe.sample_type = PERF_SAMPLE_ADDR | PERF_SAMPLE_TID; pe.disabled = 1; // 先禁用事件,创建后通过ioctl启动更稳妥 pe.sample_period = 1; pe.precise_ip = 2; // Arm平台建议设为2,对应精确IP采样
如何获取正确的配置代码
有两种可靠方式:
- 通过libpfm4自动生成:使用libpfm4的API获取带过滤条件的完整事件编码,无需手动计算:
pfm_event_info_t info; // 采样Load事件,":ld"可替换为":st"或":ldst" int ret = pfm_get_event_info("DATA_MEM_ACCESS:ld", PFM_OS_PERF_EVENT, &info); if (ret == 0) { pe.config = info.code; } - 通过perf命令查询:在终端执行
perf list raw,查找对应事件的Raw编码,例如Cortex-A57的DATA_MEM_ACCESS:ld对应Raw编码为0x10013(即0x010013)。
内容的提问来源于stack exchange,提问作者end black
相关产品推荐
相关产品推荐

