|
32 | 32 | #include <algorithm> |
33 | 33 | #include <climits> |
34 | 34 |
|
| 35 | +#if defined(__GNUC__) |
| 36 | +#define USE_UNIX_SIGNAL_HANDLING |
| 37 | +#include <execinfo.h> |
| 38 | +#endif |
| 39 | + |
| 40 | +#ifdef USE_UNIX_SIGNAL_HANDLING |
| 41 | +#include <signal.h> |
| 42 | +#include <stdio.h> |
| 43 | +#endif |
| 44 | + |
| 45 | +#ifdef _MSC_VER |
| 46 | +#include <Windows.h> |
| 47 | +#include <excpt.h> |
| 48 | +#endif |
| 49 | + |
35 | 50 | CppCheckExecutor::CppCheckExecutor() |
36 | 51 | : _settings(0), time1(0), errorlist(false) |
37 | 52 | { |
@@ -156,6 +171,83 @@ int CppCheckExecutor::check(int argc, const char* const argv[]) |
156 | 171 | return EXIT_FAILURE; |
157 | 172 | } |
158 | 173 |
|
| 174 | + if (cppCheck.settings().exceptionHandling) { |
| 175 | + return check_wrapper(cppCheck, argc, argv); |
| 176 | + } else { |
| 177 | + return check_internal(cppCheck, argc, argv); |
| 178 | + } |
| 179 | +} |
| 180 | + |
| 181 | +#if defined(USE_UNIX_SIGNAL_HANDLING) |
| 182 | +extern "C" void MySignalHandler(int signo, siginfo_t *info, void *context); |
| 183 | + |
| 184 | +/* (declare this list here, so it may be used in signal handlers in addition to main()) |
| 185 | + * A list of signals available in ISO C |
| 186 | + * Check out http://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html |
| 187 | + * For now we only want to detect abnormal behaviour for a few selected signals: |
| 188 | + */ |
| 189 | +static const int listofsignals[] = { |
| 190 | + /* don't care: SIGABRT, */ |
| 191 | + SIGFPE, |
| 192 | + SIGILL, |
| 193 | + SIGINT, |
| 194 | + SIGSEGV, |
| 195 | + /* don't care: SIGTERM */ |
| 196 | +}; |
| 197 | + |
| 198 | +static void print_stacktrace(FILE* f) |
| 199 | +{ |
| 200 | +#if defined(__GNUC__) |
| 201 | + void *array[50]= {0}; |
| 202 | + size_t size = backtrace(array, int(sizeof(array)/sizeof(array[0]))); |
| 203 | + char **strings = backtrace_symbols(array, (int)size); |
| 204 | + fprintf(f, "Callstack:\n"); |
| 205 | + for (std::size_t i = 0; i < size; i++) { |
| 206 | + fprintf(f, "%s\n", strings[i]); |
| 207 | + } |
| 208 | + free(strings); |
| 209 | +#endif |
| 210 | +} |
| 211 | + |
| 212 | +void MySignalHandler(int signo, siginfo_t * /*info*/, void * /*context*/) |
| 213 | +{ |
| 214 | + fprintf(stderr, "Internal error (caught signal %d). Please report this to the cppcheck developers!\n", |
| 215 | + signo); |
| 216 | + print_stacktrace(stderr); |
| 217 | + abort(); |
| 218 | +} |
| 219 | +#endif |
| 220 | + |
| 221 | +int CppCheckExecutor::check_wrapper(CppCheck& cppCheck, int argc, const char* const argv[]) |
| 222 | +{ |
| 223 | +#ifdef _MSC_VER |
| 224 | + /* not yet finished |
| 225 | + __try { |
| 226 | + */ |
| 227 | + return check_internal(cppCheck, argc, argv); |
| 228 | + /* |
| 229 | + } |
| 230 | + except() { |
| 231 | + return -1; |
| 232 | + } |
| 233 | + */ |
| 234 | +#elif defined(USE_UNIX_SIGNAL_HANDLING) |
| 235 | + struct sigaction act = {0}; |
| 236 | + act.sa_flags=SA_SIGINFO; |
| 237 | + act.sa_sigaction=MySignalHandler; |
| 238 | + for (std::size_t s=0; s<sizeof(listofsignals)/sizeof(listofsignals[0]); ++s) { |
| 239 | + sigaction(listofsignals[s], &act, NULL); |
| 240 | + } |
| 241 | + return check_internal(cppCheck, argc, argv); |
| 242 | +#else |
| 243 | + return check_internal(cppCheck, argc, argv); |
| 244 | +#endif |
| 245 | +} |
| 246 | + |
| 247 | +int CppCheckExecutor::check_internal(CppCheck& cppCheck, int /*argc*/, const char* const argv[]) |
| 248 | +{ |
| 249 | + Settings& settings = cppCheck.settings(); |
| 250 | + _settings = &settings; |
159 | 251 | bool std = settings.library.load(argv[0], "std.cfg"); |
160 | 252 | bool posix = true; |
161 | 253 | if (settings.standards.posix) |
|
0 commit comments