【发布时间】:2014-03-02 13:24:32
【问题描述】:
需要明确的是,这是一个 upstart/linux 调试问题,而不是 java 问题本身。
我有一个安装了shutdownhook 的java 应用程序。它在 ubuntu-GNOME 中显示了一些有趣的行为,即如果安排了重新启动或关闭电源,则关闭挂钩永远不会运行。起初我认为这是我的关闭挂钩的问题,所以我简化了它,直到它只向文件写入一行(是的,我知道关闭挂钩的 log4j2 记录器问题,所以我也禁用了他们的)。然后当这不起作用时,我开始破解 /etc/init/sendsigs
我在 do_stop 函数的开头添加了这个:
app="$(jps | grep appname.jar | cut -d' ' -f1)"
echo "$app" >> "/home/i30817/output.txt"
果然,这表明它不再运行,因此 sendigs 从未激活关闭挂钩 然后我使用 here 的 lastcomm 将我对 sendigs 的编辑替换为:
echo `/home/i30817/lastcomm` > "/home/i30817/output.txt"
它告诉我java进程以1退出并且没有发出信号:
java X i30817 ?? 10.26 secs Sun Mar 2 12:44 E 1
但这仍然没有帮助我找到真正杀死它的原因以及原因。使用较小的示例无法重现此问题,因此它可能是较大的应用程序中的某些东西(但不是关闭挂钩,因为它已被最小化)不喜欢关闭过程并设法杀死该过程,但我不能弄清楚...将进程输出重定向到文件也没有说什么,例如:
java -jar /home/i30817/Documents/projects/app/dist/app.jar > allout.text 2>&1
除了正常的应用程序输出外,什么都没有 你能帮我弄清楚这个吗?关于同一件事也有很多重复的问题(但他们认为这是关闭挂钩出现故障)。
编辑:更详细,现在我更好地理解了这个问题。我认为现在在 sendigs 上没有进程是正常的。 Java 应用程序,可能还有其他应用程序使用来自窗口管理器的协议,其中 SIGHUP、SIGHUP 和 SIGCONT 在关机/注销时发送。 JVM 挂钩 SIGHUP 以启动关闭挂钩。我用一个非常小的例子测试了这个,它只添加了一个shutdownhook并且在main上有一个无限循环,并在后台使用system tap script运行它:
java -jar app.jar
在另一个shell中
sudo stap -o process.txt sigkill.stp
但是,当我尝试使用我的应用程序时,我认为我找到了罪魁祸首:
PROCESS: SIGSEGV java.signal_generate sent to java 2280
但考虑到没有线程转储或任何东西,我真的不知道该怎么做,而且重现起来很奇怪(仅我的应用程序,仅在关闭期间)。
edit2:现在我怀疑在没有核心转储的情况下“突然”终止的原因是关机期间的 ulimit。因此,我正在尝试解决该问题以准备错误报告。我编辑了 /etc/security/limits.conf 以添加它并重新启动
* soft core unlimited
root hard core unlimited
* hard rss 10000
(fs.suid_dumpable=2 是由 ubuntu 设置的,我认为没有 apparmor) 但是在关机期间,我再次编辑 /etc/init.d/sendsigs 以打印 ulimit -a 并在终止进程之前休眠 30 秒,并且似乎在重新启动期间 ulimit 再次重置?此外,它具有不同的输出,就像它使用另一个可执行版本一样,例如,它没有说“核心文件大小”,而是使用“核心(转储)”或类似的东西)。
edit3:啊,我需要改用 fs.suid_dumpable=1 - 现在就试试。 也许 init ulimit 对于关闭核心转储触发无关紧要。毕竟 jvm 是从用户 env 执行的,所以它应该使用用户 ulimit。
edit4:嗯。在对代码进行大量评论后,我得出了以下结论,我可以从 RTFM 中得出:
sigsegv 是无害的。
非零退出码不是。
如果 AWT 仍处于启动状态,则信号始终为非零且关闭挂钩永远不会运行。如果 JFrame 已启动(与 Windows 不同,它们将在其中启动),即使是一个小示例仍会阻止在 linux 重新启动时执行关闭挂钩。查看源代码,应用程序关闭挂钩是在插槽 1 上自行运行的。我敢打赌,插槽 '0' 是 AWT,它会以某种方式停止系统。
我想是时候检查包私有信号处理库了,看看我是否可以在 JVM 决定终止所有内容之前获得 SIGHUP,甚至没有机会运行清理代码。
【问题讨论】:
-
您有不同应用程序的来源吗?如果我有这个问题,我会设置 eclipse 来调试服务器端设置断点。我提到这一点是因为您发现 java 进程没有发出信号。
-
没有不同的应用程序,这都是一个客户端摇摆应用程序。我实际上是通过安排重启来测试这个。我确实有它的来源。
-
@D-Klotz 我在这里发布了一个示例:stackoverflow.com/questions/22262190/…
标签: java linux process shutdown coredump