Commit 9579753b authored by Eugene But's avatar Eugene But Committed by Commit Bot

[ios] Attach Breadcrumbs to synthetic crash reports

Append persisted breadcrumbs to Syntheric Crash report. After this CL
Synthetic Crash reports will be uploaded only if Breadcrumbs feature is
enabled as without Breadcrumbs these reports are not useful.

Bug: 1103752
Change-Id: Ia4489b86f07ea7f77e012abb8c0124d7347c2871
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2410302
Commit-Queue: Eugene But <eugenebut@chromium.org>
Reviewed-by: default avatarMike Dougherty <michaeldo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#818712}
parent e7078c1b
......@@ -19,6 +19,7 @@ void CreateSyntheticCrashReportForUte(
const std::string& breakpad_product_display,
const std::string& breakpad_product,
const std::string& breakpad_version,
const std::string& breakpad_url);
const std::string& breakpad_url,
const std::vector<std::string>& breadcrumbs);
#endif // IOS_CHROME_BROWSER_CRASH_REPORT_SYNTHETIC_CRASH_REPORT_UTIL_H_
......@@ -51,7 +51,8 @@ void CreateSyntheticCrashReportForUte(
const std::string& breakpad_product_display,
const std::string& breakpad_product,
const std::string& breakpad_version,
const std::string& breakpad_url) {
const std::string& breakpad_url,
const std::vector<std::string>& breadcrumbs) {
std::vector<std::string> config;
AppendConfig(config, "MinidumpDir", path.value());
......@@ -93,6 +94,10 @@ void CreateSyntheticCrashReportForUte(
AppendConfig(config, "BreakpadServerParameterPrefix_platform",
base::SysInfo::HardwareModelName());
AppendConfig(config, "BreakpadServerParameterPrefix_breadcrumbs",
base::JoinString(breadcrumbs, "\n"));
AppendConfig(config, "BreakpadServerParameterPrefix_signature",
breadcrumbs.back().substr(strlen("00:00 ")));
for (NSString* key in previous_session.reportParameters.allKeys) {
AppendConfig(
......
......@@ -51,8 +51,13 @@ TEST_F(SyntheticCrashReportUtilTest, CreateSyntheticCrashReportForUte) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
std::string product_display = std::string(255, 'a') + std::string(1, 'b');
const char kBreadcrumb1[] = "52:43 Tab1 Zoom";
const char kLastEvent[] = "Tab1 Scroll 1";
std::string kBreadcrumb2 = std::string("52:46 ") + kLastEvent;
CreateSyntheticCrashReportForUte(temp_dir.GetPath(), product_display,
"Product", "Version", "URL");
"Product", "Version", "URL",
{kBreadcrumb1, kBreadcrumb2});
// CreateSyntheticCrashReportForUte creates config and empty minidump file.
// locate both files and ensure there are no other files in the directory.
base::FileEnumerator traversal(temp_dir.GetPath(), /*recursive=*/false,
......@@ -102,7 +107,7 @@ TEST_F(SyntheticCrashReportUtilTest, CreateSyntheticCrashReportForUte) {
// Verify config file content. Config file has the following format:
// <Key1>\n<Value1Length>\n<Value1>\n...<KeyN>\n<ValueNLength>\n<ValueN>
ASSERT_EQ(48U, config_lines.size())
ASSERT_EQ(55U, config_lines.size())
<< "<content>" << config_content << "</content>";
EXPECT_EQ("MinidumpDir", config_lines[0]);
......@@ -171,14 +176,25 @@ TEST_F(SyntheticCrashReportUtilTest, CreateSyntheticCrashReportForUte) {
config_lines[40]);
EXPECT_EQ(base::SysInfo::HardwareModelName(), config_lines[41]);
EXPECT_EQ("BreakpadServerParameterPrefix_url", config_lines[42]);
EXPECT_EQ(base::NumberToString(kURL.length), config_lines[43]);
EXPECT_EQ(base::SysNSStringToUTF8(kURL), config_lines[44]);
EXPECT_EQ("BreakpadServerParameterPrefix_breadcrumbs", config_lines[42]);
EXPECT_EQ(
base::NumberToString(strlen(kBreadcrumb1) + kBreadcrumb2.size() + 1),
config_lines[43]);
EXPECT_EQ(kBreadcrumb1, config_lines[44]);
EXPECT_EQ(kBreadcrumb2, config_lines[45]);
EXPECT_EQ("BreakpadServerParameterPrefix_signature", config_lines[46]);
EXPECT_EQ(base::NumberToString(strlen(kLastEvent)), config_lines[47]);
EXPECT_EQ(kLastEvent, config_lines[48]);
EXPECT_EQ("BreakpadServerParameterPrefix_url", config_lines[49]);
EXPECT_EQ(base::NumberToString(kURL.length), config_lines[50]);
EXPECT_EQ(base::SysNSStringToUTF8(kURL), config_lines[51]);
EXPECT_EQ("BreakpadProcessUpTime", config_lines[45]);
EXPECT_EQ("BreakpadProcessUpTime", config_lines[52]);
EXPECT_EQ(base::NumberToString(base::NumberToString(kUptimeMs).size()),
config_lines[46]);
EXPECT_EQ(base::NumberToString(kUptimeMs), config_lines[47]);
config_lines[53]);
EXPECT_EQ(base::NumberToString(kUptimeMs), config_lines[54]);
// Read minidump file. It must be empty as there is no stack trace, but
// Breakpad will not upload config without minidump file.
......
......@@ -73,6 +73,8 @@ source_set("metrics") {
"//ios/chrome/browser",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/crash_report",
"//ios/chrome/browser/crash_report/breadcrumbs",
"//ios/chrome/browser/crash_report/breadcrumbs:feature_flags",
"//ios/chrome/browser/google",
"//ios/chrome/browser/history",
"//ios/chrome/browser/main:public",
......
......@@ -18,6 +18,8 @@
#import "components/previous_session_info/previous_session_info.h"
#include "components/version_info/version_info.h"
#include "ios/chrome/browser/application_context.h"
#import "ios/chrome/browser/crash_report/breadcrumbs/breadcrumb_persistent_storage_manager.h"
#include "ios/chrome/browser/crash_report/breadcrumbs/features.h"
#include "ios/chrome/browser/crash_report/breakpad_helper.h"
#include "ios/chrome/browser/crash_report/features.h"
#include "ios/chrome/browser/crash_report/main_thread_freeze_detector.h"
......@@ -193,6 +195,28 @@ void LogDeviceThermalState(DeviceThermalState thermal_state) {
thermal_state,
DeviceThermalState::kMaxValue);
}
// Creates Synthetic Crash Report for Unexplained Termination Event to be
// uploaded by Breakpad.
void CreateSyntheticCrashReportWithBreadcrumbs(
std::vector<std::string> breadcrumbs) {
base::FilePath cache_dir_path;
base::PathService::Get(base::DIR_CACHE, &cache_dir_path);
NSDictionary* info_dict = NSBundle.mainBundle.infoDictionary;
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(
&CreateSyntheticCrashReportForUte,
cache_dir_path.Append(FILE_PATH_LITERAL("Breakpad")),
base::SysNSStringToUTF8(info_dict[@"BreakpadProductDisplay"]),
// Separate product makes throttling on the server easier.
base::SysNSStringToUTF8([NSString
stringWithFormat:@"%@_UTE", info_dict[@"BreakpadProduct"]]),
base::SysNSStringToUTF8(info_dict[@"BreakpadVersion"]),
base::SysNSStringToUTF8(info_dict[@"BreakpadURL"]), breadcrumbs));
}
} // namespace
const float kCriticallyLowBatteryLevel = 0.01;
......@@ -288,26 +312,16 @@ void MobileSessionShutdownMetricsProvider::ProvidePreviousSessionData(
if (!possible_explanation &&
base::FeatureList::IsEnabled(kSyntheticCrashReportsForUte) &&
base::FeatureList::IsEnabled(kLogBreadcrumbs) &&
GetApplicationContext()->GetLocalState()->GetBoolean(
metrics::prefs::kMetricsReportingEnabled)) {
// UTEs are so common that there will be a little or no value from
// generating crash reports for XTEs.
base::FilePath cache_dir_path;
base::PathService::Get(base::DIR_CACHE, &cache_dir_path);
NSDictionary* info_dict = NSBundle.mainBundle.infoDictionary;
base::ThreadPool::PostTask(
FROM_HERE, {base::MayBlock()},
base::BindOnce(
&CreateSyntheticCrashReportForUte,
cache_dir_path.Append(FILE_PATH_LITERAL("Breakpad")),
base::SysNSStringToUTF8(info_dict[@"BreakpadProductDisplay"]),
// Separate product makes throttling on the server easier.
base::SysNSStringToUTF8([NSString
stringWithFormat:@"%@_UTE", info_dict[@"BreakpadProduct"]]),
base::SysNSStringToUTF8(info_dict[@"BreakpadVersion"]),
base::SysNSStringToUTF8(info_dict[@"BreakpadURL"])));
GetApplicationContext()
->GetBreadcrumbPersistentStorageManager()
->GetStoredEvents(
base::BindOnce(CreateSyntheticCrashReportWithBreadcrumbs));
}
}
[session_info resetSessionRestorationFlag];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment