0

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?

wangxf
  • 160
  • 1
  • 11
  • Just because *you* didn't program any access to shared memory doesn't mean that the pthread framework doesn't have any, after all one thread must somehow signal to the other that it is finished. You can probably use this to zero-calibrate your measures, because any less shared access is probably impossible. – Ulrich Eckhardt Nov 27 '15 at 07:29
  • @Ulrich Eckhardt Actually I not only monitor the shared memory, but also detect the data race, so the result indicate there have data race in these memory, it means the lib function have the data race? – wangxf Nov 27 '15 at 07:47
  • To be honest, I can't tell. The output bears little meaning to me, since it is unclear which thread performs which access. Where do you see one and why? – Ulrich Eckhardt Nov 27 '15 at 07:49
  • @Ulrich Eckhardt I have use the test case which have data-races to test my tool, it can detect data race correctly, so the memory display in output must be have data race, it maybe benign data race. But I don't know how to eliminate the memory which is not defined by user? Even though the there have data race at this memory – wangxf Nov 27 '15 at 07:57
  • Exhibit 1: a widely used library written and debugged by a multiple experts over decades that has stood the test of time. Exhibit 2: some tool with unreadable output that one dude wrote which detected one data race in one test case. And you want us to believe that Exhibit 2 is correct? You've got to do better than that. – Art Nov 27 '15 at 08:19
  • @Art So you have not answer my question above, you just want to prove my tool is bad? and I just want to know how to why these memory shared in threads, and what they do. You'd better read the question seriously, instead of saying "How dare you dude suspect the library by experts" – wangxf Nov 27 '15 at 08:30
  • It is my answer. You have not shown any problem. There is no question. Your question boils down to "my tool shows me results I don't expect", the answer is then: it's probably a problem with your tool. If I had to guess with no information whatsoever is that your tool detects accesses to locks and misidentifies them as data races while they are quite the opposite. But what do I know, I have no idea what your code does because you haven't shown what it does, how it does it and what the output means. You just said it was correct based on one test you've done, which is comical. – Art Nov 27 '15 at 08:37
  • I use Intel Pin to instrument the memory access. I just indicate this memory shared by threads, and I'm not sure there must have data race between threads, this is the reason why I do not mention the data race in my question. I have not ask why there is data race, I asked about the shared memory in the simple test, why these memory share between threads, and what the thread do in these memory. Sorry, I will modify my question. – wangxf Nov 27 '15 at 08:46
  • You neglect to tell us what platform you are running this on - which would be helpful. IIRC, if it's linux, the lock count on semaphores (including murices) it stored in user-space. This is probably your smoking gun. It's also possible the pthreads internally uses a CV for `pthread_join()` – marko Nov 27 '15 at 09:05
  • 1
    In my opinion, there isn't enough code in your question for us to be able to help you. You show a single active thread — the parent launches it and waits for it to complete. WIth the code shown, that happens immediately; none of the output you claim is produced is produced by the code shown. That makes it impossible for me, at any rate, to guess what your problem is. I think you should create an MCVE ([How to create a Minimal, Complete, and Verifiable Example?](http://stackoverflow.com/help/mcve)) that produces the output you show. – Jonathan Leffler Nov 27 '15 at 09:08
  • @Jonathan Leffler Ok, thanks, I will try to edit my question – wangxf Nov 27 '15 at 09:12

1 Answers1

0
  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.

nitzanms
  • 1,786
  • 12
  • 35
  • Thank you very much. I realized that I have only detect the lock and unlock, ignore the condition signal, so maybe it is problem. BTW, I have looked up the Pin's API, it can not distinguish the instruction is from system libraries or user code, do you have some good way to solve it? – wangxf Nov 30 '15 at 01:35
  • It can. Look at source/tools/InstLibExamples/filter* for examples. – nitzanms Dec 01 '15 at 10:47
  • BTW you also need to consider atomic operations. – nitzanms Dec 01 '15 at 10:48