Search code examples
c++cmultithreadingmemoryintel-pin

The shared memory between threads


I use the Intel tool Pin to instrument the multi-thread process and monitor the shared memory access between thread on Linux, I develop a tool in Pin to record the shared memory address, the instrumentation code in Pin is as follow:

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

the function RecordMemRead and RecordMemWrite is used to record thread's information and memory address when read or write memory, and I have use lock in this function.
I want to record the memory address shared between threads, such as global variables or heap memory.
But when I use a simple multi-thread program to test my tool. The test is as follow. In this program, user have not define any shared variable or shared memory:

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

and the result indicate the memory which have accessed by muti-thread and output the debugging information of memory access instruction in the next line :

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: 

The result indicate that there is some memory access by both two threads, and the read/write instruction has no debugging information( I have add -g option in compile), So maybe these memory is accessed by library
Q1: what threads do with these memory?
Q2: If I just want to monitor the memory defined by user, not defined in library, How to distinguish them?


Solution

    1. Obviously you need more information about what's happening in these addresses. I recommend using pin's RTN_* and IMG APIs to get more info about the routines that are being executed, and then inspecting the relevant images in a disassembler.
    2. Instead of filtering by memory, you can filter accesses by code source. Simply avoid instrumenting instructions that are a part of system libraries.

    Regarding the discussion in the comments, the situation where you're not detecting the synchronization mechanism used by the library should also be considered.