[ios] Add variations to synthetic crash reports
Synthetic crash reports created for UTEs (unexpected termination events) to provide some information about the crash. Synthetic crash reports can contain Breadcrumbs, session uptime, OS version, Device Type and other similar information to understand why app has crashed. Variations will help with slicing crashes by Finch study and look for culprits among launched features. Bug: 1103752 Change-Id: I440d5acaf7fab5b5d81d6137e2ae4603c78e5330 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462822 Commit-Queue: Eugene But <eugenebut@chromium.org> Reviewed-by: Lei Zhang <thestig@chromium.org> Reviewed-by: Olivier Robin <olivierrobin@chromium.org> Cr-Commit-Position: refs/heads/master@{#817218}
This commit is contained in:
components
crash
core
previous_session_info
ios/chrome/browser/crash_report
@ -99,6 +99,7 @@ target(crash_key_target_type, "crash_key_lib") {
|
||||
|
||||
if (is_ios) {
|
||||
sources += [ "crash_key_breakpad_ios.mm" ]
|
||||
deps += [ "//components/previous_session_info" ]
|
||||
|
||||
configs += [ "//build/config/compiler:enable_arc" ]
|
||||
} else {
|
||||
|
@ -1,6 +1,7 @@
|
||||
include_rules = [
|
||||
"+components/gwp_asan/buildflags/buildflags.h",
|
||||
"+components/gwp_asan/client/sampling_malloc_shims.h",
|
||||
"+components/previous_session_info/previous_session_info.h",
|
||||
"+third_party/breakpad/breakpad/src/client/ios/Breakpad.h",
|
||||
"+third_party/breakpad/breakpad/src/client/ios/BreakpadController.h",
|
||||
]
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "base/strings/sys_string_conversions.h"
|
||||
#include "components/crash/core/common/crash_key_base_support.h"
|
||||
#import "components/previous_session_info/previous_session_info.h"
|
||||
#import "third_party/breakpad/breakpad/src/client/ios/Breakpad.h"
|
||||
#import "third_party/breakpad/breakpad/src/client/ios/BreakpadController.h"
|
||||
|
||||
@ -55,6 +56,9 @@ void CrashKeyStringImpl::Set(base::StringPiece value) {
|
||||
WithBreakpadRefAsync(^(BreakpadRef ref) {
|
||||
BreakpadAddUploadParameter(ref, key, value_ns);
|
||||
});
|
||||
|
||||
[[PreviousSessionInfo sharedInstance] setReportParameterValue:value_ns
|
||||
forKey:key];
|
||||
}
|
||||
|
||||
void CrashKeyStringImpl::Clear() {
|
||||
@ -63,6 +67,7 @@ void CrashKeyStringImpl::Clear() {
|
||||
WithBreakpadRefAsync(^(BreakpadRef ref) {
|
||||
BreakpadRemoveUploadParameter(ref, key);
|
||||
});
|
||||
[[PreviousSessionInfo sharedInstance] removeReportParameterForKey:key];
|
||||
}
|
||||
|
||||
bool CrashKeyStringImpl::is_set() const {
|
||||
|
@ -24,8 +24,8 @@ extern NSString* const kPreviousSessionInfoRestoringSession;
|
||||
// Key in the UserDefaults for an array which contains the ids for the connected
|
||||
// scene sessions on the previous run.
|
||||
extern NSString* const kPreviousSessionInfoConnectedSceneSessionIDs;
|
||||
// Key in the UserDefaults for a dictionary with navigation URLs.
|
||||
extern NSString* const kPreviousSessionInfoURLs;
|
||||
// Key in the UserDefaults for a dictionary with session info params.
|
||||
extern NSString* const kPreviousSessionInfoParams;
|
||||
|
||||
// The values of this enum are persisted (both to NSUserDefaults and logs) and
|
||||
// represent the state of the last session (which may have been running a
|
||||
@ -128,9 +128,9 @@ enum class DeviceBatteryState {
|
||||
@property(nonatomic, readonly)
|
||||
NSMutableSet<NSString*>* connectedSceneSessionsIDs;
|
||||
|
||||
// Pending and committed navigation URLs.
|
||||
// Crash report parameters as key-value pairs.
|
||||
@property(nonatomic, readonly)
|
||||
NSDictionary<NSString*, NSString*>* reportParameterURLs;
|
||||
NSDictionary<NSString*, NSString*>* reportParameters;
|
||||
|
||||
// Singleton PreviousSessionInfo. During the lifetime of the app, the returned
|
||||
// object is the same, and describes the previous session, even after a new
|
||||
@ -185,7 +185,8 @@ enum class DeviceBatteryState {
|
||||
// gets destructed.
|
||||
- (void)resetSessionRestorationFlag;
|
||||
|
||||
// Records information about pending and committed navigation URLs.
|
||||
// Records information crash report parameters.
|
||||
- (void)setReportParameterValue:(NSString*)value forKey:(NSString*)key;
|
||||
- (void)setReportParameterURL:(const GURL&)URL forKey:(NSString*)key;
|
||||
- (void)removeReportParameterForKey:(NSString*)key;
|
||||
|
||||
|
@ -105,7 +105,7 @@ NSString* const kPreviousSessionInfoRestoringSession =
|
||||
@"PreviousSessionInfoRestoringSession";
|
||||
NSString* const kPreviousSessionInfoConnectedSceneSessionIDs =
|
||||
@"PreviousSessionInfoConnectedSceneSessionIDs";
|
||||
NSString* const kPreviousSessionInfoURLs = @"PreviousSessionInfoURLs";
|
||||
NSString* const kPreviousSessionInfoParams = @"PreviousSessionInfoParams";
|
||||
} // namespace previous_session_info_constants
|
||||
|
||||
@interface PreviousSessionInfo ()
|
||||
@ -136,8 +136,7 @@ NSString* const kPreviousSessionInfoURLs = @"PreviousSessionInfoURLs";
|
||||
@property(nonatomic, strong) NSDate* sessionEndTime;
|
||||
@property(nonatomic, assign) BOOL terminatedDuringSessionRestoration;
|
||||
@property(nonatomic, strong) NSMutableSet<NSString*>* connectedSceneSessionsIDs;
|
||||
@property(nonatomic, copy)
|
||||
NSDictionary<NSString*, NSString*>* reportParameterURLs;
|
||||
@property(nonatomic, copy) NSDictionary<NSString*, NSString*>* reportParameters;
|
||||
|
||||
@end
|
||||
|
||||
@ -225,9 +224,9 @@ static PreviousSessionInfo* gSharedInstance = nil;
|
||||
[defaults boolForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoRestoringSession];
|
||||
|
||||
gSharedInstance.reportParameterURLs =
|
||||
gSharedInstance.reportParameters =
|
||||
[defaults dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
}
|
||||
return gSharedInstance;
|
||||
}
|
||||
@ -529,25 +528,31 @@ static PreviousSessionInfo* gSharedInstance = nil;
|
||||
[NSUserDefaults.standardUserDefaults synchronize];
|
||||
}
|
||||
|
||||
- (void)setReportParameterURL:(const GURL&)URL forKey:(NSString*)key {
|
||||
NSMutableDictionary* URLs = [[NSUserDefaults.standardUserDefaults
|
||||
- (void)setReportParameterValue:(NSString*)value forKey:(NSString*)key {
|
||||
NSMutableDictionary* params = [[NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs] mutableCopy];
|
||||
if (!URLs) {
|
||||
URLs = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
kPreviousSessionInfoParams] mutableCopy];
|
||||
if (!params) {
|
||||
params = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
}
|
||||
// Store only URL origin (not whole URL spec) as requested by Privacy Team.
|
||||
URLs[key] = base::SysUTF8ToNSString(URL.GetOrigin().spec().c_str());
|
||||
params[key] = value;
|
||||
[NSUserDefaults.standardUserDefaults
|
||||
setObject:URLs
|
||||
forKey:previous_session_info_constants::kPreviousSessionInfoURLs];
|
||||
setObject:params
|
||||
forKey:previous_session_info_constants::kPreviousSessionInfoParams];
|
||||
[NSUserDefaults.standardUserDefaults synchronize];
|
||||
}
|
||||
|
||||
- (void)setReportParameterURL:(const GURL&)URL forKey:(NSString*)key {
|
||||
// Store only URL origin (not whole URL spec) as requested by Privacy Team.
|
||||
[self setReportParameterValue:base::SysUTF8ToNSString(
|
||||
URL.GetOrigin().spec().c_str())
|
||||
forKey:key];
|
||||
}
|
||||
|
||||
- (void)removeReportParameterForKey:(NSString*)key {
|
||||
NSMutableDictionary* URLs = [[NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs] mutableCopy];
|
||||
kPreviousSessionInfoParams] mutableCopy];
|
||||
if (URLs) {
|
||||
URLs[key] = nil;
|
||||
if (URLs.count == 0) {
|
||||
@ -555,7 +560,7 @@ static PreviousSessionInfo* gSharedInstance = nil;
|
||||
}
|
||||
[NSUserDefaults.standardUserDefaults
|
||||
setObject:URLs
|
||||
forKey:previous_session_info_constants::kPreviousSessionInfoURLs];
|
||||
forKey:previous_session_info_constants::kPreviousSessionInfoParams];
|
||||
[NSUserDefaults.standardUserDefaults synchronize];
|
||||
}
|
||||
}
|
||||
|
@ -22,8 +22,7 @@
|
||||
@property(nonatomic, strong) NSDate* sessionEndTime;
|
||||
@property(nonatomic, assign) BOOL terminatedDuringSessionRestoration;
|
||||
@property(nonatomic, strong) NSMutableSet<NSString*>* connectedSceneSessionsIDs;
|
||||
@property(nonatomic, copy)
|
||||
NSDictionary<NSString*, NSString*>* reportParameterURLs;
|
||||
@property(nonatomic, copy) NSDictionary<NSString*, NSString*>* reportParameters;
|
||||
|
||||
+ (void)resetSharedInstanceForTesting;
|
||||
|
||||
|
@ -472,21 +472,21 @@ TEST_F(PreviousSessionInfoTest,
|
||||
terminatedDuringSessionRestoration]);
|
||||
}
|
||||
|
||||
// Tests added and removing navigation URLs.
|
||||
TEST_F(PreviousSessionInfoTest, ReportParameterURLs) {
|
||||
// Tests adding and removing report parameters.
|
||||
TEST_F(PreviousSessionInfoTest, ReportParameters) {
|
||||
// Default state.
|
||||
[NSUserDefaults.standardUserDefaults
|
||||
removeObjectForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_FALSE([PreviousSessionInfo sharedInstance].reportParameterURLs);
|
||||
EXPECT_FALSE([PreviousSessionInfo sharedInstance].reportParameters);
|
||||
|
||||
// Removing non-existing key does not crash.
|
||||
NSString* const kKey0 = @"url0";
|
||||
[[PreviousSessionInfo sharedInstance] removeReportParameterForKey:kKey0];
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_FALSE([PreviousSessionInfo sharedInstance].reportParameterURLs);
|
||||
EXPECT_FALSE([PreviousSessionInfo sharedInstance].reportParameters);
|
||||
|
||||
// Add first URL.
|
||||
[[PreviousSessionInfo sharedInstance]
|
||||
@ -495,10 +495,10 @@ TEST_F(PreviousSessionInfoTest, ReportParameterURLs) {
|
||||
NSDictionary<NSString*, NSString*>* URLs =
|
||||
[NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
EXPECT_NSEQ(@{kKey0 : @"https://example.test/"}, URLs); // stores only origin
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
|
||||
// Update first URL.
|
||||
[[PreviousSessionInfo sharedInstance]
|
||||
@ -506,10 +506,10 @@ TEST_F(PreviousSessionInfoTest, ReportParameterURLs) {
|
||||
forKey:kKey0];
|
||||
URLs = [NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
EXPECT_NSEQ(@{kKey0 : @"https://example2.test/"}, URLs);
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
|
||||
// Add second URL.
|
||||
NSString* const kKey1 = @"url1";
|
||||
@ -518,37 +518,37 @@ TEST_F(PreviousSessionInfoTest, ReportParameterURLs) {
|
||||
forKey:kKey1];
|
||||
URLs = [NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
NSDictionary<NSString*, NSString*>* expected = @{
|
||||
kKey0 : @"https://example2.test/",
|
||||
kKey1 : @"https://example3.test/",
|
||||
};
|
||||
EXPECT_NSEQ(expected, URLs);
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
|
||||
// Removing non-existing key does not crash.
|
||||
[[PreviousSessionInfo sharedInstance] removeReportParameterForKey:@"url2"];
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
|
||||
// Remove first URL.
|
||||
[[PreviousSessionInfo sharedInstance] removeReportParameterForKey:kKey0];
|
||||
URLs = [NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
EXPECT_NSEQ(@{kKey1 : @"https://example3.test/"}, URLs);
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_NSEQ(URLs, [[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
|
||||
// Remove second URL.
|
||||
[[PreviousSessionInfo sharedInstance] removeReportParameterForKey:kKey1];
|
||||
URLs = [NSUserDefaults.standardUserDefaults
|
||||
dictionaryForKey:previous_session_info_constants::
|
||||
kPreviousSessionInfoURLs];
|
||||
kPreviousSessionInfoParams];
|
||||
EXPECT_FALSE(URLs);
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
EXPECT_FALSE([[PreviousSessionInfo sharedInstance] reportParameterURLs]);
|
||||
EXPECT_FALSE([[PreviousSessionInfo sharedInstance] reportParameters]);
|
||||
[PreviousSessionInfo resetSharedInstanceForTesting];
|
||||
}
|
||||
|
||||
|
@ -93,12 +93,12 @@ void CreateSyntheticCrashReportForUte(
|
||||
AppendConfig(config, "BreakpadServerParameterPrefix_platform",
|
||||
base::SysInfo::HardwareModelName());
|
||||
|
||||
for (NSString* key in previous_session.reportParameterURLs.allKeys) {
|
||||
for (NSString* key in previous_session.reportParameters.allKeys) {
|
||||
AppendConfig(
|
||||
config,
|
||||
base::StringPrintf("BreakpadServerParameterPrefix_%s",
|
||||
base::SysNSStringToUTF8(key).c_str()),
|
||||
base::SysNSStringToUTF8(previous_session.reportParameterURLs[key]));
|
||||
base::SysNSStringToUTF8(previous_session.reportParameters[key]));
|
||||
}
|
||||
|
||||
if (previous_session.sessionStartTime && previous_session.sessionEndTime) {
|
||||
|
@ -41,7 +41,7 @@ TEST_F(SyntheticCrashReportUtilTest, CreateSyntheticCrashReportForUte) {
|
||||
previous_session.OSVersion = kOSVersion;
|
||||
previous_session.terminatedDuringSessionRestoration = YES;
|
||||
NSString* const kURL = @"URL";
|
||||
previous_session.reportParameterURLs = @{@"url" : kURL};
|
||||
previous_session.reportParameters = @{@"url" : kURL};
|
||||
previous_session.sessionStartTime = [NSDate date];
|
||||
const NSTimeInterval kUptimeMs = 5000;
|
||||
previous_session.sessionEndTime = [previous_session.sessionStartTime
|
||||
|
Reference in New Issue
Block a user