1 // The MIT License (MIT) 2 // 3 // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 #ifdef _WIN32 24 25 #include <stdlib.h> 26 #include <crtdbg.h> 27 #include <windows.h> 28 29 30 #if _MSC_VER > 1600 31 #include <timeapi.h> 32 #endif 33 34 #pragma comment( lib, "winmm.lib" ) 35 36 #endif 37 38 #include <stdio.h> 39 #include <string> 40 #include <set> 41 42 #include <MTScheduler.h> 43 #include "Tests/Tests.h" 44 45 #if !defined(_WIN32) 46 47 #include <execinfo.h> 48 49 void PosixSignalHandler(int signum) 50 { 51 pthread_t currentThread = pthread_self(); 52 53 const char* name = "Unknown"; 54 switch( signum ) 55 { 56 case SIGABRT: name = "SIGABRT"; break; 57 case SIGSEGV: name = "SIGSEGV"; break; 58 case SIGBUS: name = "SIGBUS"; break; 59 case SIGILL: name = "SIGILL"; break; 60 case SIGFPE: name = "SIGFPE"; break; 61 case SIGTRAP: name = "SIGTRAP"; break; 62 } 63 64 void *callStack[32]; 65 size_t size = backtrace(callStack, 32); 66 67 printf("Error: signal %s:\n", name); 68 69 char** symbollist = backtrace_symbols( callStack, size ); 70 71 // print the stack trace. 72 for ( size_t i = 0; i < size; i++ ) 73 { 74 printf("[%zu, %lu] %s\n", i, (unsigned long int)currentThread, symbollist[i]); 75 } 76 77 free(symbollist); 78 79 exit(1); 80 } 81 #endif 82 83 84 int main(int argc, char ** argv) 85 { 86 87 #if defined(_WIN32) 88 timeBeginPeriod(1); 89 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); 90 _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG ); 91 #else 92 // install signal handler 93 signal(SIGSEGV, PosixSignalHandler); 94 signal(SIGTRAP, PosixSignalHandler); 95 #endif 96 97 int passCount = 1; 98 if (argc >= 2) 99 { 100 passCount = atoi(argv[1]); 101 } 102 103 int res = 0; 104 printf("Tests will run %d times\n", passCount); 105 for(int pass = 0; pass < passCount; pass++) 106 { 107 printf("---- [ attempt #%d] ----\n", pass + 1); 108 109 res = Tests::RunAll(); 110 if (res != 0) 111 { 112 printf("Unit test failed - pass %d of %d\n", pass + 1, passCount); 113 return res; 114 } 115 } 116 117 #if defined(_WIN32) 118 timeEndPeriod(1); 119 #endif 120 121 return res; 122 } 123 124 125 126