Merge "processor: Retain original event ids during export + always export args"
diff --git a/src/trace_processor/export_json.cc b/src/trace_processor/export_json.cc
index 43e7979..34181a5 100644
--- a/src/trace_processor/export_json.cc
+++ b/src/trace_processor/export_json.cc
@@ -428,17 +428,13 @@
     event["cat"] = GetNonNullString(storage, slices.categories()[i]);
     event["name"] = GetNonNullString(storage, slices.names()[i]);
     event["pid"] = 0;
-    const Json::Value& args = args_builder.GetArgs(slices.arg_set_ids()[i]);
-    if (!args.empty()) {
-      event["args"] = args;  // Makes a copy of |args|.
 
-      if (event["args"].isMember(kLegacyEventArgsKey)) {
-        ConvertLegacyFlowEventArgs(event["args"][kLegacyEventArgsKey], &event);
+    event["args"] =
+        args_builder.GetArgs(slices.arg_set_ids()[i]);  // Makes a copy.
+    if (event["args"].isMember(kLegacyEventArgsKey)) {
+      ConvertLegacyFlowEventArgs(event["args"][kLegacyEventArgsKey], &event);
 
-        event["args"].removeMember(kLegacyEventArgsKey);
-        if (event["args"].empty())
-          event.removeMember("args");
-      }
+      event["args"].removeMember(kLegacyEventArgsKey);
     }
 
     // To prevent duplicate export of slices, only export slices on descriptor
@@ -546,12 +542,35 @@
       // Async event slice.
       auto opt_process_row =
           process_track.id().IndexOf(SqlValue::Long(track_id));
-      if (opt_process_row) {
+      if (legacy_chrome_track) {
+        // Legacy async tracks are always process-associated.
+        PERFETTO_DCHECK(opt_process_row);
         uint32_t upid = process_track.upid()[*opt_process_row];
-        event["id2"]["local"] = PrintUint64(track_id);
         event["pid"] = storage->GetProcess(upid).pid;
+
+        // Preserve original event IDs for legacy tracks. This is so that e.g.
+        // memory dump IDs show up correctly in the JSON trace.
+        PERFETTO_DCHECK(track_args.isMember("source_id"));
+        PERFETTO_DCHECK(track_args.isMember("source_id_is_process_scoped"));
+        PERFETTO_DCHECK(track_args.isMember("source_scope"));
+        uint64_t source_id =
+            static_cast<uint64_t>(track_args["source_id"].asInt64());
+        std::string source_scope = track_args["source_scope"].asString();
+        bool source_id_is_process_scoped =
+            track_args["source_id_is_process_scoped"].asBool();
+        if (source_id_is_process_scoped) {
+          event["id2"]["local"] = PrintUint64(source_id);
+        } else {
+          event["id2"]["global"] = PrintUint64(source_id);
+        }
       } else {
-        event["id2"]["global"] = PrintUint64(track_id);
+        if (opt_process_row) {
+          uint32_t upid = process_track.upid()[*opt_process_row];
+          event["id2"]["local"] = PrintUint64(track_id);
+          event["pid"] = storage->GetProcess(upid).pid;
+        } else {
+          event["id2"]["global"] = PrintUint64(track_id);
+        }
       }
 
       if (thread_ts_ns > 0) {
@@ -676,8 +695,6 @@
   ConvertLegacyFlowEventArgs(legacy_args, &event);
 
   event["args"].removeMember(kLegacyEventArgsKey);
-  if (event["args"].empty())
-    event.removeMember("args");
 
   return event;
 }
diff --git a/src/trace_processor/export_json_unittest.cc b/src/trace_processor/export_json_unittest.cc
index a65f894..679ef22 100644
--- a/src/trace_processor/export_json_unittest.cc
+++ b/src/trace_processor/export_json_unittest.cc
@@ -146,7 +146,8 @@
   EXPECT_EQ(event["tid"].asUInt(), kThreadID);
   EXPECT_EQ(event["cat"].asString(), kCategory);
   EXPECT_EQ(event["name"].asString(), kName);
-  EXPECT_FALSE(event.isMember("args"));
+  EXPECT_TRUE(event["args"].isObject());
+  EXPECT_EQ(event["args"].size(), 0u);
 }
 
 TEST_F(ExportJsonTest, StorageWithOneUnfinishedSlice) {
@@ -193,7 +194,8 @@
   EXPECT_EQ(event["tid"].asUInt(), kThreadID);
   EXPECT_EQ(event["cat"].asString(), kCategory);
   EXPECT_EQ(event["name"].asString(), kName);
-  EXPECT_FALSE(event.isMember("args"));
+  EXPECT_TRUE(event["args"].isObject());
+  EXPECT_EQ(event["args"].size(), 0u);
 }
 
 TEST_F(ExportJsonTest, StorageWithThreadName) {
@@ -819,7 +821,7 @@
   EXPECT_EQ(begin_event["ph"].asString(), "b");
   EXPECT_EQ(begin_event["ts"].asInt64(), kTimestamp / 1000);
   EXPECT_EQ(begin_event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(begin_event["cat"].asString(), kCategory);
   EXPECT_EQ(begin_event["name"].asString(), kName);
   EXPECT_EQ(begin_event["args"][kArgName].asInt(), kArgValue);
@@ -830,7 +832,7 @@
   EXPECT_EQ(end_event["ph"].asString(), "e");
   EXPECT_EQ(end_event["ts"].asInt64(), (kTimestamp + kDuration) / 1000);
   EXPECT_EQ(end_event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(end_event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(end_event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(end_event["cat"].asString(), kCategory);
   EXPECT_EQ(end_event["name"].asString(), kName);
   EXPECT_FALSE(end_event.isMember("args"));
@@ -878,7 +880,7 @@
   EXPECT_EQ(begin_event["tts"].asInt64(), kThreadTimestamp / 1000);
   EXPECT_EQ(begin_event["use_async_tts"].asInt(), 1);
   EXPECT_EQ(begin_event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(begin_event["cat"].asString(), kCategory);
   EXPECT_EQ(begin_event["name"].asString(), kName);
 
@@ -889,7 +891,7 @@
             (kThreadTimestamp + kThreadDuration) / 1000);
   EXPECT_EQ(end_event["use_async_tts"].asInt(), 1);
   EXPECT_EQ(end_event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(end_event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(end_event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(end_event["cat"].asString(), kCategory);
   EXPECT_EQ(end_event["name"].asString(), kName);
 }
@@ -934,7 +936,7 @@
   EXPECT_EQ(begin_event["tts"].asInt64(), kThreadTimestamp / 1000);
   EXPECT_EQ(begin_event["use_async_tts"].asInt(), 1);
   EXPECT_EQ(begin_event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(begin_event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(begin_event["cat"].asString(), kCategory);
   EXPECT_EQ(begin_event["name"].asString(), kName);
 }
@@ -982,7 +984,7 @@
   EXPECT_EQ(event["ph"].asString(), "n");
   EXPECT_EQ(event["ts"].asInt64(), kTimestamp / 1000);
   EXPECT_EQ(event["pid"].asInt64(), kProcessID);
-  EXPECT_EQ(event["id2"]["local"].asString(), "0x0");
+  EXPECT_EQ(event["id2"]["local"].asString(), "0xeb");
   EXPECT_EQ(event["cat"].asString(), kCategory);
   EXPECT_EQ(event["name"].asString(), kName);
   EXPECT_EQ(event["args"][kArgName].asInt(), kArgValue);
diff --git a/src/trace_processor/track_tracker.cc b/src/trace_processor/track_tracker.cc
index f04bd34..dd57e8b 100644
--- a/src/trace_processor/track_tracker.cc
+++ b/src/trace_processor/track_tracker.cc
@@ -27,6 +27,8 @@
 TrackTracker::TrackTracker(TraceProcessorContext* context)
     : source_key_(context->storage->InternString("source")),
       source_id_key_(context->storage->InternString("source_id")),
+      source_id_is_process_scoped_key_(
+          context->storage->InternString("source_id_is_process_scoped")),
       source_scope_key_(context->storage->InternString("source_scope")),
       fuchsia_source_(context->storage->InternString("fuchsia")),
       chrome_source_(context->storage->InternString("chrome")),
@@ -106,6 +108,10 @@
                                  Variadic::String(chrome_source_));
   context_->args_tracker->AddArg(row_id, source_id_key_, source_id_key_,
                                  Variadic::Integer(source_id));
+  context_->args_tracker->AddArg(
+      row_id, source_id_is_process_scoped_key_,
+      source_id_is_process_scoped_key_,
+      Variadic::Boolean(source_id_is_process_scoped));
   context_->args_tracker->AddArg(row_id, source_scope_key_, source_scope_key_,
                                  Variadic::String(source_scope));
   return id;
diff --git a/src/trace_processor/track_tracker.h b/src/trace_processor/track_tracker.h
index fd04e63..8d064b4 100644
--- a/src/trace_processor/track_tracker.h
+++ b/src/trace_processor/track_tracker.h
@@ -123,6 +123,7 @@
 
   const StringId source_key_ = 0;
   const StringId source_id_key_ = 0;
+  const StringId source_id_is_process_scoped_key_ = 0;
   const StringId source_scope_key_ = 0;
 
   const StringId fuchsia_source_ = 0;