我继承了一些旧代码,似乎在某处有内存泄漏。我的第一个本能是只用

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

然后让Address 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”有点疯狂,因为我在玩耍……没有一个选项可以满足我的要求,但是一旦得知泄漏就退出了)。

如代码中所述,如果我加入线程然后退出程序,则会得到一个漂亮的泄漏报告。否则我什么也得不到。正如您可以想象的那样,在旧版代码库中跟踪10-100个线程并使其全部正常运行很麻烦。

几年前,我记得在使用Visual Leak Detector并很幸运,因为它会生成带有所有潜在内存泄漏的报告(而且我不记得必须将所有内容都拆下来)。问题是此工具仅适用于Windows,而我的代码仅适用于Linux。我可以使LeakSanitizer工具做类似的事情吗?

最佳答案

LeakSanitizer的公共(public)接口(interface)(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

关于c++ - LeakSanitizer : get run time leak reports?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33201345/

10-09 01:49