Merge master f83530bf9a0b into doc

This commit is contained in:
Mark Mentovai 2016-11-11 12:39:14 -05:00
commit 3d51f30415
21 changed files with 242 additions and 65 deletions

View File

@ -25,5 +25,16 @@
4201, # nonstandard extension used : nameless struct/union.
4324, # structure was padded due to __declspec(align()).
],
'conditions': [
['OS=="linux" or OS=="android"', {
'conditions': [
['clang==0', {
'cflags': [
'-Wno-multichar',
],
}],
],
}],
],
},
}

View File

@ -65,6 +65,8 @@
#define PROCESSOR_ARCHITECTURE_AMD64 9
#define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
#define PROCESSOR_ARCHITECTURE_NEUTRAL 11
#define PROCESSOR_ARCHITECTURE_ARM64 12
#define PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 13
#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xffff
//! \}
@ -104,6 +106,10 @@
#define PF_ARM_EXTERNAL_CACHE_AVAILABLE 26
#define PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE 27
#define PF_RDRAND_INSTRUCTION_AVAILABLE 28
#define PF_ARM_V8_INSTRUCTIONS_AVAILABLE 29
#define PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE 30
#define PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE 31
#define PF_RDTSCP_INSTRUCTION_AVAILABLE 32
//! \}
//! \anchor IMAGE_DEBUG_MISC_x

View File

