зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1837079 - [9/10] WinFileDialog: add ProcessingError() implementations r=ipc-reviewers,nika,win-reviewers,mhowell
Implement `ProcessingError` in `WinFileDialog{Parent,Child}` to report errors in logging -- and, in the child process, report them via telemetry and crash. Differential Revision: https://phabricator.services.mozilla.com/D180344
This commit is contained in:
Родитель
371b0d83fc
Коммит
b30ef50e6e
|
@ -38,10 +38,6 @@ WinFileDialogChild::~WinFileDialogChild() {
|
|||
mUsed = true; \
|
||||
} while (0)
|
||||
|
||||
// (this alternate definition requires data-steward review first)
|
||||
// #define MOZ_IPC_HRESULT_FAIL(hr, what) \
|
||||
// IPC_FAIL_UNSAFE_PRINTF(this, "HRESULT %8lX while %s", (hr), (what))
|
||||
|
||||
#define MOZ_IPC_HRESULT_FAIL(hr, what) IPC_FAIL(this, what)
|
||||
|
||||
#define MOZ_IPC_ENSURE_HRESULT_OK(hr, what) \
|
||||
|
@ -132,4 +128,8 @@ WinFileDialogChild::IPCResult WinFileDialogChild::RecvShowFolderDialog(
|
|||
#undef MOZ_IPC_ENSURE_HRESULT_OK
|
||||
#undef MOZ_IPC_HRESULT_FAIL
|
||||
|
||||
void WinFileDialogChild::ProcessingError(Result aCode, const char* aReason) {
|
||||
detail::LogProcessingError(sLogFileDialog, this, aCode, aReason);
|
||||
}
|
||||
|
||||
} // namespace mozilla::widget::filedialog
|
||||
|
|
|
@ -34,6 +34,8 @@ class WinFileDialogChild : public PWinFileDialogChild {
|
|||
private:
|
||||
~WinFileDialogChild();
|
||||
|
||||
void ProcessingError(Result aCode, const char* aReason) override;
|
||||
|
||||
// This flag properly _should_ be static (_i.e._, per-process) rather than
|
||||
// per-instance; but we can't presently instantiate two separate utility
|
||||
// processes with the same sandbox type, so we have to reuse the existing
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <shtypes.h>
|
||||
#include <winerror.h>
|
||||
#include "WinUtils.h"
|
||||
#include "mozilla/ipc/ProtocolUtils.h"
|
||||
#include "mozilla/ipc/UtilityProcessManager.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/WinHeaderOnlyUtils.h"
|
||||
|
||||
|
@ -210,4 +213,90 @@ mozilla::Result<nsString, HRESULT> GetFolderResults(::IFileDialog* dialog) {
|
|||
|
||||
#undef MOZ_ENSURE_HRESULT_OK
|
||||
|
||||
namespace detail {
|
||||
void LogProcessingError(LogModule* aModule, ipc::IProtocol* aCaller,
|
||||
ipc::HasResultCodes::Result aCode,
|
||||
const char* aReason) {
|
||||
LogLevel const level = [&]() {
|
||||
switch (aCode) {
|
||||
case ipc::HasResultCodes::MsgProcessed:
|
||||
// Normal operation. (We probably never actually get this code.)
|
||||
return LogLevel::Verbose;
|
||||
|
||||
case ipc::HasResultCodes::MsgDropped:
|
||||
return LogLevel::Verbose;
|
||||
|
||||
default:
|
||||
return LogLevel::Error;
|
||||
}
|
||||
}();
|
||||
|
||||
// Processing errors are sometimes unhelpfully formatted. We can't fix that
|
||||
// directly because the unhelpful formatting has made its way to telemetry
|
||||
// (table `telemetry.socorro_crash`, column `ipc_channel_error`) and is being
|
||||
// aggregated on. :(
|
||||
nsCString reason(aReason);
|
||||
if (reason.Last() == '\n') {
|
||||
reason.Truncate(reason.Length() - 1);
|
||||
}
|
||||
|
||||
if (MOZ_LOG_TEST(aModule, level)) {
|
||||
const char* const side = [&]() {
|
||||
switch (aCaller->GetSide()) {
|
||||
case ipc::ParentSide:
|
||||
return "parent";
|
||||
case ipc::ChildSide:
|
||||
return "child";
|
||||
case ipc::UnknownSide:
|
||||
return "unknown side";
|
||||
default:
|
||||
return "<illegal value>";
|
||||
}
|
||||
}();
|
||||
|
||||
const char* const errorStr = [&]() {
|
||||
switch (aCode) {
|
||||
case ipc::HasResultCodes::MsgProcessed:
|
||||
return "Processed";
|
||||
case ipc::HasResultCodes::MsgDropped:
|
||||
return "Dropped";
|
||||
case ipc::HasResultCodes::MsgNotKnown:
|
||||
return "NotKnown";
|
||||
case ipc::HasResultCodes::MsgNotAllowed:
|
||||
return "NotAllowed";
|
||||
case ipc::HasResultCodes::MsgPayloadError:
|
||||
return "PayloadError";
|
||||
case ipc::HasResultCodes::MsgProcessingError:
|
||||
return "ProcessingError";
|
||||
case ipc::HasResultCodes::MsgRouteError:
|
||||
return "RouteError";
|
||||
case ipc::HasResultCodes::MsgValueError:
|
||||
return "ValueError";
|
||||
default:
|
||||
return "<illegal error type>";
|
||||
}
|
||||
}();
|
||||
|
||||
MOZ_LOG(aModule, level,
|
||||
("%s [%s]: IPC error (%s): %s", aCaller->GetProtocolName(), side,
|
||||
errorStr, reason.get()));
|
||||
}
|
||||
|
||||
if (level == LogLevel::Error) {
|
||||
// kill the child process...
|
||||
if (aCaller->GetSide() == ipc::ParentSide) {
|
||||
// ... which isn't us
|
||||
ipc::UtilityProcessManager::GetSingleton()->CleanShutdown(
|
||||
ipc::SandboxingKind::WINDOWS_FILE_DIALOG);
|
||||
} else {
|
||||
// ... which (presumably) is us
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
|
||||
MOZ_CRASH("IPC error");
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mozilla::widget::filedialog
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#define widget_windows_filedialog_WinFileDialogCommands_h__
|
||||
|
||||
#include "ipc/EnumSerializer.h"
|
||||
#include "mozilla/ipc/MessageLink.h"
|
||||
#include "mozilla/widget/filedialog/WinFileDialogCommandsDefn.h"
|
||||
|
||||
// Windows interface types, defined in <shobjidl.h>
|
||||
|
@ -35,6 +36,13 @@ mozilla::Result<Results, HRESULT> GetFileResults(::IFileDialog*);
|
|||
//
|
||||
// Requires that Show() has been called and has returned S_OK.
|
||||
mozilla::Result<nsString, HRESULT> GetFolderResults(::IFileDialog*);
|
||||
|
||||
namespace detail {
|
||||
// Log the error. If it's a notable error, kill the child process.
|
||||
void LogProcessingError(LogModule* aModule, ipc::IProtocol* aCaller,
|
||||
ipc::HasResultCodes::Result aCode, const char* aReason);
|
||||
} // namespace detail
|
||||
|
||||
} // namespace mozilla::widget::filedialog
|
||||
|
||||
namespace IPC {
|
||||
|
|
|
@ -53,6 +53,10 @@ PWinFileDialogParent::nsresult WinFileDialogParent::BindToUtilityProcess(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
void WinFileDialogParent::ProcessingError(Result aCode, const char* aReason) {
|
||||
detail::LogProcessingError(sLogWFD, this, aCode, aReason);
|
||||
}
|
||||
|
||||
ProcessProxy::ProcessProxy(RefPtr<WFDP>&& obj)
|
||||
: data(MakeRefPtr<Contents>(std::move(obj))) {}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ class WinFileDialogParent : public PWinFileDialogParent {
|
|||
|
||||
private:
|
||||
~WinFileDialogParent();
|
||||
|
||||
void ProcessingError(Result aCode, const char* aReason) override;
|
||||
};
|
||||
|
||||
// Proxy for the WinFileDialog process and actor.
|
||||
|
|
Загрузка…
Ссылка в новой задаче