mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-20 10:43:46 +00:00
ios: Add more tests for extra_memory_ranges and custom user streams.
Adds two end-to-end tests for iOS, testing the newly ported custom user streams and extra memory ranges. Change-Id: Ia0721e394898aac5bec7b58d3750818615cca0c5 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/6362132 Commit-Queue: Justin Cohen <justincohen@chromium.org> Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
3eba16f1ca
commit
cfe842c074
@ -538,7 +538,7 @@ class CrashpadClient {
|
||||
//! added to the minidump.
|
||||
static void ProcessIntermediateDumps(
|
||||
const std::map<std::string, std::string>& annotations = {},
|
||||
const UserStreamDataSources* user_stream_sources = {});
|
||||
const UserStreamDataSources* user_stream_sources = nullptr);
|
||||
|
||||
//! \brief Requests that the handler convert a single intermediate dump at \a
|
||||
//! file generated by DumpWithoutCrashAndDeferProcessingAtPath into a
|
||||
|
@ -110,35 +110,35 @@ TEST_F(InProcessHandlerTest, TestPendingFileLimit) {
|
||||
|
||||
// Only process other app files.
|
||||
CreateFiles(0, 20);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(0, 0);
|
||||
ClearFiles();
|
||||
|
||||
// Only process our app files.
|
||||
CreateFiles(20, 20);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(0, 20);
|
||||
ClearFiles();
|
||||
|
||||
// Process all of our files and 10 remaining.
|
||||
CreateFiles(10, 30);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(0, 20);
|
||||
ClearFiles();
|
||||
|
||||
// Process 20 our files, leaving 10 remaining, and all other files remaining.
|
||||
CreateFiles(30, 10);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(10, 10);
|
||||
ClearFiles();
|
||||
|
||||
CreateFiles(0, 0);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(0, 0);
|
||||
ClearFiles();
|
||||
|
||||
CreateFiles(10, 0);
|
||||
handler().ProcessIntermediateDumps({}, {});
|
||||
handler().ProcessIntermediateDumps({}, nullptr);
|
||||
VerifyRemainingFileCount(0, 0);
|
||||
ClearFiles();
|
||||
}
|
||||
|
@ -104,6 +104,12 @@ bool IsMacOSVersion143OrGreaterAndiOS16OrLess() {
|
||||
|
||||
- (void)setUp {
|
||||
app_ = [[XCUIApplication alloc] init];
|
||||
if ([self.name isEqualToString:@"-[CPTestTestCase testExtensionStreams]"]) {
|
||||
app_.launchArguments = @[ @"--test-extension-streams" ];
|
||||
} else if ([self.name isEqualToString:
|
||||
@"-[CPTestTestCase testCrashWithExtraMemory]"]) {
|
||||
app_.launchArguments = @[ @"--test-extra_memory" ];
|
||||
}
|
||||
[app_ launch];
|
||||
rootObject_ = [EDOClientService rootObjectWithPort:12345];
|
||||
[rootObject_ clearPendingReports];
|
||||
@ -397,12 +403,47 @@ bool IsMacOSVersion143OrGreaterAndiOS16OrLess() {
|
||||
XCTAssertFalse(reader.Pop(ringBufferEntry));
|
||||
}
|
||||
|
||||
- (void)testCrashWithExtraMemory {
|
||||
#if TARGET_OS_SIMULATOR
|
||||
// This test will fail on older (<iOS17 simulators) when running on macOS 14.3
|
||||
// or newer due to a bug in Simulator. crbug.com/328282286
|
||||
if (crashpad::IsMacOSVersion143OrGreaterAndiOS16OrLess()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
[rootObject_ crashKillAbort];
|
||||
[self verifyCrashReportException:EXC_SOFT_SIGNAL];
|
||||
|
||||
NSDictionary* dict = [rootObject_ getExtraMemory];
|
||||
BOOL found = NO;
|
||||
for (NSString* key in dict) {
|
||||
if ([dict[key] isEqualToString:@"hello world"]) {
|
||||
found = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
XCTAssertTrue(found);
|
||||
}
|
||||
|
||||
- (void)testExtensionStreams {
|
||||
#if TARGET_OS_SIMULATOR
|
||||
// This test will fail on older (<iOS17 simulators) when running on macOS 14.3
|
||||
// or newer due to a bug in Simulator. crbug.com/328282286
|
||||
if (crashpad::IsMacOSVersion143OrGreaterAndiOS16OrLess()) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
[rootObject_ crashKillAbort];
|
||||
[self verifyCrashReportException:EXC_SOFT_SIGNAL];
|
||||
XCTAssertTrue([rootObject_ hasExtensionStream]);
|
||||
}
|
||||
|
||||
- (void)testDumpWithoutCrash {
|
||||
[rootObject_ generateDumpWithoutCrash:10 threads:3];
|
||||
|
||||
// The app should not crash
|
||||
XCTAssertTrue(app_.state == XCUIApplicationStateRunningForeground);
|
||||
|
||||
XCTAssertEqual([rootObject_ pendingReportCount], 30);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ static_library("app_host_sources") {
|
||||
":app_shared_sources",
|
||||
"../../../build:apple_enable_arc",
|
||||
"../../../client",
|
||||
"../../../minidump:test_support",
|
||||
"../../../snapshot",
|
||||
"../../../test",
|
||||
"../../../third_party/edo",
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "client/ring_buffer_annotation.h"
|
||||
#include "client/simple_string_dictionary.h"
|
||||
#include "client/simulate_crash.h"
|
||||
#include "minidump/test/minidump_user_extension_stream_util.h"
|
||||
#include "snapshot/minidump/process_snapshot_minidump.h"
|
||||
#include "test/file.h"
|
||||
#import "test/ios/host/cptest_crash_view_controller.h"
|
||||
@ -55,6 +56,36 @@ using Report = crashpad::CrashReportDatabase::Report;
|
||||
|
||||
namespace {
|
||||
|
||||
class ReadToString : public crashpad::MemorySnapshot::Delegate {
|
||||
public:
|
||||
std::string result;
|
||||
|
||||
bool MemorySnapshotDelegateRead(void* data, size_t size) override {
|
||||
result = std::string(reinterpret_cast<const char*>(data), size);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static constexpr char kExpectedStreamData[] = "Injected extension stream!";
|
||||
|
||||
class TestUserStreamDataSource : public crashpad::UserStreamDataSource {
|
||||
public:
|
||||
TestUserStreamDataSource() {}
|
||||
|
||||
TestUserStreamDataSource(const TestUserStreamDataSource&) = delete;
|
||||
TestUserStreamDataSource& operator=(const TestUserStreamDataSource&) = delete;
|
||||
|
||||
std::unique_ptr<crashpad::MinidumpUserExtensionStreamDataSource>
|
||||
ProduceStreamData(crashpad::ProcessSnapshot* process_snapshot) override;
|
||||
};
|
||||
|
||||
std::unique_ptr<crashpad::MinidumpUserExtensionStreamDataSource>
|
||||
TestUserStreamDataSource::ProduceStreamData(
|
||||
crashpad::ProcessSnapshot* process_snapshot) {
|
||||
return std::make_unique<crashpad::test::BufferExtensionStreamDataSource>(
|
||||
0xCAFEBABE, kExpectedStreamData, sizeof(kExpectedStreamData));
|
||||
}
|
||||
|
||||
constexpr crashpad::Annotation::Type kRingBufferType =
|
||||
crashpad::Annotation::UserDefinedType(42);
|
||||
|
||||
@ -138,6 +169,8 @@ UIWindow* GetAnyWindow() {
|
||||
@implementation CPTestApplicationDelegate {
|
||||
crashpad::CrashpadClient client_;
|
||||
crashpad::ScopedFileHandle raw_logging_file_;
|
||||
crashpad::SimpleAddressRangeBag extra_ranges_;
|
||||
std::unique_ptr<std::string> extra_memory_string_;
|
||||
}
|
||||
|
||||
@synthesize window = _window;
|
||||
@ -173,7 +206,19 @@ UIWindow* GetAnyWindow() {
|
||||
annotations,
|
||||
crashpad::CrashpadClient::
|
||||
ProcessPendingReportsObservationCallback())) {
|
||||
client_.ProcessIntermediateDumps();
|
||||
crashpad::UserStreamDataSources user_stream_data_sources;
|
||||
if ([arguments containsObject:@"--test-extension-streams"]) {
|
||||
user_stream_data_sources.push_back(
|
||||
std::make_unique<TestUserStreamDataSource>());
|
||||
}
|
||||
client_.ProcessIntermediateDumps({}, &user_stream_data_sources);
|
||||
}
|
||||
|
||||
if ([arguments containsObject:@"--test-extra_memory"]) {
|
||||
crashpad::CrashpadInfo::GetCrashpadInfo()->set_extra_memory_ranges(
|
||||
&extra_ranges_);
|
||||
extra_memory_string_ = std::make_unique<std::string>("hello world");
|
||||
extra_ranges_.Insert((void*)extra_memory_string_->c_str(), 11);
|
||||
}
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
@ -284,6 +329,43 @@ UIWindow* GetAnyWindow() {
|
||||
return [dict passByValue];
|
||||
}
|
||||
|
||||
- (NSDictionary*)getExtraMemory {
|
||||
auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending();
|
||||
if (!process_snapshot)
|
||||
return @{};
|
||||
|
||||
NSDictionary* dict = [@{} mutableCopy];
|
||||
|
||||
for (auto memory : process_snapshot->ExtraMemory()) {
|
||||
ReadToString delegate;
|
||||
if (memory->Size() > 0 && memory->Read(&delegate) &&
|
||||
!delegate.result.empty()) {
|
||||
NSString* key = [@(memory->Address()) stringValue];
|
||||
NSString* value = @(delegate.result.c_str());
|
||||
if (value.length) {
|
||||
[dict setValue:value forKey:key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return [dict passByValue];
|
||||
}
|
||||
|
||||
- (BOOL)hasExtensionStream {
|
||||
auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending();
|
||||
if (!process_snapshot)
|
||||
return NO;
|
||||
|
||||
auto streams = process_snapshot->CustomMinidumpStreams();
|
||||
for (const auto& stream : streams) {
|
||||
if (stream->stream_type() == 0xCAFEBABE) {
|
||||
return memcmp(kExpectedStreamData,
|
||||
stream->data().data(),
|
||||
sizeof(kExpectedStreamData)) == 0;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (NSDictionary*)getProcessAnnotations {
|
||||
auto process_snapshot = GetProcessSnapshotMinidumpFromSinglePending();
|
||||
if (!process_snapshot)
|
||||
|
@ -43,11 +43,19 @@
|
||||
- (bool)pendingReportExceptionInfo:(NSNumber**)exception_info;
|
||||
|
||||
// Return an NSDictionary with a dictionary named "simplemap", an array named
|
||||
// "vector" and an array named "objects", representing the combination of all
|
||||
// modules AnnotationsSimpleMap, AnnotationsVector and AnnotationObjects
|
||||
// (strings only) respectively.
|
||||
// "vector" an array named "objects", and an array named "ringbuffers",
|
||||
// representing the combination of all modules AnnotationsSimpleMap,
|
||||
// AnnotationsVector and AnnotationObjects (String and RingBuffer type)
|
||||
// respectively.
|
||||
- (NSDictionary*)getAnnotations;
|
||||
|
||||
// Return an NSDictionary with a dictionary representing all key value pairs of
|
||||
// ExtraMemory MemorySnapshots where the data can be converted to an NSString.
|
||||
- (NSDictionary*)getExtraMemory;
|
||||
|
||||
// Returns YES if a minidump contains the expected custom stream data.
|
||||
- (BOOL)hasExtensionStream;
|
||||
|
||||
// Return an NSDictionary representing the ProcessSnapshotMinidump
|
||||
// AnnotationsSimpleMap.
|
||||
- (NSDictionary*)getProcessAnnotations;
|
||||
|
Loading…
x
Reference in New Issue
Block a user