不能对 0x7ffbdcbe4e88 处指令的非标准内存访问使用 IARG_MEMORYREAD_SIZE:xsave ptr [rsp+0x40]
Cannot use IARG_MEMORYREAD_SIZE on non-standard memory access of instruction at 0x7ffbdcbe4e88: xsave ptr [rsp+0x40]
我正在尝试使用 Intel Pin 来调查可执行文件的内存 activity。我尝试使用 IARG_MEMORYREAD_SIZE
参数。这是源代码。
#include <iostream>
#include <zlib.h>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include "pin.H"
using namespace std;
#define LINE_SIZE 50
/* Traces generation parameters*/
#define WARMUP_WINDOW 100E6
#define RUNNING_WINDOW 200E9
#define REST_WINDOW 3E9
#define NUMBER_OF_WINDOWS 2
#define PREFIX_TRACE "memory_trace_"
enum State
{
outROI,
warming,
running,
resting,
};
State state;
int nb_windows;
uint64_t cpt_time;
uint64_t accessPhase;
char buffer[LINE_SIZE];
set<int> idThreads;
PIN_LOCK lock;
gzFile trace;
using namespace std;
VOID access(uint64_t pc , uint64_t addr, int type, int size, int id_thread)
{
PIN_GetLock(&lock, id_thread);
idThreads.insert(id_thread);
if(state != outROI)
{
if(nb_windows < NUMBER_OF_WINDOWS)
{
if(state == resting && accessPhase == REST_WINDOW)
{
cout << "PINTOOLS:BEGIN OF INSTRUMENTATION" << endl;
accessPhase = 0;
state = warming;
std::string trace_str = string(PREFIX_TRACE) + to_string(nb_windows) + ".out";
trace = gzopen(trace_str.c_str(), "wb8");
}
else if(state == warming && accessPhase == WARMUP_WINDOW)
{
cout << "PINTOOLS:END OF WARMUP" << endl;
state = running;
accessPhase = 0;
}
else if(state == running && accessPhase == RUNNING_WINDOW)
{
state = resting;
accessPhase = 0;
nb_windows++;
gzclose(trace);
cout << "PINTOOLS:END OF INSTRUMENTATION" << endl;
}
if(state == running || state == warming)
{
sprintf(buffer, "#!0x%lx %d %d %d 0x%lx" , addr , type , size , id_thread, pc);
gzwrite(trace, buffer, LINE_SIZE);
}
accessPhase++;
}
else
{
PIN_ExitApplication(0);
}
cpt_time++;
}
PIN_ReleaseLock(&lock);
}
/* Record Instruction Fetch */
VOID RecordMemInst(VOID* pc, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
access(convert_pc , convert_pc , 0 , size , id_thread);
}
/* Record Data Read Fetch */
VOID RecordMemRead(VOID* pc , VOID* addr, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
uint64_t convert_addr = reinterpret_cast<uint64_t>(addr);
access(convert_pc , convert_addr , 1 , size , id_thread);
}
/* Record Data Write Fetch */
VOID RecordMemWrite(VOID * pc, VOID * addr, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
uint64_t convert_addr = reinterpret_cast<uint64_t>(addr);
access(convert_pc , convert_addr , 2 , size , id_thread);
}
VOID Routine(RTN rtn, VOID *v)
{
RTN_Open(rtn);
for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)){
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemInst,
IARG_INST_PTR,
IARG_UINT32,
INS_Size(ins),
IARG_THREAD_ID,
IARG_END);
UINT32 memOperands = INS_MemoryOperandCount(ins);
for (UINT32 memOp = 0; memOp < memOperands; memOp++){
if (INS_MemoryOperandIsRead(ins, INS_InsertPredicatedCallmemOp))
{
(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
}
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
/**************************wrong happend here*************************/
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
}
}
}
RTN_Close(rtn);
}
VOID Fini(INT32 code, VOID *v)
{
cout << "PINTOOLS:NB Access " << cpt_time << endl;
cout << "PINTOOLS:NB Threads " << idThreads.size() << endl;
// cout << ""
// if(state != outROI)
// {
gzclose(trace);
// }
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
int main(int argc, char *argv[])
{
PIN_InitLock(&lock);
nb_windows=0;
cpt_time =0;
accessPhase = 0;
RTN_AddInstrumentFunction(Routine, 0);
PIN_AddFiniFunction(Fini, 0);
state = running;
PIN_StartProgram();
return 0;
}
编译后,我试图通过 Pin 像这样 运行 它:
/home/kolin/cache/pin-2.14-71313-gcc.4.4.7-linux/pin -ifeellucky -injection child -follow-execv -t /home/kolin/cache-simulator-master/utils/pintools-trace-gen/obj-intel64/trace-gen.so -- ../run_base_test_gcc41-64bit.0000/gcc_base.gcc41-64bit cccp.in -o cccp.s
但是我收到了这个错误:
E: src/trace-gen.cc:161: Cannot use IARG_MEMORYREAD_SIZE on non-standard memory access of instruction at 0x7ffbdcbe4e88: xsave ptr [rsp+0x40].
我以前从未遇到过这个错误,有人知道我做错了什么吗?
这可能属于您需要使用 IARG_MULTI_MEMORYACCESS_EA
的情况(参见 documentation)。
基本上,根据XSAVE documentation写入指令指向的内存的字节数不是常数,取决于以下因素:
- requested-feature 位图 (RFBM)
- EDX:EAXlogical-AND
- XCR0 的 logical-OR 与 IA32_XSS MSR
您可以检查是否可以使用 IARG_MEMORYREAD_SIZE
(恒定内存大小的指令)或不使用 INS_hasKnownMemorySize
。
if (INS_MemoryOperandIsWritten(ins, memOp))
{
// known memory size (standard behavior)
if(INS_hasKnownMemorySize(ins)) {
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
} else {
// multi memory access
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWriteMulti, // use another analysis routine
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MULTI_MEMORYACCESS_EA, // the analysis routine gets a PIN_MULTI_MEM_ACCESS_INFO*
IARG_THREAD_ID,
IARG_END);
}
}
PIN_MULTI_MEM_ACCESS_INFO
结构是 documented here。
我正在尝试使用 Intel Pin 来调查可执行文件的内存 activity。我尝试使用 IARG_MEMORYREAD_SIZE
参数。这是源代码。
#include <iostream>
#include <zlib.h>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include "pin.H"
using namespace std;
#define LINE_SIZE 50
/* Traces generation parameters*/
#define WARMUP_WINDOW 100E6
#define RUNNING_WINDOW 200E9
#define REST_WINDOW 3E9
#define NUMBER_OF_WINDOWS 2
#define PREFIX_TRACE "memory_trace_"
enum State
{
outROI,
warming,
running,
resting,
};
State state;
int nb_windows;
uint64_t cpt_time;
uint64_t accessPhase;
char buffer[LINE_SIZE];
set<int> idThreads;
PIN_LOCK lock;
gzFile trace;
using namespace std;
VOID access(uint64_t pc , uint64_t addr, int type, int size, int id_thread)
{
PIN_GetLock(&lock, id_thread);
idThreads.insert(id_thread);
if(state != outROI)
{
if(nb_windows < NUMBER_OF_WINDOWS)
{
if(state == resting && accessPhase == REST_WINDOW)
{
cout << "PINTOOLS:BEGIN OF INSTRUMENTATION" << endl;
accessPhase = 0;
state = warming;
std::string trace_str = string(PREFIX_TRACE) + to_string(nb_windows) + ".out";
trace = gzopen(trace_str.c_str(), "wb8");
}
else if(state == warming && accessPhase == WARMUP_WINDOW)
{
cout << "PINTOOLS:END OF WARMUP" << endl;
state = running;
accessPhase = 0;
}
else if(state == running && accessPhase == RUNNING_WINDOW)
{
state = resting;
accessPhase = 0;
nb_windows++;
gzclose(trace);
cout << "PINTOOLS:END OF INSTRUMENTATION" << endl;
}
if(state == running || state == warming)
{
sprintf(buffer, "#!0x%lx %d %d %d 0x%lx" , addr , type , size , id_thread, pc);
gzwrite(trace, buffer, LINE_SIZE);
}
accessPhase++;
}
else
{
PIN_ExitApplication(0);
}
cpt_time++;
}
PIN_ReleaseLock(&lock);
}
/* Record Instruction Fetch */
VOID RecordMemInst(VOID* pc, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
access(convert_pc , convert_pc , 0 , size , id_thread);
}
/* Record Data Read Fetch */
VOID RecordMemRead(VOID* pc , VOID* addr, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
uint64_t convert_addr = reinterpret_cast<uint64_t>(addr);
access(convert_pc , convert_addr , 1 , size , id_thread);
}
/* Record Data Write Fetch */
VOID RecordMemWrite(VOID * pc, VOID * addr, int size, int id_thread)
{
uint64_t convert_pc = reinterpret_cast<uint64_t>(pc);
uint64_t convert_addr = reinterpret_cast<uint64_t>(addr);
access(convert_pc , convert_addr , 2 , size , id_thread);
}
VOID Routine(RTN rtn, VOID *v)
{
RTN_Open(rtn);
for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)){
INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemInst,
IARG_INST_PTR,
IARG_UINT32,
INS_Size(ins),
IARG_THREAD_ID,
IARG_END);
UINT32 memOperands = INS_MemoryOperandCount(ins);
for (UINT32 memOp = 0; memOp < memOperands; memOp++){
if (INS_MemoryOperandIsRead(ins, INS_InsertPredicatedCallmemOp))
{
(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
}
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
/**************************wrong happend here*************************/
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
}
}
}
RTN_Close(rtn);
}
VOID Fini(INT32 code, VOID *v)
{
cout << "PINTOOLS:NB Access " << cpt_time << endl;
cout << "PINTOOLS:NB Threads " << idThreads.size() << endl;
// cout << ""
// if(state != outROI)
// {
gzclose(trace);
// }
}
/* ===================================================================== */
/* Print Help Message */
/* ===================================================================== */
INT32 Usage()
{
return -1;
}
/* ===================================================================== */
/* Main */
/* ===================================================================== */
int main(int argc, char *argv[])
{
PIN_InitLock(&lock);
nb_windows=0;
cpt_time =0;
accessPhase = 0;
RTN_AddInstrumentFunction(Routine, 0);
PIN_AddFiniFunction(Fini, 0);
state = running;
PIN_StartProgram();
return 0;
}
编译后,我试图通过 Pin 像这样 运行 它:
/home/kolin/cache/pin-2.14-71313-gcc.4.4.7-linux/pin -ifeellucky -injection child -follow-execv -t /home/kolin/cache-simulator-master/utils/pintools-trace-gen/obj-intel64/trace-gen.so -- ../run_base_test_gcc41-64bit.0000/gcc_base.gcc41-64bit cccp.in -o cccp.s
但是我收到了这个错误:
E: src/trace-gen.cc:161: Cannot use IARG_MEMORYREAD_SIZE on non-standard memory access of instruction at 0x7ffbdcbe4e88: xsave ptr [rsp+0x40].
我以前从未遇到过这个错误,有人知道我做错了什么吗?
这可能属于您需要使用 IARG_MULTI_MEMORYACCESS_EA
的情况(参见 documentation)。
基本上,根据XSAVE documentation写入指令指向的内存的字节数不是常数,取决于以下因素:
- requested-feature 位图 (RFBM)
- EDX:EAXlogical-AND
- XCR0 的 logical-OR 与 IA32_XSS MSR
您可以检查是否可以使用 IARG_MEMORYREAD_SIZE
(恒定内存大小的指令)或不使用 INS_hasKnownMemorySize
。
if (INS_MemoryOperandIsWritten(ins, memOp))
{
// known memory size (standard behavior)
if(INS_hasKnownMemorySize(ins)) {
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MEMORYREAD_SIZE,
IARG_THREAD_ID,
IARG_END);
} else {
// multi memory access
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWriteMulti, // use another analysis routine
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_MULTI_MEMORYACCESS_EA, // the analysis routine gets a PIN_MULTI_MEM_ACCESS_INFO*
IARG_THREAD_ID,
IARG_END);
}
}
PIN_MULTI_MEM_ACCESS_INFO
结构是 documented here。