JAVA JNI C Debugger - java

Is there any debugger that helps debug a Java JNI program along with the C library?
I should be able to debug the program starting from static void main in Java and continue to debug and place break points in the native c function and then continue to debug in Java after the control is transferred from C to Java.

A Java Virtual Machine debugger is very different from native code debugger. There is currently no such MATURE solution as one and the same debugger which would be able to seamlessly step from Java to native code and back. While this is a very irritant problem which makes some smart people trying to develop such a solution, there is undoubtely tons of un-imaginable problems involved. I personally do it in the following way:
start your Java code in debug mode and put a breakpoint at the first native call you are interested in. You can even implement a static native call, which won't do anything significant but will enable you to break as soon as possible.
fire up a native debugger. This absolutely can be the same instance of Eclipse, given two prerequisities: you have CDT installed and your native code was compiled in a way, that the debugging info is understood by CDT. Attach to the java(w.exe) process running your Java code. Put a breakpoint in the native code.
Whenever you need to transition over JNI interfaces, put breakpoints as close to the call entry/exit as you can (or need).

I have found that running the java code in an IntelliJ IDEA debugger and setting a very early break point allows one to attach CLion's debugger to the process (after sudo echo 0 > /proc/sys/kernel/yama/ptrace_scope). Then each IDE will stop the JVM and raise it's window at it's respective brake points in either Java or JNI Native code, with inspection of objects in memory in which ever context stopped. This makes for a fairly smooth experience.

Related

How to hotswap code running on JVM through JNI

I have run into a problem which I'm not even sure is solvable considering how the JVM works. I am using the JVM as a scripting engine and need to be able to reload code on the fly as is expected of any game engine. I'm not even sure how this would be possible. I have to be able to do this through the JNI as the scripting engine interacts with the main native program that runs it. Hours of searching on the Internet tells me to use custom class loaders and such which can then be garbage collected. Is there a nice way to do this with examples. Thanks.

How to print out native stacktrace in Java?

I would like to print the stacktrace of native methods calls of a Java application. The Thread.dumpStack() is only printing java methods calls.
If you want the non-java stack, you need a "native" debugger, e.g. gdb.
You can attach to your running java with gdb, too.
For documentation on seamless debugging of Java with gdb, see also: http://gcc.gnu.org/java/gdb.html
(gcc can compile java code to native code; at which point the native debugger will also show Java backtraces.)
If it is OK to do it outside of your application you can run $JAVA_HOME/bin/jstack -m <jvm_pid>
To view the internal JVM (C-level) function calls, attach a standard C debugger to the process.
Exactly how to do this does depends on your OS and debugger of choice, for example on OSX one would use xcode. Instructions for using gdb can be read here.

Eclipse: Java Monitor won't show cpu statistics

I am profiling a java application using jvisualvm. The CPU profile from jvisualvm has narrowed down the slow part of the code to one particular method. It doesn't say which part of the method is slow though.
To get more information I tried debugging through Eclipse using Java Monitor (available through Eclipse Marketplace). Java Monitor will attach to the application but it won't display CPU statistics. I don't know why. I have modified the JVM options using:
-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=y
Then I create a profile in Eclipse using:
Remote Java Application > myapplication
Here I select the source code for the project I am profiling. I start the application and it waits for the debugger to attach:
Listening for transport dt_socket at address: 8000
I right click the PID under local host and click 'Start Monitoring'
Then in Eclipse I press F11 to kick off the application. It starts running, but under 'Properties' I get everything except CPU. Any ideas greatly appreciated..
I don't know any Java profiler which can tell you which part of a method eats most of the time. If you can't tell by looking at the method, then your method is probably too big to understand anyway. Try to refactor it into several methods.
If you have lots of local variables, use a worker object and turn local variables into fields of the worker. That way, you can avoid writing methods with a dozen parameters and still cut a overly complex method to size.
As for why Java Monitor doesn't do what you want: You need to tell it which packages to monitor and which profiling method to use. See the documentation for details.

Java console Input/Output/Error redirection to another (Delphi) application

