Intel Pin捕获RECEIVED_ACCESS_FAULT后恢复执行失败,求修复方案
修复Pin工具中异常处理函数卡住的问题
你遇到的卡住问题大概率是两个核心原因导致的:标准IO在Pin异常上下文里的兼容性问题,以及没有让线程回到触发异常的指令重新执行。下面是具体的修复建议和调整后的代码:
1. 替换std::cerr为Pin原生输出函数
Pin的异常处理运行在受限的上下文环境中,标准C++流(比如std::cerr)可能会因为内部锁或者IO操作阻塞,直接导致工具卡住。应该改用Pin提供的PIN_StderrPrintf()来输出日志,它更适配Pin的运行环境:
PIN_StderrPrintf("Exception class %d\n", cl); PIN_StderrPrintf("%s\n", PIN_ExceptionToString(pExceptInfo));
2. 调整指令指针,让线程重新执行触发异常的指令
当你修改string_pointer为有效值后,必须让触发异常的那条解引用指令重新执行——否则线程会跳过这条指令继续运行,要么逻辑出错,要么继续触发异常。你可以通过修改PHYSICAL_CONTEXT的指令指针来实现:
// 获取触发异常的指令地址 ADDRINT faultIp = PIN_GetExceptionAddress(pExceptInfo); // 将物理上下文的指令指针重置回触发异常的位置 pPhysCtxt->Ip = faultIp;
3. 确保全局变量修改的线程可见性
如果你的工具运行在多线程场景下,string_pointer需要被声明为volatile,避免编译器优化导致目标线程看不到修改后的有效值:
volatile char* string_pointer = NULL;
调整后的完整异常处理函数
EXCEPT_HANDLING_RESULT ExceptionHandler(THREADID tid, EXCEPTION_INFO *pExceptInfo, PHYSICAL_CONTEXT *pPhysCtxt, VOID *v) { EXCEPTION_CODE c = PIN_GetExceptionCode(pExceptInfo); EXCEPTION_CLASS cl = PIN_GetExceptionClass(c); // 使用Pin原生输出替代std::cerr PIN_StderrPrintf("Exception class %d\n", cl); PIN_StderrPrintf("%s\n", PIN_ExceptionToString(pExceptInfo)); // 更新全局指针为有效值 string_pointer = "<Invalid Memory>"; // 重置指令指针,让线程重新执行触发异常的指令 ADDRINT faultIp = PIN_GetExceptionAddress(pExceptInfo); pPhysCtxt->Ip = faultIp; return EHR_HANDLED; }
额外注意事项
- 注册异常处理时,确保你明确捕获了
RECEIVED_ACCESS_FAULT异常类,避免处理无关异常导致的问题。 - 异常处理函数要保持简洁,避免执行内存分配、锁操作等复杂逻辑,这些都可能引发新的阻塞或异常。
内容的提问来源于stack exchange,提问作者Simus
相关产品推荐
相关产品推荐

