Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Lesson 8: exceptions
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 16 Jul 2006 23:29:38 +0000 (23:29 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Sun, 16 Jul 2006 23:29:38 +0000 (23:29 +0000)
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@2598 48e7efb5-ca39-0410-a469-dd3cf9ba447f

doc/gtut-files/.cvsignore
doc/gtut-files/7-timers.output
doc/gtut-files/8-exceptions.c [new file with mode: 0644]
doc/gtut-files/8-exceptions.output [new file with mode: 0644]
doc/gtut-files/Makefile
doc/gtut-tour-8-exceptions.doc

index 73be037..7453afa 100644 (file)
@@ -60,3 +60,12 @@ _6-logs_simulator.c
 _7-timers_client.c
 _7-timers_server.c
 _7-timers_simulator.c
+
+8-exceptions.mk
+8-exceptions.trace
+8-exceptions_client
+8-exceptions_server
+8-exceptions_simulator
+_8-exceptions_client.c
+_8-exceptions_server.c
+_8-exceptions_simulator.c
index 152b70a..90ba2df 100644 (file)
@@ -1,55 +1,55 @@
 $ ./test_server 12345 & ./test_client 127.0.0.1 12345
-[blaise:server:(23608) 0.000005] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 0.500361] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 1.003121] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 1.507935] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 2.010545] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 2.516219] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 3.018509] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 3.518713] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 4.022585] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
-[blaise:server:(23608) 4.482905] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks...
-[blaise:server:(23608) 4.482930] gras/gras.c:79: [gras/INFO] Exiting GRAS
-[blaise:client:(23611) 0.000005] test.c:99: [test/INFO] Programming the repetitive action with a frequency of 0.5 sec
-[blaise:client:(23611) 0.000071] test.c:102: [test/INFO] Programming the delayed action in 5 secs
-[blaise:client:(23611) 0.518553] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 1.020515] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 1.523454] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 2.027895] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 2.530948] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 3.035530] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 3.538912] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 4.038965] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 4.542989] test.c:66: [test/INFO] Hello sent to server
-[blaise:client:(23611) 5.003026] test.c:73: [test/INFO] Kill sent to server
-[blaise:client:(23611) 5.003056] test.c:78: [test/INFO] Break the client's while loop
-[blaise:client:(23611) 5.003071] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(1059) 0.000005] test.c:100: [test/INFO] Programming the repetitive action with a frequency of 0.5 sec
+[blaise:client:(1059) 0.000059] test.c:103: [test/INFO] Programming the delayed action in 5 secs
+[blaise:client:(1059) 0.503528] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 1.007421] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 1.518254] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 2.021273] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 2.523439] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 3.027624] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 3.531462] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 4.054546] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 4.555526] test.c:67: [test/INFO] Hello sent to server
+[blaise:client:(1059) 5.003581] test.c:74: [test/INFO] Kill sent to server
+[blaise:client:(1059) 5.003608] test.c:79: [test/INFO] Break the client's while loop
+[blaise:client:(1059) 5.003625] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:server:(1056) 0.000005] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 0.504171] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 1.015021] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 1.517557] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 2.019864] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 2.524203] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 3.027500] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 3.551340] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 4.051570] test.c:26: [test/INFO] Cool, we received the message from 127.0.0.1:1024.
+[blaise:server:(1056) 4.499931] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks...
+[blaise:server:(1056) 4.499955] gras/gras.c:79: [gras/INFO] Exiting GRAS
 $
 $ ./test_simulator platform.xml test.xml
-[Boivin:client:(2) 0.000000] test.c:99: [test/INFO] Programming the repetitive action with a frequency of 0.5 sec
-[Boivin:client:(2) 0.000000] test.c:102: [test/INFO] Programming the delayed action in 5 secs
-[Boivin:client:(2) 0.500537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 0.000000] test.c:100: [test/INFO] Programming the repetitive action with a frequency of 0.5 sec
+[Boivin:client:(2) 0.000000] test.c:103: [test/INFO] Programming the delayed action in 5 secs
+[Boivin:client:(2) 0.500537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 0.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 1.000537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 1.000537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 1.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 1.500537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 1.500537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 1.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 2.000537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 2.000537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 2.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 2.500537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 2.500537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 2.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 3.000537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 3.000537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 3.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 3.500537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 3.500537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 3.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 4.000537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 4.000537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 4.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 4.500537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 4.500537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 4.500537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 5.000537] test.c:66: [test/INFO] Hello sent to server
+[Boivin:client:(2) 5.000537] test.c:67: [test/INFO] Hello sent to server
 [Jacquelin:server:(1) 5.000537] test.c:26: [test/INFO] Cool, we received the message from Boivin:1024.
