How can I reproduce EXCEPTION_STACK_OVERFLOW error in Java.
PS: I am not talking of StackOverflowError Error in Java which gracefully shuts the JVM. I am talking of EXCEPTION_STACK_OVERFLOW in error.log which cause JVM to crash.
Most EXCEPTION_STACK_OVERFLOW errors I found so far happen in native code outside the JVM. A crash inside the JVM is worth a bug report and will be fixed. Or are you in need of an (unknown) exploit?
So the easist and most reliable way would be to write a native library with some code that causes the JVM to crash and call that with JNI.
(general answer, I actually don't know how to do it exactly. Can't be done with java code only ;) )
public static void stackoverflow()
{
stackoverflow();
}
Call it, and enjoy :D
Blow stack:
public static void main(String[] args) {
main(null);
}
Blow heap:
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
while(true) list.add(new String("boom"));
}
Related
I'm learning to code Java...
I just installed the Java runtime environment and Visual Studio Code, and wrote this:
public class IterationDemo
{
public static void main(String[] args)
{
System.out.println('x');
}
}
However, I don't see any output, both under output or terminal. Only kind of a rectangle (▯) under terminal.
I've tried to find a solution googling, stack and so on but no answer yet...
what can I do?
Thanks!
OK; got solved on its own - I ended up clearing the cache and then the output came :)
Thanks myself!
Considering the following code
public static void main(String...arg){
//do something
if(<<the method has called by a new process>>){System.exit(0);}
else{System.setProperty("main_result","0");return;}
}
the main method would be called by a separated process by JVM or existing process, now how can I find it out?
Thanks in advance
Let's clarify: there might be another class with a main that was started, or the main is somehow called again.
Normally you want to call System.exit(0) (or return;?) but when called from the program itself you want to end in System.setProperty("main_result","0");.
public static void otherMain(String[] args) {
Main.main(args);
}
public static void main(String[] args) {
...
StackTraceElement[] elems = Thread.currentThread().getStackTrace();
//for (StackTraceElement elem : elems) {
// System.out.printf("%s%n", elem.getClassName());
//}
if (elems.length > 2) { // [0] Thread [1] main
System.setProperty("main_result","0");
}
}
In java, every Java process runs in its own JVM. So, the "same" main
method cannot be called by a different process under normal
circumstances
Even if you run the same program twice, they will be running in their
own JVMs.
You can try one thing.. Keep a static variable in your program, run it and
make it sleep for a long period of time (process 1).. Now, run the same
program again and update the static variable(runs in process 2).. See, whether it will be
updated in the first process (No, it won't be updated as each process will have it's own
set of variables..)
Do you really need it? Just don't use System.exit(0); and refactor main method to finish gracefully.
Calling System.setProperty in both cases - when run as new process and also as a class on classpath, will not make any difference.
Edit: Finding out who is calling the method is not easy and definitely bad practice.
I would refactor the code as follows:
public static void main(String...arg){
System.exit(doStuff(arg));
}
public static int doStuff(String... arg) {
//do something
}
To access this logic within the same JVM you can now call MyClass.doStuff and get the return value directly.
It would be better to consider refactoring and get rid of such problem.
Otherwise the following code can help:
if(Thread.currentThread().getStackTrace()[1].getClassName().equals(
System.getProperty("sun.java.command"))){
System.out.println("!");
}
Will not work if there is no "sun.java.command" property (on not Sun/Oracle JVMs it may absent)
public class LineNum1 extends Thread{
public synchronized void run()
{
try {
Hello.main(null);
System.out.println("Stack Trace of thread"+ this.currentThread().getName());
System.out.println(this.currentThread().getStackTrace()[1].getLineNumber());
System.out.println("End of Stack Trace");
} catch (Exception e1) {
e1.printStackTrace();
}
}
public static void main(String[] args) {
LineNum1 t = new LineNum1();
t.start();
}
}
I'm developing a code coverage tool.
Using the above program I'm executing Hello.java from here. Is there any method where I can get the control over Hello.java?
Or to make my life simpler can i get the line numbers of the executed lines(Execution path) of Hello.java?
You want to use the Java Debug Interface. It's the Java library that is used for writing Java tools like debuggers. It'll allow you to step through the program, query for line numbers and whatnots as you go.
There's a simple demo application for it called trace that does most of what you want already: http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/trace.html
There's a lot of documentation for it, if you've got the time to read it:
http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/index.html
You can probably execute the second Java class as a Process and read the output yourself.
I have not completed the code coverage completely yet. But I have used bytecode instrumentation to instrument the methods, hence i get the log of all the methods I've visited. This Javassist Turtorial might help you.
Here is some sample code to illustrate our issue:
A a = null;
try {
a = new A();
a = doSomethingThatWillThrowAnException();
} finally {
System.out.println("A = " + a);
}
The question is what is the value of 'a' as printed in the finally block...
I am not sure and I think I stumbled across something that might not be completely described. I observed on my laptop (jdk1.6.0.16 on x86) that 'a' is equal to A(). However, with a JDK 1.4 on Solaris I think that that the value is null (like if the assignment was performed even though the exception is thrown). This is obviously linked to a bug and we will deploy a version without the assignment just to make sure but we would like to know if one of you also noticed this or have some kind of explanation to propose.
What we will do, also, is to make a sample program to demonstrate this on the problematic JDK... and we will post the results.
The assignment should definitely not happen when an exception occurs - this would be a very serious bug in the JVM. But I'd first suspect that the exception actually occurs somewhere else (such in the constructor A()).
I would assume a == new A() unless it is optimized away. Isn't the code a bit silly looks like:
a=1;
a=2;
Maybe rewrite to the intend of your code:
A a = null;
try {
a = doSomethingThatWillThrowAnException();
} catch( ... ) {
a = new A();
}
Just did the test on Solaris with Sun JDK_1.4.2_05 on Solaris with the following program
public class Test {
public static void main(String[] args) throws Exception {
String test = null;
try {
test = "step1";
test = getString();
} finally {
System.out.println(test);
}
}
public static String getString() {
throw new RuntimeException();
}
}
I get the "step 1" in the console alright.
As other user have suggested, I think that the most likely is that the exception is thrown in the A() constructor. ( I hope that's the case, otherwise that would require some quite nasty defensive code )
If the optimizer can make sure that new A() has no side effects, it will optimize the first assignment away. To isolate this case, disable the JIT and run the code again. If a != null afterwards, you're seeing an optimizer glitch.
The obvious fix is to more the new A() before the try block:
A a = new A();
try {
a = doSomethingThatWillThrowAnException();
} finally {
System.out.println("A = " + a);
}
You could try compiling the code then looking at the bytecode to see what is going on. I use
the bytecode outliner eclipse plugin from http://andrei.gmxhome.de/eclipse/
I ran the code on Solaris 10 with the JDK 1.4.2 too and it had the correct behaviour. The problem was that the code in production was not the one I was looking at... (previous version)
It was interesting reading your answers though since it made it clear that optimizer glitches can happen and it is always a good idea to second guess what is going on under the hood.
Mental note for next time: "First, check the obvious: If you are having a strange behaviour, the code you are seing might not be what has been executed."
Thanks again,
Cedric
In Matlab, when a Java exception is thrown by a Java method invoked from M-code, it is converted to a Matlab error or MException, and the Java stacktrace is included in the MException's message. On Windows, the stacktrace is displayed double spaced. Here's an example.
package test;
public class Bummer {
public static void a() { b(); }
public static void b() { c(); }
public static void c() { d(); }
public static void d() { throw new RuntimeException("bummer"); }
}
Which produces this.
>> test.Bummer.a()
??? Java exception occurred:
java.lang.RuntimeException: bummer
at test.Bummer.d(Bummer.java:8)
at test.Bummer.c(Bummer.java:7)
at test.Bummer.b(Bummer.java:6)
at test.Bummer.a(Bummer.java:5)
>> disp(find(lasterr == sprintf('\r')))
61 95 129 163 197
This hurts readability, especially when you have a twenty call deep stack.
I believe this is because the stacktrace part of the error message is being constructed with DOS mode CRLF (\r\n) line endings. Which makes sense on a Windows machine. But the Matlab command window is kind of Unix mode, and converts \r\n to two line feeds.
Our current workaround is to use try/catch guard code like this around most Java method calls.
try
somejavaobject.SomeMethod();
catch err
rethrowmsg(err, 'Some additional details');
end
Rethrowmsg() is a function we wrote that munges err to convert \r\n to \n, incorporates additional details in the message, and then calls RETHROW.
Adding the workaround is a bit tedious and prone to be left out. And if you're doing "dbstop if all error", it won't fix the display of the error at that point. In the end, this is a minor annoyance, but when you spend all day debugging Matlab code, it adds up. And I'm curious about the Java exception/MException integration mechanism.
Is there a way to configure Matlab to construct the stacktrace part of the error message text with \n line separators so it displays single-spaced in the command window?
When the MATLAB Runtime intercepts the java exception, it uses the system line endings when it wraps it in a MException. To get around it, you can throw the exception on a different thread, or send the stack trace directly to stderr, such as with printStackTrace():
public class Bummer {
public static void a() { b(); }
public static void b() { c(); }
public static void c() { d(); }
public static void d() { new RuntimeException("bummer").printStackTrace(); }
}
Of course, it is a very bad thing to get a java exception in MATLAB. If you're using exceptions for things that are not really exceptional, then you may want to consider wrapping with a MException your users will find useful.
If you're using the exceptions to debug your java code, I find the stack trace analyzing functions of most java IDE's are able to deal with the extra line breaks nicely.
Try setting:
java.lang.System.setProperty('line.separator', sprintf('\n'));
Does using the FORMAT command improve the display at all? This helps display variables in a more compact form:
format compact
It may help display error messages in a more compact form too.