aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPrimiano Tucci <primiano@google.com>2020-06-29 11:28:58 +0100
committerPrimiano Tucci <primiano@google.com>2020-06-29 18:51:40 +0100
commita3502b504d3c4868bd8716e00dd649101bbe3cb3 (patch)
treed9ecb9020b67dd91f7e83f6149a047e5b2a015fe
parentee1ad0698bf61f55a1da4a0bb4f84f8705f4c041 (diff)
downloadperfetto-a3502b504d3c4868bd8716e00dd649101bbe3cb3.tar.gz
ftrace: fix pointer stability of events_ vector
This fixes an extremely subtle bug which causes traced_probes to crash when tracing on some specific devices. The root cause of the bug is the fact that in rare cirumstances the events_ vector can be resized after construction, after some Event* poitners have been handed out, hence invalidating them. The rare circumstance is: - The trace config ends up hitting a "generic event" path, i.e. the ftrace event is not known at compile time but exists on the target device (note this is not that unlikely because the expansion of some atrace categories in ftrace_config_muxer.cc can end up adding events like sde/sde_cmd_release_bw which are not in the compile-time list. - The ftrace event ID of the generic event above is > than the max(ID of events known at compile time) - The vector resize() ends up hitting the unhappy realloc() path which changes the data() pointer and mem-copies everything, invalidating all pointers. Fix: use std::deque, which guarantees pointer stability. Bug: 159998308 Change-Id: Id21fabf0c940fd0e5302518c0170686d61aaf847 Merged-In: Id21fabf0c940fd0e5302518c0170686d61aaf847 (cherry picked from commit bd3e8ecca937a76318c68ec8e8da72cb5c0239ba) (cherry picked from commit 5cceb8adf772f3638577dea0d255b8bef3a743e5)
-rw-r--r--src/traced/probes/ftrace/proto_translation_table.cc6
-rw-r--r--src/traced/probes/ftrace/proto_translation_table.h10
2 files changed, 9 insertions, 7 deletions
diff --git a/src/traced/probes/ftrace/proto_translation_table.cc b/src/traced/probes/ftrace/proto_translation_table.cc
index ceb0973a5..44fe5f587 100644
--- a/src/traced/probes/ftrace/proto_translation_table.cc
+++ b/src/traced/probes/ftrace/proto_translation_table.cc
@@ -94,13 +94,13 @@ ProtoTranslationTable::FtracePageHeaderSpec GuessFtracePageHeaderSpec() {
return spec;
}
-const std::vector<Event> BuildEventsVector(const std::vector<Event>& events) {
+const std::deque<Event> BuildEventsDeque(const std::vector<Event>& events) {
size_t largest_id = 0;
for (const Event& event : events) {
if (event.ftrace_event_id > largest_id)
largest_id = event.ftrace_event_id;
}
- std::vector<Event> events_by_id;
+ std::deque<Event> events_by_id;
events_by_id.resize(largest_id + 1);
for (const Event& event : events) {
events_by_id[event.ftrace_event_id] = event;
@@ -466,7 +466,7 @@ ProtoTranslationTable::ProtoTranslationTable(
FtracePageHeaderSpec ftrace_page_header_spec,
CompactSchedEventFormat compact_sched_format)
: ftrace_procfs_(ftrace_procfs),
- events_(BuildEventsVector(events)),
+ events_(BuildEventsDeque(events)),
largest_id_(events_.size() - 1),
common_fields_(std::move(common_fields)),
ftrace_page_header_spec_(ftrace_page_header_spec),
diff --git a/src/traced/probes/ftrace/proto_translation_table.h b/src/traced/probes/ftrace/proto_translation_table.h
index 83dd19d6b..2cf092618 100644
--- a/src/traced/probes/ftrace/proto_translation_table.h
+++ b/src/traced/probes/ftrace/proto_translation_table.h
@@ -19,6 +19,7 @@
#include <stdint.h>
+#include <deque>
#include <iostream>
#include <map>
#include <memory>
@@ -121,9 +122,10 @@ class ProtoTranslationTable {
const Event* GetEventById(size_t id) const {
if (id == 0 || id > largest_id_)
return nullptr;
- if (!events_.at(id).ftrace_event_id)
+ const Event* evt = &events_[id];
+ if (!evt->ftrace_event_id)
return nullptr;
- return &events_.at(id);
+ return evt;
}
size_t EventToFtraceId(const GroupAndName& group_and_name) const {
@@ -132,7 +134,7 @@ class ProtoTranslationTable {
return group_and_name_to_event_.at(group_and_name)->ftrace_event_id;
}
- const std::vector<Event>& events() { return events_; }
+ const std::deque<Event>& events() { return events_; }
const FtracePageHeaderSpec& ftrace_page_header_spec() const {
return ftrace_page_header_spec_;
}
@@ -173,7 +175,7 @@ class ProtoTranslationTable {
Event& event);
const FtraceProcfs* ftrace_procfs_;
- std::vector<Event> events_;
+ std::deque<Event> events_;
size_t largest_id_;
std::map<GroupAndName, const Event*> group_and_name_to_event_;
std::map<std::string, std::vector<const Event*>> name_to_events_;