Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Remove obsolete copyright notices.
[simgrid.git] / src / xbt / ex.cpp
1 /* ex - Exception Handling                                                  */
2
3 /* Copyright (c) 2005-2018. The SimGrid Team. All rights reserved.          */
4
5 /* This program is free software; you can redistribute it and/or modify it
6  * under the terms of the license (GNU LGPL) which comes with this package. */
7
8 #include <cstdio>
9 #include <cstdlib>
10
11 #include <xbt/backtrace.hpp>
12 #include "src/internal_config.h"           /* execinfo when available */
13 #include "xbt/ex.h"
14 #include <xbt/ex.hpp>
15 #include "xbt/log.h"
16 #include "xbt/log.hpp"
17 #include "xbt/backtrace.h"
18 #include "xbt/backtrace.hpp"
19 #include "src/xbt_modinter.h"       /* backtrace initialization headers */
20
21 #include "simgrid/sg_config.h"  /* Configuration mechanism of SimGrid */
22
23 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_ex, xbt, "Exception mechanism");
24
25 // Don't define ~xbt_ex() in ex.hpp.  It is defined here to ensure that there is an unique definition of xt_ex in
26 // libsimgrid, but not in libsimgrid-java.  Otherwise, sone tests are broken (seen with clang/libc++ on freebsd).
27 xbt_ex::~xbt_ex() = default;
28
29 void _xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func)
30 {
31   xbt_ex e(simgrid::xbt::ThrowPoint(file, line, func), message);
32   xbt_free(message);
33   e.category = errcat;
34   e.value = value;
35   throw e;
36 }
37
38 /** @brief shows an exception content and the associated stack if available */
39 void xbt_ex_display(xbt_ex_t * e)
40 {
41   simgrid::xbt::logException(xbt_log_priority_critical, "UNCAUGHT EXCEPTION", *e);
42 }
43
44 /** \brief returns a short name for the given exception category */
45 const char *xbt_ex_catname(xbt_errcat_t cat)
46 {
47   switch (cat) {
48   case unknown_error:
49     return "unknown error";
50   case arg_error:
51     return "invalid argument";
52   case bound_error:
53     return "out of bounds";
54   case mismatch_error:
55     return "mismatch";
56   case not_found_error:
57     return "not found";
58   case system_error:
59     return "system error";
60   case network_error:
61     return "network error";
62   case timeout_error:
63     return "timeout";
64   case cancel_error:
65     return "action canceled";
66   case thread_error:
67     return "thread error";
68   case host_error:
69     return "host failed";
70   case tracing_error:
71     return "tracing error";
72   case io_error:
73     return "io error";
74   case vm_error:
75     return "vm error";
76   default:
77     return "INVALID ERROR";
78   }
79   return "INVALID ERROR";
80 }
81
82 #ifdef SIMGRID_TEST
83 #include "xbt/ex.h"
84 #include <cstdio>
85 #include <xbt/ex.hpp>
86
87 XBT_TEST_SUITE("xbt_ex", "Exception Handling");
88
89 XBT_TEST_UNIT("controlflow", test_controlflow, "basic nested control flow")
90 {
91   xbt_ex_t ex;
92   int n = 1;
93
94   xbt_test_add("basic nested control flow");
95
96   try {
97     if (n != 1)
98       xbt_test_fail("M1: n=%d (!= 1)", n);
99     n++;
100     try {
101       if (n != 2)
102         xbt_test_fail("M2: n=%d (!= 2)", n);
103       n++;
104       THROWF(unknown_error, 0, "something");
105     }
106     catch (xbt_ex& ex) {
107       if (n != 3)
108         xbt_test_fail("M3: n=%d (!= 3)", n);
109       n++;
110     }
111     n++;
112     try {
113       if (n != 5)
114         xbt_test_fail("M2: n=%d (!= 5)", n);
115       n++;
116       THROWF(unknown_error, 0, "something");
117     }
118     catch(xbt_ex& ex){
119       if (n != 6)
120         xbt_test_fail("M3: n=%d (!= 6)", n);
121       n++;
122       throw;
123       n++;
124     }
125     xbt_test_fail("MX: n=%d (shouldn't reach this point)", n);
126   }
127   catch(xbt_ex& e) {
128     if (n != 7)
129       xbt_test_fail("M4: n=%d (!= 7)", n);
130     n++;
131   }
132   if (n != 8)
133     xbt_test_fail("M5: n=%d (!= 8)", n);
134 }
135
136 XBT_TEST_UNIT("value", test_value, "exception value passing")
137 {
138   try {
139     THROWF(unknown_error, 2, "toto");
140   }
141   catch (xbt_ex& ex) {
142     xbt_test_add("exception value passing");
143     if (ex.category != unknown_error)
144       xbt_test_fail("category=%d (!= 1)", (int)ex.category);
145     if (ex.value != 2)
146       xbt_test_fail("value=%d (!= 2)", ex.value);
147     if (strcmp(ex.what(), "toto"))
148       xbt_test_fail("message=%s (!= toto)", ex.what());
149   }
150 }
151
152 XBT_TEST_UNIT("variables", test_variables, "variable value preservation")
153 {
154   xbt_ex_t ex;
155   int r1;
156   XBT_ATTRIB_UNUSED int r2;
157   int v1;
158   int v2;
159
160   r1 = r2 = v1 = v2 = 1234;
161   try {
162     r2 = 5678;
163     v2 = 5678;
164     THROWF(unknown_error, 0, "toto");
165   }
166   catch(xbt_ex& e) {
167     xbt_test_add("variable preservation");
168     if (r1 != 1234)
169       xbt_test_fail("r1=%d (!= 1234)", r1);
170     if (v1 != 1234)
171       xbt_test_fail("v1=%d (!= 1234)", v1);
172     /* r2 is allowed to be destroyed because not volatile */
173     if (v2 != 5678)
174       xbt_test_fail("v2=%d (!= 5678)", v2);
175   }
176 }
177
178 XBT_TEST_UNIT("cleanup", test_cleanup, "cleanup handling")
179 {
180   int v1;
181   int c;
182
183   xbt_test_add("cleanup handling");
184
185   v1 = 1234;
186   c = 0;
187   try {
188     v1 = 5678;
189     THROWF(1, 2, "blah");
190   }
191   catch (xbt_ex& ex) {
192     if (v1 != 5678)
193       xbt_test_fail("v1 = %d (!= 5678)", v1);
194     c = 1;
195     if (v1 != 5678)
196       xbt_test_fail("v1 = %d (!= 5678)", v1);
197     if (not(ex.category == 1 && ex.value == 2 && not strcmp(ex.what(), "blah")))
198       xbt_test_fail("unexpected exception contents");
199   }
200   if (not c)
201     xbt_test_fail("xbt_ex_free not executed");
202 }
203 #endif                          /* SIMGRID_TEST */