bootstrap: Only show error dialogs with DCHECK_IS_ON (see #3935)

This will enable error dialogs for the Official CEF "Debug" builds.
This commit is contained in:
Marshall Greenblatt
2025-05-25 15:32:40 -04:00
parent 66457acccc
commit 4d65863278

View File

@@ -50,6 +50,12 @@ void SetCwdForBrowserProcess() {
.DirName()); .DirName());
} }
#if DCHECK_IS_ON()
// Displays a message to the user with the error message. Used for fatal
// messages, where we close the app simultaneously. This is for developers only;
// we don't use this in circumstances (like release builds) where users could
// see it, since users don't understand these messages anyway.
// Load a string from the string table in bootstrap.rc. // Load a string from the string table in bootstrap.rc.
std::wstring LoadString(int string_id) { std::wstring LoadString(int string_id) {
const int kMaxSize = 100; const int kMaxSize = 100;
@@ -76,11 +82,17 @@ void ShowError(const std::wstring& error) {
#if defined(CEF_BUILD_BOOTSTRAP_CONSOLE) #if defined(CEF_BUILD_BOOTSTRAP_CONSOLE)
std::wcerr << title.c_str() << ": " << error << extra_info; std::wcerr << title.c_str() << ": " << error << extra_info;
#else #else
const std::wstring& msg = error + extra_info; if (!::IsDebuggerPresent()) {
::MessageBox(nullptr, msg.c_str(), title.c_str(), MB_ICONERROR | MB_OK); // Displaying a dialog is unnecessary when debugging and can complicate
// debugging.
const std::wstring& msg = error + extra_info;
::MessageBox(nullptr, msg.c_str(), title.c_str(), MB_ICONERROR | MB_OK);
}
#endif #endif
} }
#endif // DCHECK_IS_ON()
std::wstring NormalizeError(const std::wstring& err) { std::wstring NormalizeError(const std::wstring& err) {
std::wstring str = err; std::wstring str = err;
// Replace newlines. // Replace newlines.
@@ -100,10 +112,12 @@ void CheckDllCodeSigning(
// signatures and the same primary thumbprint. // signatures and the same primary thumbprint.
if (!dll_thumbprints.IsSame(exe_thumbprints, /*allow_unsigned=*/true)) { if (!dll_thumbprints.IsSame(exe_thumbprints, /*allow_unsigned=*/true)) {
// Some part of the certificate validation process failed. // Some part of the certificate validation process failed.
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>( const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_path.BaseName().value()), {base::WideToUTF16(dll_path.BaseName().value()),
base::WideToUTF16(dll_thumbprints.errors)}); base::WideToUTF16(dll_thumbprints.errors)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst)); ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst));
#endif
if (dll_thumbprints.errors.empty()) { if (dll_thumbprints.errors.empty()) {
LOG(FATAL) << "Failed " << dll_path.value() LOG(FATAL) << "Failed " << dll_path.value()
<< " certificate requirements"; << " certificate requirements";
@@ -213,7 +227,9 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
} }
if (bootstrap_util::IsDefaultExeName(dll_name)) { if (bootstrap_util::IsDefaultExeName(dll_name)) {
#if DCHECK_IS_ON()
ShowError(LoadString(IDS_ERROR_NO_MODULE_NAME)); ShowError(LoadString(IDS_ERROR_NO_MODULE_NAME));
#endif
LOG(FATAL) << "Missing module name"; LOG(FATAL) << "Missing module name";
} }
@@ -223,10 +239,12 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
// The executable must either be unsigned or have all valid signatures. // The executable must either be unsigned or have all valid signatures.
if (!exe_thumbprints.IsUnsignedOrValid()) { if (!exe_thumbprints.IsUnsignedOrValid()) {
// Some part of the certificate validation process failed. // Some part of the certificate validation process failed.
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>( const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(exe_path.BaseName().value()), {base::WideToUTF16(exe_path.BaseName().value()),
base::WideToUTF16(exe_thumbprints.errors)}); base::WideToUTF16(exe_thumbprints.errors)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst)); ShowError(FormatErrorString(IDS_ERROR_INVALID_CERT, subst));
#endif
if (exe_thumbprints.errors.empty()) { if (exe_thumbprints.errors.empty()) {
LOG(FATAL) << "Failed " << exe_path.value() LOG(FATAL) << "Failed " << exe_path.value()
<< " certificate requirements"; << " certificate requirements";
@@ -245,8 +263,10 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
// Must be in the same directory as the EXE. // Must be in the same directory as the EXE.
if (dll_path.DirName() != exe_path.DirName()) { if (dll_path.DirName() != exe_path.DirName()) {
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>({u"chrome_elf"}); const auto subst = std::to_array<std::u16string>({u"chrome_elf"});
ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst)); ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst));
#endif
LOG(FATAL) << "Invalid location: " << dll_path.value(); LOG(FATAL) << "Invalid location: " << dll_path.value();
} }
@@ -270,9 +290,11 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
const auto& dll_path = bootstrap_util::GetModulePath(hModule); const auto& dll_path = bootstrap_util::GetModulePath(hModule);
if (!bootstrap_util::IsModulePathAllowed(dll_path, exe_path)) { if (!bootstrap_util::IsModulePathAllowed(dll_path, exe_path)) {
#if DCHECK_IS_ON()
const auto subst = const auto subst =
std::to_array<std::u16string>({base::WideToUTF16(dll_name)}); std::to_array<std::u16string>({base::WideToUTF16(dll_name)});
ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst)); ShowError(FormatErrorString(IDS_ERROR_INVALID_LOCATION, subst));
#endif
LOG(FATAL) << "Invalid location: " << dll_path.value(); LOG(FATAL) << "Invalid location: " << dll_path.value();
} }
@@ -280,10 +302,12 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
FreeLibrary(hModule); FreeLibrary(hModule);
} else { } else {
#if DCHECK_IS_ON()
const auto subst = std::to_array<std::u16string>( const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name), {base::WideToUTF16(dll_name),
base::WideToUTF16(cef_util::GetLastErrorAsString())}); base::WideToUTF16(cef_util::GetLastErrorAsString())});
ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst)); ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst));
#endif
LOG(FATAL) << "Failed to load " << dll_name << ".dll with error " LOG(FATAL) << "Failed to load " << dll_name << ".dll with error "
<< ::GetLastError(); << ::GetLastError();
} }
@@ -314,6 +338,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
result_code = pFunc(hInstance, lpCmdLine, nCmdShow, sandbox_info); result_code = pFunc(hInstance, lpCmdLine, nCmdShow, sandbox_info);
#endif #endif
} else { } else {
#if DCHECK_IS_ON()
if (!is_sandboxed) { if (!is_sandboxed) {
const auto subst = std::to_array<std::u16string>( const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name), {base::WideToUTF16(dll_name),
@@ -321,6 +346,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
base::ASCIIToUTF16(std::string(kProcName))}); base::ASCIIToUTF16(std::string(kProcName))});
ShowError(FormatErrorString(IDS_ERROR_NO_PROC_EXPORT, subst)); ShowError(FormatErrorString(IDS_ERROR_NO_PROC_EXPORT, subst));
} }
#endif
LOG(FATAL) << "Failed to find " << kProcName << " in " << dll_name LOG(FATAL) << "Failed to find " << kProcName << " in " << dll_name
<< ".dll with error " << ::GetLastError(); << ".dll with error " << ::GetLastError();
@@ -328,12 +354,14 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
FreeLibrary(hModule); FreeLibrary(hModule);
} else { } else {
#if DCHECK_IS_ON()
if (!is_sandboxed) { if (!is_sandboxed) {
const auto subst = std::to_array<std::u16string>( const auto subst = std::to_array<std::u16string>(
{base::WideToUTF16(dll_name), {base::WideToUTF16(dll_name),
base::WideToUTF16(cef_util::GetLastErrorAsString())}); base::WideToUTF16(cef_util::GetLastErrorAsString())});
ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst)); ShowError(FormatErrorString(IDS_ERROR_LOAD_FAILED, subst));
} }
#endif
LOG(FATAL) << "Failed to load " << dll_name << ".dll with error " LOG(FATAL) << "Failed to load " << dll_name << ".dll with error "
<< ::GetLastError(); << ::GetLastError();