M. Fernandez said:
thank you very much your help, but i don't know how o attach (eclipse or
VC) to a running process. How can I do it?
OK, here we go. It helps to be sober and alert when you do this...
===========
To attach to a running process using VC (this is Visual Studio 2003 specific,
the details are slightly different (simpler) using VC 6).
In VS. Compile your DLL for Debug (obviously!). Move the .DLL to wherever
your java application expects to find it. Set a breakpoint in your C++ code.
Now, go to your Java code. Ensure that it is a long running application, so
that it does not just startup and immediately exit. If necessary add:
System.out.println("Press return");
System.in.read();
to your main() to make it pause until you are ready. Now start the Java
program. At this stage /don't/ use Eclipse to do this, use the command line.
Go back to VS. Under the "Debug" menu, select "Processes...". In the new
process window, scroll down to java.exe, select it and press the attach button.
A prompt will come up to check what kind of program it is, it should be set
correctly (Native). Press OK. Close the "Processes" window (it just gets in
the way). Now you may see that your breakpoint has changed to show a '?'. If
so that's because Java hasn't loaded your DLL yet, if it already has, then your
breakpoint will look normal.
Go back to your app, and let it advance to the point where it uses your native
code. You should see the process stop at your breakpoint. Most of the stack
will consist of functions in the jvm.dll, but the top function should be your
JNI code.
When you've finished debugging, select Debug=>Detach all (or use the Processes
window again), or you'll kill your Java application.
===========
To attach to a running process using Eclipse (you probably won't need this
bit -- I've just put it in for completeness).
Start Eclipse (go get a cup of coffee while you wait). There's probably a way
to tell Eclipse to debug using classfiles and source that is stored elsewhere,
but I can't be bothered to find out what it is. And you've probably got all
your Java code in Eclipse already....
Set whatever breakpoints you want in Eclipse.
Set up a remote debug definition. Select "Run=>Debug..." and then create a new
debug def under "Remote Java Application", set the source if necessary (just
like a normal debug def). Chose the default connection type ("Standard (socket
attach)"). Make a note of (and change if you want) the TCP/IP port that it
will connect to -- it defaults to 8000 which may already be in use on your
machine.
Now start your Java application from the command line. It'll be a line like:
java
-cp .
-agentlib:jdwp=transport=dt_socket,address=localhost:8765,server=y,susp
end=n
MyClass arg1 arg2
(I've put it on several lines, and used no quotes -- depending on which command
line processor you use, you will have to change the details)
The -cp points to wherever Eclipse has put your compiled class files.
The next line breaks down as follows (options are detailed in the JMVTI/JPDA
documentation, see
http://java.sun.com/j2se/1.5.0/docs/guide/jpda/conninv.html ):
-agentlib:jdwp=
This tells java to start the debugging agent (which Eclipse will
connect to)
The rest of the string is a comma-separated list of options for the
agent.
transport=dt_socket
This says to use TCP/IP sockets to talk to the debugger.
server=y
This says to set up a socket waiting for the debugger to connect to the
java process (instead of the java process connecting to a waiting
debugger).
suspend=n
This says not to wait for the debugger to connect before starting. I'm
assuming that you don't want to wait.
address=localhost:8000
This says which host/port to listen for connections on, and should be
the same as you told Eclipse.
That will start your Java application. Now go back to Eclipse, and activate
your new remote debug definition[*]. Eclipse should now connect to your
application (nothing much shows in the GUI). Go back to your application and
allow it to progress to the breakpoint you set about 3 pages ago. Eclipse
should stop it, and you'll have the normal debug view of the "remote"
application.
===========
To do both at once. You could just do both of the above at once. But it's
easier to start the application under the normal (not remote) Eclipse debugger
without messing with all the command-line stuff. Once it has started, and got
to an Eclipse breakpoint, go to VS, and attach to the running process as
before. You will have to guess which javaw process to attach to. On my
machine now, there were two instances of javaw.exe running, one with a "Title"
of something like "Debug <something> Eclipse SDK", and the other with no title
at all. It's the one with no title that you want (though I don't think it'd
harm to attach the other too). Now (in Eclipse) allow the process to advance
to the VS breakpoint you set in your JNI code. VS, will trap that and come to
life. Eclipse, meanwhile, thinks the application is running normally ("not
responding"), and is not halted at a breakpoint. By advancing between
breakpoints set in either domain, you can debug through an entire JNI call.
Have fun!
/Then/ go get a beer -- you'll need it...
-- chris