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: I79a59ad505fadd123982473789bfa418dabf5241
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>
GitOrigin-RevId: ef8a063055c612466268030778bbd009bcfafcc6
diff --git a/snapshot/fuchsia/exception_snapshot_fuchsia.cc b/snapshot/fuchsia/exception_snapshot_fuchsia.cc
index f0f3ffd..2607769 100644
--- a/snapshot/fuchsia/exception_snapshot_fuchsia.cc
+++ b/snapshot/fuchsia/exception_snapshot_fuchsia.cc
@@ -24,7 +24,7 @@
 ExceptionSnapshotFuchsia::ExceptionSnapshotFuchsia() = default;
 ExceptionSnapshotFuchsia::~ExceptionSnapshotFuchsia() = default;
 
-void ExceptionSnapshotFuchsia::Initialize(
+bool ExceptionSnapshotFuchsia::Initialize(
     ProcessReaderFuchsia* process_reader,
     zx_koid_t thread_id,
     const zx_exception_report_t& exception_report) {
@@ -61,22 +61,26 @@
                    [thread_id](const ProcessReaderFuchsia::Thread& thread) {
                      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)
-    context_.architecture = kCPUArchitectureX86_64;
-    context_.x86_64 = &context_arch_;
-    // TODO(fxbug.dev/5496): Add float context once saved in |t|.
-    InitializeCPUContextX86_64_NoFloatingPoint(t->general_registers,
-                                               context_.x86_64);
+  context_.architecture = kCPUArchitectureX86_64;
+  context_.x86_64 = &context_arch_;
+  // TODO(fxbug.dev/5496): Add float context once saved in |t|.
+  InitializeCPUContextX86_64_NoFloatingPoint(t->general_registers,
+                                             context_.x86_64);
 #elif defined(ARCH_CPU_ARM64)
-    context_.architecture = kCPUArchitectureARM64;
-    context_.arm64 = &context_arch_;
-    InitializeCPUContextARM64(
-        t->general_registers, t->vector_registers, context_.arm64);
+  context_.architecture = kCPUArchitectureARM64;
+  context_.arm64 = &context_arch_;
+  InitializeCPUContextARM64(
+      t->general_registers, t->vector_registers, context_.arm64);
 #else
 #error Port.
 #endif
-  }
 
   if (context_.InstructionPointer() != 0 &&
       (exception_ == ZX_EXCP_UNDEFINED_INSTRUCTION ||
@@ -94,6 +98,7 @@
   }
 
   INITIALIZATION_STATE_SET_VALID(initialized_);
+  return true;
 }
 
 const CPUContext* ExceptionSnapshotFuchsia::Context() const {
diff --git a/snapshot/fuchsia/exception_snapshot_fuchsia.h b/snapshot/fuchsia/exception_snapshot_fuchsia.h
index 0a571e6..3126944 100644
--- a/snapshot/fuchsia/exception_snapshot_fuchsia.h
+++ b/snapshot/fuchsia/exception_snapshot_fuchsia.h
@@ -44,7 +44,10 @@
   //! \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
   //!     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,
                   const zx_exception_report_t& exception_report);
 
@@ -63,7 +66,7 @@
 #elif defined(ARCH_CPU_ARM64)
   CPUContextARM64 context_arch_;
 #endif
-  CPUContext context_ = {};
+  CPUContext context_;
   std::vector<uint64_t> codes_;
   zx_koid_t thread_id_;
   zx_vaddr_t exception_address_;
diff --git a/snapshot/fuchsia/process_snapshot_fuchsia.cc b/snapshot/fuchsia/process_snapshot_fuchsia.cc
index 294c9f9..d36335c 100644
--- a/snapshot/fuchsia/process_snapshot_fuchsia.cc
+++ b/snapshot/fuchsia/process_snapshot_fuchsia.cc
@@ -59,9 +59,14 @@
     zx_koid_t thread_id,
     const zx_exception_report_t& report) {
   INITIALIZATION_STATE_DCHECK_VALID(initialized_);
-  exception_.reset(new internal::ExceptionSnapshotFuchsia());
-  exception_->Initialize(&process_reader_, thread_id, report);
-  return true;
+
+  std::unique_ptr<internal::ExceptionSnapshotFuchsia> exception(
+      new internal::ExceptionSnapshotFuchsia());
+  if (exception->Initialize(&process_reader_, thread_id, report)) {
+    exception_.swap(exception);
+    return true;
+  }
+  return false;
 }
 
 void ProcessSnapshotFuchsia::GetCrashpadOptions(