tp: defer including prelude into NotifyEof is called

Ensures we can create tables in the prelude.

Change-Id: I9f5027e1cfd8599c7c8a499696807eeb0b4833a4
diff --git a/Android.bp b/Android.bp
index 6f2d315..f724ada 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13618,12 +13618,12 @@
         "src/trace_processor/perfetto_sql/stdlib/linux/perf/spe.sql",
         "src/trace_processor/perfetto_sql/stdlib/linux/threads.sql",
         "src/trace_processor/perfetto_sql/stdlib/pkvm/hypervisor.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/casts.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/tables.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/tables_views.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/trace_bounds.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/views.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/casts.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/slices.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tables_views.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/tables.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/trace_bounds.sql",
         "src/trace_processor/perfetto_sql/stdlib/sched/runnable.sql",
         "src/trace_processor/perfetto_sql/stdlib/sched/states.sql",
         "src/trace_processor/perfetto_sql/stdlib/sched/thread_executing_span.sql",
diff --git a/BUILD b/BUILD
index ef31a26..efe83c8 100644
--- a/BUILD
+++ b/BUILD
@@ -2973,17 +2973,29 @@
     ],
 )
 
+# GN target: //src/trace_processor/perfetto_sql/stdlib/prelude/after_eof:after_eof
+perfetto_filegroup(
+    name = "src_trace_processor_perfetto_sql_stdlib_prelude_after_eof_after_eof",
+    srcs = [
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/casts.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/slices.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tables_views.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql",
+    ],
+)
+
+# GN target: //src/trace_processor/perfetto_sql/stdlib/prelude/before_eof:before_eof
+perfetto_filegroup(
+    name = "src_trace_processor_perfetto_sql_stdlib_prelude_before_eof_before_eof",
+    srcs = [
+        "src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/tables.sql",
+        "src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/trace_bounds.sql",
+    ],
+)
+
 # GN target: //src/trace_processor/perfetto_sql/stdlib/prelude:prelude
 perfetto_filegroup(
     name = "src_trace_processor_perfetto_sql_stdlib_prelude_prelude",
-    srcs = [
-        "src/trace_processor/perfetto_sql/stdlib/prelude/casts.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/tables.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/tables_views.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/trace_bounds.sql",
-        "src/trace_processor/perfetto_sql/stdlib/prelude/views.sql",
-    ],
 )
 
 # GN target: //src/trace_processor/perfetto_sql/stdlib/sched:sched
@@ -3117,6 +3129,8 @@
         ":src_trace_processor_perfetto_sql_stdlib_linux_memory_memory",
         ":src_trace_processor_perfetto_sql_stdlib_linux_perf_perf",
         ":src_trace_processor_perfetto_sql_stdlib_pkvm_pkvm",
