diff options
author | Primiano Tucci <primiano@google.com> | 2020-06-29 11:28:58 +0100 |
---|---|---|
committer | Primiano Tucci <primiano@google.com> | 2020-06-29 18:51:40 +0100 |
commit | a3502b504d3c4868bd8716e00dd649101bbe3cb3 (patch) | |
tree | d9ecb9020b67dd91f7e83f6149a047e5b2a015fe | |
parent | ee1ad0698bf61f55a1da4a0bb4f84f8705f4c041 (diff) | |
download | perfetto-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.cc | 6 | ||||
-rw-r--r-- | src/traced/probes/ftrace/proto_translation_table.h | 10 |
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_; |