Общая память между потоками

Я использую инструмент 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 используется для записи информации о потоке и адреса памяти при чтении или записи памяти, и я использую блокировку в этой функции.
Я хочу записать адрес памяти, разделяемый между потоками, такой как глобальные переменные или куча 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;
}

и результат указывает на память, к которой осуществляется доступ с помощью многопоточности, и выводит отладочную информацию инструкции доступа к памяти в следующей строке:

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: 

Результат указывает на то, что оба потока имеют некоторый доступ к памяти, а инструкция чтения/записи не имеет отладочной информации (у меня есть опция добавления -g в компиляции). Так что, возможно, к этой памяти обращается библиотека
Q1: что нить делать с этой памятью?
Q2: Если я просто хочу отслеживать память, определенную пользователем, а не определенную в библиотеке, как их отличить?


person wangxf    schedule 27.11.2015    source источник
comment
Тот факт, что вы не запрограммировали никакого доступа к разделяемой памяти, не означает, что инфраструктура pthread не имеет его, в конце концов, один поток должен каким-то образом сигнализировать другому, что он завершен. Вероятно, вы можете использовать это для нулевой калибровки ваших мер, потому что менее общий доступ, вероятно, невозможен.   -  person Ulrich Eckhardt    schedule 27.11.2015
comment
@Ulrich Eckhardt На самом деле я не только отслеживаю общую память, но и обнаруживаю гонку данных, поэтому результат показывает, что в этой памяти есть гонка данных, это означает, что функция lib имеет гонку данных?   -  person wangxf    schedule 27.11.2015
comment
Честно говоря, я не могу сказать. Вывод для меня мало что значит, так как неясно, какой поток выполняет какой доступ. Где вы его видите и почему?   -  person Ulrich Eckhardt    schedule 27.11.2015
comment
@Ulrich Eckhardt Я использовал тестовый пример, в котором есть гонки данных, чтобы протестировать мой инструмент, он может правильно обнаруживать гонки данных, поэтому отображение памяти на выходе должно иметь гонку данных, это может быть безобидная гонка данных. Но я не знаю, как удалить память, которая не определена пользователем? Несмотря на то, что в этой памяти есть гонка данных   -  person wangxf    schedule 27.11.2015
comment
Приложение 1: широко используемая библиотека, написанная и отлаженная несколькими экспертами в течение десятилетий, которая выдержала испытание временем. Экспонат 2: какой-то инструмент с нечитаемым выводом, написанный одним чуваком, который обнаружил одну гонку данных в одном тестовом примере. И вы хотите, чтобы мы поверили, что Доказательство 2 верно? Вы должны сделать лучше, чем это.   -  person Art    schedule 27.11.2015
comment
@Art Итак, вы не ответили на мой вопрос выше, вы просто хотите доказать, что мой инструмент плохой? и я просто хочу знать, почему эта память делится на потоки и что они делают. Вы бы лучше внимательно прочитали вопрос, а не говорили: Как ты смеешь, чувак, подозревать библиотеку у экспертов?   -  person wangxf    schedule 27.11.2015
comment
Это мой ответ. Вы не показали ни одной проблемы. Нет вопросов. Ваш вопрос сводится к тому, что мой инструмент показывает результаты, которых я не ожидаю, тогда ответ таков: это, вероятно, проблема с вашим инструментом. Если бы мне пришлось догадываться без какой-либо информации, то это то, что ваш инструмент обнаруживает доступ к блокировкам и ошибочно идентифицирует их как гонки данных, в то время как они совершенно противоположны. Но откуда мне знать, я понятия не имею, что делает ваш код, потому что вы не показали, что он делает, как он это делает и что означает вывод. Вы только что сказали, что это правильно, основываясь на одном тесте, который вы сделали, что смешно.   -  person Art    schedule 27.11.2015
comment
Я использую Intel Pin для управления доступом к памяти. Я просто указываю эту память, совместно используемую потоками, и я не уверен, что между потоками должна быть гонка данных, поэтому я не упоминаю гонку данных в своем вопросе. Я не спрашивал, почему происходит гонка данных, я спросил об общей памяти в простом тесте, почему эта память делится между потоками и что поток делает в этой памяти. Извините, я изменю свой вопрос.   -  person wangxf    schedule 27.11.2015
comment
Вы забыли сообщить нам, на какой платформе вы это используете, что было бы полезно. IIRC, если это Linux, количество блокировок на семафорах (включая murices), которые он хранит в пользовательском пространстве. Это, вероятно, ваш дымящийся пистолет. Также возможно, что pthreads внутренне использует CV для pthread_join()   -  person marko    schedule 27.11.2015
comment
На мой взгляд, в вашем вопросе недостаточно кода, чтобы мы могли вам помочь. Вы показываете один активный поток — родитель запускает его и ждет завершения. С показанным кодом это происходит немедленно; ни один из результатов, о которых вы заявляете, не создается показанным кодом. Это лишает меня возможности, во всяком случае, догадаться, в чем ваша проблема. Я думаю, вам следует создать MCVE (Как создать минимальный, полный и проверяемый пример?), который выдает показанный вами результат.   -  person Jonathan Leffler    schedule 27.11.2015
comment
@Jonathan Leffler Хорошо, спасибо, я постараюсь отредактировать свой вопрос.   -  person wangxf    schedule 27.11.2015


Ответы (1)


  1. Очевидно, вам нужно больше информации о том, что происходит на этих адресах. Я рекомендую использовать API-интерфейсы RTN_* и IMG, чтобы получить больше информации о выполняемых подпрограммах, а затем проверять соответствующие изображения в дизассемблере.
  2. Вместо фильтрации по памяти вы можете фильтровать доступ по источнику кода. Просто избегайте инструментальных инструкций, которые являются частью системных библиотек.

Что касается обсуждения в комментариях, следует также рассмотреть ситуацию, когда вы не обнаруживаете механизм синхронизации, используемый библиотекой.

person nitzanms    schedule 29.11.2015
comment
Большое Вам спасибо. Я понял, что обнаруживаю только блокировку и разблокировку, игнорируя сигнал состояния, так что, возможно, это проблема. Кстати, я просмотрел API Pin, он не может отличить инструкцию от системных библиотек или пользовательского кода, у вас есть хороший способ решить эту проблему? - person wangxf; 30.11.2015
comment
Оно может. Посмотрите примеры в source/tools/InstLibExamples/filter*. - person nitzanms; 01.12.2015
comment
Кстати, вам также необходимо учитывать атомарные операции. - person nitzanms; 01.12.2015