卸载ACE动态库导致句柄泄漏问题
来源:互联网 发布:淘宝上的人参 编辑:程序博客网 时间:2024/06/11 18:29
ACE动态库在windows程序中通过LoadLibrary和FreeLibrary反复加载和卸载后,发现内存和句柄上涨严重,查看动态库的dllmain函数,发现未调用到ace初始化方法ACE::init(),因此加载动态库后,显式调用init,卸载前显式fini,内存和句柄果然就没有涨了,但出现了一个新问题,在加载到500多次以后,出现了动态库文件无法打开错误,通过更新ACE最新的6.2.0版本的库,发现问题依然存在!
前面成功的500多次加载和卸载ace库,都未看到句柄或者内存泄露现象,突然出现不能加载,问题开始有点难以理解了。
查看ace初始化函数的实现代码,包含了对对象管理器单例对象的初始化操作:
intACE::init (void){ // Don't use ACE_TRACE, because Object_Manager might not have been // instantiated yet. // ACE_TRACE ("ACE::init"); ++ACE::init_fini_count_; return ACE_Object_Manager::instance ()->init ();}
到ACE_Object_Manager::init里注释代码,也未果;由于每次都是在500多次加载后失败,因此尝试init后不调用fini,果然到100多次后问题就出现了,看来还是和资源未释放完全相关的。在退出函数fini里注释代码,希望能定位到影响问题出现概率的那行代码从而找到相关的资源信息,把fini函数如下代码注释后,问题概率加大:
// Close the main thread's TSS, including its Log_Msg instance. ACE_OS::cleanup_tss (1 /* main thread */);
很快可以想到是tss资源泄漏了,通过在tss资源申请的系统函数TlsAlloc里增加断点,定位到资源申请的位置:
ACEd.dll!ACE_OS::thr_keycreate_native(unsigned long * key=0x00ab6220, void (void *)* dest=0x00000000) Line 4791C++ ACEd.dll!ACE_OS::thr_keycreate(unsigned long * key=0x00ab6220, void (void *)* dest=0x00000000) Line 4835 + 0xd bytesC++ ACEd.dll!ACE_Thread::keycreate(unsigned long * keyp=0x00ab6220, void (void *)* destructor=0x00000000) Line 23 + 0xd bytesC++ ACEd.dll!ACE_Threading_Helper<ACE_Thread_Mutex>::ACE_Threading_Helper<ACE_Thread_Mutex>() Line 43 + 0xb bytesC++ ACEd.dll!ACE_Service_Config::ACE_Service_Config(bool ignore_static_svcs=true, unsigned int size=1024, int signum=0) Line 372 + 0x6d bytesC++>ACEd.dll!ACE_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::ACE_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>() Line 15C++ ACEd.dll!ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>() Line 19 + 0x16 bytesC++ ACEd.dll!ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::instance() Line 184 + 0x27 bytesC++ ACEd.dll!ACE_Service_Config::singleton() Line 327C++ ACEd.dll!ACE_Service_Config::current() Line 424 + 0x5 bytesC++ ACEd.dll!ACE_Service_Config::instance() Line 87C++ ACEd.dll!ACE_Service_Config::insert(ACE_Static_Svc_Descriptor * stsd=0x102609bc) Line 332 + 0x9 bytesC++ ACEd.dll!ACE_Static_Svc_ACE_Naming_Context::ACE_Static_Svc_ACE_Naming_Context() Line 650 + 0x18 bytesC++ ACEd.dll!`dynamic initializer for 'ace_static_svc_ACE_Naming_Context''() Line 650 + 0xd bytesC++
以及:
ACEd.dll!ACE_OS::thr_keycreate_native(unsigned long * key=0x00ab9648, void (void *)* dest=0x1000b2ad) Line 4791C++ ACEd.dll!ACE_OS::thr_keycreate(unsigned long * key=0x00ab9648, void (void *)* dest=0x1000b2ad) Line 4835 + 0xd bytesC++>ACEd.dll!ACE_TSS_Cleanup::tss_keys() Line 993 + 0x14 bytesC++ ACEd.dll!ACE_TSS_Cleanup::thread_use_key(unsigned long key=7) Line 941 + 0xc bytesC++ ACEd.dll!ACE_OS::thr_setspecific(unsigned long key=7, void * data=0x00ab9688) Line 5049C++ ACEd.dll!ACE_Thread::setspecific(unsigned long key=7, void * value=0x00ab9688) Line 42 + 0xd bytesC++ ACEd.dll!ACE_Threading_Helper<ACE_Thread_Mutex>::set(void * p=0x00ab9688) Line 54 + 0xf bytesC++ ACEd.dll!ACE_Service_Config::ACE_Service_Config(bool ignore_static_svcs=true, unsigned int size=1024, int signum=0) Line 386C++ ACEd.dll!ACE_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::ACE_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>() Line 15C++ ACEd.dll!ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>() Line 19 + 0x16 bytesC++ ACEd.dll!ACE_Unmanaged_Singleton<ACE_Service_Config,ACE_Recursive_Thread_Mutex>::instance() Line 184 + 0x27 bytesC++ ACEd.dll!ACE_Service_Config::singleton() Line 327C++ ACEd.dll!ACE_Service_Config::current() Line 424 + 0x5 bytesC++ ACEd.dll!ACE_Service_Config::instance() Line 87C++ ACEd.dll!ACE_Service_Config::insert(ACE_Static_Svc_Descriptor * stsd=0x102609bc) Line 332 + 0x9 bytesC++ ACEd.dll!ACE_Static_Svc_ACE_Naming_Context::ACE_Static_Svc_ACE_Naming_Context() Line 650 + 0x18 bytesC++ ACEd.dll!`dynamic initializer for 'ace_static_svc_ACE_Naming_Context''() Line 650 + 0xd bytesC++ msvcr90d.dll!0045c02c()
通过观察,发现第二次申请的tss资源在fini函数调用后并没有释放掉,导致tss资源出现了泄漏,申请代码如下:
ACE_TSS_Keys *ACE_TSS_Cleanup::tss_keys (){ if (this->in_use_ == ACE_OS::NULL_key) { ACE_TSS_CLEANUP_GUARD // Double-check; if (in_use_ == ACE_OS::NULL_key) { // Initialize in_use_ with a new key. if (ACE_OS::thr_keycreate (&in_use_, &ACE_TSS_Cleanup_keys_destroyer)) { ACE_ASSERT (false); return 0; // Major problems, this should *never* happen! } } }
因此,一个解决的办法就是在Cleanup的析构函数中,将in_use_对应的tss资源释放:
ACE_TSS_Cleanup::~ACE_TSS_Cleanup (void){ free_key(in_use_); in_use_ = 0;}
重新编译ACE库后,经过长时间测试问题不再出现!
0 0
- 卸载ACE动态库导致句柄泄漏问题
- system调用导致子进程socket句柄泄漏问题分析
- Android异常一、异步任务导致的窗口句柄泄漏问题(内存泄漏)
- Android异常一、异步任务导致的窗口句柄泄漏问题
- android异常——异步任务导致的窗口句柄泄漏问题
- 警惕动态代理导致的Metaspace内存泄漏问题
- 一个ACE内存泄漏的问题
- ACE版本问题导致编译问题
- zookeeper的句柄fd泄漏问题
- Toast导致Activity内存泄漏问题
- 常见的导致Android内存泄漏问题
- RecyclerView导致内存泄漏问题分析
- danga.memcached2.0.1存在nio管道句柄泄漏问题
- 多线程程序退出内存句柄泄漏的问题以及解决方法
- CreateToolhelp32Snapshot句柄泄漏(内存泄漏)
- 频繁通过win32api的createfile函数打开文件句柄导致内存泄漏
- 卸载detailedreview后导致的问题
- 关于静态链接导致ACE未初始化的问题
- Java实现多线程的方法
- SPOJ LCS2 1812. Longest Common Substring II
- hdu2146
- memcached日志
- setInterval和setTimeout
- 卸载ACE动态库导致句柄泄漏问题
- mygui初探(二)皮肤编辑器
- C语言中的static 详细分析
- httpclient的一些学习心得
- 从头学算法之-分治法-快速排序
- hadoop 2.4.1 部署--1 编译安装
- PHP 回文数算法
- js的output输出浮层
- You don't have permission to access / on this server.