Partially port the crashpad_client library to Linux/Android

This defines the global (per-module) CrashpadInfo structure properly on
Linux/Android, located via the “crashpad_info” section name.

Per the ELF specification, section names with a leading dot are reserved
for the system. Reading that, I realized that the same is true of Mach-O
sections with leading underscores, so this renames the section as used
on Mach-O from __DATA,__crashpad_info to __DATA,crashpad_info.

This change is sufficient to successfully build crashpad_client as a
static library on Linux/Android, but the library is incomplete. There’s
no platform-specific database implementation, no CaptureContext() or
CRASHPAD_SIMULATE_CRASH() implementation, and most notably, no
CrashpadClient implementation.

BUG=crashpad:30

Change-Id: I29df7b0f8ee1c79bf8a19502812f59d4b1577b85
Reviewed-on: https://chromium-review.googlesource.com/406427
Reviewed-by: Robert Sesek <rsesek@chromium.org>
This commit is contained in:
Mark Mentovai 2016-11-02 19:18:20 -04:00
parent 55ba6b6780
commit bb7d249d65
5 changed files with 39 additions and 24 deletions

View File

@ -59,33 +59,47 @@ union Compile_Assert {
// This may result in a static module initializer in debug-mode builds, but
// because its POD, no code should need to run to initialize this under
// release-mode optimization.
#if defined(OS_MACOSX)
#if defined(OS_POSIX)
__attribute__((
// Put the structure in a well-known section name where it can be easily
// found without having to consult the symbol table.
#if defined(OS_MACOSX)
section(SEG_DATA ",crashpad_info"),
#elif defined(OS_LINUX) || defined(OS_ANDROID)
section("crashpad_info"),
#else // !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_ANDROID)
#error Port
#endif // !defined(OS_MACOSX) && !defined(OS_LINUX) && !defined(OS_ANDROID)
// Put the structure in __DATA,__crashpad_info where it can be easily found
// without having to consult the symbol table. The “used” attribute prevents it
// from being dead-stripped.
__attribute__((section(SEG_DATA ",__crashpad_info"),
used,
visibility("hidden")
#if __has_feature(address_sanitizer)
// AddressSanitizer would add a trailing red zone of at least 32 bytes, which
// would be reflected in the size of the custom section. This confuses
// MachOImageReader::GetCrashpadInfo(), which finds that the sections size
// disagrees with the structures size_ field. By specifying an alignment
// greater than the red zone size, the red zone will be suppressed.
,
aligned(64)
#endif
)) CrashpadInfo g_crashpad_info;
// AddressSanitizer would add a trailing red zone of at least 32 bytes,
// which would be reflected in the size of the custom section. This confuses
// MachOImageReader::GetCrashpadInfo(), which finds that the sections size
// disagrees with the structures size_ field. By specifying an alignment
// greater than the red zone size, the red zone will be suppressed.
aligned(64),
#endif // __has_feature(address_sanitizer)
// The “used” attribute prevents the structure from being dead-stripped.
used,
// Theres no need to expose this as a public symbol from the symbol table.
// All accesses from the outside can locate the well-known section name.
visibility("hidden")))
#elif defined(OS_WIN)
// Put the struct in a section name CPADinfo where it can be found without the
// symbol table.
#pragma section("CPADinfo", read, write)
__declspec(allocate("CPADinfo")) CrashpadInfo g_crashpad_info;
__declspec(allocate("CPADinfo"))
#endif
#else // !defined(OS_POSIX) && !defined(OS_WIN)
#error Port
#endif // !defined(OS_POSIX) && !defined(OS_WIN)
CrashpadInfo g_crashpad_info;
// static
CrashpadInfo* CrashpadInfo::GetCrashpadInfo() {

View File

@ -477,7 +477,7 @@ bool MachOImageReader::GetCrashpadInfo(
mach_vm_address_t crashpad_info_address;
const process_types::section* crashpad_info_section =
GetSectionByName(SEG_DATA, "__crashpad_info", &crashpad_info_address);
GetSectionByName(SEG_DATA, "crashpad_info", &crashpad_info_address);
if (!crashpad_info_section) {
return false;
}

View File

@ -270,8 +270,9 @@ class MachOImageReader {
//! \brief Obtains the modules CrashpadInfo structure.
//!
//! \return `true` on success, `false` on failure. If the module does not have
//! a `__crashpad_info` section, this will return `false` without logging
//! any messages. Other failures will result in messages being logged.
//! a `__DATA,crashpad_info` section, this will return `false` without
//! logging any messages. Other failures will result in messages being
//! logged.
bool GetCrashpadInfo(process_types::CrashpadInfo* crashpad_info) const;
private:

View File

@ -21,7 +21,7 @@
// snapshot/mac/process_types.cc to produce process type struct definitions and
// accessors.
// Client Mach-O images will contain a __DATA,__crashpad_info section formatted
// Client Mach-O images will contain a __DATA,crashpad_info section formatted
// according to this structure.
PROCESS_TYPE_STRUCT_BEGIN(CrashpadInfo)
PROCESS_TYPE_STRUCT_MEMBER(uint32_t, signature)

View File

@ -165,7 +165,7 @@ class ModuleSnapshot {
//! contain multiple annotations, so they are returned in a vector.
//!
//! For Mac OS X snapshots, these annotations are found by interpreting the
//! modules `__DATA, __crash_info` section as `crashreporter_annotations_t`.
//! modules `__DATA,__crash_info` section as `crashreporter_annotations_t`.
//! System libraries using the crash reporter client interface may reference
//! annotations in this structure. Additional annotations messages may be
//! found in other locations, which may be module-specific. The dynamic linker
@ -184,7 +184,7 @@ class ModuleSnapshot {
//! keys.”
//!
//! For Mac OS X snapshots, these annotations are found by interpreting the
//! `__DATA, __crashpad_info` section as `CrashpadInfo`. Clients can use the
//! `__DATA,crashpad_info` section as `CrashpadInfo`. Clients can use the
//! Crashpad client interface to store annotations in this structure. Most
//! annotations under the clients direct control will be retrievable by this
//! method. For clients such as Chrome, this includes the process type.