Intel ツールPin
を使用してマルチスレッド プロセスを計測し、Linux 上のスレッド間の共有メモリ アクセスを監視しますPin
。共有メモリ アドレスを記録するツールを開発します。Pin の計測コードは次のとおりです。
VOID Instruction(INS ins, VOID *v)
{
UINT32 memOperands = INS_MemoryOperandCount(ins);
// Iterate over each memory operand of the instruction.
for (UINT32 memOp = 0; memOp < memOperands; memOp++)
{
if (INS_MemoryOperandIsRead(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
// Note that in some architectures a single memory operand can be
// both read and written (for instance incl (%eax) on IA-32)
// In that case we instrument it once for read and once for write.
if (INS_MemoryOperandIsWritten(ins, memOp))
{
INS_InsertPredicatedCall(
ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite,
IARG_INST_PTR,
IARG_MEMORYOP_EA, memOp,
IARG_END);
}
}
}
この関数はRecordMemRead
、RecordMemWrite
メモリの読み取りまたは書き込み時にスレッドの情報とメモリアドレスを記録するために使用され、この関数でロックを使用しています。
グローバル変数やヒープメモリなど、スレッド間で共有するメモリアドレスを記録したい。
しかし、単純なマルチスレッド プログラムを使用してツールをテストすると、. テストは以下の通り。このプログラムでは、ユーザーは共有変数または共有メモリを定義していません。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
void * fun1(void *arg)
{
}
int main(int argc,char* argv[])
{
pthread_t npid1;
pthread_create(&npid1,NULL,fun1,NULL);
pthread_join(npid1,NULL);
return 0;
}
結果はマルチスレッドでアクセスしたメモリを示し、次の行にメモリアクセス命令のデバッグ情報を出力します。
read addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
write addr: b775252c
line:0 col: 0 file:
read addr: b556ad64
line:0 col: 0 file:
read addr: b556abc4
line:0 col: 0 file:
write addr: b556abc4
line:0 col: 0 file:
結果は、2 つのスレッドの両方によるメモリ アクセスがあり、読み取り/書き込み命令にデバッグ情報がないことを示しています (コンパイルで -g オプションを追加しました)。したがって、これらのメモリはライブラリ
Q1によってアクセスされる可能性があります。メモリー?
Q2: ライブラリで定義されていない、ユーザーによって定義されたメモリを監視したいだけの場合、それらを区別する方法を教えてください。