抛出的异常在C ++中泄露

时间:2014-09-30 21:36:50

标签: c++ memory-leaks

我在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::messagehandler的子类。

这似乎工作正常,但当我运行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 ++运行时应该自动为我释放这些异常(并且它不像我有能力手动释放它们,对吧?),那么是什么原因导致它不能?

我确实发现了these two以前关于类似主题的问题,但它们似乎并不适用于此,因为它们仅在特殊情况下处理单个泄露的异常,而此代码每个请求泄漏一个异常(请注意,11个单独的块被泄露;这是因为我在此测试期间运行了此测试函数11次。)

编辑:我不知道它是否相关,但可能值得注意的是servehtstartservereq在回溯中是纯C程序中的函数。 _htstart及以上是来自dlopen() ed的共享对象的C ++代码。也可能相关的是,只有此共享对象的dlopen才会将libstdc++带入流程。

1 个答案:

答案 0 :(得分:2)

事实证明,这是glibc的某些版本中的一个错误,包括当前在Debian Stable中的版本(即2.13),但是已经修复了。在Debian测试设置(使用glibc 2.19)上运行相同的程序时,不会发生内存泄漏。

显然,glibc 2.13没有正确清理dlopen()对象引入的线程本地内存。它出现在这里是因为libstdc++仅作为dlopen()的结果而加载。之前在这两个错误报告中描述了该问题:

解决问题的glibc提交是e6c61494

谢谢@quantdev,@ DavidSchwartz。你的评论让我意识到要寻找什么。