[英]Thrown exceptions being leaked in C++
I'm fooling around a bit with C++, and as part of that have a piece of "restartable" code. 我在用C ++鬼混,作为其中一部分,有一段“可重启”代码。 To wit:
以机智:
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));
}
}
Then, in another part of the code: 然后,在代码的另一部分中:
static response serve(request &req) {
throw(resp::message("Merdel", {"Test"}));
}
Where resp::message
is a subclass of handler
. 其中
resp::message
是handler
的子类。
This appears to work fine, but when I run it an Valgrind, it tells me this leaks memory: 这似乎工作正常,但是当我运行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)
is the serve
function listed above. serve(arw::request&) (arwtest.ashc:7)
是上面列出的serve
函数。
Why does this leak memory? 为什么会有这种泄漏记忆? It is my understanding that the C++ runtime should free these exceptions for me automatically (and it's not like I have any ability to free them manually anyway, right?), so what could cause it not to?
据我了解,C ++运行时应该为我自动释放这些异常(这并不像我有任何能力手动释放它们,对吗?),那么有什么原因可能导致它不能?
I did find these two previous questions on a similar theme, but they don't seem to be applicable here as they only treat a single leaked exception under exceptional circumstances, while this code leaks an exception per request (do note that 11 individual blocks are leaked; this is because I ran this test function 11 times during this test). 我确实在相同的主题上找到了这 两个问题,但是它们似乎不适用于这里,因为它们仅在特殊情况下处理单个泄漏的异常,而此代码每个请求泄漏一个异常(请注意,有11个单独的块泄漏;这是因为我在此测试中运行了11次此测试功能)。
EDIT : I don't know if it's relevant or not, but it may be worth noting that servehtstart
and servereq
in the backtrace are functions in a pure-C program. 编辑 :我不知道它是否相关,但是值得一提的是,
servehtstart
和servereq
是纯C程序中的函数。 _htstart
and above are C++ code from a shared object that is dlopen()
ed. _htstart
及更高版本是dlopen()
ed共享对象中的C ++代码。 It may also be relevant that it is only the dlopen
of this shared object that at all brings libstdc++
into the process. 可能只有
libstdc++
才是该共享库的dlopen
才有意义。
As it turns out, this is a bug in certain versions of glibc, including the version currently in Debian Stable (namely, 2.13), but which has been since fixed. 事实证明,这是某些glibc版本中的错误,包括当前在Debian Stable(即2.13)中使用的版本,但此问题已得到修复。 When running this same program on a Debian Testing setup (which uses glibc 2.19), the memory leak does not occur.
在Debian Testing安装程序(使用glibc 2.19)上运行同一程序时,不会发生内存泄漏。
Apparently, glibc 2.13 does not properly clean up thread-local memory that is introduced by dlopen()
'ed objects. 显然,glibc 2.13无法正确清除
dlopen()
ed对象引入的线程本地内存。 It occurs here because libstdc++
was only loaded as a consequence of the dlopen()
. 之所以在这里发生,是因为
libstdc++
仅是由于dlopen()
加载的。 The issue is previously described in these two bug reports: 以前在以下两个错误报告中描述了该问题:
The glibc commit which fixed the issue was e6c61494 . 解决该问题的glibc commit是e6c61494 。
Thanks @quantdev, @DavidSchwartz. 谢谢@ quantdev,@ DavidSchwartz。 Your comments made me realize what to look for.
您的评论使我意识到要寻找什么。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.