I am constructing a Command Prompt Process in my Delphi application which is able to interact with the JDB to compile, run and debug a Java application. Cmd input/output/errors are handled through pipelining from the cmd to/from my Delphi application UI.
I want the output of the java program when using 'System.out' / 'System.err' to be directed to a component of my Delphi Application and I want input from my delphi application to be sent to 'System.in' allowing me to form a console in my Delphi UI similar to the console in the Eclipse IDE.
A few thoughts on approaches;
An obscure flag (I haven't found) in the Java compiler allowing me to redirect
Using 'System.setOut'/'System.setErr'/'System.setIn' along with a main method in a class which performs this initialization before pointing to the normal main method to run the users code.
NB - I have tried searching through the Eclipse sourcecode to see how they did it but as it is written in Java, I suspect they wouldn't face cross language issues I would face.
I have found a solution to my problem. You need two command prompt processes, each constructed with a Read, Write and Error pipe in Delphi.
One of them runs the Java application and is set to wait for a debugger to be attached before executing and the other is for debugging and is attached to the waiting Java application.
This is for the main application; all application console input/output/errors will be handled through this process.
java -agentlib:jdwp=transport=dt_shmem,address=DelphiExecutingAppAddress,server=y,suspend=y MyClassFile.java
This is for the debugger; all jdb console input/output/errors will be handled through this process (break points, resuming, getting object details).
jdb -attach DelphiExecutingAppAddress
N.B. Perhaps this is what David was referring to? It looks like it was my mistake when reading the jdb documentation in not finding this on the first work-through. Perhaps this thread may help others.

Why does Java code slow down in debugger?

Some CPU intensive routines get dramatically slower when run through a debugger. Why is this?
Currently I'm just using IntelliJ to step through code running in JBoss. When I start JBoss, I use these options:
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MaxPermSize=256m -Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n %JAVA_OPTS%
Is there a way to speed up the execution? Or to speed up certain method executions that I don't need to step through?
Update: Seems if I don't step over/into the CPU intensive routines (ie: Just run til a breakpoint set right after the routine), then the execution time is as if not in a debugger.
Some CPU intensive routines get dramatically slower when run through a debugger. Why is this?
Because the JITter won't optimize code as much (often, not at all) when debugging is enabled.
It also depends on the "breakpoints-style". E.g. having watchpoints on variables or putting breakpoints on interface level (debugger will stop on all method-implementations when they're executed) often dramatically slows down the process time.
When debugging, in addition to running your application, you are also running a debugger.
The code is compiled in debug mode with metadata symbols about local variables and other source-level information. The debugger reads to know which line of source code corresponds with the current instruction. The process is called symbolic debugging. The stored symbols increase code size and interpreting them increases execution time.
Some debuggers actually interpret the code on the fly, which is almost always a major performance hit.
More information about Java's debug compilation mode, which is performed by javac and includes debug information in class files: Java Language Compiler Options.
For example: -g generates all debugging information, including local variables.
You do need to consider that another program -- the debugger -- is hooked into your program and is watching it for things like exceptions. It's also monitoring the current line in order to react to breakpoints or user requested interruptions (like a pause request or watch condition).
Top Tip: in IDEA you can use ALT+F9 to run to where you have the cursor placed rather than set an extra breakpoint.
I have found anecdotally that debugging becomes very slow in IDEA if you are walking through code where there is a lot of data accessible from the stack. Don't forget, IDEA collects this data (anything currently in the lexical scope) and presents it up to you as a tree of objects to browse whether you are "watching" or not and does this at every subsequent step (maybe it re-creates the tree each time?).
This is especially apparent when, for example, there is a large collection as an instance variable of the "current" object.
Debugging the optimized code produced by the JIT would be very hard, because there isn't a direct relationship between a range of native instructions and a line of Java code like there is a relationship between a range of Java bytecode and a line of Java code.
So breaking into a function in the debugger forces the JVM to deoptimize the method you are stepping through. Hotspot doesn't generate native code at all and just interprets the bytecode of the method.
Prior to JDK 1.4.1 starting with debugging enabled forced the JVM to only use the interpreter: http://java.sun.com/products/hotspot/docs/whitepaper/Java_Hotspot_v1.4.1/Java_HSpot_WP_v1.4.1_1002_3.html#full
If you use Java 5, the parameter for debugging is :
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=
and before Java 5
-Xdebug -Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n

Categories

Resources