Ninja
minidump-win32.cc
Go to the documentation of this file.
00001 // Copyright 2012 Google Inc. All Rights Reserved.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 #ifndef NINJA_BOOTSTRAP
00016 
00017 #include <windows.h>
00018 #include <DbgHelp.h>
00019 
00020 
00021 #include "util.h"
00022 
00023 typedef BOOL (WINAPI *MiniDumpWriteDumpFunc) (
00024     IN HANDLE,
00025     IN DWORD,
00026     IN HANDLE,
00027     IN MINIDUMP_TYPE,
00028     IN CONST PMINIDUMP_EXCEPTION_INFORMATION, OPTIONAL
00029     IN CONST PMINIDUMP_USER_STREAM_INFORMATION, OPTIONAL
00030     IN CONST PMINIDUMP_CALLBACK_INFORMATION OPTIONAL
00031     );
00032 
00033 /// Creates a windows minidump in temp folder.
00034 void CreateWin32MiniDump(_EXCEPTION_POINTERS* pep) {
00035   char temp_path[MAX_PATH];
00036   GetTempPath(sizeof(temp_path), temp_path);
00037   char temp_file[MAX_PATH];
00038   sprintf(temp_file, "%s\\ninja_crash_dump_%d.dmp",
00039           temp_path, GetCurrentProcessId());
00040 
00041   // Delete any previous minidump of the same name.
00042   DeleteFile(temp_file);
00043 
00044   // Load DbgHelp.dll dynamically, as library is not present on all
00045   // Windows versions.
00046   HMODULE dbghelp = LoadLibrary("dbghelp.dll");
00047   if (dbghelp == NULL) {
00048     Error("failed to create minidump: LoadLibrary('dbghelp.dll'): %s",
00049           GetLastErrorString().c_str());
00050     return;
00051   }
00052 
00053   MiniDumpWriteDumpFunc mini_dump_write_dump =
00054       (MiniDumpWriteDumpFunc)GetProcAddress(dbghelp, "MiniDumpWriteDump");
00055   if (mini_dump_write_dump == NULL) {
00056     Error("failed to create minidump: GetProcAddress('MiniDumpWriteDump'): %s",
00057           GetLastErrorString().c_str());
00058     return;
00059   }
00060 
00061   HANDLE hFile = CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL,
00062                              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00063   if (hFile == NULL) {
00064     Error("failed to create minidump: CreateFileA(%s): %s",
00065           temp_file, GetLastErrorString().c_str());
00066     return;
00067   }
00068 
00069   MINIDUMP_EXCEPTION_INFORMATION mdei;
00070   mdei.ThreadId           = GetCurrentThreadId();
00071   mdei.ExceptionPointers  = pep;
00072   mdei.ClientPointers     = FALSE;
00073   MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE) (MiniDumpWithDataSegs |
00074                                              MiniDumpWithHandleData);
00075 
00076   BOOL rv = mini_dump_write_dump(GetCurrentProcess(), GetCurrentProcessId(),
00077                                  hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0);
00078   CloseHandle(hFile);
00079 
00080   if (!rv) {
00081     Error("MiniDumpWriteDump failed: %s", GetLastErrorString().c_str());
00082     return;
00083   }
00084 
00085   Warning("minidump created: %s", temp_file);
00086 }
00087 
00088 #endif  // NINJA_BOOTSTRAP