Commit 05219dde authored by Robert Sesek's avatar Robert Sesek Committed by Commit Bot

mac: Capture error messages from the main executable in crash reports.

Bug: 1042912
Change-Id: I64b0e5c0e9f6c36e9fdb7dd7d766e6a78a5f5734
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2015364
Commit-Queue: Greg Kerr <kerrnel@chromium.org>
Reviewed-by: default avatarGreg Kerr <kerrnel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#734556}
parent b3ae3d20
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <errno.h> #include <errno.h>
#include <libgen.h> #include <libgen.h>
#include <mach-o/dyld.h> #include <mach-o/dyld.h>
#include <os/availability.h>
#include <stdarg.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
...@@ -24,25 +26,44 @@ ...@@ -24,25 +26,44 @@
#include "sandbox/mac/seatbelt_exec.h" #include "sandbox/mac/seatbelt_exec.h"
#endif // defined(HELPER_EXECUTABLE) #endif // defined(HELPER_EXECUTABLE)
extern "C" {
// abort_report_np() records the message in a special section that both the
// system CrashReporter and Crashpad collect in crash reports. Using a Crashpad
// Annotation would be preferable, but this executable cannot depend on
// Crashpad directly.
void abort_report_np(const char* fmt, ...) API_AVAILABLE(macos(10.11));
}
namespace { namespace {
typedef int (*ChromeMainPtr)(int, char**); typedef int (*ChromeMainPtr)(int, char**);
[[noreturn]] void FatalError(const char* format, ...) {
va_list valist;
va_start(valist, format);
char message[4096];
if (vsnprintf(message, sizeof(message), format, valist) >= 0) {
if (__builtin_available(macOS 10.11, *)) {
abort_report_np("%s", message);
}
}
va_end(valist);
abort();
}
} // namespace } // namespace
__attribute__((visibility("default"))) int main(int argc, char* argv[]) { __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
uint32_t exec_path_size = 0; uint32_t exec_path_size = 0;
int rv = _NSGetExecutablePath(NULL, &exec_path_size); int rv = _NSGetExecutablePath(NULL, &exec_path_size);
if (rv != -1) { if (rv != -1) {
fprintf(stderr, "_NSGetExecutablePath: get length failed\n"); FatalError("_NSGetExecutablePath: get length failed.");
abort();
} }
std::unique_ptr<char[]> exec_path(new char[exec_path_size]); std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size); rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, "_NSGetExecutablePath: get path failed\n"); FatalError("_NSGetExecutablePath: get path failed.");
abort();
} }
#if defined(HELPER_EXECUTABLE) #if defined(HELPER_EXECUTABLE)
...@@ -51,12 +72,10 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) { ...@@ -51,12 +72,10 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
argv); argv);
if (seatbelt.sandbox_required) { if (seatbelt.sandbox_required) {
if (!seatbelt.server) { if (!seatbelt.server) {
fprintf(stderr, "Failed to create seatbelt sandbox server.\n"); FatalError("Failed to create seatbelt sandbox server.");
abort();
} }
if (!seatbelt.server->InitializeSandbox()) { if (!seatbelt.server->InitializeSandbox()) {
fprintf(stderr, "Failed to initialize sandbox.\n"); FatalError("Failed to initialize sandbox.");
abort();
} }
} }
...@@ -73,8 +92,7 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) { ...@@ -73,8 +92,7 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
// version framework information. // version framework information.
const char* parent_dir = dirname(exec_path.get()); const char* parent_dir = dirname(exec_path.get());
if (!parent_dir) { if (!parent_dir) {
fprintf(stderr, "dirname %s: %s\n", exec_path.get(), strerror(errno)); FatalError("dirname %s: %s.", exec_path.get(), strerror(errno));
abort();
} }
const size_t parent_dir_len = strlen(parent_dir); const size_t parent_dir_len = strlen(parent_dir);
...@@ -88,15 +106,13 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) { ...@@ -88,15 +106,13 @@ __attribute__((visibility("default"))) int main(int argc, char* argv[]) {
void* library = void* library =
dlopen(framework_path.get(), RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST); dlopen(framework_path.get(), RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
if (!library) { if (!library) {
fprintf(stderr, "dlopen %s: %s\n", framework_path.get(), dlerror()); FatalError("dlopen %s: %s.", framework_path.get(), dlerror());
abort();
} }
const ChromeMainPtr chrome_main = const ChromeMainPtr chrome_main =
reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain")); reinterpret_cast<ChromeMainPtr>(dlsym(library, "ChromeMain"));
if (!chrome_main) { if (!chrome_main) {
fprintf(stderr, "dlsym ChromeMain: %s\n", dlerror()); FatalError("dlsym ChromeMain: %s.", dlerror());
abort();
} }
rv = chrome_main(argc, argv); rv = chrome_main(argc, argv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment