log4cxx 在 ~Logger 上引发异常
我刚刚开始使用 log4cxx,通过制作一个小应用程序来熟悉它。 我用 Visual Studio 2005 编译,没有警告或错误。 基本上看起来像:
#includes<...>
...
...
LoggerPtr logger(Logger::getLogger("MyApp"));
void main(...)
{
//some logs here
}
它按预期工作,直到我在尝试销毁全局 Logger 对象时遇到异常时关闭应用程序。 这是痕迹:
log4cxx.dll!apr_pool_cleanup_kill(apr_pool_t * p=0xdddddddd, const void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 1981 + 0x3 bytes
log4cxx.dll!apr_pool_cleanup_run(apr_pool_t * p=0xdddddddd, void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 2025
log4cxx.dll!apr_thread_mutex_destroy(apr_thread_mutex_t * mutex=0x01cf6158) Line 133
log4cxx.dll!log4cxx::helpers::Mutex::~Mutex() Line 57
log4cxx.dll!log4cxx::Logger::~Logger() Line 55 + 0xb bytes
log4cxx.dll!log4cxx::Logger::`vbase destructor'() + 0x19 bytes
log4cxx.dll!log4cxx::Logger::`vector deleting destructor'() + 0x5a bytes
log4cxx.dll!log4cxx::helpers::ObjectImpl::releaseRef() Line 46 + 0x39 bytes
log4cxx.dll!log4cxx::Logger::releaseRef() Line 63
log4cxx.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT<log4cxx::Logger>() Line 100 + 0x33 bytes
NodeBHeartBeat.exe!`dynamic atexit destructor for 'logger''() + 0x2b bytes
msvcr80d.dll!doexit(int code=0x00000000, int quick=0x00000000, int retcaller=0x00000001) Line 553
msvcr80d.dll!_cexit() Line 413 + 0xb bytes
msvcr80d.dll!__CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 389
msvcr80d.dll!_CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 214 + 0x11 bytes
ntdll.dll!774b9960()
有人知道为什么会发生这种情况吗? 谢谢
I just started with log4cxx by doing a small app to get familiar with it.
I compiled with Visual Studio 2005, no warnings or errors.
Basically looks like :
#includes<...>
...
...
LoggerPtr logger(Logger::getLogger("MyApp"));
void main(...)
{
//some logs here
}
It works as expected until I close the app when I get an exception while trying to destroy the global Logger object.
Here is the trace:
log4cxx.dll!apr_pool_cleanup_kill(apr_pool_t * p=0xdddddddd, const void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 1981 + 0x3 bytes
log4cxx.dll!apr_pool_cleanup_run(apr_pool_t * p=0xdddddddd, void * data=0x01cf6158, int (void *)* cleanup_fn=0x10174250) Line 2025
log4cxx.dll!apr_thread_mutex_destroy(apr_thread_mutex_t * mutex=0x01cf6158) Line 133
log4cxx.dll!log4cxx::helpers::Mutex::~Mutex() Line 57
log4cxx.dll!log4cxx::Logger::~Logger() Line 55 + 0xb bytes
log4cxx.dll!log4cxx::Logger::`vbase destructor'() + 0x19 bytes
log4cxx.dll!log4cxx::Logger::`vector deleting destructor'() + 0x5a bytes
log4cxx.dll!log4cxx::helpers::ObjectImpl::releaseRef() Line 46 + 0x39 bytes
log4cxx.dll!log4cxx::Logger::releaseRef() Line 63
log4cxx.dll!log4cxx::helpers::ObjectPtrT<log4cxx::Logger>::~ObjectPtrT<log4cxx::Logger>() Line 100 + 0x33 bytes
NodeBHeartBeat.exe!`dynamic atexit destructor for 'logger''() + 0x2b bytes
msvcr80d.dll!doexit(int code=0x00000000, int quick=0x00000000, int retcaller=0x00000001) Line 553
msvcr80d.dll!_cexit() Line 413 + 0xb bytes
msvcr80d.dll!__CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 389
msvcr80d.dll!_CRTDLL_INIT(void * hDllHandle=0x6c710000, unsigned long dwReason=0x00000000, void * lpreserved=0x00000001) Line 214 + 0x11 bytes
ntdll.dll!774b9960()
Anybody has any idea why is this happening ?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我通过简单地将“0”分配给记录器指针来解决这个问题。
这个魔术位于 log4cxx 源代码内的文件 src/main/include/log4cxx/helpers/objectptr.h 中
,即,releaseRef() 间接控制对象销毁顺序。
因此,对于您的代码,只需在末尾添加一行:
I managed to get around the problem by simply assigning "0" to the logger pointer.
The magic trick is located inside log4cxx source code in the file src/main/include/log4cxx/helpers/objectptr.h
That is, releaseRef() giving indirect control over object destruction order.
So, for your code, simply add a line at the end :
将 LoggerPtr 放入类中可以解决此问题,例如:
请注意,如果您将构造函数替换为成员函数(如
init()
),并调用init()
在 main 中的日志函数之前,它将导致段错误,正如您再次描述的那样。这是一个去初始化序列问题。
Putting your LoggerPtr inside of a class can resolve this issue, like:
Please note, if you replace constructor with a member function, like
init()
, and callinit()
in main before the log function, it will result segment fault as you described again.This is a deinitialization sequence issue.
我会在这里用我们遇到的类似案例来插话。我们引用的记录器未在 log4cxx 配置文件中定义。在该库的某些版本中,这很好,但在其他版本中,它会导致堆栈跟踪,如下所示:
因此,我们只需删除引用,一切都很好。这是一个看起来非常无伤大雅的声明:
I'll chime in here with a similar case we had. We were referencing a logger that was not defined in our log4cxx configuration file. In some version of the library this was fine, but in others it caused a stack trace as follows:
So we simply had to remove the reference and all was good. It was a very innocuous looking statement: