Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Really rename this module to peermanagement
[simgrid.git] / doc / gtut-tour-8-exceptions.doc
1 /**
2 @page GRAS_tut_tour_exceptions Lesson 8: Handling errors through exceptions
3
4 \section GRAS_tut_tour_exceptions_toc Table of Contents
5  - \ref GRAS_tut_tour_exceptions_intro
6  - \ref GRAS_tut_tour_exceptions_use
7  - \ref GRAS_tut_tour_exceptions_recap
8    
9 <hr>
10
11 \section GRAS_tut_tour_exceptions_intro Introduction
12
13 Exceptions are a great mecanism to deal with error exception, everyone knows
14 that.
15
16 Without exceptions, you have to rely on returning a value indicating whether
17 the function call were right or not, and check the return values of every
18 single function you call. If there is one point in the calling sequence
19 where your forgot this check, the chain is broken and caller won't notice
20 the issue. In practice, dealing with error without exceptions loads user
21 code with *tons* of those stupid checks and you loose your functional code
22 in the middle of that miasm.
23
24 With them, you simply write your code. If you want to deal with errors (ie,
25 you actually know how to react to errors at this point of your code), you
26 write a catching block. If you don't, you don't. And exceptions flow through
27 from trowing point to catching point without bothering you.
28
29 At this point, you may be a bit surprised by the previous paragraphs.
30 SimGrid and GRAS are written in C, and everybody knows that there is no
31 exception in C but only in C++, Java and such. This is true, exceptions are
32 not part of the C language, but this is such a great tool that we
33 implemented an exception mecanism as part of the SimGrid library (with
34 setjmp and longjmp, for the curious). 
35
36 Being "home-grown" make our exception mecanic both stronger and weaker at
37 the same time. First it is weaker because, well, we are more limitated
38 within the library as we are than if we could change the compiler itself to
39 add some extra checks here and specific treatment there. But it is also a
40 advantage for us, since the exception mecanism is perfectly fitted to the
41 distributed settings of GRAS processes. They can easily propagate on the
42 net, as we will see in the next lesson (\ref GRAS_tut_tour_rpc) and contain
43 information about the host on which they were thrown (#xbt_ex_t) along with
44 the thrown point in the source code.
45
46 The syntax of XBT exceptions should not sound unfamilliar to most of you.
47 You throw them using the #THROW0...#THROW7 macros. They take 2 extra
48 arguments in addition to the format and its self arguments: an error
49 category (of type #xbt_errcat_t) and an error "value" (an integer;
50 pratically, this is often left to 0 in my own code). So, you may have
51 something like the following:
52 \verbatim THROW3(system_error, 0, "Cannot connect to %s:%d because of %s", hostname, port, reason);\endverbatim
53
54 Then, you simply add a #TRY/#CATCH block around your code:
55 \verbatim TRY{ 
56   /* your code */ 
57 } CATCH(e) { 
58   /* error handling code */
59 } \endverbatim
60
61 Another strange thing is that you should actually free the memory allocated
62 to the exception with xbt_ex_fres() if you manage to deal with them. There
63 is a bit more than this on the picture (#CLEANUP blocks, for example), and
64 you should check the section \ref XBT_ex for more details.
65
66 You should be <b>very carfull</b> when using the exceptions. They work great
67 when used correctly, but there is a few golden rules you should never break.
68 Moreover, the error messages and symptom can get <b>really crude</b> when
69 misusing the exceptions.
70
71  - <b>Do not move out of a TRY block with a return, a break or any other
72    kind of jump. NEVER. EVER.</b>. This is the most tempting error, and this
73    drives the system nuts. You will probably segfault in the next exception
74    raising, far away from where you incidentally typed <tt>return</tt>
75    (this is because there is some cleanups to do at the end of a TRY block,
76    you cannot just leave it).
77  - <b>Play safe with variables modified in the TRY block</b>. You may want
78    to mark them as <tt>volatile</tt>, which is a modifier (just like
79    <tt>const</tt>) indicating that the value of the denoted variable may get
80    changed by external parts of the program during the run. This is the case
81    when your data gets modified by an exception raising function, I guess.
82
83 So, as you can see, you don't want to include large sections of your program
84 in TRY blocks. If you do so, it's quite sure that one day, you'll do a break
85 or a return within this block. And believe me, finding such typos is a real
86 pain.
87
88 \section GRAS_tut_tour_exceptions_use Putting exceptions into action
89
90 Okay. I hope those little warnings didn't discourage you from using the
91 exceptions, because they really are a nice mecanism. We will now change a
92 bit our program to take advantage of them. The only issue is that when a
93 program run properly, it usually don't raise any exception. We could protect
94 the calls we already have with exception handling, but it wouldn't be really
95 exciting since we know this code does not throw any exception under the
96 condition we use (actually, most of the GRAS functions may throw exception
97 on problem).
98
99 Instead, we will code a little game between the client and the server. We
100 won't tell the client the exact port on which the server listen, and it will
101 have to find from itself. For this, it will try to open socket and send the
102 kill message to each ports of the search range. If it manage to close the
103 socket after sending the message without being interrupted by an exception,
104 it can assume that it killed the server and stop searching.
105 \dontinclude 8-exceptions.c
106 \skip port=3000
107 \until end_of_loop
108
109 To make the game a bit more fun (and to show you what an exception actually
110 look like when it's not catched), we add a potential command line argument
111 to the server, asking it to cheat and to not open its port within the search
112 range but elsewhere:
113 \dontinclude 8-exceptions.c
114 \skip strcmp
115 \until gras_socket_my_port
116 \until }
117
118 Then, when the client detects that it didn't manage to find&destroy the
119 server, it throws a suicide exception (sorry for the bad jokes):
120 \skip if(!found)
121 \until THROW
122
123 \section GRAS_tut_tour_exceptions_recap Recapping everything together
124
125 Here is the output produced by this new program. Note that when the program
126 bails out because of an uncatched exception, it displays its backtrace just
127 like a JVM would do (ok, it'a a bit cruder than the one of the JVM, but
128 anyway). For each function frame of the calling stack, it displays the
129 function name and its location in the source files (if it manage to retrieve
130 it). Don't be jalous, you can display such stacks wherever you want with 
131 xbt_backtrace_display() ;)
132
133 Unfortunately, this feature is only offered under Linux for now since I have
134 no idea of how to retrieve the call stack of the current process under the
135 other operating systems. But help is always welcome in this area too ;)
136
137 \include 8-exceptions.output
138
139 The complete program reads:
140 \include 8-exceptions.c
141
142
143 Go to \ref GRAS_tut_tour_rpc
144
145 */