49

我正在使用 32 位 Oracle Java 1.6.0 在 x86_64 CentOS 5.7 上运行 tomcat 5.5。

tomcat 使用的 JVM 进程有 6421 pid。Tomcat 工作正常。

运行jstack时失败:

[root@mybox ~]# jstack 6421
6421: well-known file is not secure

为了获得任何合理的输出,我需要使用 force 选项:

[root@mybox ~]# jstack -F 6421
Attaching to process ID 6421, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 17.0-b16
Deadlock Detection:

No deadlocks found.
(...)

问题是:

  1. 错误消息“知名文件不安全”是什么意思?
  2. 什么是“知名”文件?
  3. 为什么/何时该jstack命令在没有强制选项的情况下不起作用?

提前致谢。

4

11 回答 11

37

这可能是由于 /tmp 中用于与进程通信的文件具有与jstack获得的权限不同的权限。有问题的文件是 /tmp/hsperfdata_$USER/$PID。

不知道为什么它与 -F 一起使用,因为手册页只是说“当 'jstack [-l] pid' 没有响应时强制堆栈转储。”

于 2012-02-01T17:46:39.910 回答
25

使用时-Fjvm将被冻结

如果你能找到file: /tmp/hsperfdata_$USER/$PID. 只需尝试切换到$USER,然后exec jstack。您正在使用“ root ”运行,但该进程可能不属于 root。

如果$USER没有登录外壳(即守护程序用户),因此无法切换到该用户,您可以通过使用解决此问题sudo -u $USER jstack $PID

于 2012-04-17T09:15:18.143 回答
7

当我尝试jstackroot.

一旦我切换到另一个用户,它就会立即工作。

于 2016-06-16T11:52:54.620 回答
3

我只想补充一点,您可能需要通过 -J 选项指定 /tmp 目录,因为并非所有应用程序都使用默认目录

jstack -J-Djava.io.tmpdir=PATH -l PID
于 2013-05-14T01:27:10.970 回答
1

我在运行时遇到了同样的错误:

watch -n .5 "jstack 26259"

像 sudo 一样工作:

sudo watch -n .5 "jstack 26259"
于 2015-05-15T20:55:10.787 回答
1

如果您不想担心用户并且可以以 root 身份工作并且可以终止该进程,则可以使用最后的手段:

kill -s SIGQUIT $PID

这会将线程转储写入您的控制台日志,例如,在 Tomcat 的情况下,这将需要对“全线程”进行 grepping,这是 logs/catalina.out 中线程转储的开始,然后将 tdump 文件获取为:

DUMP_IDX=`grep -n 'Full thread' logs/catalina.out | tail -1 | cut -d':' -f1`
sed -n $DUMP_IDX,1000000000000000000p logs/catalina.out > jstack-kill-thread-dump-0309.tdump
于 2016-03-10T01:07:00.250 回答
1

您需要以拥有 java 进程的用户身份运行 jstack 命令:

例如,如果您的 java 应用程序由名为的用户拥有java-user

sudo -u java-user jstack -l <pid> 
于 2021-04-15T16:25:55.603 回答
0

这是我用来确保我始终使用正确的用户权限的一种方法:

proc="my-process-name"; pid=`pgrep -f "${proc}"`; sudo -u "#`ps axo uid,pid | grep "${pid}" | tr -s " " | cut -f2 -d" "`" /usr/bin/jstack -l "${pid}" > /mnt/dumps/"${proc}"-`date +%s`.txt
于 2017-09-19T12:17:10.057 回答
0

可能最简单的方法是:

通过 ps -ef 查看进程的所有者 | grep "进程名称"

然后切换到该用户并运行命令。

jcmd PID GC.run 或任何其他 java 实用程序

我注意到这里没有人讨论的一件事是;您还需要设置 JAVA_HOME 变量。通过 echo $JAVA_HOME 检查这个

于 2017-10-13T14:49:27.400 回答
0

要成功使用 jstack,您应该使用与进程相同的用户来运行它。

于 2018-04-02T03:53:44.407 回答
0

除了使用同一个用户运行外,还要确保运行 jstack/jmap 的用户的组 id 与进程中的相同。

查看检查文件权限的源代码(第 347 行)。我们可以看到获取组 id 的函数不是数组,因此用户可能有其他组,从而启动了该过程。

您可能必须更改用户的主要组:

#usermod -g group -G user user

于 2018-07-25T18:25:22.257 回答