How to print out native stacktrace in Java? - 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.

Related

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.

How to run java program without JVM?

I have simple java programm that will just print Hello World.Can it be possible to print without using JVM installed in a machine ?But compiler is there.
You can compile Java Byte Code to Machine Code using something like this:
http://en.wikipedia.org/wiki/GNU_Compiler_for_Java
Or you can use any of the MANY Java to C/C++ converters out there to make a C/C++ version, and compile that. (Search Google for "Java C Converter")
Warning: I have never tried any of these, including the linked GNU Compiler, so I cannot make any attestations to their usefulness or quality.
#SplinterReality already pointed you to some compilers (googling "java bytecode to native code compiler" will show you some more options).
I will just expand on that seeing some people are a bit confused:
The JVM is a program that takes java bytecode, which you get by running javac on your java source code (or you generate it in some other fashion). Bytecode is just a set of instructions that the JVM understands, it's there to give you a consistent set of opcodes which are platform independent. It's the JVM's job to then map those opcodes to native instructions, that's why JVMs are platform dependent. That's why when you compile your java source code to java bytecode you can run it on every platform.
That's why, whether you have java source or bytecode, you can take it and just compile it directly to native code (platform dependent, actually sometimes that's exactly what the JVM, and to be more precise the JIT, does - it compiles stuff to native code when it sees the need to). Still there's more to the JVM than just bytecode interpretation - for instance you need to take care of garbage collection.
So the answer is: yes, but do you really want to do it? Unless you want to be running it on some embedded systems I don't really see any reason to.
Yees, it is possible to run a java program without a JVM, albeit with limitations. Aside from the http://en.wikipedia.org/wiki/GNU_Compiler_for_Java , there is the GraalVM native-image generator, which could be used : https://www.graalvm.org.
If that program is a one file source code (not compiled in bytecode) then you can ;)
Here or here. Here will be fine as well ;)
Just put it there and press compile and run.
But it will work only with simple stuff only, and you have to have source code.
I would not be surprised if there would be a site that would allowed to upload class from users PC

JAVA JNI C Debugger

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.

Java breakpoint on Linux syscall

How could I have a breakpoint in Java that's triggered when a native method calls (directly or indirectly) a certain Linux syscall?
This is not quite a breakpoint, but at least it gives you a stack trace, which may be all you need. Furthermore, the Systemtap language does allow you to do more stuff than just print stack traces, if you need to.
In the IcedTea JVM source code, you will find a SystemTap file with functions that can be used to get stack traces from a running IcedTea (with Hotspot) JVM. As I understand it, with these functions you can get a Java stack trace from any event that SystemTap supports - even from in-kernel events.
Note that despite having the same name, these jstack functions are unrelated to the jstack(1) command-line utility supplied with the JDK. They work via memory inspection, not via calling back to the JVM, so they are quite specific to Hotspot internals, and therefore probably won't work with non-Hotspot-based JVMs.
Note: Systemtap does not fully work on default Debian kernels, so you may need to compile your own kernel on Debian-based systems. This problem does not affect Fedora or Red Hat.
In theory, it would be possible to native-compile the application using an ahead-of-time (AOT) compiler for Java, and then use a native debugger to set a breakpoint or catchpoint on the syscall. (Bonus: You then get a complete stack trace including all the C functions called by the native method, and the ability to debug those C functions seamlessly.)
You would probably want to use a debugger which knew how to demangle names produced by the AOT compiler. For example, gdb knows how to demangle names produced by gcj, so a gcj combination with gdb should work.
The trouble with this combination is that gcj is still stuck at partial JDK 1.5 compatibility, and no-one has bothered to do the work of merging in the OpenJDK class library (it was suggested on the gcj mailing list in 2009). And as a result, gcj has never been a popular option - people do often use it unintentionally (particularly on Debian and Ubuntu), but then when they hit a problem they tend to switch to a more standard JDK instead of reporting a bug.
Native compilation with an AOT compiler is also much slower than just letting the JRE JIT-compile code when it thinks it's necessary.

Debugging JNI HotSpot crashes

I am testing some custom JNI code on a remote Linux based system. I don't want to have to install DBX and JDB isn't being entirely helpful and diagnosing the issue. Is there any other light weight java JNI debugger that will actually show me where within the JNI code Im going wrong?
Thanks
In case of native code, you have to use gdb or anything else that is available. After all, once in JNI, you are debugging native code. It's no longer Java.

Categories

Resources