无法使用 jhat、jps、jstack 调试 Java Windows 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1197912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can't debug Java Windows Services with jhat, jps, jstack
提问by Matthew McCullough
I frequently showcase the jhat, jps, and jstack tool set to developers on Linux and Mac. However, a developer recently indicated that these are unusable in Windows if the Java app in question is running as a Windows Service.
我经常向 Linux 和 Mac 上的开发人员展示 jhat、jps和 jstack 工具集。但是,一位开发人员最近表示,如果有问题的 Java 应用程序作为Windows 服务运行,则这些在 Windows 中将无法使用。
A Sun-filed bug says something very similar, but was closed due to inactivity.
一个Sun 提交的错误说的非常相似,但由于不活动而被关闭。
I have tested this out for myself, and indeed it appears true, though I can hardly believe it. Here is the setup:
我已经亲自测试了这一点,确实看起来是真的,尽管我几乎不敢相信。这是设置:
- Tomcat or similar running as a Windows service with the "Log On As" == "Local System"
- A user with Admin privileges logged in to the same Windows machine.
- Admin opens Windows Task Manager, can see java.exe running
- Admin opens console, types "jps", gets back a list of processes that does not include Tomcat's java service process.
- As a brute force attempt, get the PID of tomcat as a service from Windows Task Manager. Type jstack < pid >. Get a reply: < pid > no such process
- 作为 Windows 服务运行的 Tomcat 或类似服务,“登录身份”==“本地系统”
- 具有管理员权限的用户登录到同一台 Windows 计算机。
- Admin打开Windows任务管理器,可以看到java.exe正在运行
- 管理员打开控制台,输入“jps”,得到一个不包含 Tomcat 的 java 服务进程的进程列表。
- 作为蛮力尝试,从 Windows 任务管理器获取 tomcat 的 PID 作为服务。输入 jstack <pid>。得到回复:<pid>没有这个进程
This appears reproducible under Windows XP, Windows 2003 Server, and Windows 7. Java versions 1.5 and 1.6 yield the same outcome.
这在 Windows XP、Windows 2003 Server 和 Windows 7 下似乎可以重现。Java 版本 1.5 和 1.6 产生相同的结果。
Is there a way from the terminal, even though logged in as Admin, to "sudo up" to get JPS and the other tools to see the java service?
即使以管理员身份登录,终端是否也可以通过“sudo up”获取 JPS 和其他工具来查看 Java 服务?
回答by Rob Tanzola
To get the utilities to run, you can connect to the Console session using "mstsc /admin" using a login account (not sure exact permissions it needs to have, mine was in the Administrators group) and use the Sysinternals psexec tool to run as system. Here is an example of using jstack.exe:
要使实用程序运行,您可以使用登录帐户(不确定它需要具有的确切权限,我在管理员组中)使用“mstsc /admin”连接到控制台会话,并使用 Sysinternals psexec 工具作为系统。下面是一个使用 jstack.exe 的例子:
psexec -s "%JAVA_HOME%\bin\jstack.exe" PID >stack.txt
其中 PID 是您的进程的进程 ID。您可能还需要根据您的特定环境替换 JDK 的实际路径。Also, the TEMP directory must be set correctlyor once again the tools will not work.
此外,必须正确设置 TEMP 目录,否则工具将再次不起作用。
回答by Devon_C_Miller
I've had luck debugging processes run by the SYSTEM user by running this from a command prompt:
通过从命令提示符运行它,我很幸运地调试了由 SYSTEM 用户运行的进程:
c:> time/t
11:18 AM
c:> at 11:19 /interactive cmd.exe
Added a new job with job ID = 1
Use a time 1 minute in the future. When the "at" job runs a windows command prompt will open running as the user SYSTEM. From there you should be able to see the java processes.
使用未来 1 分钟的时间。当“at”作业运行时,Windows 命令提示符将打开,以用户 SYSTEM 身份运行。从那里您应该能够看到 java 进程。
If the service is running as a local user (check the details from "mmc %windir%\system32\SERVICES.MSC" by double clicking on the service and selecting the "Log On" tab) you can do the same thing using "runas":
如果服务以本地用户身份运行(通过双击服务并选择“登录”选项卡,从“mmc %windir%\system32\SERVICES.MSC”中查看详细信息),您可以使用“runas”执行相同的操作”:
runas /user:USERNAME cmd.exe
回答by marabol
I've only found a suggest to run visuamvm (or other tools) as windows service: Monitoring Java Processes Running As a Windows Service
我只发现了将 visuamvm(或其他工具)作为 Windows 服务运行的建议:Monitoring Java Processes Running As a Windows Service
Perhaps someone else knows a better solution.
也许其他人知道更好的解决方案。
回答by Thorbj?rn Ravn Andersen
You only get those processes that "belong" to you - same user id.
您只会获得那些“属于”您的进程 - 相同的用户 ID。
Can you connect to it with jvisualvm?
你可以用 jvisualvm 连接到它吗?
回答by jim birch
This is my batch file to record a thread dump
这是我记录线程转储的批处理文件
:: Creates a thread dump for the tomcat6.exe process saved in a timestamped filename and views it!
:: Jim Birch 20111128 rev 2015-10-12
::Note this required the following files to be placed in the confluence jre/bin folder:
::
:: attach.dll - From the Java JDK (must be the same version)
:: tools.jar - ditto
:: psexec.exe - from Windows sysinternals
:: Also, the TEMP directory must be set (stack overflow)
set TEMP=c:\windows\temp
::go to run location
d:
cd \confluence.application\jre\bin
::build datetime filename
rem datetime from wmi.exe
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /format:list') do set dt0=%%I
rem datetime string as YYYY-MM-DD-hhmmss
set dt=%dt0:~0,4%-%dt0:~4,2%-%dt0:~6,2%-%dt0:~8,6%
set ff=td-%dt%.txt
echo filename: %ff%
::tomcat PID
FOR /F "tokens=2" %%I in ('TASKLIST /NH /FI "IMAGENAME eq tomcat6.exe"' ) DO SET PID=%%I
ECHO pid: %PID%
::combine above with jstack command (won't work without psexec)
psexec -s "D:\confluence.application\jre\bin\jstack.exe" -l %PID% >> %ff%
:: view output txt file
start %ff%
::pause to review script operation, or use ping to wait a few secs
::ping localhost -n 20 >nul
pause
回答by Vadzim
Here is the solution that finally worked for me for obtaining stacktraces from unprepared java process running under different user in terminal session or as windows service.
这是最终对我有用的解决方案,用于从在终端会话中的不同用户下运行的未准备好的 java 进程或作为 Windows 服务获取堆栈跟踪。
jstack.cmd:
jstack.cmd:
@for /f "usebackq tokens=2" %%I in (`tasklist /NH /FI "imagename eq tomcat.exe" /FI "username eq SYSTEM"`) DO set PID=%%I
@for /f "tokens=2 delims==." %%G in ('wmic os get localdatetime /value') do @set datetime=%%G
@set date_time=%datetime:~0,4%_%datetime:~4,2%_%datetime:~6,2%__%datetime:~8,2%_%datetime:~10,2%_%datetime:~12,2%
PsExec.exe /accepteula -h -s -d cmd /c "%JAVA_HOME%\jstack.exe" -l %PID% ^>"%~dp0jstack_%date_time%.txt"
First line determinesthe PID by process name and user.
第一行通过进程名称和用户确定PID。
Then PsExecwith accepted EULAhelps to call jstackin elevated modewith properly escapedredirection of the outputto jstack*.txt
file in script's dir with timestamp included in file name.
然后PSEXEC与接受EULA帮助调用jstack在提升模式与正确转义的重定向输出到jstack*.txt
脚本的目录文件,包括文件名中的时间戳。
You may need to add PsExec and JDK dirs to PATHbeforehand.
您可能需要事先将 PsExec 和 JDK 目录添加到PATH。
I've tried to force threaddumps by SendSignalbefore but it never worked reliably with Windows service processes.
我之前尝试过通过SendSignal强制线程转储,但它从未与 Windows 服务进程可靠地工作。
回答by Alan ZHU
For GUI based tools like jconsole, please enable JMX support in tomcat, and connect via JMX.
对于 jconsole 等基于 GUI 的工具,请在 tomcat 中启用 JMX 支持,并通过 JMX 连接。
For the command line tools, such as jps, jstat, please run following in an admin console. Note: better add psexec path and %JAVA_HOME%\bin into PATH env.
对于命令行工具,例如 jps、jstat,请在管理控制台中运行以下命令。注意:最好将 psexec 路径和 %JAVA_HOME%\bin 添加到 PATH env 中。
> psexec -S cmd.exe
The we get a new cosole. And we can run the jps,jstat or other tools to "debug" the tomcat running as windows service using local system account.
我们得到了一个新的cosole。并且我们可以运行jps、jstat或其他工具来“调试”使用本地系统帐户作为windows服务运行的tomcat。
e:\sde\PSTools>jps 7408 Jps e:\sde\PSTools>psexec -s cmd PsExec v2.2 - Execute processes remotely Copyright (C) 2001-2016 Mark Russinovich Sysinternals - www.sysinternals.com Microsoft Windows [Version 6.2.9200] (c) 2012 Microsoft Corporation. All rights reserved. C:\windows\system32>jps 9792 Jps 8812 C:\windows\system32>jstat -gc 8812 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT G CT 10752.0 10752.0 0.0 10744.3 65536.0 21751.1 175104.0 3730.9 17792.0 17138.5 2176.0 1974.8 1 0.034 0 0.00 0 0.034