Index: tools/win_dbghelp.cpp |
=================================================================== |
--- tools/win_dbghelp.cpp (revision 0) |
+++ tools/win_dbghelp.cpp (revision 0) |
@@ -0,0 +1,188 @@ |
+/* |
+ * Copyright 2013 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#ifdef SK_BUILD_FOR_WIN32 |
+ |
+#include "win_dbghelp.h" |
+#include <process.h> |
+#include <string.h> |
+#include <stdlib.h> |
+ |
+#define CDB_PRINT_CALLSTACK_CURRENT_THREAD "k" |
+ |
+char debug_app_name[MAX_PATH] = ""; |
+void setAppName(const char* app_name) { |
+ if (app_name == NULL) { |
+ app_name = ""; |
+ } |
+ strcpy(debug_app_name, app_name); |
+} |
+ |
+const char* getAppName() { |
+ return debug_app_name; |
+} |
+ |
+char debug_binaries_path[MAX_PATH] = ""; |
+void setBinariesPath(const char* binaries_path) { |
+ if (binaries_path == NULL) { |
+ binaries_path = ""; |
+ } |
+ strcpy(debug_binaries_path, binaries_path); |
+} |
+ |
+const char* getBinariesPath() { |
+ return debug_binaries_path; |
+} |
+ |
+char debug_app_version[100] = ""; |
+void setAppVersion(const char* version) { |
+ if (version == NULL) { |
+ version = ""; |
+ } |
+ strcpy(debug_app_version, version); |
+} |
+ |
+const char* getAppVersion() { |
+ return debug_app_version; |
+} |
+ |
+char debug_cdb_path[MAX_PATH] = ""; |
+void setCdbPath(const char* path) { |
+ if (path == NULL) { |
+ path = ""; |
+ } |
+ strcpy(debug_cdb_path, path); |
+} |
+ |
+const char* getCdbPath() { |
+ return debug_cdb_path; |
+} |
+ |
+int GenerateDumpAndPrintCallstack(EXCEPTION_POINTERS* pExceptionPointers) { |
+ BOOL bMiniDumpSuccessful; |
+ char szPath[MAX_PATH]; |
+ char szFileName[MAX_PATH]; |
+ char* szAppName = getAppName(); |
+ char* szVersion = getAppVersion(); |
+ DWORD dwBufferSize = MAX_PATH; |
+ HANDLE hDumpFile; |
+ SYSTEMTIME stLocalTime; |
+ MINIDUMP_EXCEPTION_INFORMATION ExpParam; |
+ |
+ GetLocalTime( &stLocalTime ); |
+ GetTempPath( dwBufferSize, szPath ); |
+ |
+ sprintf( szFileName, "%s%s", szPath, szAppName ); |
+ CreateDirectory( szFileName, NULL ); |
+ |
+ sprintf( szFileName, "%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp", |
+ szPath, szAppName, szVersion, |
+ stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, |
+ stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, |
+ GetCurrentProcessId(), GetCurrentThreadId()); |
+ |
+ SkDebugf("Minidump saved to %s.\n", szFileName); |
+ |
+ hDumpFile = CreateFile(szFileName, |
+ GENERIC_READ|GENERIC_WRITE, |
+ FILE_SHARE_WRITE|FILE_SHARE_READ, |
+ 0, |
+ CREATE_ALWAYS, |
+ 0, |
+ 0); |
+ |
+ ExpParam.ThreadId = GetCurrentThreadId(); |
+ ExpParam.ExceptionPointers = pExceptionPointers; |
+ ExpParam.ClientPointers = TRUE; |
+ |
+ bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), |
+ GetCurrentProcessId(), |
+ hDumpFile, |
+ MiniDumpWithDataSegs, |
+ &ExpParam, |
+ NULL, |
+ NULL); |
+ |
+ const char* cdbExePath = getCdbPath(); |
+ |
+ if (cdbExePath && *cdbExePath != '\0') { |
+ char exePath[MAX_PATH]; |
+ sprintf(exePath, "%s\\%s.exe", getBinariesPath(), getAppName()); |
+ |
+ char pdbPath[MAX_PATH]; |
+ sprintf(pdbPath, "%s\\%s.pdb", getBinariesPath(), getAppName()); |
+ |
+ _execl(cdbExePath, |
+ "-y", pdbPath, |
+ "-i", exePath, |
+ "-z", szFileName, |
+ "-c", CDB_PRINT_CALLSTACK_CURRENT_THREAD); |
+ } else { |
+ SkDebugf("Warning: CDB path not not set up.\n"); |
+ } |
+ |
+ return EXCEPTION_EXECUTE_HANDLER; |
+} |
+ |
+void setUpDebuggingFromArgs(const char* vargs0) { |
+ // remove .exe |
+ int i = strlen(vargs0); |
+ |
+ i--; |
+ if (i < 0 || (vargs0[i] != 'E' && vargs0[i] != 'e')) { |
+ return; |
+ } |
+ |
+ i--; |
+ if (i < 0 || (vargs0[i] != 'X' && vargs0[i] != 'x')) { |
+ return; |
+ } |
+ |
+ i--; |
+ if (i < 0 || (vargs0[i] != 'E' && vargs0[i] != 'e')) { |
+ return; |
+ } |
+ |
+ i--; |
+ if (i < 0 || vargs0[i] != '.') { |
+ return; |
+ } |
+ |
+ int pos_period = i; |
+ |
+ // Find last \ in path - this is Windows! |
+ while (i >= 0 && vargs0[i] != '\\') { |
+ i--; |
+ } |
+ |
+ if (i < 0) { |
+ return; |
+ } |
+ |
+ int pos_last_slash = i; |
+ |
+ char app_name[MAX_PATH]; |
+ strncpy(vargs0 + pos_last_slash + 1, app_name, pos_period - pos_last_slash - 1); |
+ app_name[pos_period - pos_last_slash] = '\0'; |
+ setAppName(app_name); |
+ |
+ char binaries_path[MAX_PATH]; |
+ strncpy(vargs0, binaries_path, pos_last_slash - 1); |
+ binaries_path[pos_last_slash] = '\0'; |
+ setBinariesPath(binaries_path); |
+ |
+ setAppVersion("1.0"); // Dummy for now, but use revision instead if we use |
+ // the minidump for anything else other than |
+ // collecting the callstack. |
+#ifdef _WIN64 |
edisonn
2013/02/28 16:56:23
is there a better way to get the path to an exe pa
borenet
2013/02/28 20:28:19
I think an environment variable would be okay. I
|
+ setCdbPath(getenv("CDB_PATH_X64")); |
+#else |
+ setCdbPath(getenv("CDB_PATH")); |
+#endif |
+} |
+ |
+#endif // SK_BUILD_FOR_WIN32 |