@ -15,6 +15,9 @@
#ifndef CRASHPAD_COMPAT_WIN_WINNT_H_
#define CRASHPAD_COMPAT_WIN_WINNT_H_
// include_next <winnt.h>
#include <../um/winnt.h>
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa373184.aspx:
// "Note that this structure definition was accidentally omitted from WinNT.h."
struct PROCESSOR_POWER_INFORMATION {
@ -26,7 +29,32 @@ struct PROCESSOR_POWER_INFORMATION {
ULONG CurrentIdleState;
};
// include_next <winnt.h>
#include <../um/winnt.h>
// 10.0.10240.0 SDK
#ifndef PROCESSOR_ARCHITECTURE_ARM64
#define PROCESSOR_ARCHITECTURE_ARM64 12
#endif
#ifndef PF_ARM_V8_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V8_INSTRUCTIONS_AVAILABLE 29
#endif
#ifndef PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE 30
#endif
#ifndef PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE
#define PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE 31
#endif
#ifndef PF_RDTSCP_INSTRUCTION_AVAILABLE
#define PF_RDTSCP_INSTRUCTION_AVAILABLE 32
#endif
// 10.0.14393.0 SDK
#ifndef PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64
#define PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 13
#endif
#endif // CRASHPAD_COMPAT_WIN_WINNT_H_

View File

@ -154,7 +154,12 @@ $ CC_target=~/android-ndk-r13_arm64_api21/bin/clang \
--generator-output=out_android_arm64_api21 -f ninja-android
```
Target “triplets” to use for `ar`, `nm`, and `readelf` are:
It is also possible to use GCC instead of Clang by making the appropriate
substitutions: `aarch64-linux-android-gcc` for `CC_target`;
`aarch64-linux-android-g++` for `CXX_target`; and `-Dclang=0` as an argument to
`gyp_crashpad.py`.
Target “triplets” to use for `ar`, `nm`, `readelf`, `gcc`, and `g++` are:
| Architecture | Target “triplet” |
|:-------------|:------------------------|

View File

@ -21,6 +21,7 @@
#include "minidump/minidump_context_writer.h"
#include "snapshot/exception_snapshot.h"
#include "util/file/file_writer.h"
#include "util/misc/arraysize_unsafe.h"
namespace crashpad {
@ -64,7 +65,7 @@ void MinidumpExceptionWriter::SetExceptionInformation(
const size_t parameters = exception_information.size();
const size_t kMaxParameters =
arraysize(exception_.ExceptionRecord.ExceptionInformation);
ARRAYSIZE_UNSAFE(exception_.ExceptionRecord.ExceptionInformation);
CHECK_LE(parameters, kMaxParameters);
exception_.ExceptionRecord.NumberParameters =

View File

@ -162,6 +162,16 @@ enum MinidumpCPUArchitecture : uint16_t {
kMinidumpCPUArchitectureX86Win64 = PROCESSOR_ARCHITECTURE_IA32_ON_WIN64,
kMinidumpCPUArchitectureNeutral = PROCESSOR_ARCHITECTURE_NEUTRAL,
//! \brief 64-bit ARM.
//!
//! These systems identify their CPUs generically as “arm64” or “aarch64”, or
//! with more specific names such as “armv8”.
//!
//! \sa #kMinidumpCPUArchitectureARM64Breakpad
kMinidumpCPUArchitectureARM64 = PROCESSOR_ARCHITECTURE_ARM64,
kMinidumpCPUArchitectureARM32Win64 = PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64,
kMinidumpCPUArchitectureSPARC = 0x8001,
//! \brief 64-bit PowerPC.
@ -170,11 +180,10 @@ enum MinidumpCPUArchitecture : uint16_t {
//! specific names such as “ppc970”.
kMinidumpCPUArchitecturePPC64 = 0x8002,
//! \brief 64-bit ARM.
//! \brief Used by Breakpad for 64-bit ARM.
//!
//! These systems identify their CPUs generically as “arm64” or “aarch64”, or
//! with more specific names such as “armv8”.
kMinidumpCPUArchitectureARM64 = 0x8003,
//! \deprecated Use #kMinidumpCPUArchitectureARM64 instead.
kMinidumpCPUArchitectureARM64Breakpad = 0x8003,
//! \brief Unknown CPU architecture.
kMinidumpCPUArchitectureUnknown = PROCESSOR_ARCHITECTURE_UNKNOWN,

View File

@ -26,6 +26,7 @@
#include "snapshot/process_snapshot.h"
#include "snapshot/system_snapshot.h"
#include "util/file/file_writer.h"
#include "util/misc/arraysize_unsafe.h"
#include "util/numeric/in_range_cast.h"
#include "util/numeric/safe_assignment.h"
@ -295,7 +296,7 @@ void MinidumpMiscInfoWriter::SetTimeZone(uint32_t time_zone_id,
internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
misc_info_.TimeZone.StandardName,
arraysize(misc_info_.TimeZone.StandardName),
ARRAYSIZE_UNSAFE(misc_info_.TimeZone.StandardName),
standard_name);
misc_info_.TimeZone.StandardDate = standard_date;
@ -303,7 +304,7 @@ void MinidumpMiscInfoWriter::SetTimeZone(uint32_t time_zone_id,
internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
misc_info_.TimeZone.DaylightName,
arraysize(misc_info_.TimeZone.DaylightName),
ARRAYSIZE_UNSAFE(misc_info_.TimeZone.DaylightName),
daylight_name);
misc_info_.TimeZone.DaylightDate = daylight_date;
@ -320,10 +321,12 @@ void MinidumpMiscInfoWriter::SetBuildString(
misc_info_.Flags1 |= MINIDUMP_MISC4_BUILDSTRING;
internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
misc_info_.BuildString, arraysize(misc_info_.BuildString), build_string);
misc_info_.BuildString,
ARRAYSIZE_UNSAFE(misc_info_.BuildString),
build_string);
internal::MinidumpWriterUtil::AssignUTF8ToUTF16(
misc_info_.DbgBldStr,
arraysize(misc_info_.DbgBldStr),
ARRAYSIZE_UNSAFE(misc_info_.DbgBldStr),
debug_build_string);
}

View File

@ -34,8 +34,8 @@ MinidumpSimpleStringDictionaryEntryWriter::
}
const MinidumpSimpleStringDictionaryEntry*
MinidumpSimpleStringDictionaryEntryWriter::MinidumpSimpleStringDictionaryEntry()
const {
MinidumpSimpleStringDictionaryEntryWriter::
GetMinidumpSimpleStringDictionaryEntry() const {
DCHECK_EQ(state(), kStateWritable);
return &entry_;
@ -179,7 +179,7 @@ bool MinidumpSimpleStringDictionaryWriter::WriteObject(
std::vector<WritableIoVec> iovecs(1, iov);
for (const auto& key_entry : entries_) {
iov.iov_base = key_entry.second->MinidumpSimpleStringDictionaryEntry();
iov.iov_base = key_entry.second->GetMinidumpSimpleStringDictionaryEntry();
iov.iov_len = sizeof(MinidumpSimpleStringDictionaryEntry);
iovecs.push_back(iov);
}

View File

@ -52,7 +52,7 @@ class MinidumpSimpleStringDictionaryEntryWriter final
//!
//! \note Valid in #kStateWritable.
const MinidumpSimpleStringDictionaryEntry*
MinidumpSimpleStringDictionaryEntry() const;
GetMinidumpSimpleStringDictionaryEntry() const;
//! \brief Sets the strings to be written as the entry objects key and value.
//!

View File

@ -20,6 +20,7 @@
#include "minidump/minidump_string_writer.h"
#include "snapshot/system_snapshot.h"
#include "util/file/file_writer.h"
#include "util/misc/arraysize_unsafe.h"
#include "util/misc/implicit_cast.h"
namespace crashpad {
@ -64,10 +65,12 @@ uint64_t AMD64FeaturesFromSystemSnapshot(
MAP_FEATURE(cpuid_features, F_RDRAND, PF_RDRAND_INSTRUCTION_AVAILABLE);
#define FX_XD 20
#define FX_RDTSCP 27
#define FX_3DNOW 31
uint64_t extended_features = system_snapshot->CPUX86ExtendedFeatures();
MAP_FEATURE(extended_features, FX_RDTSCP, PF_RDTSCP_INSTRUCTION_AVAILABLE);
MAP_FEATURE(extended_features, FX_3DNOW, PF_3DNOW_INSTRUCTIONS_AVAILABLE);
#define F7_FSGSBASE 0
@ -76,8 +79,8 @@ uint64_t AMD64FeaturesFromSystemSnapshot(
MAP_FEATURE(leaf7_features, F7_FSGSBASE, PF_RDWRFSGSBASE_AVAILABLE);
// This feature bit should be set if NX (XD, DEP) is enabled, not just if
// its available on the CPU as indicated by the XF_XD bit.
// This feature bit should be set if NX (XD, DEP) is enabled, not just if its
// available on the CPU as indicated by the FX_XD bit.
if (system_snapshot->NXEnabled()) {
minidump_features |= ADD_FEATURE(PF_NX_ENABLED);
}
@ -86,10 +89,10 @@ uint64_t AMD64FeaturesFromSystemSnapshot(
minidump_features |= ADD_FEATURE(PF_SSE_DAZ_MODE_AVAILABLE);
}
// PF_SECOND_LEVEL_ADDRESS_TRANSLATION cant be determined without
// consulting model-specific registers, a privileged operation. The exact
// use of PF_VIRT_FIRMWARE_ENABLED is unknown. PF_FASTFAIL_AVAILABLE is
// irrelevant outside of Windows.
// PF_SECOND_LEVEL_ADDRESS_TRANSLATION cant be determined without consulting
// model-specific registers, a privileged operation. The exact use of
// PF_VIRT_FIRMWARE_ENABLED is unknown. PF_FASTFAIL_AVAILABLE is irrelevant
// outside of Windows.
#undef MAP_FEATURE
#undef ADD_FEATURE
@ -194,7 +197,7 @@ void MinidumpSystemInfoWriter::SetCPUX86Vendor(uint32_t ebx,
system_info_.ProcessorArchitecture ==
kMinidumpCPUArchitectureX86Win64);
static_assert(arraysize(system_info_.Cpu.X86CpuInfo.VendorId) == 3,
static_assert(ARRAYSIZE_UNSAFE(system_info_.Cpu.X86CpuInfo.VendorId) == 3,
"VendorId must have 3 elements");
system_info_.Cpu.X86CpuInfo.VendorId[0] = ebx;
@ -252,8 +255,9 @@ void MinidumpSystemInfoWriter::SetCPUOtherFeatures(uint64_t features_0,
system_info_.ProcessorArchitecture !=
kMinidumpCPUArchitectureX86Win64);
static_assert(arraysize(system_info_.Cpu.OtherCpuInfo.ProcessorFeatures) == 2,
"ProcessorFeatures must have 2 elements");
static_assert(
ARRAYSIZE_UNSAFE(system_info_.Cpu.OtherCpuInfo.ProcessorFeatures) == 2,
"ProcessorFeatures must have 2 elements");
system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[0] = features_0;
system_info_.Cpu.OtherCpuInfo.ProcessorFeatures[1] = features_1;

View File

@ -405,7 +405,8 @@ TEST(MinidumpSystemInfoWriter, InitializeFromSnapshot_AMD64) {
(1 << PF_COMPARE_EXCHANGE128) |
(1 << PF_XSAVE_ENABLED) |
(1 << PF_RDWRFSGSBASE_AVAILABLE) |
(1 << PF_RDRAND_INSTRUCTION_AVAILABLE);
(1 << PF_RDRAND_INSTRUCTION_AVAILABLE) |
(UINT64_C(1) << PF_RDTSCP_INSTRUCTION_AVAILABLE);
expect_system_info.Cpu.OtherCpuInfo.ProcessorFeatures[1] = 0;
const char kOSVersionBuild[] = "13F34";

View File

@ -31,7 +31,8 @@ namespace test {
namespace {
void TestImageReaderChild(const base::string16& directory_modification) {
UUID done_uuid(UUID::InitializeWithNewTag{});
UUID done_uuid;
done_uuid.InitializeWithNew();
ScopedKernelHANDLE done(
CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));
ASSERT_TRUE(done.get());

View File

@ -157,7 +157,26 @@ base::mac::ScopedMachReceiveRight BootstrapCheckIn(
base::mac::ScopedMachSendRight BootstrapLookUp(
const std::string& service_name) {
return BootstrapCheckInOrLookUp<BootstrapLookUpTraits>(service_name);
base::mac::ScopedMachSendRight send(
BootstrapCheckInOrLookUp<BootstrapLookUpTraits>(service_name));
// Its possible to race the bootstrap server when the receive right
// corresponding to the looked-up send right is destroyed immediately before
// the bootstrap_look_up() call. If the bootstrap server believes that
// |service_name| is still registered before processing the port-destroyed
// notification sent to it by the kernel, it will respond to a
// bootstrap_look_up() request with a send right that has become a dead name,
// which will be returned to the bootstrap_look_up() caller, translated into
// the callers IPC port name space, as the special MACH_PORT_DEAD port name.
// Check for that and return MACH_PORT_NULL in its place, as though the
// bootstrap server had fully processed the port-destroyed notification before
// responding to bootstrap_look_up().
if (send.get() == MACH_PORT_DEAD) {
LOG(ERROR) << "bootstrap_look_up " << service_name << ": service is dead";
send.reset();
}
return send;
}
base::mac::ScopedMachSendRight SystemCrashReporterHandler() {

View File

@ -0,0 +1,27 @@
// Copyright 2016 The Crashpad Authors. 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 CRASHPAD_UTIL_MISC_ARRAYSIZE_UNSAFE_H_
#define CRASHPAD_UTIL_MISC_ARRAYSIZE_UNSAFE_H_
//! \file
//! \brief Not the safest way of computing an arrays size…
//!
//! `#%include "base/macros.h"` and use its `arraysize()` instead. This macro
//! should only be used in rare situations where `arraysize()` does not
//! function.
#define ARRAYSIZE_UNSAFE(array) (sizeof(array) / sizeof(array[0]))
#endif // CRASHPAD_UTIL_MISC_ARRAYSIZE_UNSAFE_H_

View File

@ -0,0 +1,73 @@
// Copyright 2016 The Crashpad Authors. 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.
#include "util/misc/arraysize_unsafe.h"
#include "gtest/gtest.h"
namespace crashpad {
namespace test {
namespace {
TEST(ArraySizeUnsafe, ArraySizeUnsafe) {
char c0[0];
static_assert(ARRAYSIZE_UNSAFE(c0) == 0, "c0");
char c1[1];
static_assert(ARRAYSIZE_UNSAFE(c1) == 1, "c1");
char c2[2];
static_assert(ARRAYSIZE_UNSAFE(c2) == 2, "c2");
char c4[4];
static_assert(ARRAYSIZE_UNSAFE(c4) == 4, "c4");
int i0[0];
static_assert(ARRAYSIZE_UNSAFE(i0) == 0, "i0");
int i1[1];
static_assert(ARRAYSIZE_UNSAFE(i1) == 1, "i1");
int i2[2];
static_assert(ARRAYSIZE_UNSAFE(i2) == 2, "i2");
int i4[4];
static_assert(ARRAYSIZE_UNSAFE(i4) == 4, "i4");
long l8[8];
static_assert(ARRAYSIZE_UNSAFE(l8) == 8, "l8");
int l9[9];
static_assert(ARRAYSIZE_UNSAFE(l9) == 9, "l9");
struct S {
char c;
int i;
long l;
bool b;
};
S s0[0];
static_assert(ARRAYSIZE_UNSAFE(s0) == 0, "s0");
S s1[1];
static_assert(ARRAYSIZE_UNSAFE(s1) == 1, "s1");
S s10[10];
static_assert(ARRAYSIZE_UNSAFE(s10) == 10, "s10");
}
} // namespace
} // namespace test
} // namespace crashpad

View File

@ -42,23 +42,15 @@ namespace crashpad {
static_assert(sizeof(UUID) == 16, "UUID must be 16 bytes");
#if CXX_LIBRARY_VERSION >= 2011
static_assert(std::is_standard_layout<UUID>::value,
"UUID must be standard layout");
static_assert(std::is_pod<UUID>::value, "UUID must be POD");
#endif
UUID::UUID() : data_1(0), data_2(0), data_3(0), data_4(), data_5() {
}
UUID::UUID(InitializeWithNewTag) {
CHECK(InitializeWithNew());
}
UUID::UUID(const uint8_t* bytes) {
InitializeFromBytes(bytes);
}
bool UUID::operator==(const UUID& that) const {
return memcmp(this, &that, sizeof(UUID)) == 0;
return memcmp(this, &that, sizeof(*this)) == 0;
}
void UUID::InitializeToZero() {
memset(this, 0, sizeof(*this));
}
void UUID::InitializeFromBytes(const uint8_t* bytes) {
@ -132,7 +124,7 @@ void UUID::InitializeFromSystemUUID(const ::UUID* system_uuid) {
"unexpected system uuid size");
static_assert(offsetof(::UUID, Data1) == offsetof(UUID, data_1),
"unexpected system uuid layout");
memcpy(this, system_uuid, sizeof(::UUID));
memcpy(this, system_uuid, sizeof(*this));
}
#endif // OS_WIN

View File

@ -36,27 +36,14 @@ namespace crashpad {
//!
//! A %UUID is a unique 128-bit number specified by RFC 4122.
//!
//! This is a standard-layout structure.
//! This is a POD structure.
struct UUID {
//! \brief Initializes the %UUID to zero.
UUID();
//! \brief Tag to pass to constructor to indicate it should initialize with
//! generated data.
struct InitializeWithNewTag {};
//! \brief Initializes the %UUID using a standard system facility to generate
//! the value.
//!
//! CHECKs on failure with a message logged.
explicit UUID(InitializeWithNewTag);
//! \copydoc InitializeFromBytes()
explicit UUID(const uint8_t* bytes);
bool operator==(const UUID& that) const;
bool operator!=(const UUID& that) const { return !operator==(that); }
//! \brief Initializes the %UUID to zero.
void InitializeToZero();
//! \brief Initializes the %UUID from a sequence of bytes.
//!
//! \a bytes is taken as a %UUID laid out in big-endian format in memory. On

View File

@ -31,6 +31,7 @@ namespace {
TEST(UUID, UUID) {
UUID uuid_zero;
uuid_zero.InitializeToZero();
EXPECT_EQ(0u, uuid_zero.data_1);
EXPECT_EQ(0u, uuid_zero.data_2);
EXPECT_EQ(0u, uuid_zero.data_3);
@ -60,7 +61,8 @@ TEST(UUID, UUID) {
0x0d,
0x0e,
0x0f};
UUID uuid(kBytes);
UUID uuid;
uuid.InitializeFromBytes(kBytes);
EXPECT_EQ(0x00010203u, uuid.data_1);
EXPECT_EQ(0x0405u, uuid.data_2);
EXPECT_EQ(0x0607u, uuid.data_3);
@ -78,7 +80,8 @@ TEST(UUID, UUID) {
EXPECT_FALSE(uuid == uuid_zero);
EXPECT_NE(uuid, uuid_zero);
UUID uuid_2(kBytes);
UUID uuid_2;
uuid_2.InitializeFromBytes(kBytes);
EXPECT_EQ(uuid, uuid_2);
EXPECT_FALSE(uuid != uuid_2);
@ -155,7 +158,8 @@ TEST(UUID, UUID) {
EXPECT_EQ(0x45u, uuid.data_5[5]);
EXPECT_EQ("45454545-4545-4545-4545-454545454545", uuid.ToString());
UUID initialized_generated(UUID::InitializeWithNewTag{});
UUID initialized_generated;
initialized_generated.InitializeWithNew();
EXPECT_NE(initialized_generated, uuid_zero);
}
@ -182,7 +186,9 @@ TEST(UUID, FromString) {
{"6d247a34-53d5-40ec-a90d-d8dea9e94cc01", false}
};
const std::string empty_uuid = UUID().ToString();
UUID uuid_zero;
uuid_zero.InitializeToZero();
const std::string empty_uuid = uuid_zero.ToString();
for (size_t index = 0; index < arraysize(kCases); ++index) {
const TestCase& test_case = kCases[index];
@ -190,6 +196,7 @@ TEST(UUID, FromString) {
"index %" PRIuS ": %s", index, test_case.uuid_string));
UUID uuid;
uuid.InitializeToZero();
EXPECT_EQ(test_case.success,
uuid.InitializeFromString(test_case.uuid_string));
if (test_case.success) {

View File

@ -84,6 +84,7 @@
'mach/task_for_pid.h',
'mach/task_memory.cc',
'mach/task_memory.h',
'misc/arraysize_unsafe.h',
'misc/clock.h',
'misc/clock_mac.cc',
'misc/clock_posix.cc',

View File

@ -55,6 +55,7 @@
'mach/scoped_task_suspend_test.cc',
'mach/symbolic_constants_mach_test.cc',
'mach/task_memory_test.cc',
'misc/arraysize_unsafe_test.cc',
'misc/clock_test.cc',
'misc/initialization_state_dcheck_test.cc',
'misc/initialization_state_test.cc',

View File

@ -132,7 +132,8 @@ TEST(ProcessInfo, Self) {
void TestOtherProcess(const base::string16& directory_modification) {
ProcessInfo process_info;
UUID done_uuid(UUID::InitializeWithNewTag{});
UUID done_uuid;
done_uuid.InitializeWithNew();
ScopedKernelHANDLE done(
CreateEvent(nullptr, true, false, done_uuid.ToString16().c_str()));