Ignore bad profiles when --force-merge is specified
The ART profiles are cleaned lazily and may stay a long time on an
obsolete version if the corresponding apps are not used or updated. For
regular profiles this is not a problem, however for boot image profiles
they can trigger unnecessary merge errors. As such, we ignore them when
--force-merge is specified.
Test: profile tests
Bug: 139884006
Change-Id: I10d9a325d79b279c8ec4fe8d70696e9335a17099
diff --git a/profman/profile_assistant.cc b/profman/profile_assistant.cc
index 7107944..1695d8c 100644
--- a/profman/profile_assistant.cc
+++ b/profman/profile_assistant.cc
@@ -58,6 +58,12 @@
ProfileCompilationInfo cur_info;
if (!cur_info.Load(profile_files[i]->Fd(), /*merge_classes=*/ true, filter_fn)) {
LOG(WARNING) << "Could not load profile file at index " << i;
+ if (options.IsForceMerge()) {
+ // If we have to merge forcefully, ignore load failures.
+ // This is useful for boot image profiles to ignore stale profiles which are
+ // cleared lazily.
+ continue;
+ }
return kErrorBadProfiles;
}
diff --git a/profman/profile_assistant_test.cc b/profman/profile_assistant_test.cc
index 1717dd1..caaff4b 100644
--- a/profman/profile_assistant_test.cc
+++ b/profman/profile_assistant_test.cc
@@ -1430,4 +1430,38 @@
ASSERT_EQ(ProcessProfiles(profile_fds, reference_profile_fd),
ProfileAssistant::kErrorDifferentVersions);
}
+
+// Under default behaviour we will abort if we cannot load a profile during a merge
+// operation. However, if we pass --force-merge to force aggregation we should
+// ignore files we cannot load
+TEST_F(ProfileAssistantTest, ForceMergeIgnoreProfilesItCannotLoad) {
+ ScratchFile profile1;
+ ScratchFile profile2;
+
+ // Write corrupt data in the first file.
+ std::string content = "giberish";
+ ASSERT_TRUE(profile1.GetFile()->WriteFully(content.c_str(), content.length()));
+ profile1.GetFile()->ResetOffset();
+
+ ProfileCompilationInfo info2(/*for_boot_image*/ true);
+ info2.Save(profile2.GetFd());
+ profile2.GetFile()->ResetOffset();
+
+ std::vector<int> profile_fds({ GetFd(profile1)});
+ int reference_profile_fd = GetFd(profile2);
+
+ // With force-merge we should merge successfully.
+ std::vector<const std::string> extra_args({"--force-merge"});
+ ASSERT_EQ(ProcessProfiles(profile_fds, reference_profile_fd, extra_args),
+ ProfileAssistant::kSuccess);
+
+ ProfileCompilationInfo result;
+ ASSERT_TRUE(profile2.GetFile()->ResetOffset());
+ ASSERT_TRUE(result.Load(reference_profile_fd));
+ ASSERT_TRUE(info2.Equals(result));
+
+ // Without force-merge we should fail.
+ ASSERT_EQ(ProcessProfiles(profile_fds, reference_profile_fd, extra_args),
+ ProfileAssistant::kErrorBadProfiles);
+}
} // namespace art