1 /********************* */
4 ** Original author: mdeters
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
14 ** \brief Utilities for the main driver.
16 ** Utilities for the main driver.
26 #include "util/exception.h"
27 #include "util/options.h"
28 #include "util/Assert.h"
29 #include "util/stats.h"
31 #include "cvc4autoconfig.h"
34 using CVC4::Exception
;
41 * If true, will not spin on segfault even when CVC4_DEBUG is on.
42 * Useful for nightly regressions, noninteractive performance runs
45 bool segvNoSpin
= false;
47 /** Handler for SIGXCPU, i.e., timeout. */
48 void timeout_handler(int sig
, siginfo_t
* info
, void*) {
49 fprintf(stderr
, "CVC4 interrupted by timeout.\n");
50 if(options
.statistics
) {
51 StatisticsRegistry::flushStatistics(cerr
);
56 /** Handler for SIGINT, i.e., when the user hits control C. */
57 void sigint_handler(int sig
, siginfo_t
* info
, void*) {
58 fprintf(stderr
, "CVC4 interrupted by user.\n");
59 if(options
.statistics
) {
60 StatisticsRegistry::flushStatistics(cerr
);
65 /** Handler for SIGSEGV (segfault). */
66 void segv_handler(int sig
, siginfo_t
* info
, void*) {
68 fprintf(stderr
, "CVC4 suffered a segfault in DEBUG mode.\n");
70 fprintf(stderr
, "No-spin requested, aborting...\n");
73 fprintf(stderr
, "Spinning so that a debugger can be connected.\n");
74 fprintf(stderr
, "Try: gdb %s %u\n", progName
, getpid());
79 #else /* CVC4_DEBUG */
80 fprintf(stderr
, "CVC4 suffered a segfault.\n");
81 if(options
.statistics
) {
82 StatisticsRegistry::flushStatistics(cerr
);
85 #endif /* CVC4_DEBUG */
88 /** Handler for SIGILL (illegal instruction). */
89 void ill_handler(int sig
, siginfo_t
* info
, void*) {
91 fprintf(stderr
, "CVC4 executed an illegal instruction in DEBUG mode.\n");
93 fprintf(stderr
, "No-spin requested, aborting...\n");
94 if(options
.statistics
) {
95 StatisticsRegistry::flushStatistics(cerr
);
99 fprintf(stderr
, "Spinning so that a debugger can be connected.\n");
100 fprintf(stderr
, "Try: gdb %s %u\n", progName
, getpid());
105 #else /* CVC4_DEBUG */
106 fprintf(stderr
, "CVC4 executed an illegal instruction.\n");
107 if(options
.statistics
) {
108 StatisticsRegistry::flushStatistics(cerr
);
111 #endif /* CVC4_DEBUG */
114 static terminate_handler default_terminator
;
116 void cvc4unexpected() {
119 "CVC4 threw an \"unexpected\" exception (one that wasn't properly "
120 "specified\nin the throws() specifier for the throwing function)."
122 if(CVC4::s_debugLastException
== NULL
) {
124 "The exception is unknown (maybe it's not a CVC4::Exception).\n\n");
126 fprintf(stderr
, "The exception is:\n%s\n\n",
127 static_cast<const char*>(CVC4::s_debugLastException
));
130 fprintf(stderr
, "No-spin requested.\n");
131 if(options
.statistics
) {
132 StatisticsRegistry::flushStatistics(cerr
);
134 set_terminate(default_terminator
);
136 fprintf(stderr
, "Spinning so that a debugger can be connected.\n");
137 fprintf(stderr
, "Try: gdb %s %u\n", progName
, getpid());
142 #else /* CVC4_DEBUG */
143 fprintf(stderr
, "CVC4 threw an \"unexpected\" exception.\n");
144 if(options
.statistics
) {
145 StatisticsRegistry::flushStatistics(cerr
);
147 set_terminate(default_terminator
);
148 #endif /* CVC4_DEBUG */
151 void cvc4terminate() {
154 "CVC4 was terminated by the C++ runtime.\n"
155 "Perhaps an exception was thrown during stack unwinding. "
156 "(Don't do that.)\n");
157 if(options
.statistics
) {
158 StatisticsRegistry::flushStatistics(cerr
);
160 default_terminator();
161 #else /* CVC4_DEBUG */
163 "CVC4 was terminated by the C++ runtime.\n"
164 "Perhaps an exception was thrown during stack unwinding.\n");
165 if(options
.statistics
) {
166 StatisticsRegistry::flushStatistics(cerr
);
168 default_terminator();
169 #endif /* CVC4_DEBUG */
172 /** Initialize the driver. Sets signal handlers for SIGINT and SIGSEGV. */
173 void cvc4_init() throw() {
174 struct sigaction act1
;
175 act1
.sa_sigaction
= sigint_handler
;
176 act1
.sa_flags
= SA_SIGINFO
;
177 sigemptyset(&act1
.sa_mask
);
178 if(sigaction(SIGINT
, &act1
, NULL
)) {
179 throw Exception(string("sigaction(SIGINT) failure: ") + strerror(errno
));
182 struct sigaction act2
;
183 act2
.sa_sigaction
= timeout_handler
;
184 act2
.sa_flags
= SA_SIGINFO
;
185 sigemptyset(&act2
.sa_mask
);
186 if(sigaction(SIGXCPU
, &act2
, NULL
)) {
187 throw Exception(string("sigaction(SIGXCPU) failure: ") + strerror(errno
));
190 struct sigaction act3
;
191 act3
.sa_sigaction
= segv_handler
;
192 act3
.sa_flags
= SA_SIGINFO
;
193 sigemptyset(&act3
.sa_mask
);
194 if(sigaction(SIGSEGV
, &act3
, NULL
)) {
195 throw Exception(string("sigaction(SIGSEGV) failure: ") + strerror(errno
));
198 struct sigaction act4
;
199 act4
.sa_sigaction
= segv_handler
;
200 act4
.sa_flags
= SA_SIGINFO
;
201 sigemptyset(&act4
.sa_mask
);
202 if(sigaction(SIGILL
, &act4
, NULL
)) {
203 throw Exception(string("sigaction(SIGILL) failure: ") + strerror(errno
));
206 set_unexpected(cvc4unexpected
);
207 default_terminator
= set_terminate(cvc4terminate
);
210 }/* CVC4::main namespace */
211 }/* CVC4 namespace */