github.com/maruel/nin@v0.0.0-20220112143044-f35891e3ce7e/src/minidump-win32.cc (about)

     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  using namespace std;
    23  
    24  typedef BOOL (WINAPI *MiniDumpWriteDumpFunc) (
    25      IN HANDLE,
    26      IN DWORD,
    27      IN HANDLE,
    28      IN MINIDUMP_TYPE,
    29      IN CONST PMINIDUMP_EXCEPTION_INFORMATION, OPTIONAL
    30      IN CONST PMINIDUMP_USER_STREAM_INFORMATION, OPTIONAL
    31      IN CONST PMINIDUMP_CALLBACK_INFORMATION OPTIONAL
    32      );
    33  
    34  /// Creates a windows minidump in temp folder.
    35  void CreateWin32MiniDump(_EXCEPTION_POINTERS* pep) {
    36    char temp_path[MAX_PATH];
    37    GetTempPathA(sizeof(temp_path), temp_path);
    38    char temp_file[MAX_PATH];
    39    sprintf(temp_file, "%s\\ninja_crash_dump_%lu.dmp",
    40            temp_path, GetCurrentProcessId());
    41  
    42    // Delete any previous minidump of the same name.
    43    DeleteFileA(temp_file);
    44  
    45    // Load DbgHelp.dll dynamically, as library is not present on all
    46    // Windows versions.
    47    HMODULE dbghelp = LoadLibraryA("dbghelp.dll");
    48    if (dbghelp == NULL) {
    49      Error("failed to create minidump: LoadLibrary('dbghelp.dll'): %s",
    50            GetLastErrorString().c_str());
    51      return;
    52    }
    53  
    54    MiniDumpWriteDumpFunc mini_dump_write_dump =
    55        (MiniDumpWriteDumpFunc)GetProcAddress(dbghelp, "MiniDumpWriteDump");
    56    if (mini_dump_write_dump == NULL) {
    57      Error("failed to create minidump: GetProcAddress('MiniDumpWriteDump'): %s",
    58            GetLastErrorString().c_str());
    59      return;
    60    }
    61  
    62    HANDLE hFile = CreateFileA(temp_file, GENERIC_READ | GENERIC_WRITE, 0, NULL,
    63                               CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    64    if (hFile == NULL) {
    65      Error("failed to create minidump: CreateFileA(%s): %s",
    66            temp_file, GetLastErrorString().c_str());
    67      return;
    68    }
    69  
    70    MINIDUMP_EXCEPTION_INFORMATION mdei;
    71    mdei.ThreadId           = GetCurrentThreadId();
    72    mdei.ExceptionPointers  = pep;
    73    mdei.ClientPointers     = FALSE;
    74    MINIDUMP_TYPE mdt       = (MINIDUMP_TYPE) (MiniDumpWithDataSegs |
    75                                               MiniDumpWithHandleData);
    76  
    77    BOOL rv = mini_dump_write_dump(GetCurrentProcess(), GetCurrentProcessId(),
    78                                   hFile, mdt, (pep != 0) ? &mdei : 0, 0, 0);
    79    CloseHandle(hFile);
    80  
    81    if (!rv) {
    82      Error("MiniDumpWriteDump failed: %s", GetLastErrorString().c_str());
    83      return;
    84    }
    85  
    86    Warning("minidump created: %s", temp_file);
    87  }
    88  
    89  #endif  // _MSC_VER