From 904b44e229dacae45649764d2a529dac823b4ed0 Mon Sep 17 00:00:00 2001 From: Carlos Galindo Date: Sun, 8 Dec 2019 14:49:52 +0000 Subject: [PATCH] solution for try-catch problem and graphs --- Makefile | 2 +- Secciones/problem_solution.tex | 326 +++++++++++++++++++++++---------- img/catch-no-dep.dot | 51 ++++++ img/catch-no-dep.pdf | Bin 0 -> 20424 bytes img/catch-order.dot | 16 ++ img/catch-order.pdf | Bin 0 -> 12745 bytes img/incorrect-try-catch.dot | 40 ++++ img/incorrect-try-catch.pdf | Bin 0 -> 17310 bytes paper.tex | 1 + 9 files changed, 341 insertions(+), 95 deletions(-) create mode 100644 img/catch-no-dep.dot create mode 100644 img/catch-no-dep.pdf create mode 100644 img/catch-order.dot create mode 100644 img/catch-order.pdf create mode 100644 img/incorrect-try-catch.dot create mode 100644 img/incorrect-try-catch.pdf diff --git a/Makefile b/Makefile index 02762e8..0b2e1ef 100644 --- a/Makefile +++ b/Makefile @@ -14,4 +14,4 @@ paper.pdf: paper.tex images clean: rm -f Secciones/*.aux rm -f *.toc *.aux *.bbl *.blg *.fls *.out *.log *.synctex.gz - $(MAKE) -C img clean + # $(MAKE) -C img clean diff --git a/Secciones/problem_solution.tex b/Secciones/problem_solution.tex index 695e0cd..1bfc7d4 100644 --- a/Secciones/problem_solution.tex +++ b/Secciones/problem_solution.tex @@ -191,116 +191,254 @@ This problem cannot be easily solved, as it is a ``dynamic'' one, requiring info \section{The \texttt{try-catch} statement} -\subsection{The problem with the control dependency's definition} +In this section we present an example where the current approximation for the \texttt{try-catch} statement fails to capture all the correct dependencies and excludes from the slice some statements which are necessary for a complete slice (both weak and strong). After that, we generalize the set of cases where that is a problem and its possible appearances in real-life development. Finally, we propose a solution which properly represent all the dependencies introduced by the \texttt{try-catch}, focusing on producing complete strong slices. -\section{Previous text} -\carlos{Here begins the old text.} -\hrulefill +\subsubsection*{The types of control dependence} -This solution is an extension of Allen's \cite{AllH03}, with some modifications to solve the problem found \josep{el problem found no ha quedado claro. Se ha diluido entre la maraña abrumadora de casos. debes formular y dejar nitido cristalino cual es el problema y por qué no lo solucinan las dsemás aproximaciones, y poner un ejempllo concreto.}. Before starting, we need to split all instructions in three categories: +\carlos{this subsection snippet could go in another place} -\begin{description} - \item[statement] non-branching instruction, e.g. an assignment or method call. - \item[predicate] conditional branch, e.g. if statements and loops. - \item[pseudo-predicate] unconditional jump, e.g. break, continue, return, goto and throw instructions. -\end{description} +Even though it continues to be used for control dependence, definition~\ref{def:ctrl-dep} does not have the same meaning when applied to conditional instructions and loops as it has when applied to unconditional jumps and other complex structures, such as the \texttt{switch} and \texttt{try-catch} statements. -Pseudo-predicates have been previously use to model unconditional jumps with a counter-intuitive reasoning: the next statement that would be executed were the pseudo-predicate not there would be executed, therefore it is control dependent on it. Going back to the definition of control dependency, one could argue that the real control dependency is on the conditional branch that lead to the \josep{???} +Originally, the definition of control dependence signified that the execution of a statement affected whether or not another one executed (or kept executing). In contrast, unconditional jumps, and \texttt{try-catch} statements' execution do not affect the following instructions; its presence or absence is what generates the control dependency. For those instructions, control dependencies are still generated with the same edges, but require the addition of extra edges to the CFG \cite{BalH93,AllH03}. -\begin{figure} -\centering -\begin{lstlisting} -if (a) { - return a; +\subsection{The control dependencies of a \texttt{catch} block} + +In the current approximation for exception handling \cite{AllH03}, \texttt{catch} blocks do not have any outgoing dependence leading anywhere except the instructions it contains. This means that, as showcased in chapter~\ref{cha:introduction}, the only way a \texttt{catch} statement may appear in a slice is if there is a data dependency or one of the statements inside it is needed. + +The only occasion in which \texttt{catch} blocks generate any kind of control dependency is when there is an exception thrown that is not covered by any of the \texttt{catch} blocks, and the function may exit with an exception. In that case, the instructions after the \texttt{try-catch} block are dependent on an uncaught exception not being thrown. + +But, compared to the treatment of unconditional exceptions does not match the treatment of \texttt{try-catch} statement: unconditional jumps have a non-executable edge to the instruction that would be executed in their absence; \texttt{catch} statements do not. + +\begin{example}[\texttt{catch} statements' outgoing dependencies] + Consider the code shown in figure~\ref{fig:catch-no-dep-code}, which depicts a \texttt{try-catch} where method \texttt{f}, which may throw an exception, is called. The function may throw either a \texttt{ExceptionA}, \texttt{ExceptionB} or \texttt{Exception}-typed exception; and the \texttt{try-catch} considers all three cases, logging the type of exception caught. Additionally, \texttt{f} accesses and modifies a global variable \texttt{x}. + + \begin{figure}[h] + \begin{lstlisting} +try { + f(); +} catch (ExceptionA e) { + log("Type A"); +} catch (ExceptionB e) { + log("Type B"); +} catch (Exception e) { + log("Exception"); } -print(a); -\end{lstlisting} -\begin{lstlisting} -if (a) { +next; + \end{lstlisting} + \caption{A snippet of code of a call to a method that throws exceptions and \texttt{catch} statements to capture and log them.} + \label{fig:catch-no-dep-code} + \end{figure} + The CFG and PDG associated to that code is depicted in figure~\ref{fig:catch-no-dep-graphs}. As can be seen, the only two elements that are dependent on any \texttt{catch} are the log statement and the unpacking of \texttt{x}. If the following statement used \texttt{x} in any way, all \texttt{catch} statements would be selected, otherwise they are ignored, and not deemed necessary. It is true that they are normally not necessary; i.e., if the slicing criterion was placed on \texttt{next} (line 10), the whole \texttt{try-catch} would be rightfully ignored; but there exist cases where \texttt{f()} (line 2) would be part of the slice, and the absence of \texttt{catch} statements would result in an incomplete slice. + + \begin{figure}[h] + \includegraphics[width=\linewidth]{img/catch-no-dep} + \caption{CFG (left) and PDG (right) of the code shown in figure~\ref{fig:catch-no-dep-code}.} + \label{fig:catch-no-dep-graphs} + \end{figure} +\end{example} + +\begin{example}[Incorrectly ignored \texttt{catch} statements] + Consider the code in figure~\ref{fig:incorrect-try-catch-code}, in which a method is called twice: once inside a \texttt{try-catch} statement, and a second time, outside. \texttt{f} also accesses and modifies variable \texttt{x}, which is redefined before the second call to \texttt{f}. Exploring this example, we demonstrate how line 3 will be necessary but not included in the slice. + + \begin{figure}[h] + \begin{minipage}{0.5\linewidth} + \begin{lstlisting} +try { + f(); +} catch (Exception e) { + log("error"); } -print(a); -\end{lstlisting} -\caption{Example of pseudo-predicates control dependencies \josep{no se referencia a esta figura desde ningún sitio}} -\end{figure} +x = 0; +f(); + \end{lstlisting} + \end{minipage} + \begin{minipage}{0.49\linewidth} + \begin{lstlisting} +void f() throws Exception { + if (x % 2 != 0) + throw new Exception(); + x++; +} + \end{lstlisting} + \end{minipage} + \caption{A method that may throw exceptions (\texttt{f}), called twice, once surrounded by a \texttt{try-catch} statement, and another time after it. On the right, the definition of \texttt{f}.} + \label{fig:incorrect-try-catch-code} + \end{figure} -This is the process used to build the Program Dependence Graph. \josep{Todo lo que sigue es demasiado verbose. No hay definiciones concretas. Es todo muy informal, y no hay un ongoing example que permita ver como las fases van evolucionando paso a paso. Nos reunimos para hablar de esta sección antes de reescribirla...} + Figure~\ref{fig:incorrect-try-catch-graph} displays the program dependence graph for the snippet of code on the left side of figure~\ref{fig:incorrect-try-catch-code}. Data dependencies are shown in red, and summary edges in blue. The set of nodes filled in grey represent the slice with respect to a slicing criterion in method \texttt{f} (line 4, \texttt{x}). In the slice, both calls to \texttt{f} and its input (\texttt{x\_in = x}) are included, but the \texttt{catch} block is not present. The execution of the slice may not be the same: if no exception is thrown, there is no change; but if \texttt{x} was odd before entering the snippet, an exception will be thrown and not caught, exiting the program prematurely. -\begin{description} - \item[Step 1 (static analysis):] Identify for each instruction the variables read and defined. Each method is annotated with the global variables that they access or modify. - \item[Step 2 (build CFGs):] Build a CFG for each method of the program. The start of all methods is a vertex labeled \textsl{enter}, which also contains the assignments for parameters and global variables used (\texttt{var = var\_in}). The \textsl{enter} node is connected to the first instruction of the method. In a similar fashion, all methods end in an \textsl{exit} vertex with the corresponding output variables. There exists one \textsl{normal exit} to which the last instruction and all return instructions are connected. If the method can throw any exceptions, there exists one \textsl{error exit} for each type of exception that may be thrown. The normal and erroneous exits are connected to the \textsl{exit} node. + \begin{figure}[h] + \centering + \includegraphics[width=0.9\linewidth]{img/incorrect-try-catch} + \caption{The system dependence graph of the left snippet of figure~\ref{fig:incorrect-try-catch-code}. \texttt{f} and the edges that connect to it are not shown for simplicity.} + \label{fig:incorrect-try-catch-graph} + \end{figure} + +\end{example} - Every normal statement is connected to the subsequent one by an unlabeled edge. Predicates have two outgoing edges, labeled \textsl{true} and \textsl{false}. Pseudo-predicates also have two outgoing edges. The \textsl{true} edge is connected to the destination of the jump (\textsl{normal exit} in the case of return, the begin or end of the loop in the case of continue and break, etc.). The \textsl{false} edge is a non-executable edge, marked with a dashed line, and it is connected to the next instruction that would be executed if the pseudo-predicate was a \textsl{nop}. - Nodes that represent a call to a method $M$ include the transfer of parameters and variables that may be read or written to, then execute the call, and finally the extraction of modified variables. Call nodes are an exception to the previous paragraph, as they can have an unlimited amount of outgoing edges. Each outgoing edge lands on a pseudo-predicate which indicates if the execution was correct or an exception was raised. The executable edge of each pseudo-predicate will lead to the next instruction to be executed, whereas the non-executable one will lead to the end of the try-catch block. All call nodes can lead to a \textsl{normal return} node, which is linked to the next instruction, and one error node for each type of exception that may be thrown. The erroneous returns are labeled \textsl{catch ExType}, and lead to the first instruction in the corresponding catch block\footnotemark. Any exception that may not be caught will lead to the erroneous exit node of the method it's in. See the example for more details. +\subsubsection*{A solution for the \texttt{catch}'s lack of control dependencies} - \footnotetext{A problem presents itself here, as some exceptions may be able to trigger different catch blocks, due to the secuential nature of catches and polymorphism in Java. A way to fix this is to make catch blocks behave as a switch.}. %TODO +\texttt{catch} statements should be handled like unconditional jumps: a non-executable edge should connect them to the instruction that would run if they were absent. For \texttt{catch} statements, the non-executable edge would connect them to the \texttt{catch} that contains the most immediate super-type (or multiple); or to the error exit, if no other \texttt{catch} could catch the same exception. This would create a tree-like structure among \texttt{catch} statements, with the root of each tree connected to the ``error exit'' of the method. This would generate dependencies between \texttt{catch} statements, and more importantly, dependencies from the \texttt{catch} statements to the instructions that follow the \texttt{try-catch} statement. - \item[Step 3 (compute dependences):] For each node in the CFG, compute the control and data dependencies. Non-executable edges are only included when computing control dependencies.\\ - \carlos{put inside definition} - A node $a$ is \textsl{control dependent} on node $b$ iff $a$ post-dominates one but not all of $b$'s successors.\\ - A node $a$ is \textsl{data dependent} on node $b$ iff $b$ defines or may define a variable $x$, $a$ uses or may use $x$, and there is an $x$-definition-free path in the CFG from $b$ to $a$.\\ - \item[Step 4 (convert each CFG into a PDG):] each node of the CFG is one node of the PDG, with two exceptions. The first are the \textsl{enter}, \textsl{exit} and method call nodes, where the variable input and output assignments are split and placed as control-dependent on their original node. The second is the \textsl{exit} node, which is to be removed (the control-dependencies from \textsl{exit} to the variable outputs is transferred to the \textsl{enter} node). Then all the dependencies computed in the previous step are drawn. - \item[Step 5 (connect PDGs to form a SDG):] each method call to $M$ must be connected to the \textsl{enter} node in $M$'s PDG, as a control dependence. Each variable input from the method call is connected to a variable input of the method definition via a data dependence. Each variable output from the method definition is connected to the variable output of the method call via a data dependence. Each method exit is connected \carlos{complete}. -\end{description} +Unfortunately, this creates the same behaviour as with unconditional jumps: all the instructions that follow a \texttt{try-catch} structure is dependent on the presence of the \texttt{catch} statements, which in turn are dependent on all the statements that may throw exceptions. In practice, the inclusion of any statement after a \texttt{try-catch} statement would require the slice to include all \texttt{catch} statements, the statements that may throw exceptions, and all the statements required by control or data dependencies. This is a huge number of instructions just for including the \texttt{catch} statements. -\begin{itemize} - \item An extra type of control dependency represented by an ``exception edge''. It will represent the need to include a \textsl{catch} clause when an exception can be thrown. It is represented with a dotted line (dashed line is for data dependency). These edges have a special characteristic: when one is traversed, only ``exception edges'' may be traversed from the new nodes included in the slice. If the same node is reached by another kind of edge, the restriction is lifted. The behavior is documented in algorithm \ref{alg:2pass}, with changes from the original algorithm are \underline{underlined}. - \item Add an extra ``exception edge'' from each ``exit with exception of type T'' node, where the type of the exception is \texttt{t} to all the corresponding ``\texttt{throw e}'', such that \texttt{e} is or inherits from \texttt{T}. - \item Add an extra ``exception edge'' from each catch statement to every statement that can throw that error. - \item The exception edges will only be placed when the method or the try-catch statement are loop-carrier\footnote{Loop-carrier, when referring to a statement, is the property that in a CFG for the complete program, the node representing the statement is part of a loop, meaning that it could be executed again once it is executed.}. -\end{itemize} +Our solution makes slices complete again, but makes them much less correct. As a solution for the incorrectness, we could insert an additional requirement when including \texttt{catch} blocks: if they are included because of their control dependencies on instructions outside the \texttt{try-catch}, they need to satisfy an additional condition before being in the slice: have a node in the slice which may throw a compatible exception. In order to achieve this, control dependencies whose source is a \texttt{catch} node and its destination is outside that same \texttt{catch} are coloured green and labelled (2). Additional edges are added between every \texttt{catch} and any statement that may throw a compatible exception; are also coloured green, and labelled (1). When traversing the graph, only include \texttt{catch} statements if they are reached through an unlabelled edge or if they are reached by at least one edge with each label (1 and 2). \carlos{Add que solo se pueda atravesar uno de los arcos verdes (una vez llegas a un nodo a traves de un arco verde, no continuas recorriendo arcos verdes)} \carlos{optimizacion 2, que los nodos catch se repitan para cada funcion tenga los suyos propios. El contenido del catch es comun a todos, pero las cabeceras y el despempaquetamiento de variables es individual para cada funcion. De este modo no se coge a todas las funciones. Tambien se podria emplear como alternativa a los arcos etiquetados, creando un set de nodos que no tienen padre, y sirven exclusivamente para que las instrucciones futuras dependan de ellas.} -\begin{algorithm} % generate slice -\caption{Two-pass algorithm to obtain a backward static slice with exceptions} -\label{alg:2pass} -\begin{algorithmic}[1] - \REQUIRE SDG $\mathcal{G}$ representing program P. $\mathcal{G} = \{\mathcal{S}, \mathcal{E}\}$, where $\mathcal{S}$ is a set of states (some are statements) connected by a set of edges $\mathcal{E}$. Each edge, is a triplet composed of the type of edge (control, data or \underline{exception} dependency, summary, param-in, param-out), the source and destination of the edge. - \REQUIRE A slicing criterion, composed of a statement $s \in \mathcal{S}$ and a variable $v$. - \ENSURE $\mathcal{S}' \subseteq \mathcal{S}$, representing the slice of P according to the criterion provided. - \medskip - \COMMENT{First pass (do not traverse output parameter edges).} - \STATE{$\mathcal{S}' \Leftarrow \emptyset$ (slice), $\mathcal{Q}\Leftarrow\{s\}$ (queue), $\mathcal{S}\Leftarrow \mathcal{S} - \{s\}$ (not visited), $\mathcal{R}\Leftarrow \emptyset$ (only visited via exception edge)} - \WHILE{$\mathcal{Q} \neq \emptyset$} - \STATE{$a \in \mathcal{Q}$} \COMMENT{Select an element from $\mathcal{Q}$} - \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} - \{a\}$} - \STATE{$\mathcal{S}' \Leftarrow \mathcal{S}' + \{a\}$} - \FORALL{$\mathcal{A}$ in $\{\{type, origin, a\} \in \mathcal{E}\}$} - \IF{$type \neq$ param-out \AND ($origin \notin \mathcal{S}'$ \OR ($origin \in \mathcal{R}$ \AND $a \notin \mathcal{R}$))} \label{line:param-out} - \IF{\underline{$a \in \mathcal{R}$}} - \IF{\underline{$type =$ exception}} - \STATE{\underline{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$}} - \STATE{\underline{$\mathcal{R} \Leftarrow \mathcal{R} + \{origin\}$}} - \ENDIF - \ELSE - \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$} - \ENDIF - \ENDIF - \ENDFOR - \ENDWHILE - \\ - \medskip - \COMMENT{Second pass (very similar, do not traverse input parameter edges).} - \STATE $\mathcal{Q} \Leftarrow \mathcal{S}'$ - \WHILE{$\mathcal{Q} \neq \emptyset$} - \STATE{$a \in \mathcal{Q}$} \COMMENT{Select an element from $\mathcal{Q}$} - \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} - \{a\}$} - \STATE{$\mathcal{S}' \Leftarrow \mathcal{S}' + \{a\}$} - \FORALL{$\mathcal{A}$ in $\{\{type, origin, a\} \in \mathcal{E}\}$} - \IF{$type \neq$ param-in \AND ($origin \notin \mathcal{S}'$ \OR ($origin \in \mathcal{R}$ \AND $a \notin \mathcal{R}$))} - \IF{\underline{$a \in \mathcal{R}$}} - \IF{\underline{$type =$ exception}} - \STATE{\underline{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$}} - \STATE{\underline{$\mathcal{R} \Leftarrow \mathcal{R} + \{origin\}$}} - \ENDIF - \ELSE - \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$} - \ENDIF - \ENDIF - \ENDFOR - \ENDWHILE -\end{algorithmic} -\end{algorithm} +% \begin{example}[Order of \texttt{catch} statements] +% Consider the following exception types declared in figure~\ref{fig:catch-order-code}, and their ordering in a simple \texttt{try-catch} statement. The \texttt{catch} blocks may be reorganized in any order if the type + +% \begin{figure}[h] +% \begin{minipage}{0.60\linewidth} +% \begin{lstlisting} +% class ExceptionA extends Exception {...}; +% class ExceptionB extends Exception {...}; +% class ExceptionB1 extends ExceptionB {...}; +% class ExceptionB2 extends ExceptionB {...}; +% \end{lstlisting} +% \end{minipage} +% \begin{minipage}{0.39\linewidth} +% \begin{lstlisting} +% try { +% [...] +% } catch (ExceptionB2 e) { +% [...] +% } catch (ExceptionA e) { +% [...] +% } catch (ExceptionB1 e) { +% [...] +% } catch (ExceptionB e) { +% [...] +% } catch (Exception e) { +% [...] +% } +% \end{lstlisting} +% \end{minipage} +% \caption{A set of type declarations that extend the class \texttt{Exception} (left) and a small \texttt{try-catch} with the exceptions sorted in one of the valid orders (right).} +% \label{fig:catch-order-code} +% \end{figure} +% \end{example} + +% \texttt{catch} blocks can be organized in two different orders: the physical order in which they are placed by the developer, which is the order in which they will be evaluated to check for type compatibility (in Java specifically); or a tree-like structure according to their types. Figure~\ref{fig:catch-order} showcases a couple of examples of each order. In Java's case, the tree structure is more correct; because though the order ``seems'' to matter, there is only one possible execution order. + +% \begin{figure} +% \centering +% \includegraphics[width=0.5\linewidth]{img/catch-order} +% \caption{Two ways of looking at \texttt{catch} block orders: user-specified (left) and type-based tree (right).} +% \label{fig:catch-order} +% \end{figure} + +% \newpage +% \section{Previous text} +% \carlos{Here begins the old text.} +% \hrulefill + +% This solution is an extension of Allen's \cite{AllH03}, with some modifications to solve the problem found \josep{el problem found no ha quedado claro. Se ha diluido entre la maraña abrumadora de casos. debes formular y dejar nitido cristalino cual es el problema y por qué no lo solucinan las dsemás aproximaciones, y poner un ejempllo concreto.}. Before starting, we need to split all instructions in three categories: + +% \begin{description} +% \item[statement] non-branching instruction, e.g. an assignment or method call. +% \item[predicate] conditional branch, e.g. if statements and loops. +% \item[pseudo-predicate] unconditional jump, e.g. break, continue, return, goto and throw instructions. +% \end{description} + +% Pseudo-predicates have been previously use to model unconditional jumps with a counter-intuitive reasoning: the next statement that would be executed were the pseudo-predicate not there would be executed, therefore it is control dependent on it. Going back to the definition of control dependency, one could argue that the real control dependency is on the conditional branch that lead to the \josep{???} + +% \begin{figure} +% \centering +% \begin{lstlisting} +% if (a) { +% return a; +% } +% print(a); +% \end{lstlisting} +% \begin{lstlisting} +% if (a) { + +% } +% print(a); +% \end{lstlisting} +% \caption{Example of pseudo-predicates control dependencies \josep{no se referencia a esta figura desde ningún sitio}} +% \end{figure} + +% This is the process used to build the Program Dependence Graph. \josep{Todo lo que sigue es demasiado verbose. No hay definiciones concretas. Es todo muy informal, y no hay un ongoing example que permita ver como las fases van evolucionando paso a paso. Nos reunimos para hablar de esta sección antes de reescribirla...} + +% \begin{description} +% \item[Step 1 (static analysis):] Identify for each instruction the variables read and defined. Each method is annotated with the global variables that they access or modify. +% \item[Step 2 (build CFGs):] Build a CFG for each method of the program. The start of all methods is a vertex labeled \textsl{enter}, which also contains the assignments for parameters and global variables used (\texttt{var = var\_in}). The \textsl{enter} node is connected to the first instruction of the method. In a similar fashion, all methods end in an \textsl{exit} vertex with the corresponding output variables. There exists one \textsl{normal exit} to which the last instruction and all return instructions are connected. If the method can throw any exceptions, there exists one \textsl{error exit} for each type of exception that may be thrown. The normal and erroneous exits are connected to the \textsl{exit} node. + +% Every normal statement is connected to the subsequent one by an unlabeled edge. Predicates have two outgoing edges, labeled \textsl{true} and \textsl{false}. Pseudo-predicates also have two outgoing edges. The \textsl{true} edge is connected to the destination of the jump (\textsl{normal exit} in the case of return, the begin or end of the loop in the case of continue and break, etc.). The \textsl{false} edge is a non-executable edge, marked with a dashed line, and it is connected to the next instruction that would be executed if the pseudo-predicate was a \textsl{nop}. + +% Nodes that represent a call to a method $M$ include the transfer of parameters and variables that may be read or written to, then execute the call, and finally the extraction of modified variables. Call nodes are an exception to the previous paragraph, as they can have an unlimited amount of outgoing edges. Each outgoing edge lands on a pseudo-predicate which indicates if the execution was correct or an exception was raised. The executable edge of each pseudo-predicate will lead to the next instruction to be executed, whereas the non-executable one will lead to the end of the try-catch block. All call nodes can lead to a \textsl{normal return} node, which is linked to the next instruction, and one error node for each type of exception that may be thrown. The erroneous returns are labeled \textsl{catch ExType}, and lead to the first instruction in the corresponding catch block\footnotemark. Any exception that may not be caught will lead to the erroneous exit node of the method it's in. See the example for more details. + +% \footnotetext{A problem presents itself here, as some exceptions may be able to trigger different catch blocks, due to the secuential nature of catches and polymorphism in Java. A way to fix this is to make catch blocks behave as a switch.}. %TODO + +% \item[Step 3 (compute dependences):] For each node in the CFG, compute the control and data dependencies. Non-executable edges are only included when computing control dependencies.\\ +% \carlos{put inside definition} +% A node $a$ is \textsl{control dependent} on node $b$ iff $a$ post-dominates one but not all of $b$'s successors.\\ +% A node $a$ is \textsl{data dependent} on node $b$ iff $b$ defines or may define a variable $x$, $a$ uses or may use $x$, and there is an $x$-definition-free path in the CFG from $b$ to $a$.\\ +% \item[Step 4 (convert each CFG into a PDG):] each node of the CFG is one node of the PDG, with two exceptions. The first are the \textsl{enter}, \textsl{exit} and method call nodes, where the variable input and output assignments are split and placed as control-dependent on their original node. The second is the \textsl{exit} node, which is to be removed (the control-dependencies from \textsl{exit} to the variable outputs is transferred to the \textsl{enter} node). Then all the dependencies computed in the previous step are drawn. +% \item[Step 5 (connect PDGs to form a SDG):] each method call to $M$ must be connected to the \textsl{enter} node in $M$'s PDG, as a control dependence. Each variable input from the method call is connected to a variable input of the method definition via a data dependence. Each variable output from the method definition is connected to the variable output of the method call via a data dependence. Each method exit is connected \carlos{complete}. +% \end{description} + +% \begin{itemize} +% \item An extra type of control dependency represented by an ``exception edge''. It will represent the need to include a \textsl{catch} clause when an exception can be thrown. It is represented with a dotted line (dashed line is for data dependency). These edges have a special characteristic: when one is traversed, only ``exception edges'' may be traversed from the new nodes included in the slice. If the same node is reached by another kind of edge, the restriction is lifted. The behavior is documented in algorithm \ref{alg:2pass}, with changes from the original algorithm are \underline{underlined}. +% \item Add an extra ``exception edge'' from each ``exit with exception of type T'' node, where the type of the exception is \texttt{t} to all the corresponding ``\texttt{throw e}'', such that \texttt{e} is or inherits from \texttt{T}. +% \item Add an extra ``exception edge'' from each catch statement to every statement that can throw that error. +% \item The exception edges will only be placed when the method or the try-catch statement are loop-carrier\footnote{Loop-carrier, when referring to a statement, is the property that in a CFG for the complete program, the node representing the statement is part of a loop, meaning that it could be executed again once it is executed.}. +% \end{itemize} + +% \begin{algorithm} % generate slice +% \caption{Two-pass algorithm to obtain a backward static slice with exceptions} +% \label{alg:2pass} +% \begin{algorithmic}[1] +% \REQUIRE SDG $\mathcal{G}$ representing program P. $\mathcal{G} = \{\mathcal{S}, \mathcal{E}\}$, where $\mathcal{S}$ is a set of states (some are statements) connected by a set of edges $\mathcal{E}$. Each edge, is a triplet composed of the type of edge (control, data or \underline{exception} dependency, summary, param-in, param-out), the source and destination of the edge. +% \REQUIRE A slicing criterion, composed of a statement $s \in \mathcal{S}$ and a variable $v$. +% \ENSURE $\mathcal{S}' \subseteq \mathcal{S}$, representing the slice of P according to the criterion provided. + +% \medskip +% \COMMENT{First pass (do not traverse output parameter edges).} +% \STATE{$\mathcal{S}' \Leftarrow \emptyset$ (slice), $\mathcal{Q}\Leftarrow\{s\}$ (queue), $\mathcal{S}\Leftarrow \mathcal{S} - \{s\}$ (not visited), $\mathcal{R}\Leftarrow \emptyset$ (only visited via exception edge)} +% \WHILE{$\mathcal{Q} \neq \emptyset$} +% \STATE{$a \in \mathcal{Q}$} \COMMENT{Select an element from $\mathcal{Q}$} +% \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} - \{a\}$} +% \STATE{$\mathcal{S}' \Leftarrow \mathcal{S}' + \{a\}$} +% \FORALL{$\mathcal{A}$ in $\{\{type, origin, a\} \in \mathcal{E}\}$} +% \IF{$type \neq$ param-out \AND ($origin \notin \mathcal{S}'$ \OR ($origin \in \mathcal{R}$ \AND $a \notin \mathcal{R}$))} \label{line:param-out} +% \IF{\underline{$a \in \mathcal{R}$}} +% \IF{\underline{$type =$ exception}} +% \STATE{\underline{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$}} +% \STATE{\underline{$\mathcal{R} \Leftarrow \mathcal{R} + \{origin\}$}} +% \ENDIF +% \ELSE +% \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$} +% \ENDIF +% \ENDIF +% \ENDFOR +% \ENDWHILE +% \\ +% \medskip +% \COMMENT{Second pass (very similar, do not traverse input parameter edges).} +% \STATE $\mathcal{Q} \Leftarrow \mathcal{S}'$ +% \WHILE{$\mathcal{Q} \neq \emptyset$} +% \STATE{$a \in \mathcal{Q}$} \COMMENT{Select an element from $\mathcal{Q}$} +% \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} - \{a\}$} +% \STATE{$\mathcal{S}' \Leftarrow \mathcal{S}' + \{a\}$} +% \FORALL{$\mathcal{A}$ in $\{\{type, origin, a\} \in \mathcal{E}\}$} +% \IF{$type \neq$ param-in \AND ($origin \notin \mathcal{S}'$ \OR ($origin \in \mathcal{R}$ \AND $a \notin \mathcal{R}$))} +% \IF{\underline{$a \in \mathcal{R}$}} +% \IF{\underline{$type =$ exception}} +% \STATE{\underline{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$}} +% \STATE{\underline{$\mathcal{R} \Leftarrow \mathcal{R} + \{origin\}$}} +% \ENDIF +% \ELSE +% \STATE{$\mathcal{Q} \Leftarrow \mathcal{Q} + \{origin\}$} +% \ENDIF +% \ENDIF +% \ENDFOR +% \ENDWHILE +% \end{algorithmic} +% \end{algorithm} % vim: set noexpandtab:ts=2:sw=2:wrap diff --git a/img/catch-no-dep.dot b/img/catch-no-dep.dot new file mode 100644 index 0000000..2c3f823 --- /dev/null +++ b/img/catch-no-dep.dot @@ -0,0 +1,51 @@ +digraph g { + before [label = "", style=invis, width =0.001, height = 0.001]; + t [label = "try"]; + f [label = f()>]; + er [label = "error return"]; + nr [label = "normal return"]; + o [label = "x = x_out"]; + o1 [label = "x = x_out"]; + o2 [label = "x = x_out"]; + o3 [label = "x = x_out"]; + c1 [label = "catch (ExceptionA e)"] + c2 [label = "catch (ExceptionB e)"] + c3 [label = "catch (Exception e)"] + l1 [label = "log(\"Type A\")"]; + l2 [label = "log(\"Type B\")"]; + l3 [label = "log(\"Exception\")"]; + after [label = "next"]; + after2 [label = "", style= invis, height = 0.0001, width = 0.0001] + before -> t -> f -> er -> {c1, c2, c3}; + f -> nr -> o -> after; + c1 -> o1 -> l1; + c2 -> o2 -> l2; + c3 -> o3 -> l3; + {t nr c1 c2 c3} -> after [style = dashed, constraint = false]; + {l1 l2 l3} -> after -> after2; + + BEFORE [label = "", style = invis, width = 0.001, height = 0.001]; + T [label = "try"]; + F [label = "f()"]; + X_IN [label = "x_in = x"]; + X_OUT_NORMAL [label = "x = x_out"]; + X_OUT_1 [label = "x = x_out"]; + X_OUT_2 [label = "x = x_out"]; + X_OUT_3 [label = "x = x_out"]; + NORMAL_RET [label = "normal return"]; + ERROR_RET [label = "error return"]; + C1 [label = "catch (ExceptionA e)"] + C2 [label = "catch (ExceptionB e)"] + C3 [label = "catch (Exception e)"] + L1 [label = "log(\"Type A\")"]; + L2 [label = "log(\"Type B\")"]; + L3 [label = "log(\"Exception\")"]; + NEXT [label = "next"]; + BEFORE -> NEXT; + BEFORE -> T -> F -> {X_IN NORMAL_RET ERROR_RET} + NORMAL_RET -> X_OUT_NORMAL + ERROR_RET -> {C1 C2 C3} + C1 -> {X_OUT_1 L1} + C2 -> {X_OUT_2 L2} + C3 -> {X_OUT_3 L3} +} \ No newline at end of file diff --git a/img/catch-no-dep.pdf b/img/catch-no-dep.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1fba6f489356da723eb1959e6819a21d9292ddad GIT binary patch literal 20424 zcmY!laBogG(kNl|KIE>{KP);Zq&Z;zF>KK~=y;$F+XFmerh zcQcRD!O3TM?$1n-a8&OTit)TQmG{JdyZg7kK6+_qb2q#!LGsnA!&Muy-tN6#7hr#O z|NQz{^}oNK&-?d_|8v&=--oZ4SpL3zHu0+c`TOS!Z%?!RWpn(hZhP_Xns>!{Cksyp zm%N@7)KgsIUa2Lsu`k>9eDR6blMX-g^Iv*r-YVnPdzY^z$GqldufB2JB#rCl{)qKo zea`CymtXyL?Dm(Lar^Io{&V*a`?=$O&woCzoLgdNZ-3u}K6k~Uf z?GB6GH02)!ZCl>m_~qB|`g|;N-Y16r8Ou+U?48QA*>c@IW%gy$%l?&xDu4X``OWoJ z-5I%7_9b_&9N#)ma*Eye`ved&lTj?hkIz8O}=L_-o{N~G*bt51D*`;6jJ=3o< zJ;fVZh;Oyt8RxeA&^2rk-PVy-ATuw1@%%~azrPA|>@tq;+w(kf_HE1m8o|)qQSB7GV*{VsC#UlKO_mQQ=C0pk6~z#0P;Ih$p&xGp^A8K%bH4jG zPA(O0xpm><;X5{Wjt|#CHT**(pZ- zJfUExA3L`+_^g)g!R*^5y$>{|nk)%L;P5JP_63o^jw^*z(U$R`qRo z{no;*Ag!(8G#|(9eLEUB*^WtGK9=bcu;bMVmgZ{ioI1z(%(4b7a&M2xh)X!JoINh| zIFU^t`o-Ssb5lwPC5b*c6^-P900Tlwmj$Isud zF8bB~>%ITi`}&NA_ZgCQRmV@ zOSa|v6}NcNtrwO%MEAYSv{{^Y`;y7=bFVIBe%bK#dlOSt^FH_DTp7P`?zvBG_B*%) za(oVc{Xg&Dx0mH#XU0dRUzV%Se6`qcseJv9?fgLx3hQRwc22V5-?_D2LF%u|3e_iq z&vrAe61n(C&gc1tXO+!fJ4=_dTi%YnmEO+C_HvJ8+UJPHXYR}1RdQYF-rsZb&VpdY zMCO;x?CljR^b1^8Ec5@e@JUUAsfkqhymb?nc-n?>7BH|mU&=5usW1t(+AxXfJljK) z#nBVC6zW&HMqi#I(|3yRR;GwR(#+`o*smF861^WCQqT0RWLsJrTPJ-x%h~;Ww85-4 zeb)T=OY5pF4zGxw-qy1$;@#mD7SZ7bv*xq)?5mQmc_Woz{L#VXFPry`hQ@Vl(K}={ zB)`<(NLlpbqk;GSM{7>j{S2-0E~@)+^sQ!5QTYSq`L~@fd}D6m5Ic84S!B`E9flR( z+N_#q9awMHA>@DX{AV%wK;aDD7v7@Qd#}E;mzfzWRxx9)X;RRFWWUxE(`U)CZS(qG z`l3f}_q~fb-|rvuf0VuHA?q{~1-07PS+(K0Derf%ozspIDhb$85YID*Y1;P}^NkDM zJ$$zBFIP->!_|&Sx=PIgQa0?(E#)t~jxRgRCT-fit!TNx1kD9Y`WU#c>8d-v7BXYp zy(M38cER!v)}8?eqNMe$9Y2EKErswVKI#v10)$Zr~xEcEk`Ep;fPDszU=(|g8rVy<6f+D z><;YwILjixAR{EfiBW8$UfjYGmAigAHOg&^xgT1Z>+qRRQ<*(`{p1!;IfhuRdkdx8H=VS@lNkBc(67fxp+jU&;OV#YDTA_td}KnVB;0_V24s?+r5f z93Sqo{B_UC?aXs=u4~Lc%PmCI_Q;6(xOdID+Wgre(pP88dBN=h-SKUGa?9G%zp@Jy zU!IWrM9a%tiE^oCfmh*`XVa-;)>tZ{du21zwUG5 zKXC^;``SMS?_YoU@_oNam7R3r{pad4swyWz*`e#y$w%^WZmc~`1Gc}o6^ zZ}wzJ>j}OxzT8mzE%a;j{gCO)FD8Hcspr-uX#2VB&(m^=i>o8H%oXctzp?hE|I1DH z-Xv{wnr(DY((`PE`ecoodY7*656!0t^VudoRSaBwyuf~zuimkWz;$K99#j6z*{8R^ zH+Sp8#m}Rb#m%3-SJvQ{)5KZ3J$(H?hrbtJ_|eO`CF=ea*A-uR1f^{GT|M5jyKn8e zm~u(2Ffe{|gL8`+lhL%uRp&KtlueCPy4rexSMJvA*cK+n`RAOOV?MdK3;a`aIwH&| zdeC{f;ihjAM~|w$JgerEyCdOhdRTM&>s1*lb+4=6C|944R$_^(mYQhrKw#nR4YxYm z<2om-Q&^hscZs@GsVB=1f&1sikRC+g@Ti&{!XZKUzb3#`h`tB2Dj7e3q|AFX~@`=fG@ z0C|GMyZ)-}#Y=ahEH8-1SEvr}xXWw*Id$r0H`>G0KB_ttIsyzIyF zHCl%2bCsiw^FJA-hQ4fkDO5Z4V&&mgMedTbbNYogP5I1Sa4q-feADGiqeA~k%n32k zH!4ubj#Zs;xoGOC!k{x=6BqgklzgmdcYj+RaZ{~p=c6di?JU&^wyHCeydu_0FF*Qr z&niydyzC>qj=vpeKDE&fc3m)idVF@s+5#Qdqc+~Y7T0C^-ZJRN=O0M7WgS)r$oQ$(6Jt`NTM!t`OHUfxZ$ zR=K01o%VM(J*xN@;IZoNrYaq=yLyqbeiysSPF@exep##Z_G;(U{?IS~7;UZNH+`}D zryv!v<6?2{ZGPL}*0Y;f1$LyYn7&Ni`1s99wO4fI=k&8aDDdSBdw6IKV|wViA1B2s z^yZqVDlPGd3OmC$eM*Il*$kB+m1>u!rA*FR0Hjj?$W*&VUUUgqKd^?#lF-604}G4tCgrpCFq$XNpr5#P+w8fsI_oM$hj!7wM%BK7kVq@c%(^C>Cajx#!zno=bbJ} zvb*%=6-k>h86G>!pzJGGr}SgVE#(!i+Q*y3n=1}k?UCQj!O6`~5m;}eaKvt@hdG1y zoHXG8k5}4Vd?F%$)n_T?Z$Ii6rxP%RU*UG(X$^TEo|)?x)tpF+Xke*KP12MXxzwlK zD(U=D(N27~-ee`m7L5zDB(h~$j&;|t6sEkLxnjkkM=f>}c|O0eU|-_1Fh;B4P0)m! zZ==3z7`fh?#v`8I$-~XI=yghip!gxfGkLq)Cb%xC3#z(M{p4BF^|aix9D(^y9!M;C zIKz0sf6bbMH@9uzdHm76bG4DO_WJ^_kjAFu59+Fd8y&>c*Rpo}I2jXow4o#A=!+-s z4*Wah$H~IR^Lt_J>|F3rKR5QM;llt^6+kyo%@Q%J$|im ziwVR3*;a?|6unscNnk?CnuED>6OTzvx%t~?Z~7IE-0;2Y z-`AY^^6Kxs*@0)h)aIS$%8zBz*4AlF&Yvdw$RxQ|Cv3%KyCt?9;=)T?rn$T<`Lr;` z)uFc`ck1qiPbX^m{GPS8#DCA3nEBQ_wRgMsXtavA$cZvtPnhQ5*0EHe0(#nssXhUmx>r&vTOtm+8wlGV{xQ=IVbpecg*$jXZyN3kpI{ zm1dseTEzZ9VpH4B^{&eo_y6eH)adMTaEq-8%g%3eMBQKbo0=}Pnd5uK`c~G7`uEO{ z1^3?fuVQZdm9+C(@ipnS`EPcgzw*URe`T${iO1|Ms{&Y~>Rdx#SS$(@z4dDamuS24 z$Lm#V0u0t#^e%Rvd)$jZFj{Jd~ z>qdJF<-{w`_%<&;y(w&=x!G0sdF6ladEeW3G-pou(We!$&0kYpkBaO&@b`nVYu!qX z8>w;)mIrm2js&RBNsQyN-5AuGX&P2><%ishq8Ey@8+e5BYY)g?__Bh(T4c4_{Hebm zMrc^3a&AmY-C$>^8ovIObjF2w3or1CG;BGw@?b7GP7h~PScfRkrl;v6;+*Wu` z>~62zf|euS*l(@v{m9j6Vx&~xxcv97KW5vmw)M%){$0!XttPnS`l=JviD#_4-l^F+ zYt%f<&ksxdCVuGZ0p=E&hK_%e7#Qm{{1+d8VXk-SMPrTdw5vDoD)OZBGR*n1!kT5* zJ{HcjuX9Zus^4)5&AJk~bt;#$FY}gVKciH&m#6@YKF&Y40<7 zcx+b6<4LZ0QNsN91r*#Cv>aTrNi9v=ZNU_q)QtA0cfJUp(6`)fx9PjV))J@c1=n;R za$S2^Dz%tPJhRpq>Tzl?j~PR*EwDO*)|-d#C0SBR~jD||`U5Bp4i z3Cr)dXW4o>^!6nPOv54pZkB!lJGpy7caN0yQDpE@yhYbg@iW{?^T}noAXGlcYStyq$%80lSK|&&{OIS({h-sJU(p4paN96`k0#TjO@~)R3p^ zt_l_%>ay@LSv612c9~FganReDq6d3EuDD{jedXlPh85q3LF`c{?N+usjO=bzD) zcUyI2u5d{1t+hTi#$Ua@9bbB~wZT@)SMTeJ{i_biGBF7&#Ch!VdlF_N*X-pmae>yV zxo>1=)wRC0uDzLX(|C`nyF_?k0rye0RNeQpaxOPmFt9A;&~YwI{22Cgi;?O4;-b=D z-CZ7#A6It+4MrN+g9oCKE_$ue)Mfbv}@#v+@d8u*JuCz_w<66Bv06m%$4$&`dKaH*slw<{qoJ^ zJo=EmsLJ2bFaO)`^^e!?+Iu$l6bpavApnHP($wMk`rbR%w;m-Q=e|kbCD|9 zP-9)Nu=vc0imXR_SE?(lVv1fDRmpxvM4Zk3q4brX!mfI5CsNNQWOixCXvq3jy|^7x zTio7wK>vYs)-MAO>#HZGg+6nh+p@no>B^f+4q>kfUOeXZFPXhwjU&$H*P1sCULSm= z)_44kE9EJ2?GhZQwgt-xJA^acn$;Y|ptvt?DkcW;lci4a{h>0?-H%o&bfu(+e003XvTN=R?W<-Av-hmu zH~U!cf*7$S0q>f(^8PyX`VjZiz!o=+!_2BrQs?h%)Oj(Hg*kJn6pPRUkr@ih*R7g2 z^;Z}Br;ZOy^-oqQ?KWlK6q@F==h%c^$r=Ia>Cu}Rr@c< zNqkuI_^fDdad^0hZ0I%9l;ky19Pp&QqNq`1VWOG-tgUAMp2N)C%j^2xpem znhbBDb8Q_Sa_p+U3*1FZuc+u4c!mnTstZk4T;F1Fo;hiS`-ua$V<-PLQ`HTa>}l%p zCPsFGf>O)9tI13z&mJ)ewD1FS4nQ` zB9-bX{}~)N>K<9TGDvXNtUn*;7*4&u)w^6M>xGVtncwcDou=&5zN!|s%#)4_mCanU zH6gOpSnIIPenrbw=2FgI;~h3|sT`iY+IK?tz3az=Ev}^QdARlLTDCn))@5Ii+x^D* zwcGv|uQh-4hE030uS?{C=wIPi25*ZSPyX{(5=7wmv9qg&RX`VsoHQL z=IBgzAr+3m=EeJh9{u_KpZQ(rrd?dAc`4Azl+?Tw&>ReC;sr#TnV6Y@WI=2rr1_bU z%7Rn{{eZ-DFj1Qif-D401O*i3CkLmNC`2ph2e`N?=!c|Mlqke1 z=sV}<_9U{P~TZ1`2;%C zWC(Ihkb=ISg0X_WBWSuQFR>(5LEj~{EHgPZ$lZzXEY#d-~&F9;%-%NjBdwmx}z@H|TLnRT64JHdCMBcqV7$YQn`p9=C z2?0jF2*v{s)6!Vnf4DGR`Low{=FAly$2Na^r`M3O`?k*h0JY+4|LZ3znLDenF>twF zHM6Nx6MxDyC3y2uNu&QPr@l0;^hOj;&*eMaWf7bntwecT-UGs#eU%3@GZ1fBpFho&Q8hAmX2!&~Yh~WPjlA|O|Jt6Y`W^aF?aldl zjy>}t@8`T(qrX>-;hRd-Y}w8GriLJW$Ri$g z?(R2la*7$}XX|OdF#kQjDgV^|Hp}lbPrv&eX1z?@zERmz)Hv1k>9Xa^yj{+m;o+Np zKIQLsf&Y&WSZ1C*d01!8`~%`2TVI3*zL>(<(wVWl)uu6Gf?f(&Oa0Y{^%7?4?2>hJ zvqdsW;~8pOEdzFVvY*JeWpGwzR>`xkVyb-|EnvuXV&9&OwG-DD_ZwCHd;UwFJEkk| zp^u|d@Uw3`{V7GNi*zIx-*3q|$Rsp@y<`EGNu!xa;c!26`hiP@=p1(O1GgV~?GUr$+kQy= zq4Wm^o!0n6lQ|qta4=tVi{Oy{=;AaXLWNOKF?*uY5~h`|vnKE@k>1(sF|qIoGh6$@ z#2FG|$0Q%ONA^5S3QN3}AMs~qX#&QLKbw{&UER1WLVb;W8K;@x>|Wg? zVF~>S(Ho|3WWJI3##)B&_yNgBG6i)zBw~#6OxLk&=fB>wyW#a=-iK-*EB0vJ6M5gn zf3WyNQjOw1u6mhzx%>U{$M&mF;EZC)ZsJ#*rl69e5+WeQ@tosti{K%Xz{VB+B}#1q zl}BQdG&lC$aNOf5qvkhR#IsFBJV-@z=9b0~&n%@_HCwg4ijz-TrMMSKL^{OzuTz#RjnlRA=SC3Pk>KQcWUsJdrT7gNi0zO;!Vlvh$)!D$dv^Eqe>Qox^ZeuU zx6RgP#{J);IrXPjo>t9NrKxFC8K?HI@(InqDspx1s@zrnR}8Y$vJ$gyX8pdZx4QTI z^7G~M&d-fE`Tyik`>PGRI;(d4%KCcvmF=s^QnRG?Nl8kDN=-L8W-2)=Z`R3KPiH+h zIld($ihC)tNcy=b@O?rPh$$tyNTq%Zc{d`>ua zl3ujAC!R1c=-ue;x@#_QMFSHAszjpqT{qFmt>rWlHpl~ap+i~{66$`r-?oXVT zxcFhR@~VleFKR80T5NsHB6(Y3*GId@(P|qy=Xy@^>^yDJv2^HwKV_qC3Eq-G>*MDCVX z8-5+Wb!1j{Y;x`Kwyej=o6jw~`)uplmAd!K_P?#Qo)x>{uGntB-RHmYeN+0a_S=x% zw!NZ#FW>hYC1o1BTWYTgzJBp=$GML^kJ;6$)i+-DTz-FUCzoIKq zbg}T^4w<5fdMSE6@f8INuY}&7`Z((KuQR^ad!Lsb$vtxShV9M2JAP~Pd-G3p?>;_d z`Q+zP=egrLrmqj57`}e{r0+@Zv)(Vav$E^7>$MZ!SGI3;t^SY1zf6D2e%<|i{loKL z*MIx7Sg@?&e8IJZ#f>G5-HzLcQ;4;cPzOL1-(_Ou% zN9aUue&W^>)uXV?R!m-6v|6RCXyx}ycfH#mzj?&<_?@0{%(TsKZWV2Py7Kh-bra$b zMiy$xNz2RL7x>>Pd}!rUpLJj2ca}e8xjuP!`|nB5k7+;e{TTZr_0L3>=`EXDF1k!V z65E;Vxz1D6^D&dZYYii??={#|GazVTg%(MOTR7sUH+hqqx{a@m%Bbk%uI@myLn;VgV?oC z&wN_+Y5VT*H~Yd8qYD%GGy7Bew-~M1wAX8WmiyJ^ua>-Olvd#z*c(Zo9s*Bn0odeN(0`_t>=>s{V@e4KdRz14l` z@k9NkSFNvHH(y~s#q3b;q+=T&7aq_5`{1i{weaef0mh4W{$R0CwEXz!_z(H_^LT7- zR(92{da3?*{3YK9%l$ ze&RXNIkPS2m)CuAI@bEJyHmW~D!jyQ*On)j=C0eY?%wIf>FeV@?krk)d++Z*q0?8V zud|G`uAN)E_ifwX-fMEZ=S_=$Q-*fjFAFyRo%VQb-#*sb=f7fq>)-pftM+N% z|GCo4-E6FuljA9u(0W$nGc7ui?x$Jw8$viO_vH~G!uMe1DsTJu)ful;-V$Mv+8 zd%wI{a6RGt=8p9KwjIv;|EK<3?|+!}{L1s%Zd=@5xvzCU-}AHQZq>#wM?akInSS|k z>we9D+rCe|xO#qF`R~2yNhgnd$iDb`roGp_75glIUHg{%Jmtlc%jKExmo4wQw|bxb zx5mE#4WR^xWqXlu}Hz#NI~Bx5y~+%GE~qH&rB)F0DIEZfXhI^!~o<_ zP)LKYv9YlN2!q&!v8frT8v{~jZe+w|W(JBI0|hg1Sb;>bV_fp41|an&CMF$z|8YqC|Kw==XObraUKx~wV1O*>vydVM?65xJ` zxv2{JSfe8+F})ZZuAnG$a>}pZiqb#^SfpFOzYpXZl)K#e{yct%riblCwxhQ8o{WY=I7X4}-uPsJwP-B9=B)yt0;Z%+`@laI9b;u7$x`pPW}1LQhfY%+v{7FbW<3OvE#uk3W^cbB*z z^HmSaKVq*ZWbafg=bJsH=vTC__mdCPKg&(*IxH`LK{n*Lg7a6;S|P0f!A&LlqV3&> zcQuQ9KPh`qc`UHBM5cAoB*(9lf8H>V-@Zrc;P>;#gI4p!H@xz^DV}m)<2OhA1QQ9) z3iGZ&3h0Auw zKV}{8mqc((?QoV>NN0YM(=dm3!r=u^C%kGGoaWr+wpr2DZLaR}NfWXfLxTKN6SlA{ z5i06hJ|#Iq)3*74!|xAwmh=AMp8e&|<{jeS7m9WqznW}*?%Djq{R)gPKjdzz-@8P- zb*IkEI%i5+W}8i7+x$)bO4<{m^XAl*6kFgY@=i=?FHa%|1TseRIO)h|iJ@ zkAp;}b6@XWdd?y5?~OmHHLJOnFZ;d5u~PNr=Bzb88AQVSj@F&oKC6J^Xd%OvXjLtuW+f_lyrM_{o!s&dhX0(B^y=;G&N-ah`D2Gr(|xyNE1i@7 zSaWiySpQ#r#OUAjv$lUcUpzeeGyTVN;prdGA9=#o|9rmc;swVGgyg4~{5jmo{KvU- z_RoB?(?|K2Jo)!-hCcgtcZJUq^~NQeE$#Zm`#y#*Il&?IFX%;K?3(HEoHyB3ndSRa ze^hq9|5z*({$aDXa_RG@a=V4jpE&(X-}Cybr_sW3`&RxuUXv^rW^^pw^RwZ;Z6+1I zF>!IFpMC7OPAB($ocek7Pc8`|@6bO@-aDS&VbVK%wa`=V1nZ8XbEl_jp7mNBwEl|L zRj;K%3sa^zY(KT>bQkQ{QN=lg{^iar~FhV((teH4msbWF4_WaiZq?g#3kh^EQ+`u=uC^&)NN- zMO{Bj^Mr2??aR(g{apL=prd zj-qCLWv4^SHWvo5GU%VR;q?9NF7&`rx0F%+X{GvA)}6}h?*wYGhR!-DEn^Whxrxg? z$h4^N(d9=GD=YF=R;-KJ^W^fQij_YagFZ3`{BafdfB#AEw!hVD=S3BrFa2KD(A1#@hlg~duUl|ghjSd7`1+k9t5YK%-};E1Z7s@+TdR*;ta)f&rHs0q&MixvTX<_<9g8+Et;t(6TfcAX%WL`)ufs0gR5QBPTeQ1g zYIU>7eUD?W6p~9PY|NXIH|4m}>h}@W>vKPg|JfE(`E=9S+0zxvxEI}sd&2sB!Fv~l zCClsh^O)|;@5)`k=n(nwcX0lNrv+(!Lhho`MH(DNxy&T?`C{4sYK}9HANfdw~m_w#MU17J<(s^c4-Ck-S&CSVz)1_t+?H}udU|7tC=gs z74&=g78aJsJ=q{`x{&cjs{XF(S1MHud;8D%+FE>7pW?K8!LirD`<*#2WPCdmS+Lh&yKUPv{@p;#pC~TlsWbB-b>T{Z2GpzsP>k{zTzAx&1~@XIfdA zvL<)0klT9l>GwtX3)nB3pY*z*{b7!yaD`l)OLxiJDS4~XUNK!UXUGzI~9M^Y|$(JptnN(UUU4yTN&JkH*Q|Gu02wV@x59_+TlOuhkd>;yv=y{ z_=U+I_H@+oomjoWV{4H0%FSCkr_Hc@b8V%*zwErKyjSWQlyxpK|J(cFj7zjb=B?hm zwy$s8k6++^;d^5>|3#H&8w77B^0|Ms{&8MpkxvLq)o;bUjrW}8(*%n3Kl9x_b1$T3 zNk!VLNh@zJuQU02e?t}5mtKZ9HEi>$Bo?!tb^LrmA&NC3UhDGlyDto^n);Z_)-T?E z!8$`ow9s;mar5mDNqc1Lx#u5Q{?T2;RZ>&#SWkd?;P=DDO;)~p{dQ;Q%Pw2}GWCn> zm%m?<&oGvW?(Y0+RqgUIJ+HhlwJ@|W`{S%fn}hcTm;2RLzhXIajD53W^{v)jiCc>= z)Z93DHDhc=_99he6+wFJwPF?porn9v?7AsO@WExzA(hK>_58K=> zlq+w(Wh{NZ{cmIo`v;D=_VNeWAHzTF{ZPYf&+*!V>wMuK+ds;GwEnT$q<>)lP~);u z#NAS3B3F>mRqpdj6>cl0UXjYu-8yfV=sfoohpz-?&2cL+zU$e4Ab5fQh4q*BFR1tZ zKex~@dWOE?|ATYV?j@Zw_H!;U(4E#Kk2Q+?<53la%`WFs!8 z*K1!id&T!k{zX(4+nmk83ZLsdN)P(IIpF`WondAB#k~b~S&riM(i*`|S3j(HxKqwx zO$)o{!h{3*VLw>*-FaQOdk)|3vr%b=vwPU~`mGLJJ!MW)YDU21B-y0r8v;1^#AhtH zaW&NS(j$(Po*K2}9SRO%&!4{*VY!sY(q$JO+%#+T|CP%^R%ynr>Fjmld%7ygsa->) zZjN|s;hu_f3`g?Mb~igEI`w@&`LVVrhP`k;zZ8dTpK0a7hW6Gzr{~v9tF78ThZ@$z zFnzfaYN){H;OuOrx8U1ESp~iT>y;M+3p#)HH3hd=Ou5+DH!-yJpCz+w<@WRD5u(}; zzD<49#Uyl_tL;Te@g=?+WeM*XdSXSRxhL&y$h){sDEzLG-a^sCDrTEX7C7|th^v75*xWn`g-2I)bTjHo#BOwrB9G@wc=IpB{_|^Of3Qq z>`o|35&Cq;d$k7VwgVrm7A_FFeZ;i-8ZYy+jCTiSco&@%TGH@~{n(sI!G0k}`>faH zeqq!&zB+1kl;@2X#WB%b|0|p||EH^ayx8&WNxs6Hxz&Q=KF7p%C(dF`Tx!$7QM^|D zUWV)lv-1) z^@Cg(`!YMN9`uR5mUUnCuTfc|zI4Ki>c<-IZTW)Q;`Xh{l4<3%Tyxer+ruSkLg35h zh*X~!Es^DuYK6aXRPPFZD`?efy5XUZ1K+}glJf~n(~R>IbbowiuVKx+P-|#qWpRVy zuZySs1(sFsC0pdK`F>|uIA`jN7O#yF`hsu&G8eOPS$}@lG)11pqv43(7k&{xhEiTW zC*6q0UwjnrY`kV@``qHp&Q(IEgqOxSu;1m3<#~70`PUqCg|tMeg{E z`Nm6L_7u9T5(tt!ZvA_qF3Y0xzD6$dUo>a(K1*DoGU2-VZEo|2|BVlsia+Po4K}zf zCHe5ye|L`Sf2}!||JQ9X7Ek|W+44H^oMcnMxBv2oc;`FLsAc`B@xZr4&eq$uaayCd zvH1eE6Z+}mN)vzDZfgE~AeQ~&_C;|8oCS$1#M}0mSQt-jEfHfCiG0#*Qn>X&NPs)* zPro4cIUId2+~(i#+mgUh$#;qAg;PN`)5`xZ``LaU+W$Ry`D#rEugUQzd5q`&)Ngzh zU*ypyHHU4E*c`qsQp`81d<5Dno1aCo?V88?sH}kRiOS6d(z~7-@XmU=_XW?ogQr)p zy>kAg=XUl-q;7S<#RWh3w#Uy5vs>`T;p?(rRbTB*{4YVE(<7p5`IW!hNY zB)$6;F5NuG{>AQ` zW}B+}Gfx_;ZMMBVrJ(jhsI?N&&mlqz5Jq)#zF5$ zt;o>R2BD&bAD2q?^|4L1^O~4o=Ox*_`s3Vrvo<9x(hJ=3aJ|{hsV^(k)@iNQUZ;9x z^O}l=TMXHT3;9kizG}F|Z{=2lo-p^>C1Txo-zDu^{Km-g?6kr)m8Z&`Ik)UPxp}jd z+voQSr->Dtb^AWkVR^xROg=>Y?6i_&>mG=xExw!cyh-uYmN!@D-rs0*W23I!bMtlj zcg-C258r9luCdr(?4KYh@XE&XiIvt9Y${Xd?1^mFa?b?-m@T6gE4T3qMPWC{5Xygj1- zgZ`LZh!FlIZQNXT(nPF2DlqqffqCE7NuBH1tmOp6S*L8he%;(R(jipC@S?e;N#NWg zVeztsXL`7wOMY$rTygx~-XGG{-w(~oWZ7=^EwN0sM?pdUoTvWY;KTFMO53B2H(77yn)z7DJecEmX2(l+QMc`m&#$##wUaoYaAVGtX16lieNx(? zO+gDgW-eUhwYG1@!lj2iZ#(pU*;w^v%SzE6=K~2(dTz=-u4r5m>S;H1k{C}_l;*Zo z8m5;XPZu~AyFq4F(88`Gk<*KdE-^ltbo%LmohK4!pP9L-($RcU(3%_$7t1WO#eOk{ys7Bl~#5Kw&pC$zkOvD$Gz|J@vnQUwBGH1 zd-y2ltMxVS=Dqh?w02j7v+zH@PfeAq8~7G;{90J@G9x29BfR6<{7XA{v)1f$d%ySe zQ!|T=n@@TFo?tEW&Dd_ck#MlAzOk=-V6n8$D(jgtk8eSLnBU{Nx)*P5Zniui zJwt)>M4XR=`U$ZasUHe6g*hsfAMaGO`RHg8#kG90!v^P>-5a8gScuiKxW@ZhO*T5| z*<|B+(Jtrym3w8Z%7t6knYwq^uiEtJnDnlklS}r#{`JVaRz0q^vaIaIp~+V+HJI&g z-IrUt+bE(YyL`WS%$YO0R!Qtxwf=4O& zu6O$%iXJQC$ycs86Fg<*@wKa01^l{mOY36Msb|aHhzSQJEWNZOIO0*l;;Wfc{TMQO zULAe>LCWd8rgGZ7Eq6-xzueGi=y*-y)mC|SwFe#yG0qH^ZfN_($0{?mcqm zU%ThSztG4~g#~%Hk1i197mjRNCSYr7%B6l)`Q^b)t~(=+Y^bhv-_Iz-yyRcC#zpo$ zH$$FpcCt0`%KGN_w|C!6J1(i7mZ-+<>;DCRaGLPQX)c$Swp@t(8M}3LF`s9=i@eGo zYVY+&2+LW=HR(+q*=eUH zUd`8cH`}e6p>uqp!CF_xo{9GkY|}VBQ8Og0uaQ}z_*jfcb94Pm^Rs*n+nab)eMB@i zoty8;?sa_Llg6!#5st0_*ZdBAOVGM{DqYf;m&#A!^ii+-Y*uV#T#_M{b#3LfmDi)L-`ci%+sf_H+i#mBF1>qj zWp5dKYI%gk*1oGtk8r(fV2zHlm716(TzTBW)mGHtS>>i+M*EwZk1LC()_dfX4SopOTITQH=7#WbVA`p6H8UjluCU$rdCz~)f1`(8;(SA z%Ac5GqAi&|MQG()|KpRB=7y~nu6e1w@8gq3)8a?G^Kwpa`~Ci}fVSV!7l*HZ{kiF6 z#inyf+n;F{o3ZZQo{xXd*EbzZad{G6@v3&iEnCK@o$MwzT{S*1jSi3C$PgNvxsa*?x?kMRrViZBZX@J<nd(_zt^VM|C#=L|6JiO zKLmSsR~3u?J<{#J_y4V@i*M=g@3cK$-|+YD;+H#DuVUZTxW9$bMR~XAn|7l>wA+P@=G)ZfX=G2aOy%2=#?3Kpl27|n%N})Emx=|Geh9n{+A8@o%D~rH z!9&ZURebrHq|Vy5>s#fmMCSfp-55Pd^q$vxPx&=7UYf=HsJ>h}x&GS*S?Lw8Z@-WJ zfBBqS{91|P$h~_XUhDjJGTVIXiW9t(8Rzcltz$elfmLT4_d%}zt4uE4y>_+E`}Wzl z{yQSg&ZLFBUH2{Lx7DvrzuZsB6|RWVJysE}^C~IlAeXu5oXniHfsV8KbVAOqT-h1G z9UNPeQugF0hwMy4>#ZkLEi6}Au8!ZLkulpcJ^lk@l4c^9ZJ}iE)mbaU26OtYN&bKnMm|(#xWhP_)V}4z((2S*PSPxp}Sn{68t*y?`Ubup# z!sxV)=A0rXmQqf)&1Wt(O-9YtBJ32FCTmRu+R57)6R*$+Dy~do}O~_|0J{X`P*M=@QB6O z-d0+=^1{J~+V$5Q&#!zUowdFqZflb`Pgee;dB5k~z54e33G=M8YIZUbF`;4e_GJBx zZ(Fr{+kS_yOnYZF#{Fk_KWWm787Z$fJlubKg7uaf9#q%dc$7JRv%W{KXiMGX zru$bPX^J1o=vG(kn6-UI-B$O_`but#1uv#95?!d0yhSQt#m!Ty!ZkZ@={G%MFM1Qv zYbfH|u#IJRaIkK+x5A-@Ht$#eS#}x;{pft*{#?!O*z=A#j9Jqvmlz6cv1~H4&v@V0 zU>m}x#UPVraa^I^%s1QHMUdg>KGxg54Hc{0rdfzzWw{X9DW>|G_t{R({JqCkb;mxJ zSr)a5J*<9n;EH*XbM~%SR{C+x->uwT#x}E#oqj3&wbbP4b=E0Q?>srUuItXbb=uw8 z*F3ZO-ES9I?vvfuW+>p?|{-*4rP z*YzKe=Iv2muxGB5oZf@*_7qP2jJ$N`JsldwdO3ONuE4e<6?_#E zcb3`PUMt00eaZ&4yR7|hUdhw92f6}QQk=UGF zJ3aOGCInrN?Yy5^>Ly{k{(RNeIYpbEb+LVN6uda~z$V7*U2I<*ca%p9-tDs~JD4wg z=GOKZY`yNg&*vm%u>DwmcNtqRzpUv@VH4*t##yp!oZ^_?WZh3+9)D~7OU>oR2|F}= zcNDGg4ZgPIyJdb=-{RuaU2^?e*8Tr7XKxN#_~B>qtxep;VoNP%NUD{|y6XOw*rWTW z{fVb_HtQ)Bn^nux+|!^!&~H_U^l$D|fHzrCtiHE0;W-VVxGqV=8<0+pM&C z+og9z*6uv!5pmbw%wPGJ@WX#wR; zQv+xE23RKFsVaLdu<=1m&lJ6bpGeX0Mmbo#nGI!?tOUu@VmNp+<)4jPuJTS+9PNHkO z-ui3zx9nJKeB;*Z{Cx|bH$FPiGv(6Lz-7-L9#;OiGcbKw$FnobWA$?D#LHxIA}-FG zSCgK`TsF~|<+s=WdH?wKXs&a;Kb39nIy>>w_J4x52Fmx+*E|g7jPLH}-BMBG#Hx5~ z%7gDF6)cV{vdi0Y5<9hcKdx#xe&|BXshkdz+smk^n6M)Cj@*r%@0Xoj zSkbgh^3cRfr7g;mongG&x1F3*Q``L3g8S1|mZ&qXZAbVFRog_ktYZ@01*Y(XpOE}H zMUmHc^J4!KyICj4{#^9-$D6zd2YS|AyR>4{3*~bC$1j#{-TdtNYyIpK;^HOd9^BHi zwJrs@ZxrAEHt?!0t5zASrq`8gAF{4CwmOw&JnKHXN{_SJ=GC&RKQ0{dO{~8AWOeM- zDeM!L1irnJ@91aGSkoC1_T78q^w9c%z;cQA+iVkTQmmJ!<*w-2cw2nMbLpFGOO>B4 zu_*RhSs3-%kC*$^O~dVq`4y{e=E@ii*j;M(q z(UCdw<%Hl7Gd7#Ww`5w*R~?uvx!dQg(SNxj#*<3flB!_`u5-9}%sLsnXqu4m*2(Ml z^vvw{pQ|zNcr)*6xjng$w>AG}zB2bl(4QY?!@KemufP7W@0RL*IqiA>;`{A7vx{2V zLN>(}vAogOED4hGS$%1r^_+6{c^oz}R>D@|L93W^R;WAJKRPa37qif0+iRPZ+y8tl z^FOnhxg;^h=Cn}`U;T_{FASuQ%#pWIb77sRw1B7S zAnU*DvFyvVClvgfBo`!0Pj9aJUfabzHhX=2GR&yWiKpy%|@N z7^yYkQpB0lHz(`d4%=Mub6)trUnR9JUfXjuW^LQ@|Iv{j8&x+h%K9`x>Avs$8Insg zY{_{gQF9tB9t zOT}Cj>AzB*cS>}&*tXyU3pm)$t>j!au~NY0w9?9;)I;yMR`r~k7OtVv>u=kfZI+?3 z)&KGIQ?)Cayr%4wounDYw(7#m?Xk;a^3CU#NT~bIYg_S=_d~$xC)cjW^aZb*b~)ki zgsuJw@53g}+oylqvdEq>c2Y!rhZCo_%5T4we!*7m%lEH4l)C!vq z{z=L++&?e+eE#Ei58piu-P3nHIBw~#gNwzFBs8mQb)+sh8DW$9dyZWCh3t^kH&)1L zHu#(THZeRW9Hh>(G2%c*!)uu;tG)sy0hQ-UajM!imJil#*vIlA@@5jFTfBvo_|DZe zDrZFNx)wJ3uvoWTw#cgF|uabn!curCuyzH4Hq9l)dd}w z;=~X5PCIa_CR<@fbkFV8>FHUsW0-ZOu8-eP6L^0OSG4#)?b`cK&ef!(O*MA=`Fqlu z{Ge0IGx`q(EL#l&SgK#XIV@cYZ$5t-YbAsisPH-`1=nZZChxTk_1mp77}v zm-`Bqsb7|{*D#ARKMK3;d&c*T;d#UN-d*3Fp82gieIa#DV)~_0$&G$%Lsq;NDO(!F zYhIA;!gweuu|MMQ#2ya29VN^B<_fNj+-x<;^t$6#YY~3!KFxap2H#pDLmEzZ%=C$M z*%Ez~E7h0TY{pBr{)<;Ulv~XMop;;JOEG;LmM)T|eL2IZ)O^yeUbWWUQANq+!KHd1 zKi$^n7yPTV(Uh^Q#3DfV+nwXzVos_{ezZ95)_YNrL-E0sV={jfEmpGZw%RfIN&G3T z$Qzso{iH8DUTbWX@HsRg@xW!a@*w;%`n#;`cXOO=d~}U*tn}ae>QYIzU*^i?Xl~~@a{Kv_>Kr}e zw;v5UFSsA=-TY|Eapyq3%}Ya1>}c243z@oFH|pHuiyfMVf){&BG9eeEF+bxt^nclX zrDopJDJuV;y6f>jxoygOB7yPeLovsF#@WsKKdqjw-(B_O{mrz)?N5s@#Qb=b!x+KO zc0uUJw!S|ndPPnfvhJL%_hRnef(5o#^>2S&JR4eUzD9oMpL&Kf%PYh{OZbW*Cz(OF zrx=2kCxMnMSsELdfTTfeL*&JHnI$=?3L5E}3i<&>`6;EzsYMDJxrxdC!3triMa7x< zc?yOGdWNQYh6*tnPNkVSDGG*`P8Jq1nhJrXiA5z<3IQ%|;C(q2C7N9N&PAz-CHX}P z8tFxe1sP?TRSHIWCdPUOnhFr9%=|nT&}JA77b_zJLrX&=0}DfALqj8@C<6m^0|RwU z1%2QA6p#`w+)5Cu1S^VC)3^*23{ANV;6TC5)YRBiAx!}yW@u>+T4x86R>*^j8JL+` z7%6~+3=m?Lrluz7Vg?3A80ySS%`nBxEX>jMTACVKVu+bpSfGoUnOk7kYiVMMq0Z9G z7+uWJz`)WJ%{)T`V-pN@mgXkL2z4bziJ3X6Mc~u%f-|d96%0)k^n>#AOBBFs4}%o+ zJ@eA?6+p=Z#CB1LRTSTmWn1js^e# literal 0 HcmV?d00001 diff --git a/img/catch-order.dot b/img/catch-order.dot new file mode 100644 index 0000000..2db6a0c --- /dev/null +++ b/img/catch-order.dot @@ -0,0 +1,16 @@ +digraph g { + ea [label="ExceptionA e"]; + eb [label="ExceptionB e"]; + eb1[label="ExceptionB1 e"]; + eb2[label="ExceptionB2 e"]; + e [label="Exception e"]; + eb2 -> ea -> eb1 -> eb -> e; + + EA [label="ExceptionA e"]; + EB [label="ExceptionB e"]; + EB1 [label="ExceptionB1 e"]; + EB2 [label="ExceptionB2 e"]; + E [label="Exception e"]; + {EA EB} -> E; + {EB1 EB2} -> EB; +} \ No newline at end of file diff --git a/img/catch-order.pdf b/img/catch-order.pdf new file mode 100644 index 0000000000000000000000000000000000000000..bbe7b04eff410f9d9b68d91d9980278eea4c14b2 GIT binary patch literal 12745 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 literal 0 HcmV?d00001 diff --git a/img/incorrect-try-catch.dot b/img/incorrect-try-catch.dot new file mode 100644 index 0000000..0223270 --- /dev/null +++ b/img/incorrect-try-catch.dot @@ -0,0 +1,40 @@ +digraph g { + enter [style = filled]; + mxin [label = "x = x_in", style = filled]; + try [style = filled]; + x_in [label = "x_in = x", style = filled]; + f [label = "f()", style = filled]; + nr [label = "normal return"]; + x_out_nr [label = "x = x_out"]; + er [label = "error return"]; + catch [label = "catch (Exception e)"]; + x_out_catch [label = "x = x_out"]; + log [label = "log(\"error\")"]; + x_0 [label = "x = 0", style = filled]; + x_in2 [label = "x_in = x", style = filled]; + f2 [label = "f()", style = filled]; + nr2 [label = "normal return"]; + er2 [label = "error return"]; + ee [label = "error exit"]; + x_out_nr2 [label = "x = x_out"]; + x_out_ee [label = "x = x_out"]; + + enter -> {mxin try}; + try -> f -> {x_in nr er} + nr -> x_out_nr + er -> catch -> {x_out_catch log} + enter -> {x_0 f2} + f2 -> {x_in2 nr2 er2} + nr2 -> x_out_nr2 + er2 -> ee -> x_out_ee; + + {edge [color = red, constraint = false]; + mxin -> x_in; + x_0 -> x_in2; + } + + {edge [color = blue, constraint = false]; + x_in -> {x_out_nr x_out_catch} + x_in2 -> {x_out_nr2 x_out_ee} + } +} \ No newline at end of file diff --git a/img/incorrect-try-catch.pdf b/img/incorrect-try-catch.pdf new file mode 100644 index 0000000000000000000000000000000000000000..06d5261cf86609a6eaad6773145745a24be96a19 GIT binary patch literal 17310 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 Qp_zrL5tpi}tG^o;0Gvyq2><{9 literal 0 HcmV?d00001 diff --git a/paper.tex b/paper.tex index 3f6d28d..15a18f7 100644 --- a/paper.tex +++ b/paper.tex @@ -15,6 +15,7 @@ \theoremstyle{definition} \newtheorem{definition}{Definition} \newtheorem{example}{Example} +\newtheorem{problem}{Problem} \usepackage{hyperref} \usepackage{graphics} \usepackage{title/mitssTitle}