2013-06-04 2 views
4

У меня есть набор программ, работающих совместно с общей памятью (ipc) ~ 48 ГБ.Устранение утечек памяти без valgrind

программы, работающая в Linux 3.6.0-RC5, написанный простым С, составленный GCC средней нагрузки на главном компьютере 6,0 прыгает 16,0 каждые 10 секунд (24 ядер)

Один прокси принимает данные от других машин по 0mq (3.2.3, ~ 1000 msgs/s из 12 машин в одной сети), запись в разделяемую память Многие (< 50) работники считывают эти данные и выполняют некоторые вычисления.

Прокси-сервер, использующий около 20% процессора Каждый рабочий, использующий 1% процессор, прыгает на 10% периодически.

Все программы написаны таким образом, когда все распределения сделано в Init() - вызывается при запуске программы, все бесплатно сделано уничтожить() - вызывается перед выходом

Серийное код не используя любой таНос/calloc/бесплатно на всех ,

Но обе программы все еще протекают. Около 120-240 байт в минуту. Это не так много - память исчерпана за 7-8 дней, и я просто запускаю/останавливаю процесс, но те просочившиеся байты едят мой разум каждый раз, когда приложение мониторинга сообщает мне об этом перезагрузке :)

Плохие вещи - я не могу запустить valgrind из-за использования разделяемая память - ее просто останавливается при распределении/подключении разделяемой памяти, а затем все начинает раздавливаться.

Пытаясь найти эту утечку, я сделал разделенную версию прокси - никаких утечек, но я не могу ее подавать с таким же количеством данных.

При работе под gdb по-прежнему нет утечек, но скорость снижается примерно на 2/3 - поэтому может быть не так быстро воспроизвести эту ошибку.

Так возможные утечки в:

  • мой код. но нет malloc/calloc. Просто указатели + -, memcpy, memcmp
  • некоторые стандартные библиотеки. GLibC? системный журнал?
  • 0mq работать со многими источниками (не думаю, что 1к/сообщ за секунды слишком много трафика)

ли какие-либо другие инструменты/LIBS/хаки существует, что может помочь в такой ситуации?

Редактировать: Шиван Раптор спросил о коде. Повторяющаяся часть - 5k строк математики. Без каких-либо ассигнований, как я упоминал.

Но старт, стоп и повторяющийся ввод здесь:

int main(int argc, char **argv) 
{ 
    ida_init(argc, argv, PROXY); 
    ex_pollponies(); // repetive 
    ida_destroy(); 
    return(0); 
} 


// with some cuttings 

int ex_pollponies(void) 
{ 
    int i, rc; 
    unsigned char buf[90]; 
    uint64_t fos[ROLLINGBUFFERSIZE]; 
    uint64_t bhs[ROLLINGBUFFERSIZE]; 
    int bfcnt = 0; 

    uint64_t *fo; 
    uint64_t *bh; 

    while(1) { 
    rc = zmq_poll(ex_in->poll_items, ex_in->count, EX_POLL_TIMEOUT); 
    for (i=0; i < ex_in->count; i++) { 
     if (ex_in->poll_items[i].revents & ZMQ_POLLIN) { 

     if (zmq_recv(ex_in->poll_items[i].socket, &buf, max_size, 0) == 0) 
      continue; 
     fo = &fos[bfcnt]; 
     bh = &bhs[bfcnt]; 
     bfcnt++; 
     if (bfcnt >= ROLLINGBUFFERSIZE) 
      bfcnt = 0; 

     memcpy(fo, (void *)&buf[1], sizeof(FRAMEOBJECT)); 
     memcpy(bh, &buf[sizeof(FRAMEOBJECT)+1], sizeof(FRAMEHASH)); 

     // then store fo, bh into shared memory, with some adjusting and checkings 
     // storing every second around 1000 msgs 16 bytes each. But leaking is only 200 bytes per minute. 

     } 
    } 

    } 
} 

edit2:

я, наконец, сделать VALGRIND работу - просто сделать использование часть данных (6GB) и, наконец, прошел. И не обнаруживайте утечек. Но по мере работы он берет 100% -ный процессор и определенно моя программа не обрабатывает все входящие данные - она ​​не работает при полной нагрузке. Эта половина подтвердила мое предположение о lasthope - утечка находится на блоке обмена данными. Я нахожу информацию о mtrace (часть libc) Это помогло мне отслеживать ADDRESS утечки - вне моего кода, в одном из потоков. Единственные потоки в моем коде создаются zeromq.Затем я начинаю играть с опциями для сокетов (увеличение hwm, буферов), а скорость утечки уменьшилась, но не полностью ушла даже по абсурдно большим значениям :(

Итак, теперь я на 95% уверен, что его нулевой уровень протекает. . в их списке почты

+1

где ваш код? – Raptor

+0

Посмотрите документацию по функциям библиотеки, которые вы используете. Кто-нибудь из них выделяет вам память и ожидает, что вы ее освободите? – Shahbaz

+0

Что заставляет вас думать, что есть утечка? Статистика может вводить в заблуждение. если вы выделите память на init и коснитесь ее только позже, страницы будут выделены только при касании, что выглядит как выделение. – ugoren

ответ

3

Если Valgrind не решить - вы можете попробовать отслеживать выделение памяти себя

Есть два пути -. заменяющие звонки на таНос с вызовами собственных версий таНоса и бесплатно, а также передать этим функциям какой-то идентификатор, например ФАЙЛ и ЛИНИЯ, или вы можете пройти мимо e имя системы, которая выделяет.

В режиме обнаружения утечки без памяти вы проходите непосредственно в malloc и бесплатно, а в режиме обнаружения утечки памяти вы сначала регистрируете выделение и бесплатные вызовы, а затем вызываете malloc и получаете бесплатный доступ. Когда программа заканчивается, вы сопоставляете распределения и освобождает, и вы увидите, где вы теряете память.

Вы можете сделать это с помощью макросов, поэтому ваша регулярная сборка не будет замедлена.

Вы не поймаете утечки из клиентских библиотек, которые вы не можете перекомпилировать самостоятельно.

Другой способ - использовать флаг gw-wrap для времени ссылки, чтобы gcc называет вашу версию malloc/free вместо glibc. Смотрите этот пост:

Create a wrapper function for malloc and free in C

Преимущество этого в том, что вы будете иметь возможность войти распределения в клиентских библиотеках, а также. Недостаток заключается в том, что вы ограничены одной и той же сигнатурой функции, поэтому вы не сможете получить ФАЙЛ и LINE в вашей контрольной проверке.

Если это C++, вы можете перегрузить глобальный оператор new.

Смежные вопросы