我一直在排查 Linux 上一个相当棘手的问题,即 JVM 似乎挂起了。作为调查的一部分,我一直在尝试使用其中一个“神奇”的 sysrq 命令来捕获当前任务及其状态的列表:
echo t > /proc/sysrq-trigger
令人惊讶的是,如果我在健康的系统上执行此操作,我会得到所有进程、它们的状态和当前调用堆栈的完整列表。当我在“不健康”的系统(即 JVM 不知何故挂起的系统)上执行此操作时,一些进程会丢失。例如,我的多线程 Java 应用程序的父进程根本没有被报告。这让我很难得出任何结论,因为我无法准确了解正在发生的事情。
有人知道在什么情况下可以将某个流程排除在报告之外吗?
谢谢!
答案1
JVM 是否因为尝试写入不再存在的进程而挂起?从查看 linux-source-2.6.38 代码可以看出,sysrq 触发器只调用:
/linux-source-2.6.38/include/linux/sched.h
283 /*
284 * Only dump TASK_* tasks. (0 for all tasks)
285 */
286 extern void show_state_filter(unsigned long state_filter);
287
288 static inline void show_state(void)
289 {
290 show_state_filter(0);
291 }
其中调用:
/linux-source-2.6.38/kernel/sched.c
5485 void show_state_filter(unsigned long state_filter)
5486 {
5487 struct task_struct *g, *p;
5488
5489 #if BITS_PER_LONG == 32
5490 printk(KERN_INFO
5491 " task PC stack pid father\n");
5492 #else
5493 printk(KERN_INFO
5494 " task PC stack pid father\n");
5495 #endif
5496 read_lock(&tasklist_lock);
5497 do_each_thread(g, p) {
5498 /*
5499 * reset the NMI-timeout, listing all files on a slow
5500 * console might take alot of time:
5501 */
5502 touch_nmi_watchdog();
5503 if (!state_filter || (p->state & state_filter))
5504 sched_show_task(p);
5505 } while_each_thread(g, p);
5506
5507 touch_all_softlockup_watchdogs();
5508
5509 #ifdef CONFIG_SCHED_DEBUG
5510 sysrq_sched_debug_show();
5511 #endif
5512 read_unlock(&tasklist_lock);
5513 /*
5514 * Only show locks if all tasks are dumped:
5515 */
5516 if (!state_filter)
5517 debug_show_all_locks();
5518 }
那里没有任何过滤器,所以它会打印出所有表明父级已消失的信息。您是否运行过 lsof 或 ps 并验证它是否仍在运行?