Imported Upstream version 1.7.1
[platform/upstream/ninja.git] / src / minidump-win32.cc
1 // Copyright 2012 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifdef _MSC_VER
16
17 #include <windows.h>
18 #include <DbgHelp.h>
19
20 #include "util.h"
21
22 typedef BOOL (WINAPI *MiniDumpWriteDumpFunc) (
23     IN HANDLE,
24     IN DWORD,
25     IN HANDLE,
26     IN MINIDUMP_TYPE,
27     IN CONST PMINIDUMP_EXCEPTION_INFORMATION, OPTIONAL
28     IN CONST PMINIDUMP_USER_STREAM_INFORMATION, OPTIONAL
29     IN CONST PMINIDUMP_CALLBACK_INFORMATION OPTIONAL
30     );
31
32 /// Creates a windows minidump in temp folder.
33 void CreateWin32MiniDump(_EXCEPTION_POINTERS* pep) {
34   char temp_path[MAX_PATH];
35   GetTempPath(sizeof(temp_path), temp_path);
36   char temp_file[MAX_PATH];
37   sprintf(temp_file, "%s\\ninja_crash_dump_%d.dmp",
38           temp_path, GetCurrentProcessId());
39
40   // Delete any previous minidump of the same name.
41   DeleteFile(temp_file);
42
43   // Load DbgHelp.dll dynamically, as library is not present on all
44   // Windows versions.
45   HMODULE dbghelp = LoadLibrary("dbghelp.dll");
46   if (dbghelp == NULL) {
47     Error("failed to create minidump: LoadLibrary('dbghelp.dll'): %s",
48           GetLastErrorString().c_str());
49     return;
50   }
51
52   MiniDumpWriteDumpFunc mini_dump_write_dump =
53       (MiniDumpWriteDumpFunc)GetProcAddress(dbghelp, "MiniDumpWriteDump");
54   if (mini_dump_write_dump == NULL) {
55     Error("failed to create minidump: GetProcAddress('MiniDumpWriteDump'): %s",
56           GetLastErrorString().c_str());
57     return;
58   }
59
60   HANDLE hFile = CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL,
61                              CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
62   if (hFile == NULL) {
63     Error("failed to create minidump: CreateFileA(%s): %s",
64           temp_file, GetLastErrorString().c_str());
65     return;
66   }
67
68   MINIDUMP_EXCEPTION_INFORMATION mdei;
69   mdei.ThreadId           = GetCurrentThreadId();
70   mdei.ExceptionPointers  = pep;
71   mdei.ClientPointers     = FALSE;
72   MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE) (MiniDumpWithDataSegs |
73                                              MiniDumpWithHandleData);
74
75   BOOL rv = mini_dump_write_dump(GetCurrentProcess(), GetCurrentProcessId(),
76                                  hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0);
77   CloseHandle(hFile);
78
79   if (!rv) {
80     Error("MiniDumpWriteDump failed: %s", GetLastErrorString().c_str());
81     return;
82   }
83
84   Warning("minidump created: %s", temp_file);
85 }
86
87 #endif  // _MSC_VER