| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "windows.h" | 8 #include "windows.h" |
| 9 #include "win_dbghelp.h" | 9 #include "win_dbghelp.h" |
| 10 #include <process.h> | 10 #include <process.h> |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 #define MARKER_EXCEPTION_CALLSTACK_STOP "Evaluate expression: 305397763 = 123400
03" | 38 #define MARKER_EXCEPTION_CALLSTACK_STOP "Evaluate expression: 305397763 = 123400
03" |
| 39 | 39 |
| 40 // k - print stack | 40 // k - print stack |
| 41 // ? val - evaluate expression. Used to mark the log file. | 41 // ? val - evaluate expression. Used to mark the log file. |
| 42 // .ecxr - load exception, if exception was thrown. | 42 // .ecxr - load exception, if exception was thrown. |
| 43 // k - print the resolved stack by .ecxr | 43 // k - print the resolved stack by .ecxr |
| 44 // q - quit cdb.exe | 44 // q - quit cdb.exe |
| 45 #define CDB_PRINT_CALLSTACK_CURRENT_THREAD "? " MARKER_THREAD_CALLSTACK_START_NU
MBER "; k; ? " MARKER_THREAD_CALLSTACK_STOP_NUMBER "; .ecxr; ? " MARKER_EXCEPTIO
N_CALLSTACK_START_NUMBER "; k; ? " MARKER_EXCEPTION_CALLSTACK_STOP_NUMBER "; q" | 45 #define CDB_PRINT_CALLSTACK_CURRENT_THREAD "? " MARKER_THREAD_CALLSTACK_START_NU
MBER "; k; ? " MARKER_THREAD_CALLSTACK_STOP_NUMBER "; .ecxr; ? " MARKER_EXCEPTIO
N_CALLSTACK_START_NUMBER "; k; ? " MARKER_EXCEPTION_CALLSTACK_STOP_NUMBER "; q" |
| 46 | 46 |
| 47 static void strncpyOrSetBlank(char* dest, const char* src, size_t len) { | 47 static void strncpyOrSetBlank(char* dest, const char* src, size_t len) { |
| 48 const char* srcOrEmptyString = (NULL == src) ? "" : src; | 48 const char* srcOrEmptyString = (nullptr == src) ? "" : src; |
| 49 strncpy(dest, srcOrEmptyString, len); | 49 strncpy(dest, srcOrEmptyString, len); |
| 50 } | 50 } |
| 51 | 51 |
| 52 char debug_app_name[MAX_PATH] = ""; | 52 char debug_app_name[MAX_PATH] = ""; |
| 53 void setAppName(const char* app_name) { | 53 void setAppName(const char* app_name) { |
| 54 strncpyOrSetBlank(debug_app_name, app_name, sizeof(debug_app_name)); | 54 strncpyOrSetBlank(debug_app_name, app_name, sizeof(debug_app_name)); |
| 55 } | 55 } |
| 56 | 56 |
| 57 const char* getAppName() { | 57 const char* getAppName() { |
| 58 return debug_app_name; | 58 return debug_app_name; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 bool started = false; | 98 bool started = false; |
| 99 // Not the most performant code, but this will be used only to collect | 99 // Not the most performant code, but this will be used only to collect |
| 100 // the callstack from a log files, only when the application had failed. | 100 // the callstack from a log files, only when the application had failed. |
| 101 while (fgets(line, sizeof(line), file)) { | 101 while (fgets(line, sizeof(line), file)) { |
| 102 if (!started && strncmp(start, line, strlen(start)) == 0) { | 102 if (!started && strncmp(start, line, strlen(start)) == 0) { |
| 103 started = true; | 103 started = true; |
| 104 } else if (started && strncmp(stop, line, strlen(stop)) == 0) { | 104 } else if (started && strncmp(stop, line, strlen(stop)) == 0) { |
| 105 break; | 105 break; |
| 106 } else if (started) { | 106 } else if (started) { |
| 107 // Filter messages. Calstack lines contain "exe/dll!function" | 107 // Filter messages. Calstack lines contain "exe/dll!function" |
| 108 if (strchr(line, '!') != NULL && strlen(line) > CDB_CALLSTACK_PREFIX
) { | 108 if (strchr(line, '!') != nullptr && strlen(line) > CDB_CALLSTACK_PRE
FIX) { |
| 109 printf("%s", line + CDB_CALLSTACK_PREFIX); // fgets includes \n
already. | 109 printf("%s", line + CDB_CALLSTACK_PREFIX); // fgets includes \n
already. |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 fclose(file); | 113 fclose(file); |
| 114 } | 114 } |
| 115 | 115 |
| 116 #define BUILD_UNIQUE_FILENAME(var, ext, szPath, szAppName, szVersion, stLocalTim
e) \ | 116 #define BUILD_UNIQUE_FILENAME(var, ext, szPath, szAppName, szVersion, stLocalTim
e) \ |
| 117 sprintf(szFileName, "%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld" ext, \ | 117 sprintf(szFileName, "%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld" ext, \ |
| 118 szPath, szAppName, szVersion, \ | 118 szPath, szAppName, szVersion, \ |
| (...skipping 13 matching lines...) Expand all Loading... |
| 132 const char* szVersion = getAppVersion(); | 132 const char* szVersion = getAppVersion(); |
| 133 DWORD dwBufferSize = MAX_PATH; | 133 DWORD dwBufferSize = MAX_PATH; |
| 134 HANDLE hDumpFile; | 134 HANDLE hDumpFile; |
| 135 SYSTEMTIME stLocalTime; | 135 SYSTEMTIME stLocalTime; |
| 136 MINIDUMP_EXCEPTION_INFORMATION ExpParam; | 136 MINIDUMP_EXCEPTION_INFORMATION ExpParam; |
| 137 | 137 |
| 138 GetLocalTime( &stLocalTime ); | 138 GetLocalTime( &stLocalTime ); |
| 139 GetTempPath( dwBufferSize, szPath ); | 139 GetTempPath( dwBufferSize, szPath ); |
| 140 | 140 |
| 141 sprintf( szFileName, "%s%s", szPath, szAppName ); | 141 sprintf( szFileName, "%s%s", szPath, szAppName ); |
| 142 CreateDirectory( szFileName, NULL ); | 142 CreateDirectory( szFileName, nullptr ); |
| 143 | 143 |
| 144 BUILD_UNIQUE_FILENAME(szFileName, ".dmp", szPath, szAppName, szVersion, stLo
calTime); | 144 BUILD_UNIQUE_FILENAME(szFileName, ".dmp", szPath, szAppName, szVersion, stLo
calTime); |
| 145 BUILD_UNIQUE_FILENAME(szFileNameOutput, ".out", szPath, szAppName, szVersion
, stLocalTime); | 145 BUILD_UNIQUE_FILENAME(szFileNameOutput, ".out", szPath, szAppName, szVersion
, stLocalTime); |
| 146 | 146 |
| 147 hDumpFile = CreateFile(szFileName, | 147 hDumpFile = CreateFile(szFileName, |
| 148 GENERIC_READ|GENERIC_WRITE, | 148 GENERIC_READ|GENERIC_WRITE, |
| 149 FILE_SHARE_WRITE|FILE_SHARE_READ, | 149 FILE_SHARE_WRITE|FILE_SHARE_READ, |
| 150 0, | 150 0, |
| 151 CREATE_ALWAYS, | 151 CREATE_ALWAYS, |
| 152 0, | 152 0, |
| 153 0); | 153 0); |
| 154 | 154 |
| 155 ExpParam.ThreadId = GetCurrentThreadId(); | 155 ExpParam.ThreadId = GetCurrentThreadId(); |
| 156 ExpParam.ExceptionPointers = pExceptionPointers; | 156 ExpParam.ExceptionPointers = pExceptionPointers; |
| 157 ExpParam.ClientPointers = TRUE; | 157 ExpParam.ClientPointers = TRUE; |
| 158 | 158 |
| 159 bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), | 159 bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), |
| 160 GetCurrentProcessId(), | 160 GetCurrentProcessId(), |
| 161 hDumpFile, | 161 hDumpFile, |
| 162 MiniDumpWithDataSegs, | 162 MiniDumpWithDataSegs, |
| 163 &ExpParam, | 163 &ExpParam, |
| 164 NULL, | 164 nullptr, |
| 165 NULL); | 165 nullptr); |
| 166 | 166 |
| 167 printf("MiniDump file: %s\n", szFileName); | 167 printf("MiniDump file: %s\n", szFileName); |
| 168 printf("App exe and pdb: %s\n", getBinariesPath()); | 168 printf("App exe and pdb: %s\n", getBinariesPath()); |
| 169 | 169 |
| 170 const char* cdbExePath = getCdbPath(); | 170 const char* cdbExePath = getCdbPath(); |
| 171 if (cdbExePath && *cdbExePath != '\0') { | 171 if (cdbExePath && *cdbExePath != '\0') { |
| 172 printf("Cdb exe: %s\n", cdbExePath); | 172 printf("Cdb exe: %s\n", cdbExePath); |
| 173 | 173 |
| 174 char command[MAX_PATH * 4]; | 174 char command[MAX_PATH * 4]; |
| 175 sprintf(command, "%s -y \"%s\" -i \"%s\" -z \"%s\" -c \"%s\" -kqm >\"%s\
"", | 175 sprintf(command, "%s -y \"%s\" -i \"%s\" -z \"%s\" -c \"%s\" -kqm >\"%s\
"", |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 | 234 |
| 235 // cdb.exe is the app used to load the minidump which prints the callstack. | 235 // cdb.exe is the app used to load the minidump which prints the callstack. |
| 236 char cdbExePath[MAX_PATH]; | 236 char cdbExePath[MAX_PATH]; |
| 237 #ifdef _WIN64 | 237 #ifdef _WIN64 |
| 238 sprintf(cdbExePath, "%s\\x64\\cdb.exe", SK_CDB_PATH); | 238 sprintf(cdbExePath, "%s\\x64\\cdb.exe", SK_CDB_PATH); |
| 239 #else | 239 #else |
| 240 sprintf(cdbExePath, "%s\\cdb.exe", SK_CDB_PATH); | 240 sprintf(cdbExePath, "%s\\cdb.exe", SK_CDB_PATH); |
| 241 #endif | 241 #endif |
| 242 setCdbPath(cdbExePath); | 242 setCdbPath(cdbExePath); |
| 243 } | 243 } |
| OLD | NEW |