Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge pull request #237 from oar-team/upstream
[simgrid.git] / src / xbt / ex.cpp
1 /* ex - Exception Handling                                                  */
2
3 /* Copyright (c) 2005-2017. The SimGrid Team. All rights reserved.          */
4
5 /*  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>       */
6 /*  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>         */
7 /*  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>           */
8 /*  All rights reserved.                                                    */
9
10 /* This code is inspirated from the OSSP version (as retrieved back in 2004)*/
11 /* It was heavily modified to fit the SimGrid framework.                    */
12
13 /* The OSSP version has the following copyright notice:
14 **  OSSP ex - Exception Handling
15 **  Copyright (c) 2002-2004 Ralf S. Engelschall <rse@engelschall.com>
16 **  Copyright (c) 2002-2004 The OSSP Project <http://www.ossp.org/>
17 **  Copyright (c) 2002-2004 Cable & Wireless <http://www.cw.com/>
18 **
19 **  This file is part of OSSP ex, an exception handling library
20 **  which can be found at http://www.ossp.org/pkg/lib/ex/.
21 **
22 **  Permission to use, copy, modify, and distribute this software for
23 **  any purpose with or without fee is hereby granted, provided that
24 **  the above copyright notice and this permission notice appear in all
25 **  copies.
26 **
27 **  THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESSED OR IMPLIED
28 **  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
29 **  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 **  IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
31 **  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 **  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 **  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
34 **  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35 **  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36 **  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37 **  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 **  SUCH DAMAGE.
39  */
40
41 /* The extensions made for the SimGrid project can either be distributed    */
42 /* under the same license, or under the LGPL v2.1                           */
43
44 #include <cstdio>
45 #include <cstdlib>
46
47 #include <xbt/backtrace.hpp>
48 #include "src/internal_config.h"           /* execinfo when available */
49 #include "xbt/ex.h"
50 #include <xbt/ex.hpp>
51 #include "xbt/log.h"
52 #include "xbt/log.hpp"
53 #include "xbt/backtrace.h"
54 #include "xbt/backtrace.hpp"
55 #include "src/xbt_modinter.h"       /* backtrace initialization headers */
56
57 #include "simgrid/sg_config.h"  /* Configuration mechanism of SimGrid */
58
59 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex, xbt, "Exception mechanism");
60
61 // Don't define ~xbt_ex() in ex.hpp.  It is defined here to ensure that there is an unique definition of xt_ex in
62 // libsimgrid, but not in libsimgrid-java.  Otherwise, sone tests are broken (seen with clang/libc++ on freebsd).
63 xbt_ex::~xbt_ex() = default;
64
65 void _xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func)
66 {
67   xbt_ex e(simgrid::xbt::ThrowPoint(file, line, func), message);
68   xbt_free(message);
69   e.category = errcat;
70   e.value = value;
71   throw e;
72 }
73
74 /** @brief shows an exception content and the associated stack if available */
75 void xbt_ex_display(xbt_ex_t * e)
76 {
77   simgrid::xbt::logException(xbt_log_priority_critical, "UNCAUGHT EXCEPTION", *e);
78 }
79
80 /** \brief returns a short name for the given exception category */
81 const char *xbt_ex_catname(xbt_errcat_t cat)
82 {
83   switch (cat) {
84   case unknown_error:
85     return "unknown error";
86   case arg_error:
87     return "invalid argument";
88   case bound_error:
89     return "out of bounds";
90   case mismatch_error:
91     return "mismatch";
92   case not_found_error:
93     return "not found";
94   case system_error:
95     return "system error";
96   case network_error:
97     return "network error";
98   case timeout_error:
99     return "timeout";
100   case cancel_error:
101     return "action canceled";
102   case thread_error:
103     return "thread error";
104   case host_error:
105     return "host failed";
106   case tracing_error:
107     return "tracing error";
108   case io_error:
109     return "io error";
110   case vm_error:
111     return "vm error";
112   default:
113     return "INVALID ERROR";
114   }
115   return "INVALID ERROR";
116 }
117
118 #ifdef SIMGRID_TEST
119 #include "xbt/ex.h"
120 #include <cstdio>
121 #include <xbt/ex.hpp>
122
123 XBT_TEST_SUITE("xbt_ex", "Exception Handling");
124
125 XBT_TEST_UNIT("controlflow", test_controlflow, "basic nested control flow")
126 {
127   xbt_ex_t ex;
128   int n = 1;
129
130   xbt_test_add("basic nested control flow");
131
132   try {
133     if (n != 1)
134       xbt_test_fail("M1: n=%d (!= 1)", n);
135     n++;
136     try {
137       if (n != 2)
138         xbt_test_fail("M2: n=%d (!= 2)", n);
139       n++;
140       THROWF(unknown_error, 0, "something");
141     }
142     catch (xbt_ex& ex) {
143       if (n != 3)
144         xbt_test_fail("M3: n=%d (!= 3)", n);
145       n++;
146     }
147     n++;
148     try {
149       if (n != 5)
150         xbt_test_fail("M2: n=%d (!= 5)", n);
151       n++;
152       THROWF(unknown_error, 0, "something");
153     }
154     catch(xbt_ex& ex){
155       if (n != 6)
156         xbt_test_fail("M3: n=%d (!= 6)", n);
157       n++;
158       throw;
159       n++;
160     }
161     xbt_test_fail("MX: n=%d (shouldn't reach this point)", n);
162   }
163   catch(xbt_ex& e) {
164     if (n != 7)
165       xbt_test_fail("M4: n=%d (!= 7)", n);
166     n++;
167   }
168   if (n != 8)
169     xbt_test_fail("M5: n=%d (!= 8)", n);
170 }
171
172 XBT_TEST_UNIT("value", test_value, "exception value passing")
173 {
174   try {
175     THROWF(unknown_error, 2, "toto");
176   }
177   catch (xbt_ex& ex) {
178     xbt_test_add("exception value passing");
179     if (ex.category != unknown_error)
180       xbt_test_fail("category=%d (!= 1)", (int)ex.category);
181     if (ex.value != 2)
182       xbt_test_fail("value=%d (!= 2)", ex.value);
183     if (strcmp(ex.what(), "toto"))
184       xbt_test_fail("message=%s (!= toto)", ex.what());
185   }
186 }
187
188 XBT_TEST_UNIT("variables", test_variables, "variable value preservation")
189 {
190   xbt_ex_t ex;
191   int r1;
192   XBT_ATTRIB_UNUSED int r2;
193   int v1;
194   int v2;
195
196   r1 = r2 = v1 = v2 = 1234;
197   try {
198     r2 = 5678;
199     v2 = 5678;
200     THROWF(unknown_error, 0, "toto");
201   }
202   catch(xbt_ex& e) {
203     xbt_test_add("variable preservation");
204     if (r1 != 1234)
205       xbt_test_fail("r1=%d (!= 1234)", r1);
206     if (v1 != 1234)
207       xbt_test_fail("v1=%d (!= 1234)", v1);
208     /* r2 is allowed to be destroyed because not volatile */
209     if (v2 != 5678)
210       xbt_test_fail("v2=%d (!= 5678)", v2);
211   }
212 }
213
214 XBT_TEST_UNIT("cleanup", test_cleanup, "cleanup handling")
215 {
216   int v1;
217   int c;
218
219   xbt_test_add("cleanup handling");
220
221   v1 = 1234;
222   c = 0;
223   try {
224     v1 = 5678;
225     THROWF(1, 2, "blah");
226   }
227   catch (xbt_ex& ex) {
228     if (v1 != 5678)
229       xbt_test_fail("v1 = %d (!= 5678)", v1);
230     c = 1;
231     if (v1 != 5678)
232       xbt_test_fail("v1 = %d (!= 5678)", v1);
233     if (not(ex.category == 1 && ex.value == 2 && not strcmp(ex.what(), "blah")))
234       xbt_test_fail("unexpected exception contents");
235   }
236   if (not c)
237     xbt_test_fail("xbt_ex_free not executed");
238 }
239 #endif                          /* SIMGRID_TEST */