mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 06:31:50 +08:00
ios: Capture signal exception context memory regions correctly.
Previously, Crashpad would only capture iOS thread context memory regions by iterating the task_threads->thread_get_state's. For Mach exception this worked as intended. However, for signal exceptions this missed the registers from the actual signal context. This change correctly captures these regions and stores them in the exception snapshot. Change-Id: I494e753a25c2687e61b5183ed0135f520ca8bf52 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/5380505 Reviewed-by: Mark Mentovai <mark@chromium.org> Commit-Queue: Justin Cohen <justincohen@chromium.org>
This commit is contained in:
parent
ccd20652bc
commit
1cea0473a5
@ -967,19 +967,19 @@ void InProcessIntermediateDumpHandler::WriteExceptionFromSignal(
|
|||||||
WriteProperty(writer, IntermediateDumpKey::kSignalNumber, &siginfo->si_signo);
|
WriteProperty(writer, IntermediateDumpKey::kSignalNumber, &siginfo->si_signo);
|
||||||
WriteProperty(writer, IntermediateDumpKey::kSignalCode, &siginfo->si_code);
|
WriteProperty(writer, IntermediateDumpKey::kSignalCode, &siginfo->si_code);
|
||||||
WriteProperty(writer, IntermediateDumpKey::kSignalAddress, &siginfo->si_addr);
|
WriteProperty(writer, IntermediateDumpKey::kSignalAddress, &siginfo->si_addr);
|
||||||
|
|
||||||
#if defined(ARCH_CPU_X86_64)
|
#if defined(ARCH_CPU_X86_64)
|
||||||
WriteProperty(
|
x86_thread_state64_t thread_state = context->uc_mcontext->__ss;
|
||||||
writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss);
|
x86_float_state64_t float_state = context->uc_mcontext->__fs;
|
||||||
WriteProperty(
|
|
||||||
writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__fs);
|
|
||||||
#elif defined(ARCH_CPU_ARM64)
|
#elif defined(ARCH_CPU_ARM64)
|
||||||
WriteProperty(
|
arm_thread_state64_t thread_state = context->uc_mcontext->__ss;
|
||||||
writer, IntermediateDumpKey::kThreadState, &context->uc_mcontext->__ss);
|
arm_neon_state64_t float_state = context->uc_mcontext->__ns;
|
||||||
WriteProperty(
|
|
||||||
writer, IntermediateDumpKey::kFloatState, &context->uc_mcontext->__ns);
|
|
||||||
#else
|
#else
|
||||||
#error Port to your CPU architecture
|
#error Port to your CPU architecture
|
||||||
#endif
|
#endif
|
||||||
|
WriteProperty(writer, IntermediateDumpKey::kThreadState, &thread_state);
|
||||||
|
WriteProperty(writer, IntermediateDumpKey::kFloatState, &float_state);
|
||||||
|
CaptureMemoryPointedToByThreadState(writer, thread_state);
|
||||||
|
|
||||||
// Thread ID.
|
// Thread ID.
|
||||||
thread_identifier_info identifier_info;
|
thread_identifier_info identifier_info;
|
||||||
|
@ -149,6 +149,33 @@ bool ExceptionSnapshotIOSIntermediateDump::InitializeFromSignal(
|
|||||||
GetDataValueFromMap(exception_data, Key::kSignalCode, &code);
|
GetDataValueFromMap(exception_data, Key::kSignalCode, &code);
|
||||||
codes_.push_back(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<uint8_t>& bytes = region_data->bytes();
|
||||||
|
vm_size_t data_size = bytes.size();
|
||||||
|
if (data_size == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const vm_address_t data =
|
||||||
|
reinterpret_cast<const vm_address_t>(bytes.data());
|
||||||
|
|
||||||
|
auto memory =
|
||||||
|
std::make_unique<internal::MemorySnapshotIOSIntermediateDump>();
|
||||||
|
memory->Initialize(address, data, data_size);
|
||||||
|
extra_memory_.push_back(std::move(memory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
INITIALIZATION_STATE_SET_VALID(initialized_);
|
INITIALIZATION_STATE_SET_VALID(initialized_);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -281,8 +308,11 @@ const std::vector<uint64_t>& ExceptionSnapshotIOSIntermediateDump::Codes()
|
|||||||
|
|
||||||
std::vector<const MemorySnapshot*>
|
std::vector<const MemorySnapshot*>
|
||||||
ExceptionSnapshotIOSIntermediateDump::ExtraMemory() const {
|
ExceptionSnapshotIOSIntermediateDump::ExtraMemory() const {
|
||||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
std::vector<const MemorySnapshot*> extra_memory;
|
||||||
return std::vector<const MemorySnapshot*>();
|
for (const auto& memory : extra_memory_) {
|
||||||
|
extra_memory.push_back(memory.get());
|
||||||
|
}
|
||||||
|
return extra_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExceptionSnapshotIOSIntermediateDump::LoadContextFromThread(
|
void ExceptionSnapshotIOSIntermediateDump::LoadContextFromThread(
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "snapshot/cpu_context.h"
|
#include "snapshot/cpu_context.h"
|
||||||
#include "snapshot/exception_snapshot.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/ios/ios_intermediate_dump_map.h"
|
||||||
#include "util/mach/mach_extensions.h"
|
#include "util/mach/mach_extensions.h"
|
||||||
#include "util/misc/initialization_state_dcheck.h"
|
#include "util/misc/initialization_state_dcheck.h"
|
||||||
@ -106,6 +107,8 @@ class ExceptionSnapshotIOSIntermediateDump final : public ExceptionSnapshot {
|
|||||||
uintptr_t exception_address_;
|
uintptr_t exception_address_;
|
||||||
uint32_t exception_;
|
uint32_t exception_;
|
||||||
uint32_t exception_info_;
|
uint32_t exception_info_;
|
||||||
|
std::vector<std::unique_ptr<internal::MemorySnapshotIOSIntermediateDump>>
|
||||||
|
extra_memory_;
|
||||||
InitializationStateDcheck initialized_;
|
InitializationStateDcheck initialized_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -577,6 +577,18 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) {
|
|||||||
IOSIntermediateDumpWriter::ScopedMap map(writer(), Key::kSignalException);
|
IOSIntermediateDumpWriter::ScopedMap map(writer(), Key::kSignalException);
|
||||||
uint64_t thread_id = 1;
|
uint64_t thread_id = 1;
|
||||||
EXPECT_TRUE(writer()->AddProperty(Key::kThreadID, &thread_id));
|
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(),
|
IOSIntermediateDumpWriter::ScopedArray threadArray(writer(),
|
||||||
@ -589,6 +601,12 @@ TEST_F(ProcessSnapshotIOSIntermediateDumpTest, EmptySignalDump) {
|
|||||||
CloseWriter();
|
CloseWriter();
|
||||||
ProcessSnapshotIOSIntermediateDump process_snapshot;
|
ProcessSnapshotIOSIntermediateDump process_snapshot;
|
||||||
ASSERT_TRUE(process_snapshot.InitializeWithFilePath(path(), annotations()));
|
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_FALSE(IsRegularFile(path()));
|
||||||
EXPECT_TRUE(DumpSnapshot(process_snapshot));
|
EXPECT_TRUE(DumpSnapshot(process_snapshot));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user