зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1194935 - Add a C++ implementation of kill_and_get_minidump as part of the build to accommodate dumping 64 bit Firefox from 32 bit python. r=ted
--HG-- extra : commitid : K6BGWSIH6Nk
This commit is contained in:
Родитель
02e869c79a
Коммит
4c18bc2045
|
@ -33,6 +33,7 @@ ifeq ($(OS_ARCH),WINNT)
|
|||
TEST_HARNESS_BINS += \
|
||||
crashinject$(BIN_SUFFIX) \
|
||||
crashinjectdll$(DLL_SUFFIX) \
|
||||
minidumpwriter$(BIN_SUFFIX) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -1783,7 +1783,8 @@ class MochitestDesktop(MochitestBase):
|
|||
try:
|
||||
minidump_path = os.path.join(self.profile.profile,
|
||||
'minidumps')
|
||||
mozcrash.kill_and_get_minidump(processPID, minidump_path)
|
||||
mozcrash.kill_and_get_minidump(processPID, minidump_path,
|
||||
utilityPath)
|
||||
except OSError:
|
||||
# https://bugzilla.mozilla.org/show_bug.cgi?id=921509
|
||||
self.log.info(
|
||||
|
|
|
@ -364,7 +364,7 @@ if mozinfo.isWin:
|
|||
OpenProcess = kernel32.OpenProcess
|
||||
CloseHandle = kernel32.CloseHandle
|
||||
|
||||
def write_minidump(pid, dump_directory):
|
||||
def write_minidump(pid, dump_directory, utility_path):
|
||||
"""
|
||||
Write a minidump for a process.
|
||||
|
||||
|
@ -379,13 +379,38 @@ if mozinfo.isWin:
|
|||
FILE_ATTRIBUTE_NORMAL = 0x80
|
||||
INVALID_HANDLE_VALUE = -1
|
||||
|
||||
file_name = os.path.join(dump_directory,
|
||||
str(uuid.uuid4()) + ".dmp")
|
||||
|
||||
if (mozinfo.info['bits'] != ctypes.sizeof(ctypes.c_voidp) * 8 and
|
||||
utility_path):
|
||||
# We're not going to be able to write a minidump with ctypes if our
|
||||
# python process was compiled for a different architecture than
|
||||
# firefox, so we invoke the minidumpwriter utility program.
|
||||
|
||||
log = get_logger()
|
||||
minidumpwriter = os.path.normpath(os.path.join(utility_path,
|
||||
"minidumpwriter.exe"))
|
||||
log.info("Using %s to write a dump to %s for [%d]" %
|
||||
(minidumpwriter, file_name, pid))
|
||||
if not os.path.exists(minidumpwriter):
|
||||
log.error("minidumpwriter not found in %s" % utility_path)
|
||||
return
|
||||
|
||||
if isinstance(file_name, unicode):
|
||||
# Convert to a byte string before sending to the shell.
|
||||
file_name = file_name.encode(sys.getfilesystemencoding())
|
||||
|
||||
status = subprocess.Popen([minidumpwriter, str(pid), file_name]).wait()
|
||||
if status:
|
||||
log.error("minidumpwriter exited with status: %d" % status)
|
||||
return
|
||||
|
||||
proc_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
0, pid)
|
||||
if not proc_handle:
|
||||
return
|
||||
|
||||
file_name = os.path.join(dump_directory,
|
||||
str(uuid.uuid4()) + ".dmp")
|
||||
if not isinstance(file_name, unicode):
|
||||
# Convert to unicode explicitly so our path will be valid as input
|
||||
# to CreateFileW
|
||||
|
@ -433,7 +458,7 @@ else:
|
|||
"""
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
def kill_and_get_minidump(pid, dump_directory=None):
|
||||
def kill_and_get_minidump(pid, dump_directory, utility_path=None):
|
||||
"""
|
||||
Attempt to kill a process and leave behind a minidump describing its
|
||||
execution state.
|
||||
|
@ -453,7 +478,7 @@ def kill_and_get_minidump(pid, dump_directory=None):
|
|||
"""
|
||||
needs_killing = True
|
||||
if mozinfo.isWin:
|
||||
write_minidump(pid, dump_directory)
|
||||
write_minidump(pid, dump_directory, utility_path)
|
||||
elif mozinfo.isLinux or mozinfo.isMac:
|
||||
os.kill(pid, signal.SIGABRT)
|
||||
needs_killing = False
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
/*
|
||||
* Given a PID and a path to a target file, write a minidump of the
|
||||
* corresponding process in that file. This is taken more or less
|
||||
* verbatim from mozcrash and translated to C++ to avoid problems
|
||||
* writing a minidump of 64 bit Firefox from a 32 bit python.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
|
||||
int wmain(int argc, wchar_t** argv)
|
||||
{
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: minidumpwriter <PID> <DUMP_FILE>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
DWORD pid = (DWORD) _wtoi(argv[1]);
|
||||
|
||||
if (pid <= 0) {
|
||||
fprintf(stderr, "Usage: minidumpwriter <PID> <DUMP_FILE>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t* dumpfile = argv[2];
|
||||
int rv = 1;
|
||||
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
|
||||
0, pid);
|
||||
if (!hProcess) {
|
||||
fprintf(stderr, "Couldn't get handle for %d\n", pid);
|
||||
return rv;
|
||||
}
|
||||
|
||||
HANDLE file = CreateFileW(dumpfile, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
fprintf(stderr, "Couldn't open dump file at %S\n", dumpfile);
|
||||
CloseHandle(hProcess);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
if (!MiniDumpWriteDump(hProcess, pid, file, MiniDumpNormal,
|
||||
nullptr, nullptr, nullptr)) {
|
||||
fprintf(stderr, "Error 0x%X in MiniDumpWriteDump\n", GetLastError());
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
CloseHandle(hProcess);
|
||||
return rv;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if CONFIG['ENABLE_TESTS'] and CONFIG['CPU_ARCH'] == 'x86_64' and CONFIG['OS_ARCH'] == 'WINNT':
|
||||
Program('minidumpwriter')
|
||||
OS_LIBS += [
|
||||
'dbghelp',
|
||||
]
|
||||
SOURCES += [
|
||||
'minidumpwriter.cpp',
|
||||
]
|
||||
USE_STATIC_LIBS = True
|
||||
|
||||
NO_PGO = True
|
|
@ -172,6 +172,7 @@ if CONFIG['ENABLE_TESTS']:
|
|||
DIRS += [
|
||||
'/testing/mochitest',
|
||||
'/testing/xpcshell',
|
||||
'/testing/tools/minidumpwriter',
|
||||
'/testing/tools/screenshot',
|
||||
'/testing/profiles',
|
||||
'/testing/mozbase',
|
||||
|
|
Загрузка…
Ссылка в новой задаче