1184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com/* 2184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * Copyright 2013 Google Inc. 3184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * 4184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * Use of this source code is governed by a BSD-style license that can be 5184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * found in the LICENSE file. 6184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com */ 7184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 8184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include "windows.h" 9184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include "win_dbghelp.h" 10184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include <process.h> 11184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include <string.h> 12184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include <stdlib.h> 13184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#include <stdio.h> 14184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 15184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// Remove prefix addresses. 18 = 2 * (8 digit hexa + 1 space). 16184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// e.g. "abcd1234 abcd1234 render_pdf!processInput 17184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define CDB_CALLSTACK_PREFIX (18) 18184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 19184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// CDB.EXE prints a lot of garbage and there is no argument to pass which 20184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// would remove all that noise. 21184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// Using eval feature that evaluates a number in hex and prints it to stdout 22184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// to mark where the callstack is printed. 23184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// For example, each thread's callstack will be marked with "12340000" at 24184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// the beginning and "12340001" at the end. 25184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// We just made up these numbers; they could be anything, as long as they 26184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// match up with their decimal equivalents. 27184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 28184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_THREAD_CALLSTACK_START_NUMBER "12340000" 29184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_THREAD_CALLSTACK_START "Evaluate expression: 305397760 = 12340000" 30184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 31184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_THREAD_CALLSTACK_STOP_NUMBER "12340001" 32184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_THREAD_CALLSTACK_STOP "Evaluate expression: 305397761 = 12340001" 33184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 34184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_EXCEPTION_CALLSTACK_START_NUMBER "12340002" 35184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_EXCEPTION_CALLSTACK_START "Evaluate expression: 305397762 = 12340002" 36184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 37184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_EXCEPTION_CALLSTACK_STOP_NUMBER "12340003" 38184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define MARKER_EXCEPTION_CALLSTACK_STOP "Evaluate expression: 305397763 = 12340003" 39184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 40184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// k - print stack 41184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// ? val - evaluate expression. Used to mark the log file. 42184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// .ecxr - load exception, if exception was thrown. 43184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// k - print the resolved stack by .ecxr 44184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// q - quit cdb.exe 45184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define CDB_PRINT_CALLSTACK_CURRENT_THREAD "? " MARKER_THREAD_CALLSTACK_START_NUMBER "; k; ? " MARKER_THREAD_CALLSTACK_STOP_NUMBER "; .ecxr; ? " MARKER_EXCEPTION_CALLSTACK_START_NUMBER "; k; ? " MARKER_EXCEPTION_CALLSTACK_STOP_NUMBER "; q" 46184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 47184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comstatic void strncpyOrSetBlank(char* dest, const char* src, size_t len) { 482880df2609eba09b555ca37be04b6ad89290c765Tom Hudson const char* srcOrEmptyString = (nullptr == src) ? "" : src; 49184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpy(dest, srcOrEmptyString, len); 50184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 51184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 52184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comchar debug_app_name[MAX_PATH] = ""; 53eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.comvoid setAppName(const char* app_name) { 54184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpyOrSetBlank(debug_app_name, app_name, sizeof(debug_app_name)); 55184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 56184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 57184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comconst char* getAppName() { 58184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com return debug_app_name; 59184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 60184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 61184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comchar debug_binaries_path[MAX_PATH] = ""; 62184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comvoid setBinariesPath(const char* binaries_path) { 63184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpyOrSetBlank(debug_binaries_path, binaries_path, 64184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sizeof(debug_binaries_path)); 65184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 66184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 67184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comconst char* getBinariesPath() { 68184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com return debug_binaries_path; 69184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 70184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 71184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comchar debug_app_version[100] = ""; 72184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comvoid setAppVersion(const char* version) { 73184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpyOrSetBlank(debug_app_version, version, sizeof(debug_app_version)); 74184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 75184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 76184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comconst char* getAppVersion() { 77184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com return debug_app_version; 78184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 79184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 80184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comchar debug_cdb_path[MAX_PATH] = ""; 81184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comvoid setCdbPath(const char* path) { 82184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpyOrSetBlank(debug_cdb_path, path, sizeof(debug_cdb_path)); 83184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 84184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 85184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comconst char* getCdbPath() { 86184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com return debug_cdb_path; 87184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 88184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 89184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com/** Print all the lines of a CDB k command whicha are callstacks. 90184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * Callstack lines are marked by start and stop markers and they are prefixed 91184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * byt 2 hex adresses, which will not be reported. 92184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com */ 93184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comstatic void printCallstack(const char* filename, 94184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com const char* start, 95184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com const char* stop) { 96184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com FILE* file = fopen(filename, "rt"); 97184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com char line[1000]; 98184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com bool started = false; 99184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // Not the most performant code, but this will be used only to collect 100184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // the callstack from a log files, only when the application had failed. 101184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com while (fgets(line, sizeof(line), file)) { 102184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com if (!started && strncmp(start, line, strlen(start)) == 0) { 103184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com started = true; 104184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } else if (started && strncmp(stop, line, strlen(stop)) == 0) { 105184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com break; 106184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } else if (started) { 107184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // Filter messages. Calstack lines contain "exe/dll!function" 1082880df2609eba09b555ca37be04b6ad89290c765Tom Hudson if (strchr(line, '!') != nullptr && strlen(line) > CDB_CALLSTACK_PREFIX) { 109184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printf("%s", line + CDB_CALLSTACK_PREFIX); // fgets includes \n already. 110184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 111184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 112184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 113184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com fclose(file); 114184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 115184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 116184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#define BUILD_UNIQUE_FILENAME(var, ext, szPath, szAppName, szVersion, stLocalTime) \ 117184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sprintf(szFileName, "%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld" ext, \ 118184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com szPath, szAppName, szVersion, \ 119184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay, \ 120184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com stLocalTime.wHour, stLocalTime.wMinute, stLocalTime.wSecond, \ 121eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com GetCurrentProcessId(), GetCurrentThreadId()); 122184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 123184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// Exception execution handler. Exception is recognized. Transfer control to 124184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// the exception handler by executing the __except compound statement, 125184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com// then continue execution after the __except block. 126184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comint GenerateDumpAndPrintCallstack(EXCEPTION_POINTERS* pExceptionPointers) { 127184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com BOOL bMiniDumpSuccessful; 128eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com char szPath[MAX_PATH]; 129eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com char szFileName[MAX_PATH]; 130eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com char szFileNameOutput[MAX_PATH]; 131184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com const char* szAppName = getAppName(); 132184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com const char* szVersion = getAppVersion(); 133184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com DWORD dwBufferSize = MAX_PATH; 134184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com HANDLE hDumpFile; 135184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com SYSTEMTIME stLocalTime; 136184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MINIDUMP_EXCEPTION_INFORMATION ExpParam; 137184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 138184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com GetLocalTime( &stLocalTime ); 139184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com GetTempPath( dwBufferSize, szPath ); 140184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 141184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sprintf( szFileName, "%s%s", szPath, szAppName ); 1422880df2609eba09b555ca37be04b6ad89290c765Tom Hudson CreateDirectory( szFileName, nullptr ); 143184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 144184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com BUILD_UNIQUE_FILENAME(szFileName, ".dmp", szPath, szAppName, szVersion, stLocalTime); 145184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com BUILD_UNIQUE_FILENAME(szFileNameOutput, ".out", szPath, szAppName, szVersion, stLocalTime); 146184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 147184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com hDumpFile = CreateFile(szFileName, 148eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com GENERIC_READ|GENERIC_WRITE, 149184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com FILE_SHARE_WRITE|FILE_SHARE_READ, 150184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 0, 151184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com CREATE_ALWAYS, 152184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 0, 153184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 0); 154184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 155184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com ExpParam.ThreadId = GetCurrentThreadId(); 156184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com ExpParam.ExceptionPointers = pExceptionPointers; 157184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com ExpParam.ClientPointers = TRUE; 158184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 159184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(), 160eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com GetCurrentProcessId(), 161184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com hDumpFile, 162184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MiniDumpWithDataSegs, 163184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com &ExpParam, 1642880df2609eba09b555ca37be04b6ad89290c765Tom Hudson nullptr, 1652880df2609eba09b555ca37be04b6ad89290c765Tom Hudson nullptr); 166184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 167184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printf("MiniDump file: %s\n", szFileName); 168184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printf("App exe and pdb: %s\n", getBinariesPath()); 169184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 170184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com const char* cdbExePath = getCdbPath(); 171184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com if (cdbExePath && *cdbExePath != '\0') { 172184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printf("Cdb exe: %s\n", cdbExePath); 173eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com 174184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com char command[MAX_PATH * 4]; 175184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sprintf(command, "%s -y \"%s\" -i \"%s\" -z \"%s\" -c \"%s\" -kqm >\"%s\"", 176184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com cdbExePath, 177184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com getBinariesPath(), 178184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com getBinariesPath(), 179184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com szFileName, 180184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com CDB_PRINT_CALLSTACK_CURRENT_THREAD, 181184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com szFileNameOutput); 182184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com system(command); 183184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 184184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printf("\nThread Callstack:\n"); 185eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com printCallstack(szFileNameOutput, 186184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MARKER_THREAD_CALLSTACK_START, 187184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MARKER_THREAD_CALLSTACK_STOP); 188184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 189eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com printf("\nException Callstack:\n"); 190184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com printCallstack(szFileNameOutput, 191184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MARKER_EXCEPTION_CALLSTACK_START, 192184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com MARKER_EXCEPTION_CALLSTACK_STOP); 193184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } else { 194eed625df23ee83a94f1814c43744b1961b79adf1skia.committer@gmail.com printf("Warning: CDB path not set up.\n"); 195184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 196184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 197184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com return EXCEPTION_EXECUTE_HANDLER; 198184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 199184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 200184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com/** Sets the debugging variables. Input parameter is app location. 201184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * e.g out\Debug\render_pdfs.exe 202184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com * This function expects the .pdb file to be in the same directory. 203184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com */ 204184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.comvoid setUpDebuggingFromArgs(const char* vargs0) { 20581aca547caeb6d2a526e474eb7e49f234628966ebsalomon size_t i = strlen(vargs0); 206184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 2072d137b6f8a29bf99c810aef35af6ba4ffc39932dborenet@google.com if (i >= 4 && _stricmp(vargs0 - 4, ".exe") == 0) { 208184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // Ignore .exe 209184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com i -= 4; 210184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 211184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 2125d8388b667d7b794cb83a66f04154f672207e3e2fmalita size_t pos_period = i; 213184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 214184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // Find last \ in path - this is Windows! 215184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com while (i >= 0 && vargs0[i] != '\\') { 216184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com i--; 217184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com } 218184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 2195d8388b667d7b794cb83a66f04154f672207e3e2fmalita size_t pos_last_slash = i; 220184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 221184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com char app_name[MAX_PATH]; 222184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpy(app_name, vargs0 + pos_last_slash + 1, pos_period - pos_last_slash - 1); 223184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com app_name[pos_period - pos_last_slash] = '\0'; 224184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com setAppName(app_name); 225184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 226184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com char binaries_path[MAX_PATH]; 227184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com strncpy(binaries_path, vargs0, pos_last_slash); 228184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com binaries_path[pos_last_slash] = '\0'; 229184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com setBinariesPath(binaries_path); 230184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 231184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com setAppVersion("1.0"); // Dummy for now, but use revision instead if we use 232184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // the minidump for anything else other than 233184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // collecting the callstack. 234184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com 235184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com // cdb.exe is the app used to load the minidump which prints the callstack. 236184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com char cdbExePath[MAX_PATH]; 237184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#ifdef _WIN64 238184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sprintf(cdbExePath, "%s\\x64\\cdb.exe", SK_CDB_PATH); 239184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#else 240184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com sprintf(cdbExePath, "%s\\cdb.exe", SK_CDB_PATH); 241184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com#endif 242184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com setCdbPath(cdbExePath); 243184487c8083e4e3958f9efe6fb6a9b1d4865fdf5edisonn@google.com} 244