Problem with Exceptions..

6 views
Skip to first unread message

alex

unread,
Sep 17, 2008, 10:16:58 AM9/17/08
to ReCrash
Hi,
I think I found a bug/limitation on the current reCrash..

I have the following modification of the original CrashExample. It
seems that there is a problem with exceptions, as there are some
remaining elements on the shadow stack..

I added a loop to call the method f with argument true, which
always throws a Runtime exception that is catched, so should not be in
the shadow stack...

public static int abs(Integer i) {
Integer ret = null;
if (i < 0) {
ret = -i;
} else if (i > 0) {
ret = i;
}
// return ret.intValue(); // original

for(int j=0; j<5; j++) { // put wrong cases on the shadow
stack...
try{
f(rand(),true);
}catch(Exception e) {
System.out.println("Captured exception should not be a case"
+ e);
}
}
return f(ret,false); // emulates the original
}

public static int f(Integer i,boolean b) {
System.out.print(""); // to force the creation of YouMayCrash/
YouAreOK
if(b == true) {
throw new RuntimeException();
}
return i.intValue();
}

When I run recrash, and I obtain several false positives... cases
where the call to f() should not crash the whole application...

Here you can see that ReCrash reports that f(Integer(-337), true) is
crashing, which is of course false... Only f(null, false) should crash
the application...

Cheers,

Alex

//-----Stack trace: java.lang.NullPointerException ------------
//CrashSample.f(CrashSample.java:40)
//CrashSample.abs(CrashSample.java:31)
//CrashSample.__original_main__(CrashSample.java:73)
//CrashSample.main(CrashSample.java)

public class Recrash_reCrash65166_trace_gz extends TestCase {
public void setUp() throws Exception {
TraceReader.readTrace("/var/tmp/reCrash65166.trace.gz");
}


public void test_CrashSample_f_7() throws Throwable {
TraceReader.setMethodTraceItem(7);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = -337;
Integer arg_1 = (Integer)TraceReader.readObject(1);
boolean arg_2 = true;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_f_6() throws Throwable {
TraceReader.setMethodTraceItem(6);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = -1185;
Integer arg_1 = (Integer)TraceReader.readObject(1);
boolean arg_2 = true;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_f_5() throws Throwable {
TraceReader.setMethodTraceItem(5);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = -1575;
Integer arg_1 = (Integer)TraceReader.readObject(1);
boolean arg_2 = true;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_f_4() throws Throwable {
TraceReader.setMethodTraceItem(4);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = 960;
Integer arg_1 = (Integer)TraceReader.readObject(1);
boolean arg_2 = true;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_f_3() throws Throwable {
TraceReader.setMethodTraceItem(3);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = -1835;
Integer arg_1 = (Integer)TraceReader.readObject(1);
boolean arg_2 = true;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_f_2() throws Throwable {
TraceReader.setMethodTraceItem(2);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
Integer arg_1 = null;
boolean arg_2 = false;

// Method invocation
thisObject.f(arg_1, arg_2);
}

public void test_CrashSample_abs_1() throws Throwable {
TraceReader.setMethodTraceItem(1);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// Integer arg_1 = 0;
Integer arg_1 = (Integer)TraceReader.readObject(1);

// Method invocation
thisObject.abs(arg_1);
}

public void test_CrashSample_main_0() throws Throwable {
TraceReader.setMethodTraceItem(0);
CrashSample thisObject = (CrashSample) TraceReader.readObject(0);

// load arguments
// String[] arg_1 = [Ljava.lang.String;@126f75b;
String[] arg_1 = (String[])TraceReader.readObject(1);

// Method invocation
thisObject.main(arg_1);
}
}

java.lang.NullPointerException
at CrashSample.f(CrashSample.java:40)
at CrashSample.abs(CrashSample.java:31)
at CrashSample.__original_main__(CrashSample.java:73)
at CrashSample.main(CrashSample.java)



Sung Kim

unread,
Sep 17, 2008, 10:32:03 AM9/17/08
to rec...@googlegroups.com
Hi Alex,

Thanks for this email. However, it is a ReCrash feature. ReCrash
captures all exceptions happened in a method. For example, the
exception of the f (x, true) is caught by abs, but if you consider
only f (x, true), the exception was thrown.

In other words, we add instrumentation like this:

f() {

// add f () in stack

[...]

// remove f() from stack right before return or any legal exit points
return;
}

If exception happens before the stack removal, f() will remain in the
shadow stack. Do you think we should remove this feature? Perhaps we
can compare arguments of f() and remove the same kinds of
arguments/test cases. (For example, test_f3 to test_f7 are the same.)

- Sung

Alex Villazon

unread,
Sep 17, 2008, 10:49:19 AM9/17/08
to rec...@googlegroups.com
On Wed, Sep 17, 2008 at 4:32 PM, Sung Kim <hun...@gmail.com> wrote:

Hi Alex,

Thanks for this email. However, it is a ReCrash feature. ReCrash
captures all exceptions happened in a method. For example, the
exception of the f (x, true) is caught by abs, but if you consider
only f (x, true), the exception was thrown.

In other words, we add instrumentation like this:

f() {

// add f () in stack

[...]

// remove f() from stack right before return or any legal exit points
return;
}

If exception happens before the stack removal, f() will remain in the
shadow stack. Do you think we should remove this feature? Perhaps we
can compare arguments of f() and remove the same kinds of
arguments/test cases. (For example, test_f3 to test_f7 are the same.)

Hi,
     I though that it was a bug, because if you replace the invocation to f(ret, false) to another method, let say ff(Integer o) { return o.intValue() } , then the false positives dissappear.  

    I think that handling the exceptions will not be very easy. Removing the same test cases will certainly help, but I have the impression that there will be other cases where the elements on the shadow stack could mixture up with other elements and give wrong results...
   

Many thanks,

Alex
Reply all
Reply to author
Forward
0 new messages