Skip to content

Commit 954914a

Browse files
committed
Don't execute finally clauses on Java exceptions
Such exceptions signify interpreter crash and shouldn't be handed over to the program, as it might suppress them. There's a internal setting `CatchAllExceptions` which allows the Python code to catch Java exceptions. When this setting is on, Java exceptions get wrapped in Python exceptions and re-raised, thus the finally handlers are executed as well.
1 parent 8611c08 commit 954914a

File tree

1 file changed

+19
-7
lines changed
  • graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement

1 file changed

+19
-7
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/TryFinallyNode.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2020, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -30,6 +30,7 @@
3030
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.SaveExceptionStateNode;
3131
import com.oracle.graal.python.nodes.util.ExceptionStateNodes.SetCaughtExceptionNode;
3232
import com.oracle.graal.python.runtime.exception.PException;
33+
import com.oracle.truffle.api.CompilerAsserts;
3334
import com.oracle.truffle.api.CompilerDirectives;
3435
import com.oracle.truffle.api.frame.VirtualFrame;
3536
import com.oracle.truffle.api.nodes.ControlFlowException;
@@ -56,19 +57,30 @@ public void executeVoid(VirtualFrame frame) {
5657
restoreExceptionState(frame, exceptionState);
5758
}
5859
} else {
60+
boolean executeFinalbody = true;
5961
try {
6062
body.executeVoid(frame);
6163
} catch (PException e) {
6264
// any thrown Python exception is visible in the finally block
6365
SetCaughtExceptionNode.execute(frame, e);
6466
throw e;
67+
} catch (ControlFlowException e) {
68+
throw e;
69+
} catch (Throwable e) {
70+
// Don't execute finally block on exceptions that occured in the interpreter itself
71+
CompilerDirectives.transferToInterpreter();
72+
executeFinalbody = false;
73+
throw e;
6574
} finally {
66-
try {
67-
finalbody.executeVoid(frame);
68-
} catch (ControlFlowException e) {
69-
// restore
70-
restoreExceptionState(frame, exceptionState);
71-
throw e;
75+
CompilerAsserts.partialEvaluationConstant(executeFinalbody);
76+
if (executeFinalbody) {
77+
try {
78+
finalbody.executeVoid(frame);
79+
} catch (ControlFlowException e) {
80+
// restore
81+
restoreExceptionState(frame, exceptionState);
82+
throw e;
83+
}
7284
}
7385
// restore
7486
restoreExceptionState(frame, exceptionState);

0 commit comments

Comments
 (0)