daisy
daisy

Reputation: 23501

Can't run jstack if tomcat is running as root user

I'm running jdk1.8.0_161 + apache-tomcat-8.0.11 on CentOS 7.

If I start tomcat as root account, I can't run jstack against it:

# jstack -l 1451
<It stuck, but tomcat has output in catalina.out>

# jstack -l 1451 -F
Attaching to core -F from executable 1451, please wait...
Error attaching to core file: cannot open binary file
sun.jvm.hotspot.debugger.DebuggerException: cannot open binary file
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach0(Native Method)
    at sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal.attach(LinuxDebuggerLocal.java:286)
    at sun.jvm.hotspot.HotSpotAgent.attachDebugger(HotSpotAgent.java:673)
    at sun.jvm.hotspot.HotSpotAgent.setupDebuggerLinux(HotSpotAgent.java:611)
    at sun.jvm.hotspot.HotSpotAgent.setupDebugger(HotSpotAgent.java:337)
    at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:304)
    at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:156)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:191)
    at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
    at sun.jvm.hotspot.tools.JStack.main(JStack.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.tools.jstack.JStack.runJStackTool(JStack.java:140)
    at sun.tools.jstack.JStack.main(JStack.java:106)

If I run tomcat as a non-root user, jstack works normally.

I tried to google for "sun.jvm.hotspot.debugger.DebuggerException: cannot open binary file" but didn't find anything helpful.

Does someone know what's happening?

Upvotes: 0

Views: 710

Answers (1)

Mike Slinn
Mike Slinn

Reputation: 8403

From the jstack man page:

The PATH environment variable needs to contain the location of the jvm.dll that is used by the
target process, or the location from which the crash dump file was produced. For example:

set PATH=<jdk>\jre\bin\client;%PATH%

When running as root, set the PATH appropriately. Note: by default, sudo does not inherit the caller's environment variables. You might do something like this:

$ sudo PATH=/path/to/jre/bin/whatever;$PATH jstack -l pid

You could also invoke sudo with the -E option to preserve environment variables:

$ sudo -E jstack -l pid

man sudo has more information.

Upvotes: 1

Related Questions