blob: c79ec0e9cb2369ee01ba75fdf0bf533bd52298f2 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef NINJA_BOOTSTRAP
#include <windows.h>
#include <DbgHelp.h>
#include "util.h"
typedef BOOL (WINAPI *MiniDumpWriteDumpFunc) (
IN HANDLE,
IN DWORD,
IN HANDLE,
IN MINIDUMP_TYPE,
IN CONST PMINIDUMP_EXCEPTION_INFORMATION, OPTIONAL
IN CONST PMINIDUMP_USER_STREAM_INFORMATION, OPTIONAL
IN CONST PMINIDUMP_CALLBACK_INFORMATION OPTIONAL
);
/// Creates a windows minidump in temp folder.
void CreateWin32MiniDump(_EXCEPTION_POINTERS* pep) {
char temp_path[MAX_PATH];
GetTempPath(sizeof(temp_path), temp_path);
char temp_file[MAX_PATH];
sprintf(temp_file, "%s\\ninja_crash_dump_%d.dmp",
temp_path, GetCurrentProcessId());
// Delete any previous minidump of the same name.
DeleteFile(temp_file);
// Load DbgHelp.dll dynamically, as library is not present on all
// Windows versions.
HMODULE dbghelp = LoadLibrary("dbghelp.dll");
if (dbghelp == NULL) {
Error("failed to create minidump: LoadLibrary('dbghelp.dll'): %s",
GetLastErrorString().c_str());
return;
}
MiniDumpWriteDumpFunc mini_dump_write_dump =
(MiniDumpWriteDumpFunc)GetProcAddress(dbghelp, "MiniDumpWriteDump");
if (mini_dump_write_dump == NULL) {
Error("failed to create minidump: GetProcAddress('MiniDumpWriteDump'): %s",
GetLastErrorString().c_str());
return;
}
HANDLE hFile = CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == NULL) {
Error("failed to create minidump: CreateFileA(%s): %s",
temp_file, GetLastErrorString().c_str());
return;
}
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = FALSE;
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE) (MiniDumpWithDataSegs |
MiniDumpWithHandleData);
BOOL rv = mini_dump_write_dump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0);
CloseHandle(hFile);
if (!rv) {
Error("MiniDumpWriteDump failed: %s", GetLastErrorString().c_str());
return;
}
Warning("minidump created: %s", temp_file);
}
#endif // NINJA_BOOTSTRAP