+        ":src_trace_processor_perfetto_sql_stdlib_prelude_after_eof_after_eof",
+        ":src_trace_processor_perfetto_sql_stdlib_prelude_before_eof_before_eof",
         ":src_trace_processor_perfetto_sql_stdlib_prelude_prelude",
         ":src_trace_processor_perfetto_sql_stdlib_sched_sched",
         ":src_trace_processor_perfetto_sql_stdlib_slices_slices",
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/prelude/BUILD.gn
index 446a002..32aba6f 100644
--- a/src/trace_processor/perfetto_sql/stdlib/prelude/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/BUILD.gn
@@ -1,4 +1,4 @@
-# Copyright (C) 2023 The Android Open Source Project
+# Copyright (C) 2024 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.
@@ -15,12 +15,9 @@
 import("../../../../../gn/perfetto_sql.gni")
 
 perfetto_sql_source_set("prelude") {
-  sources = [
-    "casts.sql",
-    "slices.sql",
-    "tables.sql",
-    "tables_views.sql",
-    "trace_bounds.sql",
-    "views.sql",
+  sources = []
+  deps = [
+    "after_eof",
+    "before_eof",
   ]
 }
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/BUILD.gn
new file mode 100644
index 0000000..c564a57
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/BUILD.gn
@@ -0,0 +1,24 @@
+# Copyright (C) 2023 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.
+
+import("../../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("after_eof") {
+  sources = [
+    "casts.sql",
+    "slices.sql",
+    "tables_views.sql",
+    "views.sql",
+  ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/casts.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/casts.sql
similarity index 100%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/casts.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/casts.sql
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/slices.sql
similarity index 95%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/slices.sql
index 48f7132..f68f872 100644
--- a/src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/slices.sql
@@ -13,7 +13,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE prelude.views;
+INCLUDE PERFETTO MODULE prelude.after_eof.views;
 
 -- Given two slice ids, returns whether the first is an ancestor of the second.
 CREATE PERFETTO FUNCTION slice_is_ancestor(
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/tables_views.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tables_views.sql
similarity index 99%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/tables_views.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tables_views.sql
index 9ab309c..acd9cdb 100644
--- a/src/trace_processor/perfetto_sql/stdlib/prelude/tables_views.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tables_views.sql
@@ -13,7 +13,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE prelude.views;
+INCLUDE PERFETTO MODULE prelude.after_eof.views;
 
 -- Tracks are a fundamental concept in trace processor and represent a
 -- "timeline" for events of the same type and with the same context. See
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/views.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql
similarity index 99%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/views.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql
index fa1eece..8f3a90f 100644
--- a/src/trace_processor/perfetto_sql/stdlib/prelude/views.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/views.sql
@@ -13,7 +13,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE prelude.casts;
+INCLUDE PERFETTO MODULE prelude.after_eof.casts;
 
 -- Alias of the `counter` table.
 CREATE PERFETTO VIEW counters(
@@ -146,7 +146,7 @@
   -- Alias of `slice.thread_instruction_delta`.
   thread_instruction_delta LONG,
   -- Alias of `slice.cat`.
-  cat LONG,
+  cat STRING,
   -- Alias of `slice.slice_id`.
   slice_id LONG
 ) AS
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/BUILD.gn
new file mode 100644
index 0000000..ebe56f9
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright (C) 2023 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.
+
+import("../../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("before_eof") {
+  sources = [
+    "tables.sql",
+    "trace_bounds.sql",
+  ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/tables.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/tables.sql
similarity index 100%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/tables.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/tables.sql
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/trace_bounds.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/trace_bounds.sql
similarity index 100%
rename from src/trace_processor/perfetto_sql/stdlib/prelude/trace_bounds.sql
rename to src/trace_processor/perfetto_sql/stdlib/prelude/before_eof/trace_bounds.sql
diff --git a/src/trace_processor/tables/track_tables.py b/src/trace_processor/tables/track_tables.py
index 41e412a..5d88aaa 100644
--- a/src/trace_processor/tables/track_tables.py
+++ b/src/trace_processor/tables/track_tables.py
@@ -198,6 +198,7 @@
         doc='Tracks containing gpu_work_period events.',
         group='Tracks',
         columns={
+            'uid': 'The uid associated with this track.',
             'gpu_id': 'The identifier for the GPU.',
         }))
 
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index d2d53f3..8397d8d 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -124,8 +124,9 @@
       if (!status.ok())
         return status;
     }
-    return processor_->NotifyEndOfFile();
+    return NotifyEndOfFile();
   }
+  base::Status NotifyEndOfFile() { return processor_->NotifyEndOfFile(); }
 
   Iterator Query(const std::string& query) {
     return processor_->ExecuteQuery(query);
@@ -289,6 +290,8 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, ComputeMetricsFormattedExtension) {
+  ASSERT_OK(NotifyEndOfFile());
+
   std::string metric_output;
   base::Status status = Processor()->ComputeMetricText(
       std::vector<std::string>{"test_chrome_metric"},
@@ -302,11 +305,12 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, ComputeMetricsFormattedNoExtension) {
+  ASSERT_OK(NotifyEndOfFile());
+
   std::string metric_output;
-  base::Status status = Processor()->ComputeMetricText(
+  ASSERT_OK(Processor()->ComputeMetricText(
       std::vector<std::string>{"trace_metadata"},
-      TraceProcessor::MetricResultFormat::kProtoText, &metric_output);
-  ASSERT_TRUE(status.ok());
+      TraceProcessor::MetricResultFormat::kProtoText, &metric_output));
   // Check that metric result starts with trace_metadata field. Since this is
   // not an extension field, the field name is not fully qualified.
   ASSERT_TRUE(metric_output.rfind("trace_metadata {") == 0);
@@ -410,13 +414,13 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesInvariant) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   uint64_t first_restore = RestoreInitialTables();
   ASSERT_EQ(RestoreInitialTables(), first_restore);
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesPerfettoSql) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -465,7 +469,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesStandardSqlite) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -491,7 +495,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesModules) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -511,7 +515,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesSpanJoin) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -550,7 +554,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesWithClause) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -567,7 +571,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesIndex) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   RestoreInitialTables();
 
   for (int repeat = 0; repeat < 3; repeat++) {
@@ -605,7 +609,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreInitialTablesDependents) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   {
     auto it = Query("create perfetto table foo as select 1 as x");
     ASSERT_FALSE(it.Next());
@@ -625,7 +629,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreDependentFunction) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   {
     auto it =
         Query("create perfetto function foo0() returns INT as select 1 as x");
@@ -645,7 +649,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, RestoreDependentTableFunction) {
-  ASSERT_OK(Processor()->NotifyEndOfFile());
+  ASSERT_OK(NotifyEndOfFile());
   {
     auto it = Query(
         "create perfetto function foo0() returns TABLE(x INT) "
@@ -735,6 +739,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, ErrorMessageExecuteQuery) {
+  ASSERT_OK(NotifyEndOfFile());
   auto it = Query("select t from slice");
   ASSERT_FALSE(it.Next());
   ASSERT_FALSE(it.Status().ok());
@@ -748,6 +753,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, ErrorMessageMetricFile) {
+  ASSERT_OK(NotifyEndOfFile());
   ASSERT_TRUE(
       Processor()->RegisterMetric("foo/bar.sql", "select t from slice").ok());
 
@@ -767,6 +773,7 @@
 }
 
 TEST_F(TraceProcessorIntegrationTest, ErrorMessageModule) {
+  ASSERT_OK(NotifyEndOfFile());
   SqlPackage module;
   module.name = "foo";
   module.modules.push_back(std::make_pair("foo.bar", "select t from slice"));
@@ -819,7 +826,7 @@
                    ->Parse(TraceBlobView(
                        TraceBlob::CopyFrom(kBadData, sizeof(kBadData))))
                    .ok());
-  Processor()->NotifyEndOfFile();
+  NotifyEndOfFile();
 }
 
 TEST_F(TraceProcessorIntegrationTest, NoNotifyEndOfFileCalled) {
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index c3c7fcb..e74df47 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -485,8 +485,7 @@
   RegisterAdditionalModules(&context_);
   InitPerfettoSqlEngine();
 
-  sqlite_objects_post_constructor_initialization_ =
-      engine_->SqliteRegisteredObjectCount();
+  sqlite_objects_post_prelude_ = engine_->SqliteRegisteredObjectCount();
 
   bool skip_all_sql = std::find(config_.skip_builtin_metric_paths.begin(),
                                 config_.skip_builtin_metric_paths.end(),
@@ -552,6 +551,9 @@
                    GetTraceTimestampBoundsNs(*context_.storage));
 
   TraceProcessorStorageImpl::DestroyContext();
+
+  IncludeAfterEofPrelude();
+  sqlite_objects_post_prelude_ = engine_->SqliteRegisteredObjectCount();
   return base::OkStatus();
 }
 
@@ -559,15 +561,13 @@
   // We should always have at least as many objects now as we did in the
   // constructor.
   uint64_t registered_count_before = engine_->SqliteRegisteredObjectCount();
-  PERFETTO_CHECK(registered_count_before >=
-                 sqlite_objects_post_constructor_initialization_);
+  PERFETTO_CHECK(registered_count_before >= sqlite_objects_post_prelude_);
 
   InitPerfettoSqlEngine();
 
   // The registered count should now be the same as it was in the constructor.
   uint64_t registered_count_after = engine_->SqliteRegisteredObjectCount();
-  PERFETTO_CHECK(registered_count_after ==
-                 sqlite_objects_post_constructor_initialization_);
+  PERFETTO_CHECK(registered_count_after == sqlite_objects_post_prelude_);
   return static_cast<size_t>(registered_count_before - registered_count_after);
 }
 
