toolkit/crashreporter/InjectCrashReporter.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "InjectCrashReporter.h"
     7 #include "nsDirectoryServiceUtils.h"
     8 #include "nsDirectoryServiceDefs.h"
     9 #include "client/windows/crash_generation/crash_generation_client.h"
    10 #include "nsExceptionHandler.h"
    11 #include "LoadLibraryRemote.h"
    12 #include "nsWindowsHelpers.h"
    14 using google_breakpad::CrashGenerationClient;
    15 using CrashReporter::GetChildNotificationPipe;
    17 namespace mozilla {
    19 InjectCrashRunnable::InjectCrashRunnable(DWORD pid)
    20   : mPID(pid)
    21 {
    22   nsCOMPtr<nsIFile> dll;
    23   nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(dll));
    24   if (NS_SUCCEEDED(rv)) {
    25     dll->Append(NS_LITERAL_STRING("breakpadinjector.dll"));
    26     dll->GetPath(mInjectorPath);
    27   }
    28 }
    30 NS_IMETHODIMP
    31 InjectCrashRunnable::Run()
    32 {
    33   if (mInjectorPath.IsEmpty())
    34     return NS_OK;
    36   nsAutoHandle hProcess(
    37     OpenProcess(PROCESS_CREATE_THREAD |
    38                 PROCESS_QUERY_INFORMATION |
    39                 PROCESS_DUP_HANDLE |
    40                 PROCESS_VM_OPERATION |
    41                 PROCESS_VM_WRITE |
    42                 PROCESS_VM_READ, FALSE, mPID));
    43   if (!hProcess) {
    44     NS_WARNING("Unable to open remote process handle for crashreporter injection.");
    45     return NS_OK;
    46   }
    48   void* proc = LoadRemoteLibraryAndGetAddress(hProcess, mInjectorPath.get(),
    49                                               "Start");
    50   if (!proc) {
    51     NS_WARNING("Unable to inject crashreporter DLL.");
    52     return NS_OK;
    53   }
    55   HANDLE hRemotePipe =
    56     CrashGenerationClient::DuplicatePipeToClientProcess(
    57       NS_ConvertASCIItoUTF16(GetChildNotificationPipe()).get(),
    58       hProcess);
    59   if (INVALID_HANDLE_VALUE == hRemotePipe) {
    60     NS_WARNING("Unable to duplicate crash reporter pipe to process.");
    61     return NS_OK;
    62   }
    64   nsAutoHandle hThread(CreateRemoteThread(hProcess, nullptr, 0,
    65                                           (LPTHREAD_START_ROUTINE) proc,
    66                                           (void*) hRemotePipe, 0, nullptr));
    67   if (!hThread) {
    68     NS_WARNING("Unable to CreateRemoteThread");
    70     // We have to close the remote pipe or else our crash generation client
    71     // will be stuck unable to accept other remote requests.
    72     HANDLE toClose = INVALID_HANDLE_VALUE;
    73     if (DuplicateHandle(hProcess, hRemotePipe, ::GetCurrentProcess(),
    74                         &toClose, 0, FALSE,
    75                         DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
    76       CloseHandle(toClose);
    77       return NS_OK;
    78     }
    79   }
    81   return NS_OK;
    82 }
    84 } // namespace mozilla

mercurial