summaryrefslogtreecommitdiff
path: root/simpleperf/kallsyms.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2021-05-05 15:43:35 -0700
committerYabin Cui <yabinc@google.com>2021-05-05 15:47:10 -0700
commit6e7f33afd80d684f0bfa255993076e4bd7d976ab (patch)
tree8771027e29eca334cb8209af922e63aab75b00e8 /simpleperf/kallsyms.cpp
parentac2e71ce6971ad3b61bcafb8d0c598fc5f94d043 (diff)
downloadextras-6e7f33afd80d684f0bfa255993076e4bd7d976ab.tar.gz
simpleperf: fix printing kernel address warning.
1. In cmd_record.cpp, don't read kernel addresses when kernel samples are not recorded. 2. In kallsyms.cpp, print kernel address warning only once. 3. In kallsyms.cpp, use property only when running as root. Bug: none Test: run simpleperf_unit_test Change-Id: I06de729ff3f26f7cd2115593182d6cb9cdc7f525
Diffstat (limited to 'simpleperf/kallsyms.cpp')
-rw-r--r--simpleperf/kallsyms.cpp78
1 files changed, 47 insertions, 31 deletions
diff --git a/simpleperf/kallsyms.cpp b/simpleperf/kallsyms.cpp
index 844730f9..f9a93589 100644
--- a/simpleperf/kallsyms.cpp
+++ b/simpleperf/kallsyms.cpp
@@ -66,33 +66,41 @@ class ScopedKptrUnrestrict {
ScopedKptrUnrestrict(); // Lowers kptr_restrict if necessary.
~ScopedKptrUnrestrict(); // Restores the initial kptr_restrict.
- bool KallsymsAvailable(); // Indicates if access to kallsyms should be successful.
+ // Indicates if access to kallsyms should be successful.
+ bool KallsymsAvailable() { return kallsyms_available_; }
+
+ static void ResetWarning() { kernel_address_warning_printed_ = false; }
private:
- static bool WriteKptrRestrict(const std::string&);
+ bool WriteKptrRestrict(const std::string& value);
+ void PrintWarning();
- std::string initial_value_;
- bool use_property_;
- bool restore_on_dtor_ = true;
+ bool restore_property_ = false;
+ bool restore_restrict_value_ = false;
+ std::string saved_restrict_value_;
bool kallsyms_available_ = false;
+
+ static bool kernel_address_warning_printed_;
};
+bool ScopedKptrUnrestrict::kernel_address_warning_printed_ = false;
+
ScopedKptrUnrestrict::ScopedKptrUnrestrict() {
- use_property_ = GetAndroidVersion() >= 12;
if (CanReadKernelSymbolAddresses()) {
// Everything seems to work (e.g., we are running as root and kptr_restrict
// is < 2). Don't touching anything.
- restore_on_dtor_ = false;
kallsyms_available_ = true;
return;
}
- if (use_property_) {
- bool ret = android::base::SetProperty(kLowerPtrRestrictAndroidProp, "1");
- if (!ret) {
- LOG(ERROR) << "Unable to set " << kLowerPtrRestrictAndroidProp << " to 1.";
+ if (GetAndroidVersion() >= 12 && IsRoot()) {
+ // Enable kernel addresses by setting property.
+ if (!android::base::SetProperty(kLowerPtrRestrictAndroidProp, "1")) {
+ LOG(DEBUG) << "Unable to set " << kLowerPtrRestrictAndroidProp << " to 1.";
+ PrintWarning();
return;
}
+ restore_property_ = true;
// Init takes some time to react to the property change.
// Unfortunately, we cannot read kptr_restrict because of SELinux. Instead,
// we detect this by reading the initial lines of kallsyms and checking
@@ -104,55 +112,59 @@ ScopedKptrUnrestrict::ScopedKptrUnrestrict() {
return;
}
}
- LOG(ERROR) << "kallsyms addresses are still masked after setting "
+ LOG(DEBUG) << "kallsyms addresses are still masked after setting "
<< kLowerPtrRestrictAndroidProp;
+ PrintWarning();
return;
}
// Otherwise, read the kptr_restrict value and lower it if needed.
- bool read_res = android::base::ReadFileToString(kPtrRestrictPath, &initial_value_);
- if (!read_res) {
- LOG(WARNING) << "Failed to read " << kPtrRestrictPath;
+ if (!android::base::ReadFileToString(kPtrRestrictPath, &saved_restrict_value_)) {
+ LOG(DEBUG) << "Failed to read " << kPtrRestrictPath;
+ PrintWarning();
return;
}
// Progressively lower kptr_restrict until we can read kallsyms.
- for (int value = atoi(initial_value_.c_str()); value > 0; --value) {
- bool ret = WriteKptrRestrict(std::to_string(value));
- if (!ret) {
- LOG(WARNING) << "Access to kernel symbol addresses is restricted. If "
- << "possible, please do `echo 0 >/proc/sys/kernel/kptr_restrict` "
- << "to fix this.";
- return;
+ for (int value = atoi(saved_restrict_value_.c_str()); value > 0; --value) {
+ if (!WriteKptrRestrict(std::to_string(value))) {
+ break;
}
+ restore_restrict_value_ = true;
if (CanReadKernelSymbolAddresses()) {
kallsyms_available_ = true;
return;
}
}
+ PrintWarning();
}
ScopedKptrUnrestrict::~ScopedKptrUnrestrict() {
- if (!restore_on_dtor_) return;
- if (use_property_) {
+ if (restore_property_) {
android::base::SetProperty(kLowerPtrRestrictAndroidProp, "0");
- } else if (!initial_value_.empty()) {
- WriteKptrRestrict(initial_value_);
}
-}
-
-bool ScopedKptrUnrestrict::KallsymsAvailable() {
- return kallsyms_available_;
+ if (restore_restrict_value_) {
+ WriteKptrRestrict(saved_restrict_value_);
+ }
}
bool ScopedKptrUnrestrict::WriteKptrRestrict(const std::string& value) {
if (!android::base::WriteStringToFile(value, kPtrRestrictPath)) {
- LOG(WARNING) << "Failed to set " << kPtrRestrictPath << " to " << value;
+ LOG(DEBUG) << "Failed to set " << kPtrRestrictPath << " to " << value;
return false;
}
return true;
}
+void ScopedKptrUnrestrict::PrintWarning() {
+ if (!kernel_address_warning_printed_) {
+ kernel_address_warning_printed_ = true;
+ LOG(WARNING) << "Access to kernel symbol addresses is restricted. If "
+ << "possible, please do `echo 0 >/proc/sys/kernel/kptr_restrict` "
+ << "to fix this.";
+ }
+}
+
} // namespace
std::vector<KernelMmap> GetLoadedModules() {
@@ -221,6 +233,10 @@ bool LoadKernelSymbols(std::string* kallsyms) {
return false;
}
+void ResetKernelAddressWarning() {
+ ScopedKptrUnrestrict::ResetWarning();
+}
+
#endif // defined(__linux__)
bool ProcessKernelSymbols(std::string& symbol_data,