@@ -1082,13 +1082,9 @@
   }
 
   // Import prelude package.
-  {
-    auto result = engine_->Execute(SqlSource::FromTraceProcessorImplementation(
-        "INCLUDE PERFETTO MODULE prelude.*"));
-    if (!result.status().ok()) {
-      PERFETTO_FATAL("Failed to import prelude: %s",
-                     result.status().c_message());
-    }
+  IncludeBeforeEofPrelude();
+  if (notify_eof_called_) {
+    IncludeAfterEofPrelude();
   }
 
   for (const auto& metric : sql_metrics_) {
@@ -1106,6 +1102,22 @@
   }
 }
 
+void TraceProcessorImpl::IncludeBeforeEofPrelude() {
+  auto result = engine_->Execute(SqlSource::FromTraceProcessorImplementation(
+      "INCLUDE PERFETTO MODULE prelude.before_eof.*"));
+  if (!result.status().ok()) {
+    PERFETTO_FATAL("Failed to import prelude: %s", result.status().c_message());
+  }
+}
+
+void TraceProcessorImpl::IncludeAfterEofPrelude() {
+  auto result = engine_->Execute(SqlSource::FromTraceProcessorImplementation(
+      "INCLUDE PERFETTO MODULE prelude.after_eof.*"));
+  if (!result.status().ok()) {
+    PERFETTO_FATAL("Failed to import prelude: %s", result.status().c_message());
+  }
+}
+
 namespace {
 
 class StringInterner {
diff --git a/src/trace_processor/trace_processor_impl.h b/src/trace_processor/trace_processor_impl.h
index 8f95290..3c86da0 100644
--- a/src/trace_processor/trace_processor_impl.h
+++ b/src/trace_processor/trace_processor_impl.h
@@ -119,6 +119,8 @@
   bool IsRootMetricField(const std::string& metric_name);
 
   void InitPerfettoSqlEngine();
+  void IncludeBeforeEofPrelude();
+  void IncludeAfterEofPrelude();
 
   const Config config_;
   std::unique_ptr<PerfettoSqlEngine> engine_;
@@ -138,8 +140,8 @@
   // to prevent single-flow compiler optimizations in ExecuteQuery().
   std::atomic<bool> query_interrupted_{false};
 
-  // Track the number of objects registered with SQLite after the constructor.
-  uint64_t sqlite_objects_post_constructor_initialization_ = 0;
+  // Track the number of objects registered with SQLite post prelude.
+  uint64_t sqlite_objects_post_prelude_ = 0;
 
   std::string current_trace_name_;
   uint64_t bytes_parsed_ = 0;
diff --git a/src/traceconv/trace_to_pprof_integrationtest.cc b/src/traceconv/trace_to_pprof_integrationtest.cc
index b852854..bff3e26 100644
--- a/src/traceconv/trace_to_pprof_integrationtest.cc
+++ b/src/traceconv/trace_to_pprof_integrationtest.cc
@@ -14,9 +14,14 @@
  * limitations under the License.
  */
 
+#include <unistd.h>
 #include "test/gtest_and_gmock.h"
 
 #include <fstream>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/file_utils.h"
@@ -30,7 +35,7 @@
 
 using testing::Contains;
 
-pprof::PprofProfileReader convert_trace_to_pprof(
+pprof::PprofProfileReader ConvertTraceToPprof(
     const std::string& input_file_name) {
   const std::string trace_file = base::GetTestDataPath(input_file_name);
   std::ifstream file_istream;
@@ -84,8 +89,7 @@
 };
 
 TEST_F(TraceToPprofTest, SummaryValues) {
-  const auto pprof =
-      convert_trace_to_pprof("test/data/heap_graph/heap_graph.pb");
+  const auto pprof = ConvertTraceToPprof("test/data/heap_graph/heap_graph.pb");
 
   EXPECT_EQ(pprof.get_samples_value_sum("Foo", "Total allocation count"), 1);
   EXPECT_EQ(pprof.get_samples_value_sum("Foo", "Total allocation size"), 32);
@@ -100,7 +104,7 @@
 
 TEST_F(TraceToPprofTest, TreeLocationFunctionNames) {
   const auto pprof =
-      convert_trace_to_pprof("test/data/heap_graph/heap_graph_branching.pb");
+      ConvertTraceToPprof("test/data/heap_graph/heap_graph_branching.pb");
 
   EXPECT_THAT(get_samples_function_names(pprof, "LeftChild0"),
               Contains(std::vector<std::string>{"LeftChild0",
@@ -118,7 +122,7 @@
 
 TEST_F(TraceToPprofTest, HugeSizes) {
   const auto pprof =
-      convert_trace_to_pprof("test/data/heap_graph/heap_graph_huge_size.pb");
+      ConvertTraceToPprof("test/data/heap_graph/heap_graph_huge_size.pb");
   EXPECT_EQ(pprof.get_samples_value_sum("dev.perfetto.BigStuff",
                                         "Total allocation size"),
             3000000000);
@@ -138,7 +142,7 @@
 
 TEST_F(TraceToPprofRealTraceTest, AllocationCountForClass) {
   const auto pprof =
-      convert_trace_to_pprof("test/data/system-server-heap-graph-new.pftrace");
+      ConvertTraceToPprof("test/data/system-server-heap-graph-new.pftrace");
 
   EXPECT_EQ(pprof.get_samples_value_sum(
                 "android.content.pm.parsing.component.ParsedActivity",
diff --git a/src/traceconv/trace_to_profile.cc b/src/traceconv/trace_to_profile.cc
index b7676be..96b97fd 100644
--- a/src/traceconv/trace_to_profile.cc
+++ b/src/traceconv/trace_to_profile.cc
@@ -110,12 +110,11 @@
   tp->Flush();
   MaybeSymbolize(tp.get());
   MaybeDeobfuscate(tp.get());
-
-  TraceToPprof(tp.get(), &profiles, conversion_mode, conversion_flags, pid,
-               timestamps);
   if (auto status = tp->NotifyEndOfFile(); !status.ok()) {
     return -1;
   }
+  TraceToPprof(tp.get(), &profiles, conversion_mode, conversion_flags, pid,
+               timestamps);
   if (profiles.empty()) {
     return 0;
   }