2015-10-18 2 views
3

Я унаследовал некоторый унаследованный код и, похоже, где-то есть утечка памяти. Мой первый инстинкт должен был просто скомпилировать сLeakSanitizer: получать отчеты об утечках времени выполнения?

-faddress=sanitize -fno-omit-frame-pointer 

и пусть семья по адресу SANITIZER о инструментов поиска утечки для меня. Однако я был очень разочарован. Я надеялся на какое-то сообщение об ошибке времени выполнения (похожее на ошибку sanitizer адреса при чтении или записи памяти, которую вы не должны). Дезинфицирующее средство для утечки, по-видимому, не анализирует проверку утечки до тех пор, пока программа не завершится успешно. Моя проблема заключается в том, что укомплектованный мной код имеет несколько потоков, и он не был предназначен для присоединения к ним всех при подготовке к мягкой посадке.

я упростил мою проблему в простом примере:

#include <thread>           
#include <chrono>           
#include <iostream>           

bool exit_thread = false;         

void threadFunc()           
{               
    while(!exit_thread)          
    {               
     char* leak = new char[256];       
     std::this_thread::sleep_for(std::chrono::seconds{1}); 
    }               
}               

int main() {             
    std::thread t(threadFunc);        
    std::cout << "Waiting\n";         
    std::this_thread::sleep_for(std::chrono::seconds{5});  
    exit_thread = true;          
    std::cout << "Exiting\n";         
    //Without joining here I do not get the leak report.  
    t.join();             
    return 0;             
}  

Я компилировать это с

clang++ leaker.cpp -fsanitize=address -fno-omit-frame-pointer -g -O0 -std=c++1y -o leaker  

А потом побежал с

ASAN_OPTIONS='detect_leaks=1' LSAN_OPTIONS='exitcode=55:report_objects=true:log_threads=true:log_pointers=true' ./leaker             

(я вроде обезумела на «LSAN_OPTIONS» здесь, потому что я играл вокруг ... ни один из вариантов не сделал то, что я хотел, но должен был выйти из u pon изучение утечки).

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

Несколько лет назад я помню, как играл с Visual Leak Detector и имел удачу с ним, потому что он создавал бы отчеты со всеми потенциальными утечками памяти (и я не помнил, чтобы все было хорошо). Проблема в том, что этот инструмент предназначен только для Windows, а мой код работает только с Linux. Могу ли я заставить инструмент LeakSanitizer сделать что-то подобное?

+0

Вы можете посмотреть в [Valgrind] (http://valgrind.org/). –

+0

К сожалению, мое приложение не может справиться с замедлением valgrind – rmccabe3701

ответ

4

Открытый интерфейс LeakSanitizer (sanitizer/lsan_interface.h) имеет различные функции, которые могут соответствовать вашим потребностям. Функция __lsan_do_leak_check() выполняет проверку и завершается при обнаружении утечки. Существует также __lsan_do_recoverable_leak_check, который не заканчивается и может быть вызван несколько раз.

Рассмотрим эту модификацию к вашей программе:

#include <thread> 
#include <chrono> 
#include <iostream> 
#include <sanitizer/lsan_interface.h> 

bool exit_thread = false; 

void threadFunc() 
{ 
    while(!exit_thread) 
    { 
     char* leak = new char[256]; 
     std::this_thread::sleep_for(std::chrono::seconds{1}); 
    } 
} 

int main() { 
    std::thread t(threadFunc); 
    std::cout << "Waiting\n"; 
    std::this_thread::sleep_for(std::chrono::seconds{5}); 
    exit_thread = true; 
    std::cout << "Exiting\n"; 
    //Without joining here I do not get the leak report. 
    //t.join(); 
    __lsan_do_recoverable_leak_check(); 
    std::cout << "Done\n"; 
    return 0; 
} 

Выход:

Waiting 
Exiting 

================================================================= 
==29240==ERROR: LeakSanitizer: detected memory leaks 

Direct leak of 1024 byte(s) in 4 object(s) allocated from: 
    #0 0x4d9a30 in operator new[](unsigned long) (leaker+0x4d9a30) 
    #1 0x4dc663 in threadFunc() leaker.cpp:12:20 
    #2 0x4dffe3 in void std::_Bind_simple<void (*())()>::_M_invoke<>(std::_Index_tuple<>) /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/functional:1530:18 
    #3 0x4dff94 in std::_Bind_simple<void (*())()>::operator()() /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/functional:1520:16 
    #4 0x4dfcc8 in std::thread::_Impl<std::_Bind_simple<void (*())()> >::_M_run() /usr/bin/../lib64/gcc/x86_64-unknown-linux-gnu/5.2.0/../../../../include/c++/5.2.0/thread:115:13 
    #5 0x7f0a9664034f in execute_native_thread_routine /build/gcc-multilib/src/gcc-5.2.0/libstdc++-v3/src/c++11/thread.cc:84 

SUMMARY: AddressSanitizer: 1024 byte(s) leaked in 4 allocation(s). 
Done 
terminate called without an active exception 
Aborted 

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

  • Нет связанных вопросов^_^