抛出的异常在C++中泄漏
Thrown exceptions being leaked in C++
我在C++上玩了一些,作为其中的一部分,我有一段"可重启"的代码。也就是说:
class handler {
public:
virtual ~handler() {}
virtual response handle(request &req) = 0;
};
response dispatch(request &req, handler &hnd) {
try {
return(hnd.handle(req));
} catch(handler &rep) {
return(dispatch(req, rep));
}
}
然后,在代码的另一部分:
static response serve(request &req) {
throw(resp::message("Merdel", {"Test"}));
}
其中resp::message
是handler
的一个子类。
这看起来很好用,但当我在Valgrind上运行它时,它告诉我这会泄露内存:
==2609== 352 bytes in 11 blocks are definitely lost in loss record 12 of 16
==2609== at 0x4C270FE: memalign (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2609== by 0x4010BEF: tls_get_addr_tail (dl-tls.c:529)
==2609== by 0x401110F: __tls_get_addr (dl-tls.c:767)
==2609== by 0x668FC9B: __cxa_get_globals (eh_globals.cc:63)
==2609== by 0x668F5EE: __cxa_allocate_exception (eh_alloc.cc:132)
==2609== by 0x61DDA5E: serve(arw::request&) (arwtest.ashc:7)
==2609== by 0x640E18B: arw::funhandler::handle(arw::request&) (arw.cpp:95)
==2609== by 0x640E1C5: arw::dispatch(arw::request&, arw::handler&) (arw.cpp:100)
==2609== by 0x640E487: arw::dispatch(ashd::request const&, arw::handler&) (arw.cpp:119)
==2609== by 0x61DDBA7: _htstart (arwtest.ashc:11)
==2609== by 0x403CCD: servehtstart (request.c:228)
==2609== by 0x4040C5: servereq (request.c:303)
serve(arw::request&) (arwtest.ashc:7)
是上面列出的serve
函数。
为什么会泄漏内存?我的理解是,C++运行时应该自动为我释放这些异常(无论如何,我都没有手动释放它们的能力,对吧?),那么是什么原因导致它不能释放呢?
我确实发现前两个问题的主题相似,但它们似乎不适用于这里,因为它们只在特殊情况下处理一个泄漏的异常,而这段代码每个请求都会泄漏一个异常(请注意,有11个单独的块被泄漏;这是因为我在这次测试中运行了11次这个测试函数)。
EDIT:我不知道它是否相关,但值得注意的是,回溯中的servehtstart
和servereq
是纯C程序中的函数。_htstart
和更高版本是来自dlopen()
ed共享对象的C++代码。同样重要的是,只有该共享对象的dlopen
才将libstdc++
引入该过程。
事实证明,这是glibc某些版本中的一个错误,包括目前在Debian Stable中的版本(即2.13),但后来已经修复。当在Debian测试设置(使用glibc 2.19)上运行相同的程序时,不会发生内存泄漏。
显然,glibc 2.13并没有正确地清理dlopen()
对象引入的线程本地内存。之所以出现这种情况,是因为libstdc++
仅作为dlopen()
的结果而被加载。该问题之前在以下两个错误报告中进行了描述:
- https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39366
- https://sourceware.org/bugzilla/show_bug.cgi?id=12650
修复该问题的glibc提交是e6c61494。
谢谢@quantdev,@DavidSchwartz。你的评论让我意识到该找什么。
- valgrind-hellgrind与泄漏检查的结果不同
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 尽管遵循了规则,内存泄漏在哪里
- 为什么调用堆栈数组会导致内存泄漏
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 使用模板类的自定义列表类型中的内存泄漏
- 为什么以下C++代码中存在内存泄漏?
- Klocwork Inside的资源泄漏
- OpenCV 我应该使用智能指针来防止内存泄漏吗?
- 我是否生成线程并导致内存泄漏?
- 多线程程序中出现意外的内存泄漏
- 为什么此函数会导致内存泄漏?
- 在 C++ 库中使用cythonized python时内存泄漏
- 需要帮助查找内存泄漏
- C++功能泄漏内存,我是C++新手,不确定如何解决
- 瓦尔格林德的内存泄漏使用新的
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- 无法找出我的代码中的内存泄漏