Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acl_last_serror()内存泄露?? #207

Open
bakurise opened this issue Jul 5, 2020 · 6 comments
Open

acl_last_serror()内存泄露?? #207

bakurise opened this issue Jul 5, 2020 · 6 comments

Comments

@bakurise
Copy link

@bakurise bakurise commented Jul 5, 2020

参考官方的socket示例,accept的acl::socket_stream新开的线程来处理read/write(std::thread启动的线程),然后socket异常了就close并delete掉acl::socket_stream,但是vs的报了内存泄露
---------- Block 5257 at 0x01AB21D8: 16 bytes ----------
Leak Hash: 0x7AD9E431, Count: 1, Total 16 bytes
Call Stack (TID 10812):
ntdll.dll!RtlAllocateHeap()
f:\dd\vctools\crt\crtw32\misc\dbgmalloc.c (56): testCode.exe!malloc() + 0x15 bytes
e:\othercode\acl\lib_acl\src\stdlib\memory\acl_default_malloc.c (230): testCode.exe!acl_default_malloc() + 0x8 bytes
e:\othercode\acl\lib_acl\src\thread\acl_pthread.c (440): testCode.exe!acl_pthread_setspecific() + 0x11 bytes
e:\othercode\acl\lib_acl\src\stdlib\acl_msg.c (578): testCode.exe!acl_last_serror() + 0xE bytes <-----
e:\othercode\acl\lib_acl\src\stdlib\acl_vstream.c (304): testCode.exe!sys_read() + 0x5 bytes
e:\othercode\acl\lib_acl\src\stdlib\acl_vstream.c (355): testCode.exe!read_to_buffer() + 0xE bytes
e:\othercode\acl\lib_acl\src\stdlib\acl_vstream.c (371): testCode.exe!read_buffed() + 0x14 bytes
e:\othercode\acl\lib_acl\src\stdlib\acl_vstream.c (963): testCode.exe!acl_vstream_readn() + 0x8 bytes
e:\othercode\acl\lib_acl_cpp\src\stream\istream.cpp (29): testCode.exe!acl::istream::read() + 0x1D bytes
e:\othercode\acl\lib_acl_cpp\src\stream\istream.cpp (101): testCode.exe!acl::istream::read() + 0x1A bytes
c:\users\dell\desktop\testcode\transforhandler.cpp (384): testCode.exe!CTransforHandler::threadTransforCallBack() + 0x13 bytes

发生在acl_last_serror()里面,绑定线程的缓冲区没有被释放:
if (acl_pthread_once(&once_control, thread_buf_init) != 0) <-----看代码这里面注册了释放方法
abort();

buf = acl_pthread_getspecific(__errbuf_key);
if (buf == NULL) {
	buf = acl_mymalloc(__buf_size);
	if (acl_pthread_setspecific(__errbuf_key, buf) != 0)
		abort();

#if !defined(HAVE_NO_ATEXIT)
if ((unsigned long) acl_pthread_self()
== acl_main_thread_self())
{
__main_buf = buf;
atexit(main_free_buf);
}
#endif
}

这里有一个疑问,为什么没有释放,难道针对server_socket的accept出来的acl::socket_stream指针,如果要开线程的话只能用acl的线程么?不能用std::thread ?

@bakurise
Copy link
Author

@bakurise bakurise commented Jul 5, 2020

如果不新开线程的话,调用了acl_last_serror()会是另外一个地方提示内存泄露。

---------- Block 3503 at 0x01C49ED8: 12 bytes ----------
Leak Hash: 0x718B3997, Count: 1, Total 12 bytes
Call Stack (TID 5196):
ntdll.dll!RtlAllocateHeap()
f:\dd\vctools\crt\crtw32\misc\dbgmalloc.c (56): testCode.exe!malloc() + 0x15 bytes
e:\othercode\acl\lib_acl\src\private\private_fifo.c (121): testCode.exe!private_fifo_push() + 0x7 bytes
e:\othercode\acl\lib_acl\src\thread\acl_pthread.c (443): testCode.exe!acl_pthread_setspecific() + 0xB bytes
e:\othercode\acl\lib_acl\src\stdlib\acl_msg.c (578): testCode.exe!acl_last_serror() + 0xE bytes

@zhengshuxin
Copy link
Member

@zhengshuxin zhengshuxin commented Jul 5, 2020

acl_last_serror() 内部用了线程局部变量,虽然针对主线程设定了退出释放过程,但有时可能会因为 atexit 中注册的函数未被调用等原因而未被释放,但这并没有问题,在子线程中创建的线程局部变量还是可以被释放的;另外,你创建线程时可以不用 acl 里提供的方法,完全可以用 std::thread。

@bakurise
Copy link
Author

@bakurise bakurise commented Jul 5, 2020

感谢您的详细解答,对于这个未被释放的情况,如果频繁新建线程来操作socket_stream对象的话,是否会存在比较严重的内存泄露问题?自动释放失败了在什么时机下可以手动释放呢? 谢谢大佬。

@zhengshuxin
Copy link
Member

@zhengshuxin zhengshuxin commented Jul 6, 2020

不会, acl_msg.c 的 acl_last_serror() 创建的存放在线程局部变量的内存在线程退出时会自动释放掉。

@bakurise
Copy link
Author

@bakurise bakurise commented Jul 6, 2020

那就奇怪了。不知为何我这里,监听了两个端口用了2个线程accept,共发生了6个tcp连接,新建了6个线程处理6个socket_stream*,连接关闭后也都close,最后vld报了24处内存泄露,全是acl_last_serror()产生的。

Visual Leak Detector detected 24 memory leaks (4252973 bytes).

我去调试一下代码吧,看看为何都没有调用到注册的free方法。

感谢您的耐心解答。

@zhengshuxin
Copy link
Member

@zhengshuxin zhengshuxin commented Jul 6, 2020

我写了一个c++11 thread 的例子:https://github.com/acl-dev/acl/tree/master/lib_acl_cpp/samples-c%2B%2B1x/thread , 里面通过调用 acl::last_serror() 来调用 c 库中的 acl_last_serror(),然后在 lib_acl/src/stdlib/acl_msg.c 中的 thread_free_buf() 函数中输出当线程退出时释放的存放在线程局部变量的内存,显示是可以正常释放的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.