diff --git a/client/crashpad_client_win.cc b/client/crashpad_client_win.cc index c06b7896..0da0c228 100644 --- a/client/crashpad_client_win.cc +++ b/client/crashpad_client_win.cc @@ -1021,6 +1021,11 @@ bool CrashpadClient::DumpAndCrashTargetProcess(HANDLE process, return false; } + // The injected thread raises an exception and ultimately results in process + // termination. The suspension must be made aware that the process may be + // terminating, otherwise it’ll log an extraneous error. + suspend.TolerateTermination(); + bool result = true; if (WaitForSingleObject(injected_thread, 60 * 1000) != WAIT_OBJECT_0) { PLOG(ERROR) << "WaitForSingleObject"; diff --git a/util/win/nt_internals.h b/util/win/nt_internals.h index 41e5fa44..a14678fc 100644 --- a/util/win/nt_internals.h +++ b/util/win/nt_internals.h @@ -17,6 +17,12 @@ #include "util/win/process_structs.h" +// Copied from ntstatus.h because um/winnt.h conflicts with general inclusion of +// ntstatus.h. +#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) +#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) +#define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS)0xC000010AL) + namespace crashpad { NTSTATUS NtClose(HANDLE handle); @@ -36,11 +42,6 @@ NtCreateThreadEx(PHANDLE thread_handle, SIZE_T maximum_stack_size, PVOID /*PPS_ATTRIBUTE_LIST*/ attribute_list); -// Copied from ntstatus.h because um/winnt.h conflicts with general inclusion of -// ntstatus.h. -#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L) -#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) - // winternal.h defines THREADINFOCLASS, but not all members. enum { ThreadBasicInformation = 0 }; diff --git a/util/win/scoped_process_suspend.cc b/util/win/scoped_process_suspend.cc index f07acc3c..721eb7f5 100644 --- a/util/win/scoped_process_suspend.cc +++ b/util/win/scoped_process_suspend.cc @@ -35,10 +35,15 @@ ScopedProcessSuspend::ScopedProcessSuspend(HANDLE process) { ScopedProcessSuspend::~ScopedProcessSuspend() { if (process_) { NTSTATUS status = NtResumeProcess(process_); - if (!NT_SUCCESS(status)) { + if (!NT_SUCCESS(status) && + (!tolerate_termination_ || status != STATUS_PROCESS_IS_TERMINATING)) { NTSTATUS_LOG(ERROR, status) << "NtResumeProcess"; } } } +void ScopedProcessSuspend::TolerateTermination() { + tolerate_termination_ = true; +} + } // namespace crashpad diff --git a/util/win/scoped_process_suspend.h b/util/win/scoped_process_suspend.h index e5adea9c..913886e5 100644 --- a/util/win/scoped_process_suspend.h +++ b/util/win/scoped_process_suspend.h @@ -35,8 +35,18 @@ class ScopedProcessSuspend { explicit ScopedProcessSuspend(HANDLE process); ~ScopedProcessSuspend(); + //! \brief Informs the object that the suspended process may be terminating, + //! and that this should not be treated as an error. + //! + //! Normally, attempting to resume a terminating process during destruction + //! results in an error message being logged for + //! `STATUS_PROCESS_IS_TERMINATING`. When it is known that a process may be + //! terminating, this method may be called to suppress that error message. + void TolerateTermination(); + private: HANDLE process_; + bool tolerate_termination_ = false; DISALLOW_COPY_AND_ASSIGN(ScopedProcessSuspend); };