Changeset 6abfd07 in opengl-game
- Timestamp:
- May 31, 2019, 6:26:19 PM (6 years ago)
- Branches:
- feature/imgui-sdl, master, points-test
- Children:
- b373466
- Parents:
- a23fc08
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
CrashLogger.cpp
ra23fc08 r6abfd07 4 4 #include <cstdio> 5 5 #include <csignal> 6 #include <cstring> 6 7 7 8 #include <fcntl.h> 8 9 9 10 #include "Compiler.h" 11 #include "Consts.h" 12 13 // TODO: Double-check which includes are necessary 10 14 11 15 #ifdef WINDOWS 12 // most of this can be removed since Windows uses __try __catch instead of signals13 14 16 #include <windows.h> 15 #include "StackWalker.h"16 17 17 #include <io.h> 18 18 #include <sys/stat.h> 19 20 #include "FileStackWalker.h" 19 21 20 22 // The windows analogues to the unix open, close, and write functions … … 25 27 26 28 #define STDERR_FILENO 2 29 30 bool handleException(unsigned int expCode, EXCEPTION_POINTERS* pExp, HANDLE thread); 27 31 #else 28 32 #include <unistd.h> … … 31 35 #include <cxxabi.h> 32 36 #include <cstring> 37 38 void abortHandler(int signum); 39 static inline void printStackTrace(int fd_out = STDERR_FILENO); 33 40 #endif 34 41 35 CrashLogger::CrashLogger() { 36 // Apparently, sigaction should be used instead for Linux 37 // It gives more info. Check if I should bother switching 38 39 signal(SIGABRT, abortHandler); 40 signal(SIGSEGV, abortHandler); 41 signal(SIGILL, abortHandler); 42 signal(SIGFPE, abortHandler); 43 44 write(STDERR_FILENO, "Handlers attached\n", 18); 42 void printInfo(int fd_out); 43 44 CrashLogger::CrashLogger(int(*mainFunc)(int, char*[]), int argc, char* argv[]) { 45 write(STDERR_FILENO, "Calling main\n", 13); 46 47 #ifdef WINDOWS 48 __try { 49 mainFunc(argc, argv); 50 // maybe do this and call a function inside CrashLogger 51 // In that case, also pass GetCurrentThread() as a parameter to then pass to handleException 52 // I could also move almost all of this into CrashLogger by creating a function in CrashLogger that takes a reference 53 // to the effective main function and, for Windows, wraps it in all this error-handling stuff 54 } __except (handleException( 55 GetExceptionCode(), 56 GetExceptionInformation(), 57 GetCurrentThread()) 58 ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER) { 59 } 60 #else 61 // Apparently, sigaction should be used instead for Linux 62 // It gives more info. Check if I should bother switching 63 64 signal(SIGABRT, abortHandler); 65 signal(SIGSEGV, abortHandler); 66 signal(SIGILL, abortHandler); 67 signal(SIGFPE, abortHandler); 68 69 write(STDERR_FILENO, "Handlers attached\n", 18); 70 71 mainFunc(argc, argv); 72 #endif 45 73 } 46 74 … … 48 76 } 49 77 50 static inline void printStackTrace(int fd_out = STDERR_FILENO) { 78 #ifdef WINDOWS 79 80 bool handleException(unsigned int expCode, EXCEPTION_POINTERS* pExp, HANDLE thread) { 81 int crash_log = open(CRASH_LOG_FILE, O_RDWR | O_CREAT | O_APPEND, _S_IREAD | _S_IWRITE); 82 83 if (crash_log == -1) { 84 // TODO: Figure out exactly what perror does and if I should use it 85 perror("opening crash.log"); // TODO: Figure out exactly what perror does and if I should use it 86 } 87 88 printInfo(crash_log); 89 90 FileStackWalker sw(crash_log == -1 ? STDERR_FILENO : crash_log); 91 92 if (pExp != NULL) { 93 sw.ShowCallstack(thread, pExp->ContextRecord); 94 } else { 95 write(crash_log, "Could not get the stack trace\n", 30); 96 } 97 98 close(crash_log); 99 100 if (expCode == EXCEPTION_ACCESS_VIOLATION) { 101 write(STDERR_FILENO, "ACCESS VIOLATION\n", 17); 102 } 103 104 return true; 105 } 106 107 #else 108 109 void abortHandler(int signum) { 110 int crash_log = open(CRASH_LOG_FILE, O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR); 111 112 if (crash_log == -1) { 113 // TODO: Figure out exactly what perror does and if I should use it 114 perror("opening crash.log"); 115 } 116 117 printInfo(crash_log); 118 119 printStackTrace(crash_log); 120 121 close(crash_log); 122 123 write(STDERR_FILENO, "The game has crashed. Check crash.log for more info\n", 52); 124 125 exit(signum); 126 } 127 128 static inline void printStackTrace(int fd_out) { 51 129 write(fd_out, "stack trace:\n", 13); 52 130 … … 74 152 char* begin_name = NULL; 75 153 char* begin_offset = NULL; 76 char* end_offset = NULL; // Iirc, this is used in the Linux code 77 78 #ifdef MAC 79 for (char *p = symbollist[i]; *p; p++) { 80 if ((*p == '_') && (*(p-1) == ' ')) { 81 begin_name = p-1; 82 } else if(*p == '+') { 83 begin_offset = p-1; 84 } 154 char* end_offset = NULL; // Iirc, this is used in the Linux code (Check what it's used for) 155 156 #ifdef MAC 157 for (char *p = symbollist[i]; *p; p++) { 158 if ((*p == '_') && (*(p-1) == ' ')) { 159 begin_name = p-1; 160 } else if(*p == '+') { 161 begin_offset = p-1; 85 162 } 86 87 if (begin_name && begin_offset && (begin_name < begin_offset )) { 88 *begin_name++ = '\0'; 89 *begin_offset++ = '\0'; 90 91 // mangled name is now in [begin_name, begin_offset) and caller 92 // offset in [begin_offset, end_offset). now apply 93 // __cxa_demangle(): 94 int status; 95 char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); 96 97 if (status == 0) { 98 funcname = ret; // use possibly realloc()-ed string 99 write(fd_out, symbollist[i], strlen(symbollist[i])); 100 write(fd_out, " ", 1); 101 write(fd_out, funcname, strlen(funcname)); 102 write(fd_out, " ", 1); 103 write(fd_out, begin_offset, strlen(begin_offset)); 104 } else { 105 // demangling failed. Output function name as a C function with no arguments. 106 write(fd_out, "Error\n", 6); 107 write(fd_out, symbollist[i], strlen(symbollist[i])); 108 write(fd_out, " ", 1); 109 write(fd_out, begin_name, strlen(begin_name)); 110 write(fd_out, "() ", 3); 111 write(fd_out, begin_offset, strlen(begin_offset)); 112 } 163 } 164 165 if (begin_name && begin_offset && (begin_name < begin_offset )) { 166 *begin_name++ = '\0'; 167 *begin_offset++ = '\0'; 168 169 // mangled name is now in [begin_name, begin_offset) and caller 170 // offset in [begin_offset, end_offset). now apply 171 // __cxa_demangle(): 172 int status; 173 char* ret = abi::__cxa_demangle(begin_name, funcname, &funcnamesize, &status); 174 175 if (status == 0) { 176 funcname = ret; // use possibly realloc()-ed string 177 write(fd_out, symbollist[i], strlen(symbollist[i])); 178 write(fd_out, " ", 1); 179 write(fd_out, funcname, strlen(funcname)); 180 write(fd_out, " ", 1); 181 write(fd_out, begin_offset, strlen(begin_offset)); 113 182 } else { 114 // couldn't parse the line? print the whole line. 183 // demangling failed. Output function name as a C function with no arguments. 184 write(fd_out, "Error\n", 6); 115 185 write(fd_out, symbollist[i], strlen(symbollist[i])); 186 write(fd_out, " ", 1); 187 write(fd_out, begin_name, strlen(begin_name)); 188 write(fd_out, "() ", 3); 189 write(fd_out, begin_offset, strlen(begin_offset)); 116 190 } 117 write(fd_out, "\n", 1); 118 #else 119 // Check that this works on Linux Mint 191 } else { 192 // couldn't parse the line? print the whole line. 120 193 write(fd_out, symbollist[i], strlen(symbollist[i])); 121 write(fd_out, "\n", 1); 122 #endif 194 } 195 write(fd_out, "\n", 1); 196 #else 197 // Check that this works on Linux Mint 198 write(fd_out, symbollist[i], strlen(symbollist[i])); 199 write(fd_out, "\n", 1); 200 #endif 123 201 } 124 202 … … 129 207 } 130 208 131 // Most of this function could probably be shared between Windows and Linux/Mac 132 void abortHandler(int signum) { 133 #ifdef WINDOWS 134 int crash_log = open("crash.log", O_RDWR | O_CREAT | O_APPEND, _S_IREAD | _S_IWRITE); 209 #endif 210 211 void printInfo(int fd_out) { 212 write(fd_out, "Game Version: ", 14); 213 write(fd_out, GAME_VERSION, strlen(GAME_VERSION)); 214 write(fd_out, "\n", 1); 215 216 write(fd_out, "OS: ", 4); 217 #if defined WINDOWS 218 write(fd_out, "Windows", 7); 219 #elif defined LINUX 220 write(fd_out, "Linux", 5); 221 #elif defined MAC 222 write(fd_out, "Mac", 3); 135 223 #else 136 int crash_log = open("crash.log", O_RDWR | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);224 write(fd_out, "Unknown", 7); 137 225 #endif 138 139 if (crash_log == -1) { 140 perror("opening crash.log"); // TODO: Figure out exactly what perror does and if I should use it 141 } 142 143 printStackTrace(crash_log); 144 145 close(crash_log); 146 147 exit(signum); 148 } 226 write(fd_out, "\n", 1); 227 228 write(fd_out, "\n", 1); 229 } -
CrashLogger.h
ra23fc08 r6abfd07 2 2 #define CRASH_LOGGER_H 3 3 4 #define CRASH_LOG_FILE "crash.log" 5 4 6 class CrashLogger { 5 7 public: 6 CrashLogger( );8 CrashLogger(int(*mainFunc)(int, char*[]), int argc, char* argv[]); 7 9 ~CrashLogger(); 8 10 }; 9 11 10 void abortHandler(int signum);11 12 12 #endif -
FileStackWalker.cpp
ra23fc08 r6abfd07 1 1 #include "FileStackWalker.h" 2 3 // Put this stuff in some common header shared by this and CrashLogger 4 // Put this stuff in some common header shared by this and CrashLogger 5 6 #include <io.h> 7 8 #define write _write 2 9 3 10 FileStackWalker::FileStackWalker(int fd_out) : StackWalker() { -
NewOpenGLGame.vcxproj
ra23fc08 r6abfd07 136 136 <ItemGroup> 137 137 <ClCompile Include="CrashLogger.cpp" /> 138 <ClCompile Include="FileStackWalker.cpp" /> 138 139 <ClCompile Include="IMGUI\imgui.cpp" /> 139 140 <ClCompile Include="IMGUI\imgui_demo.cpp" /> … … 145 146 <ClCompile Include="stb_image_write.h" /> 146 147 <ClCompile Include="stb_image.cpp" /> 148 <ClCompile Include="utils.cpp" /> 147 149 </ItemGroup> 148 150 <ItemGroup> 149 151 <ClInclude Include="CrashLogger.h" /> 152 <ClInclude Include="FileStackWalker.h" /> 150 153 <ClInclude Include="IMGUI\imgui.h" /> 151 154 <ClInclude Include="IMGUI\imgui_internal.h" /> -
new-game.cpp
ra23fc08 r6abfd07 35 35 #include "Compiler.h" 36 36 37 #ifdef WINDOWS 38 #include <windows.h> 39 #include <excpt.h> 40 #include <io.h> 41 42 #include "FileStackWalker.h" 43 #else 44 // TODO: Move as much Windows crash-logging stuff into CrashLogger as well 45 #include "CrashLogger.h" 46 #endif 37 #include "CrashLogger.h" 47 38 48 39 using namespace std; … … 300 291 */ 301 292 302 CrashLogger logger;303 304 293 // Helps to test logging during crashes 305 /* 306 void badFunc() { 294 int badFunc() { 307 295 int* test = NULL; 296 297 string test2 = "lol"; 298 cout << test2 << endl; 299 308 300 *test = 1; 309 } 310 */ 311 312 #ifdef WINDOWS 313 314 // Give it a file handle to crash.log instead (using the code in CrashLogger.cpp) 315 FileStackWalker sw(2); 316 317 bool handleException(unsigned int expCode, EXCEPTION_POINTERS* pExp, HANDLE thread); 318 #endif 301 return *test; 302 } 303 304 int __main(int argc, char* argv[]); 319 305 320 306 int main(int argc, char* argv[]) { 321 #ifdef WINDOWS 322 __try { 323 __main(argc, argv); 324 // maybe do this and call a function inside CrashLogger 325 // In that case, also pass GetCurrentThread() as a parameter to then pass to handleException 326 // I could also move almost all of this into CrashLogger by creating a function in CrashLogger that takes a reference 327 // to the effective main function and, for Windows, wraps it in all this error-handling stuff 328 } __except( handleException(GetExceptionCode(), GetExceptionInformation(), GetCurrentThread()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_EXECUTE_HANDLER) { 329 _write(2, "CAUGHT\n", 7); 330 } 307 CrashLogger logger(__main, argc, argv); 331 308 332 309 exit(0); … … 334 311 335 312 int __main(int argc, char* argv[]) { 336 #endif337 313 cout << "New OpenGL Game" << endl; 338 314 … … 1023 999 delete *it; 1024 1000 } 1025 } 1026 1027 #ifdef WINDOWS 1028 bool handleException(unsigned int expCode, EXCEPTION_POINTERS* pExp, HANDLE thread) { 1029 if (pExp != NULL) { 1030 sw.ShowCallstack(thread, pExp->ContextRecord); 1031 } 1032 1033 if (expCode == EXCEPTION_ACCESS_VIOLATION) { 1034 _write(2, "ACCESS VIOLATION\n", 17); 1035 } 1036 1037 return true; 1038 } 1039 #endif 1001 1002 return 0; 1003 } 1040 1004 1041 1005 void glfw_error_callback(int error, const char* description) {
Note:
See TracChangeset
for help on using the changeset viewer.