JNI: Debugger

Discussion in 'Java' started by M. Fernandez, Apr 20, 2006.

  1. M. Fernandez

    M. Fernandez Guest

    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
     
    M. Fernandez, Apr 20, 2006
    #1
    1. Advertisements

  2. 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
     
    Gordon Beaton, Apr 20, 2006
    #2
    1. Advertisements

  3. M. Fernandez

    Chris Uppal Guest

    Re: Debugger

    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 principle limitations are C++ and
    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.
     
    Chris Uppal, Apr 20, 2006
    #3
  4. M. Fernandez

    M. Fernandez Guest

    Re: Debugger

    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
     
    M. Fernandez, Apr 24, 2006
    #4
  5. Re: Debugger

    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('$','@')
     
    Thomas Fritsch, Apr 24, 2006
    #5
  6. M. Fernandez

    Chris Uppal Guest

    Re: Debugger

    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=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
     
    Chris Uppal, Apr 24, 2006
    #6
  7. M. Fernandez

    M. Fernandez Guest

    Re: Debugger

    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=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
    >
    >
    >


    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
     
    M. Fernandez, Apr 24, 2006
    #7
  8. M. Fernandez

    M. Fernandez Guest

    Re: Debugger

    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.
     
    M. Fernandez, Apr 25, 2006
    #8
  9. M. Fernandez

    M. Fernandez Guest

    Re: Debugger

    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/CommentView.aspx?guid=68ff8e49-8bd7-4c34-94bc-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_Filter_Manager_download.htm
     
    M. Fernandez, Apr 25, 2006
    #9
  10. M. Fernandez

    Chris Uppal Guest

    Re: Debugger

    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
     
    Chris Uppal, Apr 26, 2006
    #10
  11. M. Fernandez

    vvl

    Joined:
    Sep 18, 2007
    Messages:
    1
    Likes Received:
    0
    Hello
    You can try our Eclipse* based tool for debugging Java*/JNI environment that uses CDT and JDT perspectives makes developer works comfortable for Eclipse* users and moving out two debugger scenario to the history.
    Please find time to visit http://softwarecommunity.intel.com/articles/eng/1435.htm and try it. Let us to know if it helps to you or not, and what changes should be done to meet your expectations and requirements.

    --
    Vasily v. Levchenko
    Senior Software Engineer
    Intel(R) Corporation
     
    vvl, Sep 18, 2007
    #11
    1. Advertisements

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Similar Threads
  1. Derek Goto

    Debugger question

    Derek Goto, Aug 25, 2003, in forum: Perl
    Replies:
    1
    Views:
    1,151
    Eric J. Roode
    Aug 25, 2003
  2. Alex Hunsley

    IBM's JNI fails where Sun's JNI works

    Alex Hunsley, Nov 3, 2003, in forum: Java
    Replies:
    4
    Views:
    1,221
    Alex Hunsley
    Nov 4, 2003
  3. Pasturel Jean-Louis

    Porting JNI Windows under JNI LINUX + Wine ?

    Pasturel Jean-Louis, Feb 29, 2004, in forum: Java
    Replies:
    5
    Views:
    1,363
    Pasturel Jean-Louis
    Mar 3, 2004
  4. vasanth
    Replies:
    0
    Views:
    3,459
    vasanth
    Jan 25, 2005
  5. TsanChung
    Replies:
    2
    Views:
    688
    TsanChung
    Sep 18, 2008
  6. bgabrhelik
    Replies:
    0
    Views:
    1,312
    bgabrhelik
    Sep 29, 2009
  7. Robert Oschler
    Replies:
    1
    Views:
    483
    Mcginkel
    Sep 5, 2005
  8. aflat362
    Replies:
    7
    Views:
    559
    naixn
    Dec 7, 2006
Loading...