我有一个用 c++ 编写的服务器,在 osx 上运行时会泄漏 Mach 端口。具体来说,当运行top
时,我注意到它有大约 50000(低于 #PORTS
(。奇怪的是,我让它在一夜之间运行,第二天机器基本上死了(花了 15 分钟来响应 ctrl-c,不接受新的 ssh 连接(,所以 IT 不得不重新启动它。这样的泄漏会像这样导致系统瘫痪吗?它没有以根身份运行。
无论如何,寻找这种泄漏原因有哪些好的策略?有什么好的工具吗?
我发现一个测试在运行时可靠地泄漏 5 个端口,但仅此而已。
编辑:我发现我们的线程类会产生马赫端口泄漏,但我不明白为什么。在构造函数中,我们有以下代码:
// Initialize the default attributes.
if (0 != pthread_attr_init(&m_threadAttributes))
{
throw "blah";
}
// Set the thread to be joinable.
if (0 != pthread_attr_setdetachstate(&m_threadAttributes, PTHREAD_CREATE_JOINABLE))
{
pthread_attr_destroy(&m_threadAttributes);
throw "blah";
}
if (0 != pthread_create(
&m_thread,
&m_threadAttributes,
&StartThreadFunction,
reinterpret_cast<void*>(this)))
{
throw "blah";
}
我注意到在调用 pthread_create
后,进程的端口计数增加了 1,这是意料之中的。
然后,稍后我使用以下代码加入线程:
if (0 != pthread_join(m_thread, NULL))
{
throw "blah";
}
并且没有抛出异常,所以我只能假设pthread_join
返回 0 并因此成功,但顶部端口的 # 不会下降。我还需要做什么来清理线程吗?
可以使用 Dtrace 来检测正在运行的系统上的 mach 端口使用情况。有许多与mach_port相关的探针:
sudo dtrace -l | grep mach_port
您可以编写一个 Dtrace 脚本来跟踪每个端口的创建或保留调用是否由相应的版本进行平衡。用于跟踪内存泄漏的 Dtrace 脚本将是一个有用的起点。
一旦您有了适合您目的的脚本,您就可以使用 Instruments 来控制跟踪会话并绘制结果图。