-[Boivin:client:(2) 5.001074] test.c:73: [test/INFO] Kill sent to server
-[Boivin:client:(2) 5.001074] test.c:78: [test/INFO] Break the client's while loop
+[Boivin:client:(2) 5.001074] test.c:74: [test/INFO] Kill sent to server
+[Boivin:client:(2) 5.001074] test.c:79: [test/INFO] Break the client's while loop
 [Boivin:client:(2) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS
 [Jacquelin:server:(1) 5.001074] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks...
 [Jacquelin:server:(1) 5.001074] gras/gras.c:79: [gras/INFO] Exiting GRAS
diff --git a/doc/gtut-files/8-exceptions.c b/doc/gtut-files/8-exceptions.c
new file mode 100644 (file)
index 0000000..fd3a407
--- /dev/null
@@ -0,0 +1,85 @@
+#include <gras.h>
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(test,"My little example");
+
+typedef struct {
+   int killed;
+} server_data_t;
+   
+
+int server_kill_cb(gras_msg_cb_ctx_t ctx, void *payload) {
+  gras_socket_t client = gras_msg_cb_ctx_from(ctx);
+  server_data_t *globals=(server_data_t*)gras_userdata_get();
+   
+  CRITICAL2("Argh, killed by %s:%d! Bye folks, I'm out of here...",
+       gras_socket_peer_name(client), gras_socket_peer_port(client));
+  
+  globals->killed = 1;
+   
+  return 1;
+} /* end_of_kill_callback */
+
+int server(int argc, char *argv[]) {
+  gras_socket_t mysock;   /* socket on which I listen */
+  server_data_t *globals;
+  
+  gras_init(&argc,argv);
+
+  globals=gras_userdata_new(server_data_t*);
+  globals->killed=0;
+
+  gras_msgtype_declare("kill", NULL);
+  gras_cb_register(gras_msgtype_by_name("kill"),&server_kill_cb);
+   
+  if (argc>1 && !strcmp(argv[1],"--cheat")) {
+     mysock = gras_socket_server(9999);
+     INFO0("Hi! hi! I'm not in the search range, but in 9999...");
+  } else {
+     mysock = gras_socket_server((rand() % 10) + 3000);   
+     INFO1("Ok, I'm hidden on port %d. Hope for the best.", gras_socket_my_port(mysock));
+  } 
+   
+  while (!globals->killed) {
+     gras_msg_handle(-1); /* blocking */
+  }
+    
+  gras_exit();
+  return 0;
+}
+
+int client(int argc, char *argv[]) {
+  gras_socket_t mysock;   /* socket on which I listen */
+  gras_socket_t toserver; /* socket used to write to the server */
+  int found;              /* whether we found peer */
+  int port;               /* where we think that the server is */
+  xbt_ex_t e;
+
+  gras_init(&argc,argv);
+
+  gras_msgtype_declare("kill", NULL);
+  mysock = gras_socket_server_range(1024, 10000, 0, 0);
+  
+  VERB0("Run little server, run. I'll get you. (sleep 1.5 sec)");
+  gras_os_sleep(1.5);
+   
+  for (port=3000, found=0; port<3010 && !found; port++) {
+     TRY {
+       toserver = gras_socket_client(argv[1], port);
+       gras_msg_send(toserver,gras_msgtype_by_name("kill"), NULL);
+       gras_socket_close(toserver);
+       found = 1;
+       INFO1("Yeah! I found the server on %d! It's eradicated by now.",port);
+     } CATCH(e) {
+       xbt_ex_free(e);
+     }
+     if (!found)
+       INFO1("Damn, the server is not on %d",port);
+  } /* end_of_loop */
+   
+  if(!found) 
+     THROW0(not_found_error, 0, "Damn, I failed to find the server! I cannot survive this humilliation.");
+  
+     
+  gras_exit();
+  return 0;
+}
diff --git a/doc/gtut-files/8-exceptions.output b/doc/gtut-files/8-exceptions.output
new file mode 100644 (file)
index 0000000..9a7652b
--- /dev/null
@@ -0,0 +1,45 @@
+$ ./test_server & ./test_client 127.0.0.1 
+[blaise:server:(18660) 0.000005] test.c:39: [test/INFO] Ok, I'm hidden on port 3006. Hope for the best.
+[blaise:server:(18660) 1.528036] test.c:15: [test/CRITICAL] Argh, killed by 127.0.0.1:1024! Bye folks, I'm out of here...
+[blaise:server:(18660) 1.528059] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[blaise:client:(18664) 0.000005] test.c:76: [test/INFO] Damn, the server is not on 3000
+[blaise:client:(18664) 0.000128] test.c:76: [test/INFO] Damn, the server is not on 3001
+[blaise:client:(18664) 0.000190] test.c:76: [test/INFO] Damn, the server is not on 3002
+[blaise:client:(18664) 0.000250] test.c:76: [test/INFO] Damn, the server is not on 3003
+[blaise:client:(18664) 0.000308] test.c:76: [test/INFO] Damn, the server is not on 3004
+[blaise:client:(18664) 0.000368] test.c:76: [test/INFO] Damn, the server is not on 3005
+[blaise:client:(18664) 0.000535] test.c:81: [test/INFO] Yeah! I found the server on 3006! It's eradicated by now.
+[blaise:client:(18664) 0.000553] gras/gras.c:79: [gras/INFO] Exiting GRAS
+$
+$ ./test_server --cheat & ./test_client 127.0.0.1 
+[blaise:client:(18706) 0.000005] test.c:76: [test/INFO] Damn, the server is not on 3000
+[blaise:client:(18706) 0.000130] test.c:76: [test/INFO] Damn, the server is not on 3001
+[blaise:client:(18706) 0.000192] test.c:76: [test/INFO] Damn, the server is not on 3002
+[blaise:client:(18706) 0.000251] test.c:76: [test/INFO] Damn, the server is not on 3003
+[blaise:client:(18706) 0.000309] test.c:76: [test/INFO] Damn, the server is not on 3004
+[blaise:client:(18706) 0.000368] test.c:76: [test/INFO] Damn, the server is not on 3005
+[blaise:client:(18706) 0.000426] test.c:76: [test/INFO] Damn, the server is not on 3006
+[blaise:client:(18706) 0.000485] test.c:76: [test/INFO] Damn, the server is not on 3007
+[blaise:client:(18706) 0.000543] test.c:76: [test/INFO] Damn, the server is not on 3008
+[blaise:client:(18706) 0.000601] test.c:76: [test/INFO] Damn, the server is not on 3009
+[blaise:client:(18706) 0.000631] xbt/ex.c:219: [xbt_ex/CRITICAL] Damn, I failed to find the server! I cannot survive this humilliation.
+** SimGrid: UNCAUGHT EXCEPTION received on blaise(18706): category: not found; value: 0
+** Damn, I failed to find the server! I cannot survive this humilliation.
+** Thrown by client() in this process
+
+**   In client() at /home/mquinson/CVSIMPORT/gras/gras/doc/gtut-files/test.c:79 (static symbol)
+**   In main() at /home/mquinson/CVSIMPORT/gras/gras/doc/gtut-files/_test_client.c:21 (static symbol)
+**   In __libc_start_main() at ??:0 (dynamic symbol)
+**   In _start() at ../sysdeps/i386/elf/start.S:122 (static symbol)
+$ killall test_server
+[blaise:server:(18703) 0.000005] test.c:36: [test/INFO] Hi! hi! I'm not in the search range, but in 9999...
+$
+$ ./test_simulator platform.xml test.xml
+[Jacquelin:server:(1) 0.000000] test.c:39: [test/INFO] Ok, I'm hidden on port 3001. Hope for the best.
+[Boivin:client:(2) 1.500000] test.c:76: [test/INFO] Damn, the server is not on 3000
+[Boivin:client:(2) 1.500537] test.c:81: [test/INFO] Yeah! I found the server on 3001! It's eradicated by now.
+[Boivin:client:(2) 1.500537] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[Jacquelin:server:(1) 1.500537] test.c:15: [test/CRITICAL] Argh, killed by Boivin:1024! Bye folks, I'm out of here...
+[Jacquelin:server:(1) 1.500537] gras/gras.c:79: [gras/INFO] Exiting GRAS
+[1.500537] msg/global.c:475: [msg_kernel/INFO] Congratulations ! Simulation terminated : all processes are over
+$
index 1331e0d..8f8cada 100644 (file)
@@ -2,7 +2,8 @@
 export LD_LIBRARY_PATH=$(GRAS_ROOT)/lib
 
 all: 1-bones.output 2-simple.output 3-args.output 4-callback.output \
-     5-globals.output 6-logs.output 7-timers.output
+     5-globals.output 6-logs.output 7-timers.output 8-exceptions.output \
+     
 
 veryclean: clean
        rm *.output*
@@ -192,3 +193,33 @@ clean::
        if [ -e 7-timers.mk ] ; then make -f 7-timers.mk clean; fi
        rm -f _7-timers_client.c _7-timers_server.c _7-timers_simulator.c 7-timers.trace 7-timers.mk
 
+# Lesson 8: exceptions
+########################################
+
+8-exceptions.output: 8-exceptions_client 8-exceptions_server 8-exceptions_simulator
+       echo '$$ ./test_server & ./test_client 127.0.0.1 '             > $@
+       ./8-exceptions_server                                   2>&1 |sed s/8-exceptions/test/  >> $@ 2>&1&
+       ./8-exceptions_client 127.0.0.1                         2>&1 |sed s/8-exceptions/test/  >> $@ 2>&1
+       sleep 1
+       echo '$$'                                                     >> $@
+       echo '$$ ./test_server --cheat & ./test_client 127.0.0.1 '    >> $@
+       ./8-exceptions_server --cheat                           2>&1 |sed s/8-exceptions/test/  >> $@ 2>&1&
+       ./8-exceptions_client 127.0.0.1                         2>&1 |sed s/8-exceptions/test/  >> $@ 2>&1
+       sleep 1
+       echo '$$ killall test_server'                                 >> $@
+       killall 8-exceptions_server 8-exceptions_client 2>/dev/null || true
+       echo '$$'                                                     >> $@
+       echo '$$ ./test_simulator platform.xml test.xml'              >> $@
+       ./8-exceptions_simulator gtut-platform.xml 3-args.xml   2>&1 |sed s/8-exceptions/test/  >> $@ 2>&1
+       echo '$$'                                                     >> $@ 
+
+8-exceptions_client 8-exceptions_server 8-exceptions_simulator: _8-exceptions_client.c _8-exceptions_server.c _8-exceptions_simulator.c
+       make -f 8-exceptions.mk
+
+_8-exceptions_client.c _8-exceptions_server.c _8-exceptions_simulator.c: 8-exceptions.c 3-args.xml
+       ../../tools/gras/gras_stub_generator 8-exceptions 3-args.xml >/dev/null
+
+clean::
+       if [ -e 8-exceptions.mk ] ; then make -f 8-exceptions.mk clean; fi
+       rm -f _8-exceptions_client.c _8-exceptions_server.c _8-exceptions_simulator.c 8-exceptions.trace 8-exceptions.mk
+
index 118ef26..260b5c3 100644 (file)
@@ -1,5 +1,5 @@
 /**
-@page GRAS_tut_tour_exceptions Lesson 8: Handling errors through exceptions (TODO)
+@page GRAS_tut_tour_exceptions Lesson 8: Handling errors through exceptions
 
 \section GRAS_tut_tour_exceptions_toc Table of Contents
  - \ref GRAS_tut_tour_exceptions_intro
 
 \section GRAS_tut_tour_exceptions_intro Introduction
 
+Exceptions are a great mecanism to deal with error exception, everyone knows
+that.
+
+Without exceptions, you have to rely on returning a value indicating whether
+the function call were right or not, and check the return values of every
+single function you call. If there is one point in the calling sequence
+where your forgot this check, the chain is broken and caller won't notice
+the issue. In practice, dealing with error without exceptions loads user
+code with *tons* of those stupid checks and you loose your functional code
+in the middle of that miasm.
+
+With them, you simply write your code. If you want to deal with errors (ie,
+you actually know how to react to errors at this point of your code), you
+write a catching block. If you don't, you don't. And exceptions flow through
+from trowing point to catching point without bothering you.
+
+At this point, you may be a bit surprised by the previous paragraphs.
+SimGrid and GRAS are written in C, and everybody knows that there is no
+exception in C but only in C++, Java and such. This is true, exceptions are
+not part of the C language, but this is such a great tool that we
+implemented an exception mecanism as part of the SimGrid library (with
+setjmp and longjmp, for the curious). 
+
+Being "home-grown" make our exception mecanic both stronger and weaker at
+the same time. First it is weaker because, well, we are more limitated
+within the library as we are than if we could change the compiler itself to
+add some extra checks here and specific treatment there. But it is also a
+advantage for us, since the exception mecanism is perfectly fitted to the
+distributed settings of GRAS processes. They can easily propagate on the
+net, as we will see in the next lesson (\ref GRAS_tut_tour_rpc) and contain
+information about the host on which they were thrown (#xbt_ex_t) along with
+the thrown point in the source code.
+
+The syntax of XBT exceptions should not sound unfamilliar to most of you.
+You throw them using the #THROW0...#THROW7 macros. They take 2 extra
+arguments in addition to the format and its self arguments: an error
+category (of type #xbt_errcat_t) and an error "value" (an integer;
+pratically, this is often left to 0 in my own code). So, you may have
+something like the following:
+\verbatim THROW3(system_error, 0, "Cannot connect to %s:%d because of %s", hostname, port, reason);\endverbatim
+
+Then, you simply add a #TRY/#CATCH block around your code:
+\verbatim TRY{ 
+  /* your code */ 
+} CATCH(e) { 
+  /* error handling code */
+} \endverbatim
+
+Another strange thing is that you should actually free the memory allocated
+to the exception with xbt_ex_fres() if you manage to deal with them. There
+is a bit more than this on the picture (#CLEANUP blocks, for example), and
+you should check the section \ref XBT_ex for more details.
+
+You should be <b>very carfull</b> when using the exceptions. They work great
+when used correctly, but there is a few golden rules you should never break.
+Moreover, the error messages and symptom can get <b>really crude</b> when
+misusing the exceptions.
+
+ - <b>Do not move out of a TRY block with a return, a break or any other
+   kind of jump. NEVER. EVER.</b>. This is the most tempting error, and this
+   drives the system nuts. You will probably segfault in the next exception
+   raising, far away from where you incidentally typed <tt>return</tt>
+   (this is because there is some cleanups to do at the end of a TRY block,
+   you cannot just leave it).
+ - <b>Play safe with variables modified in the TRY block</b>. You may want
+   to mark them as <tt>volatile</tt>, which is a modifier (just like
+   <tt>const</tt>) indicating that the value of the denoted variable may get
+   changed by external parts of the program during the run. This is the case
+   when your data gets modified by an exception raising function, I guess.
+
+So, as you can see, you don't want to include large sections of your program
+in TRY blocks. If you do so, it's quite sure that one day, you'll do a break
+or a return within this block. And believe me, finding such typos is a real
+pain.
+
 \section GRAS_tut_tour_exceptions_use Putting exceptions into action
 
+Okay. I hope those little warnings didn't discourage you from using the
+exceptions, because they really are a nice mecanism. We will now change a
+bit our program to take advantage of them. The only issue is that when a
+program run properly, it usually don't raise any exception. We could protect
+the calls we already have with exception handling, but it wouldn't be really
+exciting since we know this code does not throw any exception under the
+condition we use (actually, most of the GRAS functions may throw exception
+on problem).
+
+Instead, we will code a little game between the client and the server. We
+won't tell the client the exact port on which the server listen, and it will
+have to find from itself. For this, it will try to open socket and send the
+kill message to each ports of the search range. If it manage to close the
+socket after sending the message without being interrupted by an exception,
+it can assume that it killed the server and stop searching.
+\dontinclude 8-exceptions.c
+\skip port=3000
+\until end_of_loop
+
+To make the game a bit more fun (and to show you what an exception actually
+look like when it's not catched), we add a potential command line argument
+to the server, asking it to cheat and to not open its port within the search
+range but elsewhere:
+\dontinclude 8-exceptions.c
+\skip strcmp
+\until gras_socket_my_port
+\until }
+
+Then, when the client detects that it didn't manage to find&destroy the
+server, it throws a suicide exception (sorry for the bad jokes):
+\skip if(!found)
+\until THROW
 
 \section GRAS_tut_tour_exceptions_recap Recapping everything together
 
-The program now reads:
-\include 8-exceptions.c
+Here is the output produced by this new program. Note that when the program
+bails out because of an uncatched exception, it displays its backtrace just
+like a JVM would do (ok, it'a a bit cruder than the one of the JVM, but
+anyway). For each function frame of the calling stack, it displays the
+function name and its location in the source files (if it manage to retrieve
+it). Don't be jalous, you can display such stacks wherever you want with 
+xbt_backtrace_display() ;)
+
+Unfortunately, this feature is only offered under Linux for now since I have
+no idea of how to retrieve the call stack of the current process under the
+other operating systems. But help is always welcome in this area too ;)
 
-Which produces the expected output:
 \include 8-exceptions.output
 
+The complete program reads:
+\include 8-exceptions.c
+
+
 Go to \ref GRAS_tut_tour_rpc
 
 */