diff --git a/client/ios_handler/in_process_intermediate_dump_handler.cc b/client/ios_handler/in_process_intermediate_dump_handler.cc index 6cc6360d..29e26cb8 100644 --- a/client/ios_handler/in_process_intermediate_dump_handler.cc +++ b/client/ios_handler/in_process_intermediate_dump_handler.cc @@ -967,19 +967,19 @@ void InProcessIntermediateDumpHandler::WriteExceptionFromSignal( WriteProperty(writer, IntermediateDumpKey::kSignalNumber, &siginfo->si_signo); WriteProperty(writer, IntermediateDumpKey::kSignalCode, &siginfo->si_code); WriteProperty(writer, IntermediateDumpKey::kSignalAddress, &siginfo->si_addr); + #if defined(ARCH_CPU_X86_64) - WriteProperty( - writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss); - WriteProperty( - writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__fs); + x86_thread_state64_t thread_state = context->uc_mcontext->__ss; + x86_float_state64_t float_state = context->uc_mcontext->__fs; #elif defined(ARCH_CPU_ARM64) - WriteProperty( - writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss); - WriteProperty( - writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__ns); + arm_thread_state64_t thread_state = context->uc_mcontext->__ss; + arm_neon_state64_t float_state = context->uc_mcontext->__ns; #else #error Port to your CPU architecture #endif + WriteProperty(writer, IntermediateDumpKey::kThreadState, &thread_state); + WriteProperty(writer, IntermediateDumpKey::kFloatState, &float_state); + CaptureMemoryPointedToByThreadState(writer, thread_state); // Thread ID. thread_identifier_info identifier_info; diff --git a/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc b/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc index e3478454..9f1852a6 100644 --- a/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc +++ b/snapshot/ios/exception_snapshot_ios_intermediate_dump.cc @@ -149,6 +149,33 @@ bool ExceptionSnapshotIOSIntermediateDump::InitializeFromSignal( GetDataValueFromMap(exception_data, Key::kSignalCode, &code); codes_.push_back(code); + const IOSIntermediateDumpList* thread_context_memory_regions = + GetListFromMap(exception_data, Key::kThreadContextMemoryRegions); + if (thread_context_memory_regions) { + for (auto& region : *thread_context_memory_regions) { + vm_address_t address; + const IOSIntermediateDumpData* region_data = + region->GetAsData(Key::kThreadContextMemoryRegionData); + if (!region_data) + continue; + if (GetDataValueFromMap( + region.get(), Key::kThreadContextMemoryRegionAddress, &address)) { + const std::vector& bytes = region_data->bytes(); + vm_size_t data_size = bytes.size(); + if (data_size == 0) + continue; + + const vm_address_t data = + reinterpret_cast(bytes.data()); + + auto memory = + std::make_unique(); + memory->Initialize(address, data, data_size); + extra_memory_.push_back(std::move(memory)); + } + } + } + INITIALIZATION_STATE_SET_VALID(initialized_); return true; } @@ -281,8 +308,11 @@ const std::vector& ExceptionSnapshotIOSIntermediateDump::Codes() std::vector ExceptionSnapshotIOSIntermediateDump::ExtraMemory() const { - INITIALIZATION_STATE_DCHECK_VALID(initialized_); - return std::vector(); + std::vector extra_memory; + for (const auto& memory : extra_memory_) { + extra_memory.push_back(memory.get()); + } + return extra_memory; } void ExceptionSnapshotIOSIntermediateDump::LoadContextFromThread( diff --git a/snapshot/ios/exception_snapshot_ios_intermediate_dump.h b/snapshot/ios/exception_snapshot_ios_intermediate_dump.h index 90966df1..dc9d5954 100644 --- a/snapshot/ios/exception_snapshot_ios_intermediate_dump.h +++ b/snapshot/ios/exception_snapshot_ios_intermediate_dump.h @@ -23,6 +23,7 @@ #include "build/build_config.h" #include "snapshot/cpu_context.h" #include "snapshot/exception_snapshot.h" +#include "snapshot/ios/memory_snapshot_ios_intermediate_dump.h" #include "util/ios/ios_intermediate_dump_map.h" #include "util/mach/mach_extensions.h" #include "util/misc/initialization_state_dcheck.h" @@ -106,6 +107,8 @@ class ExceptionSnapshotIOSIntermediateDump final : public ExceptionSnapshot { uintptr_t exception_address_; uint32_t exception_; uint32_t exception_info_; + std::vector> + extra_memory_; InitializationStateDcheck initialized_; }; diff --git a/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc b/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc index 29d26a83..69cb43ed 100644 --- a/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc +++ b/snapshot/ios/process_snapshot_ios_intermediate_dump_test.cc @@ -577,6 +577,18 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) { IOSIntermediateDumpWriter::ScopedMap map(writer(), Key::kSignalException); uint64_t thread_id = 1; EXPECT_TRUE(writer()->AddProperty(Key::kThreadID, &thread_id)); + { + IOSIntermediateDumpWriter::ScopedArray contextMemoryRegions( + writer(), Key::kThreadContextMemoryRegions); + IOSIntermediateDumpWriter::ScopedArrayMap memoryMap(writer()); + + std::string random_data("random_data"); + EXPECT_TRUE(writer()->AddProperty( + Key::kThreadContextMemoryRegionAddress, &thread_id)); + EXPECT_TRUE(writer()->AddProperty(Key::kThreadContextMemoryRegionData, + random_data.c_str(), + random_data.length())); + } } { IOSIntermediateDumpWriter::ScopedArray threadArray(writer(), @@ -589,6 +601,12 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) { CloseWriter(); ProcessSnapshotIOSIntermediateDump process_snapshot; ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations())); + EXPECT_EQ(process_snapshot.Exception()->ExtraMemory().size(), 1u); + ReadToString delegate; + for (auto memory : process_snapshot.Exception()->ExtraMemory()) { + memory->Read(&delegate); + EXPECT_STREQ(delegate.result.c_str(), "random_data"); + } EXPECT_FALSE(IsRegularFile(path())); EXPECT_TRUE(DumpSnapshot(process_snapshot)); }