exception handling
play

exception handling Bart Jacobs and Frank Piessens Katholieke - PowerPoint PPT Presentation

Failboxes: Provably safe exception handling Bart Jacobs and Frank Piessens Katholieke Universiteit Leuven Overview of Presentation Purpose of exceptions: Dependency safety Conflicts with: Non-exception-safe objects and:


  1. Failboxes: Provably safe exception handling Bart Jacobs and Frank Piessens Katholieke Universiteit Leuven

  2. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

  3. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

  4. Problem Purpose of exceptions = Skipping operations that depend on success of failed operations ( dependency safety )

  5. Dependency safety: Example 1 int* x = malloc(1024 * sizeof(int)); x[1023] = 42;

  6. Dependency safety: Example 1 int* x = malloc(1024 * sizeof(int)); depends on x[1023] = 42;

  7. Dependency safety: Example 1 int* x = malloc(1024 * sizeof(int)); x == 0 depends on x[1023] = 42; Dependency violation!

  8. Dependency Safety: Example 2 int[] x = new int[1024]; depends on x[1023] = 42;

  9. Dependency Safety: Example 2 int[] x = new int[1024]; depends on x[1023] = 42; Dependency-safe!

  10. Problem Dependency safety = Hard to achieve Non-exception-safe objects Try-catch Threads and locks Thread.stop Try-finally

  11. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

  12. Exception Safety Object is exception-safe  A checked or unchecked exception Leaves the object In a consistent state

  13. Example: ArrayList class ArrayList { int count; int[] elems; void add(int x) { count++; if (count > elems.length) { int[] elems2 = new int[count * 2]; System.arraycopy(elems, elems2, 0, 0, elems.length); elems = elems2; } elems[count – 1] = x; } } Not exception-safe!

  14. Exception Safety Hard to achieve Goal: Achieve dependency safety in the absence of exception safety

  15. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

  16. Example: Interpreter 1 while (true) { String cmd = readCommand(); try { … compute(cmd); … } catch (Throwable t) {t.printStackTrace();} }

  17. Example: Interpreter 1 while (true) { String cmd = readCommand(); try { … compute(cmd); … } catch (Throwable t) {t.printStackTrace();} } OK!

  18. Example: Interpreter 2 ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); try { … compute(cmd); … … list.add(…); … } catch (Throwable t) {t.printStackTrace();} }

  19. Example: Interpreter 2 ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); try { … compute(cmd); … … list.add(…); … } catch (Throwable t) {t.printStackTrace();} } Bad!

  20. Proposed Solution: Failboxes = Language extension • API class Failbox: class Failbox { public Failbox(Failbox parent) { … } public static Failbox getCurrent() { … } public boolean hasFailed() { … } … } • new statement: enter (f) { ... } catch (Throwable t) { … }

  21. Failboxes root failbox public static void main(String[] args) { … }

  22. Failboxes root failbox child failbox (= f) public static void main(String[] args) { Failbox f = Failbox.getCurrent(); … enter (new Failbox(f)) { … } catch (Throwable t) { … } … }

  23. Failboxes root failbox child failbox (= f) public static void main(String[] args) { Failbox f = Failbox.getCurrent(); … enter (new Failbox(f)) { throw new RuntimeException(); … … } catch (Throwable t) { … } … }

  24. Failboxes root failbox child failbox (= f) public static void main(String[] args) { Failbox f = Failbox.getCurrent(); … enter (new Failbox(f)) { … enter (f) { … } catch (Throwable t) { throw t; } … } catch (Throwable t) { … } … }

  25. Failboxes root failbox child failbox (= f) public static void main(String[] args) { Failbox f = Failbox.getCurrent(); … enter (new Failbox(f)) { … enter (f) { throw new RuntimeException(); } catch (Throwable t) { throw t; } … } catch (Throwable t) { … } … }

  26. Example: Interpreter 2 ArrayList list = new ArrayList(); ArrayList list = new ArrayList(); Failbox f = Failbox.getCurrent(); while (true) { while (true) { String cmd = readCommand(); String cmd = readCommand(); try { enter (new Failbox(f)) { … compute(cmd); … … compute(cmd); … … … enter (f) { list.add(…); list.add(…); } catch (Throwable t) { throw t; } … … } catch (Throwable t) } catch (Throwable t) { t.printStackTrace(); } { t.printStackTrace(); } } }

  27. Example: Interpreter 2 root failbox child failbox (= f) ArrayList list = new ArrayList(); Failbox f = Failbox.getCurrent(); while (true) { String cmd = readCommand(); enter (new Failbox(f)) { … compute(cmd); … … enter (f) { list.add(…); } catch (Throwable t) { throw t; } … } catch (Throwable t) { t.printStackTrace(); } }

  28. Syntactic Sugar try { enter (new Failbox(Failbox.getCurrent())) { block1 block1 } catch (Throwable t) { } catch (Throwable t) { block2 block2 } } enter (f) { enter (f) { block block } } catch (Throwable t) { throw t; }

  29. Example: Interpreter 2 root failbox child failbox (= f) ArrayList list = new ArrayList(); Failbox f = Failbox.getCurrent(); while (true) { String cmd = readCommand(); try { … compute(cmd); … … enter (f) { list.add(…); } … } catch (Throwable t) { t.printStackTrace(); } }

  30. Syntactic Sugar (2) failboxed class C { class C { Failbox f = Failbox.getCurrent(); void foo() { void foo() { enter (f) { … … } } } void bar() { void bar() { enter (f) { … … } } } } }

  31. Example: Interpreter 2 root failbox child failbox (= f) ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); try { … compute(cmd); … … list.add(…); … } catch (Throwable t) { t.printStackTrace(); } }

  32. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

  33. Example: Concurrent Interpreter while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … } }.start(); }

  34. Example: Concurrent Interpreter while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … } OK! }.start(); }

  35. Example: Concurrent Interpreter 2 ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … … synchronized (list) { list.add(…); } … } }.start(); }

  36. Example: Concurrent Interpreter 2 ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … … synchronized (list) { list.add(…); } … } }.start(); } Bad!

  37. Solution: Failboxes Failbox f = Failbox.getCurrent(); ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … … synchronized (list) { enter (f) { list.add(…); } } … } }.start(); }

  38. Failboxes and Threads main failbox job 1 failbox job 2 failbox (= f) void run() { void run() { … … synchronized (o) { enter (f) { ... } } synchronized (o) { ... enter (f) { } ... } } ... }

  39. Failboxes and Threads main failbox job 1 failbox job 2 failbox (= f) void run() { void run() { … throw new RTE(); synchronized (o) { enter (f) { ... } } synchronized (o) { ... enter (f) { } ... } } ... }

  40. Failboxes and Threads main failbox job 1 failbox job 2 failbox (= f) void run() { void run() { … … synchronized (o) { enter (f) { throw new RTE(); } } synchronized (o) { ... enter (f) { } ... } } ... }

  41. The need for Fail Fast Failbox f = Failbox.getCurrent(); ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … … synchronized (list) { enter (f) { list.add(…); } } … } }.start(); }

  42. Asynchronous failure: Fail Fast main failbox job 1 failbox (= f) public static void main(String[] args) { … void run() { … synchronized (o) { serverSocket.accept(); async serverSocket.accept(); enter (f) { signal serverSocket.accept(); throw new RTE(); serverSocket.accept(); } serverSocket.accept(); } serverSocket.accept(); ... serverSocket.accept(); serverSocket.accept(); } serverSocket.accept(); serverSocket.accept(); }

  43. Solution: Failboxes Failbox f = Failbox.getCurrent(); ArrayList list = new ArrayList(); while (true) { String cmd = readCommand(); new Thread() { public void run() { … compute(cmd); … … synchronized (list) { enter (f) { list.add(…); } } … } }.start(); }

  44. Overview of Presentation • Purpose of exceptions: Dependency safety • Conflicts with: – Non-exception-safe objects and: – Try-catch – Threads and locks – Thread.stop – Try-finally • Solution: Failboxes!

Recommend


More recommend