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 服务崩溃的主要内容,如果未能解决你的问题,请参考以下文章