应用程序崩溃时未删除 Unix 域套接字文件
Posted
技术标签:
【中文标题】应用程序崩溃时未删除 Unix 域套接字文件【英文标题】:Unix domain socket file not removed on application crash 【发布时间】:2017-03-02 12:21:36 【问题描述】:我有一个 Linux C++ 应用程序,它通过 Unix 域套接字生成并与另一个进程交互。这个新进程基本上只是在任务栏中显示当前正在运行的进程的图标,并在图标中显示一些菜单项。
问题: 当主应用程序正常关闭时,UDS 文件将被删除。 但是在应用程序崩溃的情况下,这个 UDS 文件不会被删除并且会一直存在。
有什么方法可以在应用程序崩溃时通过编码删除 UDS 文件?
【问题讨论】:
1.信号处理程序,2. 编写不会崩溃的更好的代码。 Richard Hodges:信号处理程序不会捕获应用程序崩溃或 SIGKILL 您有什么理由在一个明确的 C++ 问题上向无关语言 C 的标签发送垃圾邮件? @saras_ankit 在这种情况下,你会被困在编写不会崩溃的代码上。检查您的错误情况,抛出错误异常并使用 RAII 自动关闭套接字并删除文件! c++ 101. @Olaf 我没有在问题中使用 C 标签 【参考方案1】:有没有什么方法可以在应用程序崩溃时通过编码删除UDS文件?
是的。几种方法取决于您是否可以使用潜在的不可移植功能。
使用单独的流程:
使用单独的进程来监控您的应用程序;也许您为此目的编写了一个。当此监控进程检测到您的应用程序已结束时,它会检查 Unix 域套接字文件。如果找到,它会删除它。然后它会重新启动应用程序(如果需要)。
使用“抽象套接字”:
我相信你也可以使用“抽象套接字”,虽然我自己没有尝试过。
在线linux manual page for the Unix domain socket 描述了一个名为“抽象套接字”的扩展。它解释说:“当所有对套接字的打开引用都关闭时,抽象套接字会自动消失。”。
使用“紧随其后的语义”:
基于 Linux 的Unix domain socket manual page 注释部分声称:“应用通常的 UNIX 后置语义;套接字可以随时取消链接,并在对它的最后一次引用关闭时最终从文件系统中删除”。 IE。调用bind
创建套接字,等待客户端连接,然后调用unlink
套接字,然后执行可能崩溃的代码。但是,一旦从目录条目中删除了套接字,新的客户端连接尝试就会失败。
使用潜在的解决方法
在调用bind
之前,在您的套接字上使用SO_REUSEADDR
。这可能允许应用程序重新启动而无需删除套接字。我不知道这种行为对于 Unix 套接字是否定义得很好。它可以在一个平台上运行,但在另一个平台上不行。
问题:当主应用程序正常关闭时,UDS 文件会被删除。但在应用程序崩溃的情况下,此 UDS 文件不会被删除并且会一直存在。
处理 Unix 域套接字文件(它的可移植/标准版本)的另一种方法是在创建应用程序之前删除应用程序中的套接字文件。因此,在您的应用程序调用bind
之前,它将使用unlink
。只要它是创建此文件的唯一过程,事情就应该是合乎情理的。避免比赛。
请注意,如果您的应用程序以更高的权限运行(例如,使用 set-user-ID 功能以 root 身份运行),使用 unlink
可能会打开一个潜在的安全漏洞。然后确保用户不能告诉应用程序使用什么路径用于套接字,并且用户不能修改套接字所在的目录。否则,用户可以告诉应用程序套接字的完整路径类似于 /etc/passwd
并运行它以删除该文件,即使他们自己的用户没有权限这样做。
这种潜在的损害当然可以通过使用最低权限帐户来获得 set-user-ID 权限或同时避免 set-user-ID 等方式来减轻。另一种缓解措施是不允许用户指示应用程序为其套接字使用什么路径 - 可能只使用用户对其任何目录都没有写入权限的硬编码路径名。
【讨论】:
嗨,我在哪里可以找到套接字文件?【参考方案2】:不确定这是否有帮助,但您可以检测和孤立的 unix 套接字。
您可以尝试在启动时锁定文件或套接字。如果锁定成功,则意味着套接字是孤立的并且可以被删除。这是因为当进程因任何原因终止时,操作系统会释放文件锁。
或者,bind
到那个 unix 套接字。 bind
仅在未使用套接字名称时成功。
【讨论】:
“或者,绑定到该 unix 套接字。仅当套接字名称未使用时,绑定才会成功” - 问题是,如果套接字名称存在但已过时(即从死/崩溃的过程)。您不能使用它来判断套接字是否处于活动状态。做到这一点的唯一方法是尝试连接到它,但这很有趣。以上是关于应用程序崩溃时未删除 Unix 域套接字文件的主要内容,如果未能解决你的问题,请参考以下文章
Nginx 无法使用 Unicorn 找到 unix 套接字文件