![]() |
|
|
|
#1 |
|
Posts: n/a
|
Hello,
I have terrible bug in my JNI code and I would like to use a debugger such as the debugger of Eclipse (for java) or the VC++. However, because it is a JNI code, I don't know how to "see" my java and c++ variables/objects. Do you have any idea/program that may help me ?? thanks a lot, Marcelo |
|
|
|
#2 |
|
Posts: n/a
|
On Thu, 20 Apr 2006 16:37:07 +0200, M. Fernandez wrote:
> I have terrible bug in my JNI code and I would like to use a > debugger such as the debugger of Eclipse (for java) or the VC++. > However, because it is a JNI code, I don't know how to "see" my java > and c++ variables/objects. > > Do you have any idea/program that may help me ?? I don't know about Windows debuggers, but maybe this general info will help... - compile your native lib with debugging info - start java under control of a native debugger. - set a breakpoint in one of your native methods It can be tricky getting the debugger to see dynamically loaded code (especially if you need to start your application and load the library before setting the breakpoint), this is a workaround that may be easier: - write a java launcher in C (or use the one included in the src.zip that comes with the JDK). - statically link your native methods in the launcher (i.e. don't build a shared library or DLL). Make sure debugging info is turned on when you compile. - temoporarily comment out System.loadLibrary() from your application (loading isn't necessary when your methods are already in the executable). - run your launcher in the native debugger. /gordon -- [ do not email me copies of your followups ] g o r d o n + n e w s @ b a l d e r 1 3 . s e |
|
|
|
#3 |
|
Posts: n/a
|
M. Fernandez wrote:
> I have terrible bug in my JNI code and I would like to use a debugger > such as the debugger of Eclipse (for java) or the VC++. However, because > it is a JNI code, I don't know how to "see" my java and c++ > variables/objects. I don't know of any really good way of doing this, but you should be able to get part of the way there by using both debuggers at the same time. Basically, the idea is that you start your Java program under Eclipse, and then tell VC to attach to the running process too. Alternatively, you could do it the other way around, run the program (java.exe) under VC with your debug DLL, and tell Eclipse to attach to that running program. I admit I haven't tried either approach, but I can't think of any reason why they should not work. I think the first one would be less fiddly. If you need help on attaching to a running process then ask again. Once that's working (if it does!) then you've be able to "see" objects on both sides of the JNI interface. Since, at any one time, either Eclipse or VC will think the code is "running" (not at a breakpoint), you'll have to take more notes than you normally would, in order to keep the connection between objects and JNI handles clear. So it'll be pretty tedious, but it should be manageable. Another approach would be to use something like Jace, http://sourceforge.net/projects/jace to generate complete wrappers for your Java classes. You could then (in so far as the VC debugger allows it) "see into" the Java objects using C++ code. That sounds rather elaborate, and might easily not pay for itself, but it's worth thinking about. If you do try it and it works[*] then please let us know -- chris [*] I know that it /could/ work because I have a similar -- but more dynamic -- system with Smalltalk talking to Java via the JNI API. With it the Smalltalk debugger and inspectors can "see" right into Java objects just as if they were Smalltalk[**] -- so it is possible the VC debugger, not Java or the JNI barrier itself. [**] They can see in, but they can't, say, step into Java code any more than VC could. However I can play the same "two debuggers" trick, if I need to -- and I have needed to once or twice. |
|
|
|
#4 |
|
Posts: n/a
|
Hi,
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? thanks a lot, Marcelo |
|
|
|
#5 |
|
Posts: n/a
|
M. Fernandez wrote:
> Hi, > 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? > Attaching an debugger (like the one of eclipse) to a running process is called "remote debugging". For how to start a debuggable remote java process: see for example <http://groups.google.de/groups?selm=newscache$c2q9wi$w4j$>. For how to attach the Eclipse-debugger to it: From Eclipse's menu open "Run" -> "Debug..." -> select "Remote Java Application". -- "Thomas:Fritsch$ops:de".replace(':','.').replace(' $','@') |
|
|
|
#6 |
|
Posts: n/a
|
M. Fernandez wrote:
> 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=localhos t: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/...a/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 |
|
|
|
#7 |
|
Posts: n/a
|
Chris Uppal wrote:
> M. Fernandez wrote: > >> 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=localhos t: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/...a/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 > > > Merci beaucoup!! Thank you very much, this was really useful and well-explained. Now I can debug my horrible JNI program. thanks a lot, Marcelo |
|
|
|
#8 |
|
Posts: n/a
|
Hello,
I do really appreciate the answer given in this newsgroup. However, I still have some problems with the VC++ debugger with the JNI. 1.- Launch the java application on the command line (long process System.in.read). 2.- Attach VC++ debugger to the java.exe process. 3.- Set a breakpoint in the cpp code. Here, I have a problem attaching the process because VC++ shows me a "not normal debug icon" (with an important sign to it). It seams that the library msvcm80d.dll (message: Using symbol files from an unkwon or untrusted location can be harmful to your computer). With this problem, the debugging doesn't work. Do you have an idea about what I am doing wrong? Thanks a lot, Marcelo PS: With Eclipse, it works perfectly with the remote debugging or by using the TCP/IP connexion for debugging. |
|
|
|
#9 |
|
Posts: n/a
|
M. Fernandez wrote:
> Hello, > I do really appreciate the answer given in this newsgroup. However, I > still have some problems with the VC++ debugger with the JNI. > > 1.- Launch the java application on the command line (long process > System.in.read). > 2.- Attach VC++ debugger to the java.exe process. > > 3.- Set a breakpoint in the cpp code. Here, I have a problem attaching > the process because VC++ shows me a "not normal debug icon" (with an > important sign to it). It seams that the library msvcm80d.dll (message: > Using symbol files from an unkwon or untrusted location can be harmful > to your computer). With this problem, the debugging doesn't work. > > Do you have an idea about what I am doing wrong? > > Thanks a lot, > > Marcelo > > PS: With Eclipse, it works perfectly with the remote debugging or by > using the TCP/IP connexion for debugging. Sorry for this question, The problem is not related to the method described in this thread. Actually the problem is about Nero 6 and the DirectShow filters. A thread that may be useful can be found http://www.atrevido.net/blog/Comment...c-15145270ecbc another problem may be ACDSee, but i cannot prove it. Marcelo PS: I have uninstalled Nero PhotoSnap and similar programs. And I have unregister some programs that were using the DirectShow filters. A tool that may help you can be found on http://www.free-codecs.com/RadLight_...r_download.htm |
|
|
|
#10 |
|
Posts: n/a
|
M. Fernandez wrote:
> The problem is not related to the method described in this thread. > Actually the problem is about Nero 6 and the DirectShow filters. Eek! I'm glad you found the problem. I, for one, would never have thought of anything like that. -- chris |
|