Fuchsia: Propagate failure to initialize exception snapshot

If the process' threads can't be read, then the cpu context object won't
be able to be initialized.

Previously, the process snapshot always assumed that the context would
be filled out, as there was no error returned, which could result in
later checks failing.

Return an error from the exception snapshot's initialization so that
process snapshot can correctly handle failure to initialize.

Bug: fuchsia:55837
Change-Id: Ia3fecef1230a19dfa23401b0339c6a94370c6baf
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2296039
Commit-Queue: Scott Graham <scottmg@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Scott Graham 2020-07-13 12:10:02 -07:00 committed by Commit Bot
parent fd001f792e
commit ef8a063055
3 changed files with 30 additions and 17 deletions

View File

@ -24,7 +24,7 @@ namespace internal {
ExceptionSnapshotFuchsia::ExceptionSnapshotFuchsia() = default; ExceptionSnapshotFuchsia::ExceptionSnapshotFuchsia() = default;
ExceptionSnapshotFuchsia::~ExceptionSnapshotFuchsia() = default; ExceptionSnapshotFuchsia::~ExceptionSnapshotFuchsia() = default;
void ExceptionSnapshotFuchsia::Initialize( bool ExceptionSnapshotFuchsia::Initialize(
ProcessReaderFuchsia* process_reader, ProcessReaderFuchsia* process_reader,
zx_koid_t thread_id, zx_koid_t thread_id,
const zx_exception_report_t& exception_report) { const zx_exception_report_t& exception_report) {
@ -61,22 +61,26 @@ void ExceptionSnapshotFuchsia::Initialize(
[thread_id](const ProcessReaderFuchsia::Thread& thread) { [thread_id](const ProcessReaderFuchsia::Thread& thread) {
return thread.id == thread_id; return thread.id == thread_id;
}); });
if (t != threads.end()) { if (t == threads.end()) {
// If no threads have been read, then context_ can't be initalized, and the
// exception snapshot can't be considered initialized_.
return false;
}
#if defined(ARCH_CPU_X86_64) #if defined(ARCH_CPU_X86_64)
context_.architecture = kCPUArchitectureX86_64; context_.architecture = kCPUArchitectureX86_64;
context_.x86_64 = &context_arch_; context_.x86_64 = &context_arch_;
// TODO(fxbug.dev/5496): Add float context once saved in |t|. // TODO(fxbug.dev/5496): Add float context once saved in |t|.
InitializeCPUContextX86_64_NoFloatingPoint(t->general_registers, InitializeCPUContextX86_64_NoFloatingPoint(t->general_registers,
context_.x86_64); context_.x86_64);
#elif defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_ARM64)
context_.architecture = kCPUArchitectureARM64; context_.architecture = kCPUArchitectureARM64;
context_.arm64 = &context_arch_; context_.arm64 = &context_arch_;
InitializeCPUContextARM64( InitializeCPUContextARM64(
t->general_registers, t->vector_registers, context_.arm64); t->general_registers, t->vector_registers, context_.arm64);
#else #else
#error Port. #error Port.
#endif #endif
}
if (context_.InstructionPointer() != 0 && if (context_.InstructionPointer() != 0 &&
(exception_ == ZX_EXCP_UNDEFINED_INSTRUCTION || (exception_ == ZX_EXCP_UNDEFINED_INSTRUCTION ||
@ -94,6 +98,7 @@ void ExceptionSnapshotFuchsia::Initialize(
} }
INITIALIZATION_STATE_SET_VALID(initialized_); INITIALIZATION_STATE_SET_VALID(initialized_);
return true;
} }
const CPUContext* ExceptionSnapshotFuchsia::Context() const { const CPUContext* ExceptionSnapshotFuchsia::Context() const {

View File

@ -44,7 +44,10 @@ class ExceptionSnapshotFuchsia final : public ExceptionSnapshot {
//! \param[in] thread_id The koid of the thread that sustained the exception. //! \param[in] thread_id The koid of the thread that sustained the exception.
//! \param[in] exception_report The `zx_exception_report_t` retrieved from the //! \param[in] exception_report The `zx_exception_report_t` retrieved from the
//! thread in the exception state, corresponding to \a thread_id. //! thread in the exception state, corresponding to \a thread_id.
void Initialize(ProcessReaderFuchsia* process_reader, //!
//! \return `true` if the exception data was initialized, `false` otherwise
//! with an error logged.
bool Initialize(ProcessReaderFuchsia* process_reader,
zx_koid_t thread_id, zx_koid_t thread_id,
const zx_exception_report_t& exception_report); const zx_exception_report_t& exception_report);
@ -63,7 +66,7 @@ class ExceptionSnapshotFuchsia final : public ExceptionSnapshot {
#elif defined(ARCH_CPU_ARM64) #elif defined(ARCH_CPU_ARM64)
CPUContextARM64 context_arch_; CPUContextARM64 context_arch_;
#endif #endif
CPUContext context_ = {}; CPUContext context_;
std::vector<uint64_t> codes_; std::vector<uint64_t> codes_;
zx_koid_t thread_id_; zx_koid_t thread_id_;
zx_vaddr_t exception_address_; zx_vaddr_t exception_address_;

View File

@ -59,9 +59,14 @@ bool ProcessSnapshotFuchsia::InitializeException(
zx_koid_t thread_id, zx_koid_t thread_id,
const zx_exception_report_t& report) { const zx_exception_report_t& report) {
INITIALIZATION_STATE_DCHECK_VALID(initialized_); INITIALIZATION_STATE_DCHECK_VALID(initialized_);
exception_.reset(new internal::ExceptionSnapshotFuchsia());
exception_->Initialize(&process_reader_, thread_id, report); std::unique_ptr<internal::ExceptionSnapshotFuchsia> exception(
return true; new internal::ExceptionSnapshotFuchsia());
if (exception->Initialize(&process_reader_, thread_id, report)) {
exception_.swap(exception);
return true;
}
return false;
} }
void ProcessSnapshotFuchsia::GetCrashpadOptions( void ProcessSnapshotFuchsia::GetCrashpadOptions(