1

I would like to do some debugging on a Java program running on Windows: backtrace, print some variables, set breakpoints, single-step through a critical function.

The first thing I tried was jdb -attach 5312. This failed with "shmemBase_attach failed: The system cannot find the file specified". I found some related questions about that error message but they seem to be talking about a more complex scenario involving debugger and target on separate hosts.

What I'm doing is a local process attach, so I think it should be easier. But there is something making it harder.

The target process isn't run as java -jar foo.jar or anything normal like that. It's an application-specific EXE file wrapping the java code. It identifies itself in a process listing as "Commons Daemon Service Runner" and looking at the strings inside it, it seems to be the prunsrv program from Apache Commons Daemon.

Process Explorer tells me that there are no command line arguments, and the process is a child of services.exe. I have the ability to start and stop it from Windows Services, but I don't know how to do anything else with it.

The jps command doesn't show this process, but I know that it is a Java program... lightly wrapped. Is there any way to debug it?

1 Answers1

0

Try to set _JAVA_OPTIONS variable to something like this:

_JAVA_OPTIONS "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=32887"

This variable should be picked up by JVM while it is started.

Then, you can try to attach to this JVM by calling

jdb -attach 32887

where 32887 is an arbitrary port number used by debugger (numbers have to match).

Update:

You can use different means of connection. It's up to you. What I have given you is just one example of many, different, ways of settings things up. Take a look here for more details:

https://docs.oracle.com/javase/8/docs/technotes/guides/jpda/conninv.html

You can also use VisualVM. In that case you need to have JVM process visible to user that is running VisualVM.

Oo.oO
  • 12,464
  • 3
  • 23
  • 45
  • I have to alter the way the program is run to make it debuggable? And I have to use a remote debugging protocol to debug a local process? This seems very strange to me, being used to gdb on unix where I can attach to any process by PID, without needing any cooperation from it (if I am the owner or root). I will try it out... –  Jun 19 '17 at 14:12
  • And it accepts remote connections from everyone, with [no authentication whatsoever](http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html)! That's not usable. –  Jun 19 '17 at 14:51
  • 1
    After looking at several options, I found this combination: `jdb -connector com.sun.jdi.SocketListen:port=12345` and then configure the target service using `prunmgr`, and add the option `-agentlib:jdwp=transport=dt_socket,address=127.0.0.1:12345,server=n,suspend=y`. I figure it's slightly less stupid to give the world unauthenticated access to attach to my debugger as a debuggee than the other way around. Still amazed that there's no simple `PTRACE_ATTACH`-style interface. –  Jun 19 '17 at 19:34
  • `jdb -attach` doesn't work on Windows if the debugee is listening on a port. – Robin Green Aug 28 '21 at 09:55