ftrace_reader: Add dynamic parser (part 1)

To dynamically parse ftrace events into protos we need to merge some
build time information (proto field ids, proto field types) with
some runtime information (ftrace field types). This CL:
- Refactors ProtoTranslationTable to accept partially filled in Event
  structs rather than generating them from scratch.
- Adds event_info.cc, which holds the (eventually auto generated)
  build time info.
- Also happens to fix the issue with available_events (since we
  only need to look for the events we have static information
  for).

Bug: 69662589,70328826
Change-Id: I1db48a71b0972f3b9ebc76011ca28a2a764d9ce6
diff --git a/Android.bp b/Android.bp
index 852e834..9ce2e99 100644
--- a/Android.bp
+++ b/Android.bp
@@ -290,6 +290,7 @@
 filegroup {
   name: "perfetto_ftrace_reader",
   srcs: [
+    "src/ftrace_reader/event_info.cc",
     "src/ftrace_reader/cpu_reader.cc",
     "src/ftrace_reader/format_parser.cc",
     "src/ftrace_reader/ftrace_controller.cc",
@@ -505,6 +506,7 @@
     "src/base/utils_unittest.cc",
     "src/base/weak_ptr_unittest.cc",
     "src/ftrace_reader/cpu_reader_unittest.cc",
+    "src/ftrace_reader/event_info_unittest.cc",
     "src/ftrace_reader/format_parser_unittest.cc",
     "src/ftrace_reader/ftrace_controller_unittest.cc",
     "src/ftrace_reader/ftrace_to_proto_unittest.cc",
diff --git a/include/perfetto/ftrace_reader/ftrace_to_proto.h b/include/perfetto/ftrace_reader/ftrace_to_proto.h
index b97803f..ec476a5 100644
--- a/include/perfetto/ftrace_reader/ftrace_to_proto.h
+++ b/include/perfetto/ftrace_reader/ftrace_to_proto.h
@@ -30,8 +30,8 @@
 struct FtraceEvent {
   struct Field {
     std::string type_and_name;
-    size_t offset;
-    size_t size;
+    uint16_t offset;
+    uint16_t size;
     bool is_signed;
 
     bool operator==(const Field& other) const {
diff --git a/src/ftrace_reader/BUILD.gn b/src/ftrace_reader/BUILD.gn
index cce7e22..6837de3 100644
--- a/src/ftrace_reader/BUILD.gn
+++ b/src/ftrace_reader/BUILD.gn
@@ -35,6 +35,7 @@
   ]
   sources = [
     "cpu_reader_unittest.cc",
+    "event_info_unittest.cc",
     "format_parser_unittest.cc",
     "ftrace_controller_unittest.cc",
     "ftrace_to_proto_unittest.cc",
@@ -88,6 +89,8 @@
   sources = [
     "cpu_reader.cc",
     "cpu_reader.h",
+    "event_info.cc",
+    "event_info.h",
     "format_parser.cc",
     "ftrace_controller.cc",
     "ftrace_procfs.cc",
diff --git a/src/ftrace_reader/cpu_reader.cc b/src/ftrace_reader/cpu_reader.cc
index cd47ae6..a7d1b48 100644
--- a/src/ftrace_reader/cpu_reader.cc
+++ b/src/ftrace_reader/cpu_reader.cc
@@ -38,7 +38,7 @@
                                            const std::set<std::string>& names) {
   std::vector<bool> enabled(table.largest_id() + 1);
   for (const std::string& name : names) {
-    const ProtoTranslationTable::Event* event = table.GetEventByName(name);
+    const Event* event = table.GetEventByName(name);
     if (!event)
       continue;
     enabled[event->ftrace_event_id] = true;
diff --git a/src/ftrace_reader/cpu_reader_unittest.cc b/src/ftrace_reader/cpu_reader_unittest.cc
index 28dbfc7..73689e1 100644
--- a/src/ftrace_reader/cpu_reader_unittest.cc
+++ b/src/ftrace_reader/cpu_reader_unittest.cc
@@ -16,6 +16,7 @@
 
 #include "cpu_reader.h"
 
+#include "event_info.h"
 #include "ftrace_procfs.h"
 #include "gtest/gtest.h"
 #include "proto_translation_table.h"
@@ -108,7 +109,7 @@
   if (!g_tables->count(name)) {
     std::string path = "src/ftrace_reader/test/data/" + name + "/";
     FtraceProcfs ftrace(path);
-    auto table = ProtoTranslationTable::Create(&ftrace);
+    auto table = ProtoTranslationTable::Create(&ftrace, GetStaticEventInfo());
     g_tables->emplace(name, std::move(table));
   }
   return g_tables->at(name).get();
@@ -166,9 +167,6 @@
 }
 
 TEST(EventFilterTest, EventFilter) {
-  using Event = ProtoTranslationTable::Event;
-  using Field = ProtoTranslationTable::Field;
-
   std::vector<Field> common_fields;
   std::vector<Event> events;
 
diff --git a/src/ftrace_reader/event_info.cc b/src/ftrace_reader/event_info.cc
new file mode 100644
index 0000000..c493489
--- /dev/null
+++ b/src/ftrace_reader/event_info.cc
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/ftrace_reader/event_info.h"
+
+namespace perfetto {
+namespace {
+
+Field FieldFromNameIdType(const char* name, size_t id, ProtoFieldType type) {
+  Field field{};
+  field.ftrace_name = name;
+  field.proto_field_id = id;
+  field.proto_field_type = type;
+  return field;
+}
+
+}  // namespace
+
+// TODO(hjd): Auto-generate this file.
+// TODO(b/70373826): Reduce runetime overhead with constexpr magic etc.
+std::vector<Event> GetStaticEventInfo() {
+  std::vector<Event> events;
+
+  {
+    events.emplace_back(Event{});
+    Event* event = &events.back();
+    event->name = "print";
+    event->group = "ftrace";
+    event->proto_field_id = 3;
+    event->fields.push_back(FieldFromNameIdType("buf", 2, kProtoString));
+  }
+
+  {
+    events.emplace_back(Event{});
+    Event* event = &events.back();
+    event->name = "sched_switch";
+    event->group = "sched";
+    event->proto_field_id = 4;
+    event->fields.push_back(FieldFromNameIdType("prev_comm", 1, kProtoString));
+    event->fields.push_back(FieldFromNameIdType("prev_pid", 2, kProtoInt32));
+    event->fields.push_back(FieldFromNameIdType("prev_prio", 3, kProtoInt32));
+    event->fields.push_back(FieldFromNameIdType("prev_state", 4, kProtoInt32));
+    event->fields.push_back(FieldFromNameIdType("next_comm", 5, kProtoString));
+    event->fields.push_back(FieldFromNameIdType("next_pid", 6, kProtoInt32));
+    event->fields.push_back(FieldFromNameIdType("next_prio", 7, kProtoInt32));
+  }
+
+  return events;
+}
+
+}  // namespace perfetto
diff --git a/src/ftrace_reader/event_info.h b/src/ftrace_reader/event_info.h
new file mode 100644
index 0000000..359e2ce
--- /dev/null
+++ b/src/ftrace_reader/event_info.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SRC_FTRACE_READER_EVENT_PROTO_INFO_H_
+#define SRC_FTRACE_READER_EVENT_PROTO_INFO_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+namespace perfetto {
+
+enum ProtoFieldType {
+  kProtoNumber = 1,
+  kProtoString,
+  kProtoInt32,
+};
+
+enum FtraceFieldType {
+  kFtraceNumber = 1,
+};
+
+struct Field {
+  Field() = default;
+  Field(uint16_t offset, uint16_t size)
+      : ftrace_offset(offset), ftrace_size(size) {}
+
+  uint16_t ftrace_offset;
+  uint16_t ftrace_size;
+  FtraceFieldType ftrace_type;
+  const char* ftrace_name;
+
+  uint32_t proto_field_id;
+  ProtoFieldType proto_field_type;
+};
+
+struct Event {
+  Event() = default;
+  Event(const char* event_name, const char* event_group)
+      : name(event_name), group(event_group) {}
+
+  const char* name;
+  const char* group;
+  std::vector<Field> fields;
+  uint32_t ftrace_event_id;
+
+  // Field id of the subevent proto (e.g. PrintFtraceEvent) in the FtraceEvent
+  // parent proto.
+  uint32_t proto_field_id;
+};
+
+// The compile time information needed to read the raw ftrace buffer.
+// Specifically for each event we have a proto we fill:
+//  The event name (e.g. sched_switch)
+//  The event group  (e.g. sched)
+//  The the proto field ID of this event in the FtraceEvent proto.
+//  For each field in the proto:
+//    The field name (e.g. prev_comm)
+//    The proto field id for this field
+//    The proto field type for this field (e.g. kProtoString or kProtoUint32)
+// The other fields: ftrace_event_id, ftrace_size, ftrace_offset, ftrace_type
+// are zeroed.
+std::vector<Event> GetStaticEventInfo();
+
+}  // namespace perfetto
+
+#endif  // SRC_FTRACE_READER_EVENT_PROTO_INFO_H_
diff --git a/src/ftrace_reader/event_info_unittest.cc b/src/ftrace_reader/event_info_unittest.cc
new file mode 100644
index 0000000..dcbfe0d
--- /dev/null
+++ b/src/ftrace_reader/event_info_unittest.cc
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "event_info.h"
+
+#include "gtest/gtest.h"
+
+namespace perfetto {
+namespace {
+
+TEST(GetStaticEventInfo, SanityCheck) {
+  std::vector<Event> events = GetStaticEventInfo();
+  for (const Event& event : events) {
+    // For each event the following fields should be filled
+    // statically:
+    // Non-empty name.
+    ASSERT_TRUE(event.name);
+    // Non-empty group.
+    ASSERT_TRUE(event.group);
+    // Non-zero proto field id.
+    ASSERT_TRUE(event.proto_field_id);
+    // Zero the ftrace id.
+    ASSERT_FALSE(event.ftrace_event_id);
+
+    for (const Field& field : event.fields) {
+      // Non-empty name.
+      ASSERT_TRUE(field.ftrace_name);
+      // Non-zero proto field id.
+      ASSERT_TRUE(field.proto_field_id);
+      // Should have set the proto field type.
+      ASSERT_TRUE(field.proto_field_type);
+      // Other fields should be zeroed.
+      ASSERT_FALSE(field.ftrace_offset);
+      ASSERT_FALSE(field.ftrace_size);
+      ASSERT_FALSE(field.ftrace_type);
+    }
+  }
+}
+
+}  // namespace
+}  // namespace perfetto
diff --git a/src/ftrace_reader/format_parser.cc b/src/ftrace_reader/format_parser.cc
index c4599e1..dc38232 100644
--- a/src/ftrace_reader/format_parser.cc
+++ b/src/ftrace_reader/format_parser.cc
@@ -72,13 +72,13 @@
       continue;
     }
 
-    size_t offset = 0;
-    size_t size = 0;
+    uint16_t offset = 0;
+    uint16_t size = 0;
     int is_signed = 0;
     if (sscanf(line,
                "\tfield:%" STRINGIFY(MAX_FIELD_LENGTH) "[^;];\toffset: "
-                                                       "%zu;\tsize: "
-                                                       "%zu;\tsigned: %d;",
+                                                       "%hu;\tsize: "
+                                                       "%hu;\tsigned: %d;",
                buffer, &offset, &size, &is_signed) == 4) {
       std::string type_and_name(buffer);
 
diff --git a/src/ftrace_reader/ftrace_controller.cc b/src/ftrace_reader/ftrace_controller.cc
index f68853f..c37cf0e 100644
--- a/src/ftrace_reader/ftrace_controller.cc
+++ b/src/ftrace_reader/ftrace_controller.cc
@@ -26,6 +26,7 @@
 #include <string>
 
 #include "cpu_reader.h"
+#include "event_info.h"
 #include "ftrace_procfs.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/base/utils.h"
@@ -46,7 +47,8 @@
     base::TaskRunner* runner) {
   auto ftrace_procfs =
       std::unique_ptr<FtraceProcfs>(new FtraceProcfs(kTracingPath));
-  auto table = ProtoTranslationTable::Create(ftrace_procfs.get());
+  auto table =
+      ProtoTranslationTable::Create(ftrace_procfs.get(), GetStaticEventInfo());
   return std::unique_ptr<FtraceController>(
       new FtraceController(std::move(ftrace_procfs), runner, std::move(table)));
 }
@@ -63,7 +65,7 @@
 FtraceController::~FtraceController() {
   for (size_t id = 1; id <= table_->largest_id(); id++) {
     if (enabled_count_[id]) {
-      const ProtoTranslationTable::Event* event = table_->GetEventById(id);
+      const Event* event = table_->GetEventById(id);
       ftrace_procfs_->DisableEvent(event->group, event->name);
     }
   }
@@ -164,7 +166,7 @@
 
 void FtraceController::RegisterForEvent(const std::string& name) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
-  const ProtoTranslationTable::Event* event = table_->GetEventByName(name);
+  const Event* event = table_->GetEventByName(name);
   if (!event) {
     PERFETTO_DLOG("Can't enable %s, event not known", name.c_str());
     return;
@@ -177,7 +179,7 @@
 
 void FtraceController::UnregisterForEvent(const std::string& name) {
   PERFETTO_DCHECK_THREAD(thread_checker_);
-  const ProtoTranslationTable::Event* event = table_->GetEventByName(name);
+  const Event* event = table_->GetEventByName(name);
   if (!event)
     return;
   size_t& count = enabled_count_.at(event->ftrace_event_id);
diff --git a/src/ftrace_reader/ftrace_controller_unittest.cc b/src/ftrace_reader/ftrace_controller_unittest.cc
index e03f0b9..1c091cc 100644
--- a/src/ftrace_reader/ftrace_controller_unittest.cc
+++ b/src/ftrace_reader/ftrace_controller_unittest.cc
@@ -79,9 +79,6 @@
 };
 
 std::unique_ptr<Table> FakeTable() {
-  using Event = Table::Event;
-  using Field = Table::Field;
-
   std::vector<Field> common_fields;
   std::vector<Event> events;
 
diff --git a/src/ftrace_reader/proto_translation_table.cc b/src/ftrace_reader/proto_translation_table.cc
index b5674ca..74349b9 100644
--- a/src/ftrace_reader/proto_translation_table.cc
+++ b/src/ftrace_reader/proto_translation_table.cc
@@ -16,6 +16,9 @@
 
 #include "proto_translation_table.h"
 
+#include <algorithm>
+
+#include "event_info.h"
 #include "ftrace_procfs.h"
 #include "perfetto/ftrace_reader/format_parser.h"
 #include "perfetto/ftrace_reader/ftrace_to_proto.h"
@@ -26,18 +29,13 @@
 
 namespace {
 
-#define MAX_FIELD_LENGTH 127
-#define STRINGIFY(x) STRINGIFY2(x)
-#define STRINGIFY2(x) #x
-
-using Event = ProtoTranslationTable::Event;
 const std::vector<Event> BuildEventsVector(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<ProtoTranslationTable::Event> events_by_id;
+  std::vector<Event> events_by_id;
   events_by_id.resize(largest_id + 1);
   for (const Event& event : events) {
     events_by_id[event.ftrace_event_id] = event;
@@ -50,49 +48,29 @@
 
 // static
 std::unique_ptr<ProtoTranslationTable> ProtoTranslationTable::Create(
-    const FtraceProcfs* ftrace_procfs) {
-  std::vector<Event> events;
+    const FtraceProcfs* ftrace_procfs,
+    std::vector<Event> events) {
   std::vector<Field> common_fields;
 
-  std::string available = ftrace_procfs->ReadAvailableEvents();
-  if (available == "") {
-    PERFETTO_DLOG("Could not read available_events");
-    return nullptr;
-  }
-  {
-    std::unique_ptr<char[], base::FreeDeleter> copy(strdup(available.c_str()));
-    char group_buffer[MAX_FIELD_LENGTH + 1];
-    char name_buffer[MAX_FIELD_LENGTH + 1];
-    char* s = copy.get();
-    for (char* line = strtok(s, "\n"); line; line = strtok(nullptr, "\n")) {
-      if (sscanf(line,
-                 "%" STRINGIFY(MAX_FIELD_LENGTH) "[^:]:%" STRINGIFY(
-                     MAX_FIELD_LENGTH) "s",
-                 group_buffer, name_buffer) == 2) {
-        std::string name = std::string(name_buffer);
-        std::string group = std::string(group_buffer);
-        events.emplace_back(Event{name, group});
-      }
-    }
-  }
-
-  // TODO(b/69662589): Hack to get around events missing from available_events.
-  events.emplace_back(Event{"print", "ftrace"});
-
   for (Event& event : events) {
     std::string contents =
         ftrace_procfs->ReadEventFormat(event.group, event.name);
     FtraceEvent ftrace_event;
     if (contents == "" || !ParseFtraceEvent(contents, &ftrace_event)) {
-      PERFETTO_DLOG("Could not read '%s'", event.name.c_str());
+      PERFETTO_DLOG("Could not read '%s'", event.name);
       continue;
     }
     event.ftrace_event_id = ftrace_event.id;
-    event.fields.reserve(ftrace_event.fields.size());
-    for (FtraceEvent::Field ftrace_field : ftrace_event.fields) {
-      event.fields.push_back(Field{ftrace_field.offset, ftrace_field.size});
+    for (Field& field : event.fields) {
+      for (FtraceEvent::Field ftrace_field : ftrace_event.fields) {
+        if (GetNameFromTypeAndName(ftrace_field.type_and_name) !=
+            field.ftrace_name)
+          continue;
+        field.ftrace_offset = ftrace_field.offset;
+        field.ftrace_size = ftrace_field.size;
+        field.ftrace_type = kFtraceNumber;
+      }
     }
-
     if (common_fields.empty()) {
       for (const FtraceEvent::Field& ftrace_field :
            ftrace_event.common_fields) {
@@ -101,8 +79,15 @@
     }
   }
 
+  events.erase(std::remove_if(events.begin(), events.end(),
+                              [](const Event& event) {
+                                return event.proto_field_id == 0 ||
+                                       event.ftrace_event_id == 0;
+                              }),
+               events.end());
+
   auto table = std::unique_ptr<ProtoTranslationTable>(
-      new ProtoTranslationTable(events, std::move(common_fields)));
+      new ProtoTranslationTable(std::move(events), std::move(common_fields)));
   return table;
 }
 
diff --git a/src/ftrace_reader/proto_translation_table.h b/src/ftrace_reader/proto_translation_table.h
index 9a49ec0..55967b0 100644
--- a/src/ftrace_reader/proto_translation_table.h
+++ b/src/ftrace_reader/proto_translation_table.h
@@ -26,6 +26,7 @@
 #include <vector>
 
 #include "perfetto/base/scoped_file.h"
+#include "src/ftrace_reader/event_info.h"
 
 namespace perfetto {
 
@@ -39,40 +40,9 @@
 
 class ProtoTranslationTable {
  public:
-  enum FtraceFieldType {
-    kFtraceNumber = 0,
-  };
-
-  enum ProtoFieldType {
-    kProtoNumber = 0,
-  };
-
-  struct Field {
-    Field() = default;
-    Field(size_t offset, size_t size)
-        : ftrace_offset(offset), ftrace_size(size) {}
-
-    size_t ftrace_offset = 0;
-    size_t ftrace_size = 0;
-    FtraceFieldType ftrace_type = kFtraceNumber;
-    size_t proto_field_id = 0;
-    ProtoFieldType proto_field_type = kProtoNumber;
-  };
-
-  struct Event {
-    Event() = default;
-    Event(const std::string& event_name, const std::string& event_group)
-        : name(event_name), group(event_group) {}
-
-    std::string name;
-    std::string group;
-    std::vector<Field> fields;
-    size_t ftrace_event_id = 0;
-    size_t proto_field_id = 0;
-  };
-
   static std::unique_ptr<ProtoTranslationTable> Create(
-      const FtraceProcfs* ftrace_procfs);
+      const FtraceProcfs* ftrace_procfs,
+      std::vector<Event> events);
   ~ProtoTranslationTable();
 
   ProtoTranslationTable(const std::vector<Event>& events,
@@ -102,6 +72,8 @@
     return name_to_event_.at(name)->ftrace_event_id;
   }
 
+  const std::vector<Event>& events() { return events_; }
+
  private:
   ProtoTranslationTable(const ProtoTranslationTable&) = delete;
   ProtoTranslationTable& operator=(const ProtoTranslationTable&) = delete;
diff --git a/src/ftrace_reader/proto_translation_table_unittest.cc b/src/ftrace_reader/proto_translation_table_unittest.cc
index 09bc548..98e37c7 100644
--- a/src/ftrace_reader/proto_translation_table_unittest.cc
+++ b/src/ftrace_reader/proto_translation_table_unittest.cc
@@ -31,7 +31,8 @@
     std::string path =
         "src/ftrace_reader/test/data/" + std::string(GetParam()) + "/";
     FtraceProcfs ftrace_procfs(path);
-    table_ = ProtoTranslationTable::Create(&ftrace_procfs);
+    table_ =
+        ProtoTranslationTable::Create(&ftrace_procfs, GetStaticEventInfo());
   }
 
   std::unique_ptr<ProtoTranslationTable> table_;
@@ -44,6 +45,20 @@
 
 TEST_P(AllTranslationTableTest, Create) {
   EXPECT_TRUE(table_);
+  EXPECT_TRUE(table_->GetEventByName("print"));
+  EXPECT_TRUE(table_->GetEventByName("sched_switch"));
+  for (const Event& event : table_->events()) {
+    if (!event.ftrace_event_id)
+      continue;
+    EXPECT_TRUE(event.name);
+    EXPECT_TRUE(event.group);
+    EXPECT_TRUE(event.proto_field_id);
+    for (const Field& field : event.fields) {
+      EXPECT_TRUE(field.proto_field_id);
+      EXPECT_TRUE(field.ftrace_type);
+      EXPECT_TRUE(field.proto_field_type);
+    }
+  }
 }
 
 INSTANTIATE_TEST_CASE_P(ByDevice, AllTranslationTableTest, ValuesIn(kDevices));
@@ -51,23 +66,20 @@
 TEST(TranslationTable, Seed) {
   std::string path = "src/ftrace_reader/test/data/android_seed_N2F62_3.10.49/";
   FtraceProcfs ftrace_procfs(path);
-  auto table = ProtoTranslationTable::Create(&ftrace_procfs);
-  EXPECT_EQ(table->largest_id(), 744ul);
+  auto table =
+      ProtoTranslationTable::Create(&ftrace_procfs, GetStaticEventInfo());
   EXPECT_EQ(table->common_fields().at(0).ftrace_offset, 0u);
   EXPECT_EQ(table->common_fields().at(0).ftrace_size, 2u);
 
   auto sched_switch_event = table->GetEventByName("sched_switch");
-  EXPECT_EQ(sched_switch_event->name, "sched_switch");
-  EXPECT_EQ(sched_switch_event->group, "sched");
+  EXPECT_EQ(std::string(sched_switch_event->name), "sched_switch");
+  EXPECT_EQ(std::string(sched_switch_event->group), "sched");
   EXPECT_EQ(sched_switch_event->ftrace_event_id, 68ul);
   EXPECT_EQ(sched_switch_event->fields.at(0).ftrace_offset, 8u);
   EXPECT_EQ(sched_switch_event->fields.at(0).ftrace_size, 16u);
 }
 
 TEST(TranslationTable, Getters) {
-  using Event = ProtoTranslationTable::Event;
-  using Field = ProtoTranslationTable::Field;
-
   std::vector<Field> common_fields;
   std::vector<Event> events;