jstack - 众所周知的文件不安全

时间:2012-02-01 17:14:12

标签: java jvm jstack

我使用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

要获得任何合理的输出,我需要使用强制选项:

[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 个答案:

答案 0 :(得分:31)

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

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

答案 1 :(得分:23)

使用-F时, jvm 冻结

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

如果$USER没有登录shell(即守护程序用户),因此无法切换到该用户,则可以使用sudo -u $USER jstack $PID

解决此问题

答案 2 :(得分:6)

当我尝试将jstack作为root运行时,我遇到了这个问题。

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

答案 3 :(得分:3)

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

jstack -J-Djava.io.tmpdir=PATH -l PID

答案 4 :(得分:1)

我遇到了同样的错误:

watch -n .5 "jstack 26259"

以sudo的方式工作:

sudo watch -n .5 "jstack 26259"

答案 5 :(得分:1)

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

std::map<uint32_t, uint32_t> items;
std::vector<uint32_t> itemKeys;
for (auto & kvp : items)
{
    itemKeys.emplace_back(kvp.first);
    std::cout << kvp.first << std::endl;
}

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

kill -s SIGQUIT $PID

答案 6 :(得分:1)

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

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

sudo -u java-user jstack -l <pid> 

答案 7 :(得分: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

答案 8 :(得分:0)

可能最简单的方法是:

通过以下方式查看流程所有者  ps -ef | grep“进程名称”

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

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

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

除了以相同的用户身份运行外,请确保运行jstack / jmap的用户的组标识也与进程相同。

看看source code that checks for file permission(第347行)。我们可以看到,获取组ID的函数不是数组,因此用户可能有其他组,从而启动了该过程。

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

#usermod -g group -G user user