mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
Squashed commit of the following: (#32)
commit a25c09bb738e7e82d2dfd909381ba052f7b69687 Merge: aa6664214 92af5d169 Author: Joel Dice <joel.dice@gmail.com> Date: Tue Sep 5 11:38:08 2017 -0600 Merge pull request #545 from corda/chrisr3-uncaught-exceptions Support Thread.uncaughtExceptionHandler with OpenJDK commit aa666421499d0e9ed46b6c745a93abd9998a58b0 Merge: dc8c99bd2 1cb11e964 Author: Joel Dice <joel.dice@gmail.com> Date: Tue Sep 5 11:23:41 2017 -0600 Merge pull request #546 from corda/chrisr3-werror Fix "fallthrough" warnings with recent GCC. commit dc8c99bd2f045c787f2c322cd65f866626fa9461 Author: Joel Dice <joel.dice@gmail.com> Date: Tue Sep 5 11:17:54 2017 -0600 fix bootimage-test build regression commit 1cb11e964fab925e9d98373ba58e181b1a1f11fd Author: Chris Rankin <chris.rankin@r3.com> Date: Tue Sep 5 10:25:48 2017 +0100 Fix "fallthrough" warnings with recent GCC. commit 92af5d169dbfb7b9b9f5b667b0dc71ca7b98b416 Author: Chris Rankin <chris.rankin@r3.com> Date: Mon Sep 4 17:26:31 2017 +0100 Ensure that the thread resources are only cleaned up once. commit 05d260f8bed68e3f999619aee338a781ba0f4c63 Author: Chris Rankin <chris.rankin@r3.com> Date: Mon Sep 4 17:10:04 2017 +0100 Test exception thrown from uncaught-exception handler. commit b1c5dca36163a876fba86221493883ddbd5fe805 Author: Chris Rankin <chris.rankin@r3.com> Date: Tue Aug 29 17:17:24 2017 +0100 Support Thread.uncaughtExceptionHandler.
This commit is contained in:
parent
e075e52377
commit
c0c75c3e19
@ -296,6 +296,10 @@ object makeJconstructor(Thread* t, GcMethod* vmMethod, int index = -1);
|
||||
|
||||
object makeJfield(Thread* t, GcField* vmField, int index = -1);
|
||||
|
||||
void uncaughtException(Thread *t, GcThrowable *e);
|
||||
|
||||
void disposeThread(Thread *t);
|
||||
|
||||
#ifdef AVIAN_OPENJDK_SRC
|
||||
void interceptFileOperations(Thread*, bool);
|
||||
#endif
|
||||
@ -588,22 +592,15 @@ class MyClasspath : public Classpath {
|
||||
objectMonitor(t, t->javaThread, true);
|
||||
|
||||
THREAD_RESOURCE0(t, {
|
||||
vm::acquire(t, t->javaThread);
|
||||
t->clearFlag(Thread::ActiveFlag);
|
||||
vm::notifyAll(t, t->javaThread);
|
||||
vm::release(t, t->javaThread);
|
||||
|
||||
GcThrowable* e = t->exception;
|
||||
PROTECT(t, e);
|
||||
if (e != NULL) {
|
||||
PROTECT(t, e);
|
||||
|
||||
t->exception = 0;
|
||||
t->exception = NULL;
|
||||
uncaughtException(t, e);
|
||||
}
|
||||
|
||||
t->m->processor->invoke(t,
|
||||
cast<GcMethod>(t, roots(t)->threadTerminated()),
|
||||
t->javaThread->group(),
|
||||
t->javaThread);
|
||||
|
||||
t->exception = e;
|
||||
disposeThread(t);
|
||||
});
|
||||
|
||||
GcMethod* method = resolveMethod(
|
||||
@ -972,6 +969,43 @@ class EmbeddedFile {
|
||||
unsigned pathLength;
|
||||
};
|
||||
|
||||
void uncaughtException(Thread *t, GcThrowable *e)
|
||||
{
|
||||
GcMethod* dispatch = resolveMethod(t,
|
||||
roots(t)->bootLoader(),
|
||||
"java/lang/Thread",
|
||||
"dispatchUncaughtException",
|
||||
"(Ljava/lang/Throwable;)V");
|
||||
if (dispatch != NULL) {
|
||||
THREAD_RESOURCE0(t, {
|
||||
if (t->exception != NULL) {
|
||||
// We ignore any exceptions from the uncaught
|
||||
// exception handler itself.
|
||||
t->exception = NULL;
|
||||
|
||||
// The stack will be unwound when this resource is
|
||||
// released, which means that uncaughtException()
|
||||
// will not return. So repeat the thread clean-up here.
|
||||
disposeThread(t);
|
||||
}
|
||||
});
|
||||
|
||||
t->m->processor->invoke(t, dispatch, t->javaThread, e);
|
||||
}
|
||||
}
|
||||
|
||||
void disposeThread(Thread *t) {
|
||||
vm::acquire(t, t->javaThread);
|
||||
t->clearFlag(Thread::ActiveFlag);
|
||||
vm::notifyAll(t, t->javaThread);
|
||||
vm::release(t, t->javaThread);
|
||||
|
||||
t->m->processor->invoke(t,
|
||||
cast<GcMethod>(t, roots(t)->threadTerminated()),
|
||||
t->javaThread->group(),
|
||||
t->javaThread);
|
||||
}
|
||||
|
||||
#ifdef AVIAN_OPENJDK_SRC
|
||||
int64_t JNICALL
|
||||
getFileAttributes(Thread* t, GcMethod* method, uintptr_t* arguments)
|
||||
|
@ -4029,13 +4029,13 @@ bool isLambda(Thread* t,
|
||||
GcCharArray* bootstrapArray,
|
||||
GcInvocation* invocation)
|
||||
{
|
||||
GcMethod* bootstrap = cast<GcMethod>(t,
|
||||
GcMethod* bootstrap = cast<GcMethodHandle>(t,
|
||||
resolve(t,
|
||||
loader,
|
||||
invocation->pool(),
|
||||
bootstrapArray->body()[0],
|
||||
findMethodInClass,
|
||||
GcNoSuchMethodError::Type));
|
||||
GcNoSuchMethodError::Type))->method();
|
||||
PROTECT(t, bootstrap);
|
||||
|
||||
return vm::strcmp(reinterpret_cast<const int8_t*>(
|
||||
@ -5191,14 +5191,8 @@ loop:
|
||||
"I"
|
||||
")[B");
|
||||
|
||||
GcReference* reference = cast<GcReference>(
|
||||
t,
|
||||
singletonObject(
|
||||
t, invocation->pool(), bootstrapArray->body()[2]));
|
||||
int kind = reference->kind();
|
||||
|
||||
GcMethod* method
|
||||
= cast<GcMethod>(t,
|
||||
GcMethodHandle* handle
|
||||
= cast<GcMethodHandle>(t,
|
||||
resolve(t,
|
||||
c->loader(),
|
||||
invocation->pool(),
|
||||
@ -5206,6 +5200,10 @@ loop:
|
||||
findMethodInClass,
|
||||
GcNoSuchMethodError::Type));
|
||||
|
||||
int kind = handle->kind();
|
||||
|
||||
GcMethod* method = handle->method();
|
||||
|
||||
jarray lambda = e->vtable->CallStaticObjectMethod(
|
||||
e,
|
||||
lmfClass,
|
||||
|
@ -571,6 +571,7 @@ int printInstruction(uint8_t* code, unsigned& ip, const char* prefix)
|
||||
return fprintf(stderr, "wide astore %4d", read16(code, ip));
|
||||
case iinc:
|
||||
fprintf(stderr, "wide iinc %4d %4d", read16(code, ip), read16(code, ip));
|
||||
/* fallthrough */
|
||||
case iload:
|
||||
return fprintf(stderr, "wide iload %4d", read16(code, ip));
|
||||
case istore:
|
||||
@ -582,10 +583,10 @@ int printInstruction(uint8_t* code, unsigned& ip, const char* prefix)
|
||||
case ret:
|
||||
return fprintf(stderr, "wide ret %4d", read16(code, ip));
|
||||
|
||||
default: {
|
||||
default:
|
||||
fprintf(
|
||||
stderr, "unknown wide instruction %2d %4d", instr, read16(code, ip));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4105,6 +4105,7 @@ void enter(Thread* t, Thread::State s)
|
||||
} else {
|
||||
// fall through to slow path
|
||||
}
|
||||
/* fallthrough */
|
||||
|
||||
case Thread::ZombieState: {
|
||||
ACQUIRE_LOCK;
|
||||
@ -6189,7 +6190,7 @@ GcCallSite* resolveDynamic(Thread* t, GcInvocation* invocation)
|
||||
}
|
||||
|
||||
// `i` iterates through the bootstrap arguments (the +1 is because we skip
|
||||
// the boostrap method's name), `it` iterates through the corresponding types
|
||||
// the bootstrap method's name), `it` iterates through the corresponding types
|
||||
// in the method signature
|
||||
unsigned i = 0;
|
||||
while (i + 1 < bootstrapArray->length() && it.hasNext()) {
|
||||
|
71
sgx-jvm/avian/test/ThreadExceptions.java
Normal file
71
sgx-jvm/avian/test/ThreadExceptions.java
Normal file
@ -0,0 +1,71 @@
|
||||
public class ThreadExceptions {
|
||||
|
||||
private static void expect(boolean v) {
|
||||
if (! v) throw new RuntimeException("Expectation failed");
|
||||
}
|
||||
|
||||
private static class Handler implements Thread.UncaughtExceptionHandler {
|
||||
public String message;
|
||||
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
message = e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
{ Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
throw new RuntimeException("TEST-DEFAULT-HANDLER");
|
||||
}
|
||||
};
|
||||
|
||||
Handler handler = new Handler();
|
||||
Thread.setDefaultUncaughtExceptionHandler(handler);
|
||||
thread.start();
|
||||
thread.join();
|
||||
|
||||
expect("TEST-DEFAULT-HANDLER".equals(handler.message));
|
||||
}
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(null);
|
||||
|
||||
{ Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
throw new RuntimeException("TEST-HANDLER");
|
||||
}
|
||||
};
|
||||
|
||||
Handler handler = new Handler();
|
||||
thread.setUncaughtExceptionHandler(handler);
|
||||
thread.start();
|
||||
thread.join();
|
||||
|
||||
expect("TEST-HANDLER".equals(handler.message));
|
||||
}
|
||||
|
||||
{ Thread thread = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
throw new RuntimeException("TEST-BAD-HANDLER");
|
||||
}
|
||||
};
|
||||
|
||||
Handler handler = new Handler() {
|
||||
@Override
|
||||
public void uncaughtException(Thread t, Throwable e) {
|
||||
super.uncaughtException(t, e);
|
||||
throw new IllegalStateException("BAD THING");
|
||||
}
|
||||
};
|
||||
thread.setUncaughtExceptionHandler(handler);
|
||||
thread.start();
|
||||
thread.join();
|
||||
|
||||
expect("TEST-BAD-HANDLER".equals(handler.message));
|
||||
System.out.println("Exception from UncaughtExceptionHandler was ignored");
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ public class Threads implements Runnable {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
((Thread.UncaughtExceptionHandler) Thread.currentThread().getThreadGroup())
|
||||
Thread.currentThread().getThreadGroup()
|
||||
.uncaughtException(Thread.currentThread(), new Exception());
|
||||
|
||||
{ Threads test = new Threads();
|
||||
|
Loading…
Reference in New Issue
Block a user