Linux 服务崩溃

Posted

技术标签:

【中文标题】Linux 服务崩溃【英文标题】:Linux service crashes 【发布时间】:2011-12-10 01:41:06 【问题描述】:

我有一个 linux 服务(c++,有很多可加载的模块,基本上是在运行时拾取的 .so 文件),它不时崩溃......我想了解这个崩溃并调查它,但是在那一刻我不知道如何进行。所以,我想问你以下问题:

    如果 linux 服务崩溃,“核心”文件是在哪里创建的?我已经设置了ulimit -c 102400,这应该足够了,但是我在任何地方都找不到核心文件:(。 是否有任何跟踪服务的 linux 日志?服务自己的日志显然并没有告诉我我现在会崩溃...... 可能是其中一个模块崩溃了……但是我不知道是哪一个。我什至不知道加载了哪些模块。你知道如何在 linux 中显示服务正在使用哪些模块吗? 在调试 linux 服务时您可能有任何其他提示?

谢谢 f-

【问题讨论】:

看看 strace。它将能够告诉您正在加载哪些模块。最简单的方法是集成到init脚本中并重定向到一个日志文件 【参考方案1】:

在 Linux 下,出于安全原因,切换用户 ID 的进程会禁用其核心文件。这是因为他们经常做诸如读取特权文件(想想 /etc/shadow)之类的事情,而核心文件可能包含敏感信息。

要在已切换用户 ID 的进程上启用核心转储,您可以将 prctl 与 PR_SET_DUMPABLE 结合使用。

核心文件通常转储在当前工作目录中 - 如果当前用户不可写,那么它将失败。确保进程的当前工作目录是可写的。

【讨论】:

【参考方案2】:

0) 获得一个尽可能模拟生产的暂存环境。在那里重现问题。

1) 您可以使用gdb -a 附加到正在运行的进程(当然需要调试版本)

2) 确保 ulimit 是您认为的那样(将 ulimit 从 shell 脚本输出到文件 它在启动之前运行您的服务)。通常需要在 /etc/profile 文件中设置 ulimit;将其设置为ulimit -c 0 无限

3) 使用find / -name \*core\* -print 或类似方法查找核心文件

4) 我认为 gdb 会在您附加到进程时为您提供已加载共享对象 (.so) 的列表。

5) 为您的服务添加更多日志记录

祝你好运!

【讨论】:

谢谢 :) 我认为我无法将调试器附加到它。如果服务出现故障,该服务会自动重新启动,我将不得不进行一些努力以允许我在该机器上进行调试(即保持服务关闭)。我将更新 ulimit。 :) 您实际上并不需要调试版本。 gdb --pid 也不错 @sehe 好吧,是的,您可以附加无调试版本,甚至在崩溃时获取堆栈跟踪。 @MK: 或者...查看加载了哪些模块(info shared,IIRC)【参考方案3】:

您的首要任务应该是获取核心文件。看看this answer 是否适用。

其次,你应该在 Valgrind 下运行你的服务器,并修复它发现的任何错误。

在 GDB 下运行时重现崩溃是可能的(正如 MK 建议的那样),但有点不太可能:当您寻找它们时,错误往往会隐藏起来,并且调试器可能会影响时间(特别是如果您的服务器是多线程的)。

【讨论】:

以上是关于Linux 服务崩溃的主要内容,如果未能解决你的问题,请参考以下文章

linux程序崩溃自动重启

当一台linux服务器崩溃之后怎么迅速用另一台服务器顶上

如何配置Linux的服务设置为自动启动或崩溃重新启动后

Linux系统崩溃,数据迁移

当我尝试在远程 Linux 节点上更改 Eclipse 中的设置时,X 服务器崩溃

R 并行中的 Linux 服务器崩溃 - 反序列化错误(node$con):从连接读取错误