0

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);
        }
    }
}

この関数はRecordMemReadRecordMemWriteメモリの読み取りまたは書き込み時にスレッドの情報とメモリアドレスを記録するために使用され、この関数でロックを使用しています。
グローバル変数やヒープメモリなど、スレッド間で共有するメモリアドレスを記録したい。
しかし、単純なマルチスレッド プログラムを使用してツールをテストすると、. テストは以下の通り。このプログラムでは、ユーザーは共有変数または共有メモリを定義していません。

#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: ライブラリで定義されていない、ユーザーによって定義されたメモリを監視したいだけの場合、それらを区別する方法を教えてください。

4

1 に答える 1

0
  1. 明らかに、これらのアドレスで何が起こっているかについて、より多くの情報が必要です。pin の RTN_* および IMG API を使用して、実行中のルーチンに関する詳細情報を取得し、逆アセンブラーで関連する画像を検査することをお勧めします。
  2. メモリでフィルタリングする代わりに、コード ソースでアクセスをフィルタリングできます。システム ライブラリの一部であるインストルメント化命令は避けてください。

コメントでの議論に関しては、ライブラリが使用する同期メカニズムを検出していない状況も考慮する必要があります。

于 2015-11-29T07:56:09.400 に答える