Merge "perfetto: Fix fuzzer"
diff --git a/.travis.yml b/.travis.yml
index 3e89e9e..69f9cdb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -140,7 +140,7 @@
       for TEST_TARGET in $TEST_TARGETS; do
         "out/dist/$TEST_TARGET"
       done
-      bash -c "out/dist/perfetto_benchmarks --benchmark_filter=\"(\$(out/dist/perfetto_benchmarks  --benchmark_list_tests | sed \"/BM_EndToEnd\/.....*\//d\" | xargs | tr \" \" \"|\"))\""
+      BENCHMARK_FUNCTIONAL_TEST_ONLY=true out/dist/perfetto_benchmarks
       if [[ "$CFG" == *-libfuzzer ]]; then
         # Run a single iteration each to make sure they are not crashing.
         out/dist/end_to_end_shared_memory_fuzzer -runs=1
@@ -152,7 +152,7 @@
       for TEST_TARGET in $TEST_TARGETS; do
         tools/run_android_test out/dist "$TEST_TARGET"
       done
-      tools/run_android_test out/dist "perfetto_benchmarks" "--benchmark_filter=\"(\$(perfetto_benchmarks  --benchmark_list_tests | sed \"/BM_EndToEnd\/.....*\//d\" | xargs | tr \" \" \"|\"))\""
+      tools/run_android_test --env BENCHMARK_FUNCTIONAL_TEST_ONLY=true out/dist "perfetto_benchmarks"
     fi
 
 after_script:
diff --git a/docs/running_perfetto.md b/docs/running_perfetto.md
index ba59432..0763505 100644
--- a/docs/running_perfetto.md
+++ b/docs/running_perfetto.md
@@ -62,7 +62,7 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.ftrace"
+    name: "linux.ftrace"
     target_buffer: 0
     ftrace_config {
       buffer_size_kb: 40 # Kernel ftrace buffer size.
@@ -74,7 +74,7 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.process_stats"
+    name: "linux.process_stats"
     target_buffer: 0
   }
 }
diff --git a/include/perfetto/tracing/core/data_source_config.h b/include/perfetto/tracing/core/data_source_config.h
index 9b41045..c722cbb 100644
--- a/include/perfetto/tracing/core/data_source_config.h
+++ b/include/perfetto/tracing/core/data_source_config.h
@@ -79,6 +79,9 @@
   const ChromeConfig& chrome_config() const { return chrome_config_; }
   ChromeConfig* mutable_chrome_config() { return &chrome_config_; }
 
+  const std::string& legacy_config() const { return legacy_config_; }
+  void set_legacy_config(const std::string& value) { legacy_config_ = value; }
+
   const TestConfig& for_testing() const { return for_testing_; }
   TestConfig* mutable_for_testing() { return &for_testing_; }
 
@@ -88,6 +91,7 @@
   uint32_t trace_duration_ms_ = {};
   FtraceConfig ftrace_config_ = {};
   ChromeConfig chrome_config_ = {};
+  std::string legacy_config_ = {};
   TestConfig for_testing_ = {};
 
   // Allows to preserve unknown protobuf fields for compatibility
diff --git a/include/perfetto/tracing/core/test_config.h b/include/perfetto/tracing/core/test_config.h
index 48f4629..95af155 100644
--- a/include/perfetto/tracing/core/test_config.h
+++ b/include/perfetto/tracing/core/test_config.h
@@ -60,6 +60,11 @@
   uint32_t message_count() const { return message_count_; }
   void set_message_count(uint32_t value) { message_count_ = value; }
 
+  uint32_t max_messages_per_second() const { return max_messages_per_second_; }
+  void set_max_messages_per_second(uint32_t value) {
+    max_messages_per_second_ = value;
+  }
+
   uint32_t seed() const { return seed_; }
   void set_seed(uint32_t value) { seed_ = value; }
 
@@ -68,6 +73,7 @@
 
  private:
   uint32_t message_count_ = {};
+  uint32_t max_messages_per_second_ = {};
   uint32_t seed_ = {};
   uint64_t message_size_ = {};
 
diff --git a/protos/perfetto/config/data_source_config.proto b/protos/perfetto/config/data_source_config.proto
index 3c33a10..07824fe 100644
--- a/protos/perfetto/config/data_source_config.proto
+++ b/protos/perfetto/config/data_source_config.proto
@@ -50,6 +50,15 @@
   optional FtraceConfig ftrace_config = 100;
   optional ChromeConfig chrome_config = 101;
 
+  // This is a fallback mechanism to send a free-form text config to the
+  // producer. In theory this should never be needed. All the code that
+  // is part of the platform (i.e. traced service) is supposed to *not* truncate
+  // the trace config proto and propagate unknown fields. However, if anything
+  // in the pipeline (client or backend) ends up breaking this forward compat
+  // plan, this field will become the escape hatch to allow future data sources
+  // to get some meaningful configuration.
+  optional string legacy_config = 1000;
+
   // This field is only used for testing.
   optional TestConfig for_testing =
       536870911;  // 2^29 - 1, max field id for protos.
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index c302917..e8f5d7b 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -52,6 +52,15 @@
   optional FtraceConfig ftrace_config = 100;
   optional ChromeConfig chrome_config = 101;
 
+  // This is a fallback mechanism to send a free-form text config to the
+  // producer. In theory this should never be needed. All the code that
+  // is part of the platform (i.e. traced service) is supposed to *not* truncate
+  // the trace config proto and propagate unknown fields. However, if anything
+  // in the pipeline (client or backend) ends up breaking this forward compat
+  // plan, this field will become the escape hatch to allow future data sources
+  // to get some meaningful configuration.
+  optional string legacy_config = 1000;
+
   // This field is only used for testing.
   optional TestConfig for_testing =
       536870911;  // 2^29 - 1, max field id for protos.
@@ -85,14 +94,20 @@
   // The number of messages the fake producer should send.
   optional uint32 message_count = 1;
 
+  // The maximum number of messages which should be sent each second.
+  // The actual obserced speed may be lower if the producer is unable to
+  // work fast enough.
+  // If this is zero or unset, the producer will send as fast as possible.
+  optional uint32 max_messages_per_second = 2;
+
   // The seed value for a simple multiplicative congruential pseudo-random
   // number sequence.
-  optional uint32 seed = 2;
+  optional uint32 seed = 3;
 
   // The size of each message in bytes. Should be greater than or equal 5 to
   // account for the number of bytes needed to encode the random number and a
   // null byte for the string.
-  optional uint64 message_size = 3;
+  optional uint64 message_size = 4;
 }
 
 // End of protos/perfetto/config/test_config.proto
diff --git a/protos/perfetto/config/test_config.proto b/protos/perfetto/config/test_config.proto
index b679235..8f0045d 100644
--- a/protos/perfetto/config/test_config.proto
+++ b/protos/perfetto/config/test_config.proto
@@ -27,12 +27,18 @@
   // The number of messages the fake producer should send.
   optional uint32 message_count = 1;
 
+  // The maximum number of messages which should be sent each second.
+  // The actual obserced speed may be lower if the producer is unable to
+  // work fast enough.
+  // If this is zero or unset, the producer will send as fast as possible.
+  optional uint32 max_messages_per_second = 2;
+
   // The seed value for a simple multiplicative congruential pseudo-random
   // number sequence.
-  optional uint32 seed = 2;
+  optional uint32 seed = 3;
 
   // The size of each message in bytes. Should be greater than or equal 5 to
   // account for the number of bytes needed to encode the random number and a
   // null byte for the string.
-  optional uint64 message_size = 3;
+  optional uint64 message_size = 4;
 }
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index ac5f8da..5a86919 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -130,7 +130,7 @@
         test_config.add_buffers()->set_size_kb(4096);
         test_config.set_duration_ms(2000);
         auto* ds_config = test_config.add_data_sources()->mutable_config();
-        ds_config->set_name("com.google.perfetto.ftrace");
+        ds_config->set_name("linux.ftrace");
         ds_config->mutable_ftrace_config()->add_ftrace_events("sched_switch");
         ds_config->mutable_ftrace_config()->add_ftrace_events("cpu_idle");
         ds_config->mutable_ftrace_config()->add_ftrace_events("cpu_frequency");
diff --git a/src/process_stats/procfs_utils.cc b/src/process_stats/procfs_utils.cc
index a0a9cbd..98b949e 100644
--- a/src/process_stats/procfs_utils.cc
+++ b/src/process_stats/procfs_utils.cc
@@ -67,7 +67,9 @@
 std::unique_ptr<ProcessInfo> ReadProcessInfo(int pid) {
   ProcessInfo* process = new ProcessInfo();
   process->pid = pid;
-  char cmdline_buf[256];
+  // It's not enough to just null terminate this since cmdline uses null as
+  // the argument seperator:
+  char cmdline_buf[256]{};
   ReadProcString(pid, "cmdline", cmdline_buf, sizeof(cmdline_buf));
   if (cmdline_buf[0] == 0) {
     // Nothing in cmdline_buf so read name from /comm instead.
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index 1a8167c..a18181d 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -40,9 +40,9 @@
 
 uint64_t kInitialConnectionBackoffMs = 100;
 uint64_t kMaxConnectionBackoffMs = 30 * 1000;
-constexpr char kFtraceSourceName[] = "com.google.perfetto.ftrace";
-constexpr char kProcessStatsSourceName[] = "com.google.perfetto.process_stats";
-constexpr char kInodeMapSourceName[] = "com.google.perfetto.inode_file_map";
+constexpr char kFtraceSourceName[] = "linux.ftrace";
+constexpr char kProcessStatsSourceName[] = "linux.process_stats";
+constexpr char kInodeMapSourceName[] = "linux.inode_file_map";
 
 }  // namespace.
 
@@ -239,7 +239,7 @@
   PERFETTO_DCHECK(state_ == kNotConnected);
   state_ = kConnecting;
   endpoint_ = ProducerIPCClient::Connect(
-      socket_name_, this, "com.google.perfetto.traced_probes", task_runner_);
+      socket_name_, this, "perfetto.traced_probes", task_runner_);
 }
 
 void ProbesProducer::IncreaseConnectionBackoff() {
@@ -274,6 +274,15 @@
     const FtraceMetadata& metadata) {
   trace_packet_->Finalize();
 
+  if (ps_source_ && !metadata.pids.empty()) {
+    const auto& pids = metadata.pids;
+    auto weak_ps_source = ps_source_;
+    task_runner_->PostTask([weak_ps_source, pids] {
+      if (weak_ps_source)
+        weak_ps_source->OnPids(pids);
+    });
+  }
+
   if (file_source_ && !metadata.inode_and_device.empty()) {
     auto inodes = metadata.inode_and_device;
     auto weak_file_source = file_source_;
diff --git a/src/traced/probes/process_stats_data_source.cc b/src/traced/probes/process_stats_data_source.cc
index 27f05ba..a1bffd8 100644
--- a/src/traced/probes/process_stats_data_source.cc
+++ b/src/traced/probes/process_stats_data_source.cc
@@ -20,7 +20,6 @@
 
 #include "perfetto/trace/ps/process_tree.pbzero.h"
 #include "perfetto/trace/trace_packet.pbzero.h"
-#include "perfetto/tracing/core/trace_packet.h"
 #include "src/process_stats/file_utils.h"
 #include "src/process_stats/procfs_utils.h"
 
@@ -39,36 +38,51 @@
 }
 
 void ProcessStatsDataSource::WriteAllProcesses() {
-  procfs_utils::ProcessMap processes;
   auto trace_packet = writer_->NewTracePacket();
-  protos::pbzero::ProcessTree* process_tree = trace_packet->set_process_tree();
+  auto* trace_packet_ptr = &*trace_packet;
+  std::set<int32_t>* seen_pids = &seen_pids_;
 
-  file_utils::ForEachPidInProcPath(
-      "/proc", [&processes, process_tree](int pid) {
-        // ForEachPid will list all processes and threads. Here we want to
-        // iterate first only by processes (for which pid == thread group id)
-        if (!processes.count(pid)) {
-          if (procfs_utils::ReadTgid(pid) != pid)
-            return;
-          processes[pid] = procfs_utils::ReadProcessInfo(pid);
-        }
-        ProcessInfo* process = processes[pid].get();
-        procfs_utils::ReadProcessThreads(process);
-        auto* process_writer = process_tree->add_processes();
-        process_writer->set_pid(process->pid);
-        process_writer->set_ppid(process->ppid);
-        for (const auto& field : process->cmdline)
-          process_writer->add_cmdline(field.c_str());
-        for (auto& thread : process->threads) {
-          auto* thread_writer = process_writer->add_threads();
-          thread_writer->set_tid(thread.second.tid);
-          thread_writer->set_name(thread.second.name);
-        }
-      });
+  file_utils::ForEachPidInProcPath("/proc",
+                                   [trace_packet_ptr, seen_pids](int pid) {
+                                     // ForEachPid will list all processes and
+                                     // threads. Here we want to iterate first
+                                     // only by processes (for which pid ==
+                                     // thread group id)
+                                     if (procfs_utils::ReadTgid(pid) != pid)
+                                       return;
+
+                                     WriteProcess(pid, trace_packet_ptr);
+                                     seen_pids->insert(pid);
+                                   });
 }
 
 void ProcessStatsDataSource::OnPids(const std::vector<int32_t>& pids) {
-  PERFETTO_DLOG("Saw FtraceBundle with %zu pids.", pids.size());
+  auto trace_packet = writer_->NewTracePacket();
+  for (int32_t pid : pids) {
+    auto it_and_inserted = seen_pids_.emplace(pid);
+    if (it_and_inserted.second)
+      WriteProcess(pid, &*trace_packet);
+  }
+}
+
+// static
+void ProcessStatsDataSource::WriteProcess(
+    int32_t pid,
+    protos::pbzero::TracePacket* trace_packet) {
+  auto* process_tree = trace_packet->set_process_tree();
+
+  std::unique_ptr<ProcessInfo> process = procfs_utils::ReadProcessInfo(pid);
+  procfs_utils::ReadProcessThreads(process.get());
+  auto* process_writer = process_tree->add_processes();
+  process_writer->set_pid(process->pid);
+  process_writer->set_ppid(process->ppid);
+  for (const auto& field : process->cmdline)
+    process_writer->add_cmdline(field.c_str());
+  for (auto& thread : process->threads) {
+    auto* thread_writer = process_writer->add_threads();
+    thread_writer->set_tid(thread.second.tid);
+    thread_writer->set_name(thread.second.name);
+  }
 }
 
 }  // namespace perfetto
diff --git a/src/traced/probes/process_stats_data_source.h b/src/traced/probes/process_stats_data_source.h
index 2b691ab..f134bff 100644
--- a/src/traced/probes/process_stats_data_source.h
+++ b/src/traced/probes/process_stats_data_source.h
@@ -18,6 +18,7 @@
 #define SRC_TRACED_PROBES_PROCESS_STATS_DATA_SOURCE_H_
 
 #include <memory>
+#include <set>
 #include <vector>
 
 #include "perfetto/base/weak_ptr.h"
@@ -37,11 +38,15 @@
   void OnPids(const std::vector<int32_t>& pids);
 
  private:
+  static void WriteProcess(int32_t pid, protos::pbzero::TracePacket*);
+
   ProcessStatsDataSource(const ProcessStatsDataSource&) = delete;
   ProcessStatsDataSource& operator=(const ProcessStatsDataSource&) = delete;
 
   const TracingSessionID session_id_;
   std::unique_ptr<TraceWriter> writer_;
+  // TODO(b/76663469): Optimization: use a bitmap.
+  std::set<int32_t> seen_pids_;
   base::WeakPtrFactory<ProcessStatsDataSource> weak_factory_;  // Keep last.
 };
 
diff --git a/src/tracing/core/data_source_config.cc b/src/tracing/core/data_source_config.cc
index 622eb4c..d4f0fc1 100644
--- a/src/tracing/core/data_source_config.cc
+++ b/src/tracing/core/data_source_config.cc
@@ -60,6 +60,10 @@
 
   chrome_config_.FromProto(proto.chrome_config());
 
+  static_assert(sizeof(legacy_config_) == sizeof(proto.legacy_config()),
+                "size mismatch");
+  legacy_config_ = static_cast<decltype(legacy_config_)>(proto.legacy_config());
+
   for_testing_.FromProto(proto.for_testing());
   unknown_fields_ = proto.unknown_fields();
 }
@@ -86,6 +90,11 @@
 
   chrome_config_.ToProto(proto->mutable_chrome_config());
 
+  static_assert(sizeof(legacy_config_) == sizeof(proto->legacy_config()),
+                "size mismatch");
+  proto->set_legacy_config(
+      static_cast<decltype(proto->legacy_config())>(legacy_config_));
+
   for_testing_.ToProto(proto->mutable_for_testing());
   *(proto->mutable_unknown_fields()) = unknown_fields_;
 }
diff --git a/src/tracing/core/service_impl.cc b/src/tracing/core/service_impl.cc
index a7d4edb..d7ab856 100644
--- a/src/tracing/core/service_impl.cc
+++ b/src/tracing/core/service_impl.cc
@@ -341,7 +341,7 @@
           if (weak_this)
             weak_this->ReadBuffers(tsid, nullptr);
         },
-        tracing_session->next_write_period_ms());
+        tracing_session->delay_to_next_write_period_ms());
   }
 
   tracing_session->tracing_enabled = true;
@@ -575,7 +575,7 @@
           if (weak_this)
             weak_this->ReadBuffers(tsid, nullptr);
         },
-        tracing_session->next_write_period_ms());
+        tracing_session->delay_to_next_write_period_ms());
     return;
   }  // if (tracing_session->write_into_file)
 
diff --git a/src/tracing/core/service_impl.h b/src/tracing/core/service_impl.h
index ba74bb5..baf9f73 100644
--- a/src/tracing/core/service_impl.h
+++ b/src/tracing/core/service_impl.h
@@ -190,10 +190,10 @@
 
     size_t num_buffers() const { return buffers_index.size(); }
 
-    int next_write_period_ms() const {
-      PERFETTO_DCHECK(write_period_ms);
-      // TODO(primiano): this will drift. Synchronize % period so it aligns.
-      return write_period_ms;
+    int delay_to_next_write_period_ms() const {
+      PERFETTO_DCHECK(write_period_ms > 0);
+      return write_period_ms -
+             (base::GetWallTimeMs().count() % write_period_ms);
     }
 
     // The consumer that started the session.
diff --git a/src/tracing/core/test_config.cc b/src/tracing/core/test_config.cc
index e352ec3..d58cbce 100644
--- a/src/tracing/core/test_config.cc
+++ b/src/tracing/core/test_config.cc
@@ -43,6 +43,12 @@
                 "size mismatch");
   message_count_ = static_cast<decltype(message_count_)>(proto.message_count());
 
+  static_assert(sizeof(max_messages_per_second_) ==
+                    sizeof(proto.max_messages_per_second()),
+                "size mismatch");
+  max_messages_per_second_ = static_cast<decltype(max_messages_per_second_)>(
+      proto.max_messages_per_second());
+
   static_assert(sizeof(seed_) == sizeof(proto.seed()), "size mismatch");
   seed_ = static_cast<decltype(seed_)>(proto.seed());
 
@@ -60,6 +66,13 @@
   proto->set_message_count(
       static_cast<decltype(proto->message_count())>(message_count_));
 
+  static_assert(sizeof(max_messages_per_second_) ==
+                    sizeof(proto->max_messages_per_second()),
+                "size mismatch");
+  proto->set_max_messages_per_second(
+      static_cast<decltype(proto->max_messages_per_second())>(
+          max_messages_per_second_));
+
   static_assert(sizeof(seed_) == sizeof(proto->seed()), "size mismatch");
   proto->set_seed(static_cast<decltype(proto->seed())>(seed_));
 
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index c56b7a7..0f8dba6 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -93,7 +93,7 @@
 
     // Create and connect a Producer.
     producer_endpoint_ = ProducerIPCClient::Connect(
-        kProducerSockName, &producer_, "com.google.perfetto.mock_producer",
+        kProducerSockName, &producer_, "perfetto.mock_producer",
         task_runner_.get());
     auto on_producer_connect =
         task_runner_->CreateCheckpoint("on_producer_connect");
diff --git a/test/configs/BUILD.gn b/test/configs/BUILD.gn
index 3923c02..485d4f6 100644
--- a/test/configs/BUILD.gn
+++ b/test/configs/BUILD.gn
@@ -27,6 +27,7 @@
       "atrace.cfg",
       "ftrace.cfg",
       "long_trace.cfg",
+      "processes.cfg",
     ]
 
     outputs = [
diff --git a/test/configs/atrace.cfg b/test/configs/atrace.cfg
index 9267238..1362a20 100644
--- a/test/configs/atrace.cfg
+++ b/test/configs/atrace.cfg
@@ -6,7 +6,7 @@
 # TODO(hjd): Add some atrace config here.
 data_sources {
   config {
-    name: "com.google.perfetto.ftrace"
+    name: "linux.ftrace"
     target_buffer: 0
     ftrace_config {
       atrace_categories: "input"
diff --git a/test/configs/ftrace.cfg b/test/configs/ftrace.cfg
index 2bb2810..65ea849 100644
--- a/test/configs/ftrace.cfg
+++ b/test/configs/ftrace.cfg
@@ -5,7 +5,7 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.ftrace"
+    name: "linux.ftrace"
     target_buffer: 0
     ftrace_config {
       buffer_size_kb: 40 # 4 (page size) * 10
@@ -245,20 +245,20 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.process_stats"
+    name: "linux.process_stats"
     target_buffer: 0
   }
 }
 
 data_sources {
   config {
-    name: "com.google.perfetto.inode_file_map"
+    name: "linux.inode_file_map"
     target_buffer: 0
   }
 }
 
 producers {
-  producer_name: "com.google.perfetto.traced_probes"
+  producer_name: "perfetto.traced_probes"
   shm_size_kb: 4096
   page_size_kb: 4
 }
diff --git a/test/configs/long_trace.cfg b/test/configs/long_trace.cfg
index ee62800..e81ecab 100644
--- a/test/configs/long_trace.cfg
+++ b/test/configs/long_trace.cfg
@@ -10,7 +10,7 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.ftrace"
+    name: "linux.ftrace"
     target_buffer: 1
     ftrace_config {
       buffer_size_kb: 40 # 4 (page size) * 10
@@ -141,20 +141,20 @@
 
 data_sources {
   config {
-    name: "com.google.perfetto.process_stats"
+    name: "linux.process_stats"
     target_buffer: 0
   }
 }
 
 data_sources {
   config {
-    name: "com.google.perfetto.inode_file_map"
+    name: "linux.inode_file_map"
     target_buffer: 0
   }
 }
 
 producers {
-  producer_name: "com.google.perfetto.traced_probes"
+  producer_name: "perfetto.traced_probes"
   shm_size_kb: 4096
   page_size_kb: 4
 }
diff --git a/test/configs/processes.cfg b/test/configs/processes.cfg
new file mode 100644
index 0000000..f8c24b8
--- /dev/null
+++ b/test/configs/processes.cfg
@@ -0,0 +1,57 @@
+buffers {
+  size_kb: 100024
+  fill_policy: RING_BUFFER
+}
+
+data_sources {
+  config {
+    name: "com.google.perfetto.ftrace"
+    target_buffer: 0
+    ftrace_config {
+      buffer_size_kb: 40 # 4 (page size) * 10
+      drain_period_ms: 200
+      ftrace_events: "sched_process_exec"
+      ftrace_events: "sched_process_exit"
+      ftrace_events: "sched_process_fork"
+      ftrace_events: "sched_process_free"
+      ftrace_events: "sched_process_hang"
+      ftrace_events: "sched_process_wait"
+      ftrace_events: "sched_wakeup_new"
+      ftrace_events: "sched_wakeup"
+      ftrace_events: "sched_waking"
+      ftrace_events: "smbus_read"
+      ftrace_events: "smbus_reply"
+      ftrace_events: "smbus_result"
+      ftrace_events: "smbus_write"
+      ftrace_events: "softirq_entry"
+      ftrace_events: "softirq_exit"
+      ftrace_events: "softirq_raise"
+      ftrace_events: "suspend_resume"
+      ftrace_events: "sync_pt"
+      ftrace_events: "sync_timeline"
+      ftrace_events: "sync_wait"
+      ftrace_events: "task_newtask"
+      ftrace_events: "task_rename"
+      ftrace_events: "tracing_mark_write"
+      ftrace_events: "workqueue_activate_work"
+      ftrace_events: "workqueue_execute_end"
+      ftrace_events: "workqueue_execute_start"
+      ftrace_events: "workqueue_queue_work"
+    }
+  }
+}
+
+data_sources {
+  config {
+    name: "com.google.perfetto.process_stats"
+    target_buffer: 0
+  }
+}
+
+producers {
+  producer_name: "com.google.perfetto.traced_probes"
+  shm_size_kb: 4096
+  page_size_kb: 4
+}
+
+duration_ms: 10000
diff --git a/test/end_to_end_benchmark.cc b/test/end_to_end_benchmark.cc
index 57f9cae..8c3d2fb 100644
--- a/test/end_to_end_benchmark.cc
+++ b/test/end_to_end_benchmark.cc
@@ -29,6 +29,8 @@
 
 namespace perfetto {
 
+namespace {
+
 // If we're building on Android and starting the daemons ourselves,
 // create the sockets in a world-writable location.
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
@@ -40,7 +42,11 @@
 #define TEST_CONSUMER_SOCK_NAME PERFETTO_CONSUMER_SOCK_NAME
 #endif
 
-static void BM_EndToEnd(benchmark::State& state) {
+bool IsBenchmarkFunctionalOnly() {
+  return getenv("BENCHMARK_FUNCTIONAL_TEST_ONLY") != nullptr;
+}
+
+void BenchmarkCommon(benchmark::State& state) {
   base::TestTaskRunner task_runner;
 
 #if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS)
@@ -56,10 +62,13 @@
   };
   std::unique_ptr<FakeProducerDelegate> producer_delegate(
       new FakeProducerDelegate(TEST_PRODUCER_SOCK_NAME,
-                               posted_on_producer_enabled));
+                               std::move(posted_on_producer_enabled)));
   FakeProducerDelegate* producer_delegate_cached = producer_delegate.get();
   producer_thread.Start(std::move(producer_delegate));
 
+  // Once conneced, we can retrieve the inner producer.
+  FakeProducer* producer = producer_delegate_cached->producer();
+
   // Setup the TraceConfig for the consumer.
   TraceConfig trace_config;
   trace_config.add_buffers()->set_size_kb(512);
@@ -71,13 +80,19 @@
 
   // The parameters for the producer.
   static constexpr uint32_t kRandomSeed = 42;
-  uint32_t message_count = state.range(0);
-  uint32_t message_size = state.range(1);
+  size_t message_count = state.range(0);
+  size_t message_bytes = state.range(1);
+  size_t mb_per_s = state.range(2);
+
+  size_t messages_per_s = mb_per_s * 1024 * 1024 / message_bytes;
+  size_t time_for_messages_ms =
+      10000 + (messages_per_s == 0 ? 0 : message_count * 1000 / messages_per_s);
 
   // Setup the test to use a random number generator.
   ds_config->mutable_for_testing()->set_seed(kRandomSeed);
   ds_config->mutable_for_testing()->set_message_count(message_count);
-  ds_config->mutable_for_testing()->set_message_size(message_size);
+  ds_config->mutable_for_testing()->set_message_size(message_bytes);
+  ds_config->mutable_for_testing()->set_max_messages_per_second(messages_per_s);
 
   bool is_first_packet = true;
   auto on_readback_complete = task_runner.CreateCheckpoint("readback.complete");
@@ -87,10 +102,10 @@
                                         bool has_more) {
     for (auto& packet : packets) {
       ASSERT_TRUE(packet.Decode());
-      ASSERT_TRUE(packet->has_for_testing() || packet->has_clock_snapshot());
-      if (packet->has_clock_snapshot()) {
+      ASSERT_TRUE(packet->has_for_testing() || packet->has_clock_snapshot() ||
+                  packet->has_trace_config());
+      if (packet->has_clock_snapshot() || packet->has_trace_config())
         continue;
-      }
       ASSERT_EQ(protos::TracePacket::kTrustedUid,
                 packet->optional_trusted_uid_case());
       if (is_first_packet) {
@@ -118,7 +133,8 @@
   task_runner.RunUntilCheckpoint("producer.enabled");
 
   uint64_t wall_start_ns = base::GetWallTimeNs().count();
-  uint64_t thread_start_ns = service_thread.GetThreadCPUTimeNs();
+  uint64_t service_start_ns = service_thread.GetThreadCPUTimeNs();
+  uint64_t producer_start_ns = producer_thread.GetThreadCPUTimeNs();
   uint64_t iterations = 0;
   for (auto _ : state) {
     auto cname = "produced.and.committed." + std::to_string(iterations++);
@@ -127,29 +143,65 @@
                                              &on_produced_and_committed] {
       task_runner.PostTask(on_produced_and_committed);
     };
-    FakeProducer* producer = producer_delegate_cached->producer();
     producer->ProduceEventBatch(posted_on_produced_and_committed);
-    task_runner.RunUntilCheckpoint(cname);
+    task_runner.RunUntilCheckpoint(cname, time_for_messages_ms);
   }
-  uint64_t thread_ns = service_thread.GetThreadCPUTimeNs() - thread_start_ns;
+  uint64_t service_ns = service_thread.GetThreadCPUTimeNs() - service_start_ns;
+  uint64_t producer_ns =
+      producer_thread.GetThreadCPUTimeNs() - producer_start_ns;
   uint64_t wall_ns = base::GetWallTimeNs().count() - wall_start_ns;
 
-  state.counters["Ser CPU"] = benchmark::Counter(100.0 * thread_ns / wall_ns);
+  state.counters["Pro CPU"] = benchmark::Counter(100.0 * producer_ns / wall_ns);
+  state.counters["Ser CPU"] = benchmark::Counter(100.0 * service_ns / wall_ns);
   state.counters["Ser ns/m"] =
-      benchmark::Counter(1.0 * thread_ns / message_count);
+      benchmark::Counter(1.0 * service_ns / message_count);
 
   // Read back the buffer just to check correctness.
   consumer.ReadTraceData();
   task_runner.RunUntilCheckpoint("readback.complete");
-  state.SetBytesProcessed(int64_t(state.iterations()) * message_size *
-                          message_count);
+  state.SetBytesProcessed(iterations * message_bytes * message_count);
 
   consumer.Disconnect();
 }
 
-BENCHMARK(BM_EndToEnd)
+void SaturateCpuArgs(benchmark::internal::Benchmark* b) {
+  int min_message_count = 16;
+  int max_message_count = IsBenchmarkFunctionalOnly() ? 1024 : 1024 * 1024;
+  int min_payload = 8;
+  int max_payload = IsBenchmarkFunctionalOnly() ? 256 : 2048;
+  for (int count = min_message_count; count <= max_message_count; count *= 2) {
+    for (int bytes = min_payload; bytes <= max_payload; bytes *= 2) {
+      b->Args({count, bytes, 0 /* speed */});
+    }
+  }
+}
+
+void ConstantRateArgs(benchmark::internal::Benchmark* b) {
+  int message_count = IsBenchmarkFunctionalOnly() ? 2 * 1024 : 128 * 1024;
+  int min_speed = IsBenchmarkFunctionalOnly() ? 64 : 8;
+  int max_speed = IsBenchmarkFunctionalOnly() ? 128 : 128;
+  for (int speed = min_speed; speed <= max_speed; speed *= 2) {
+    b->Args({message_count, 128, speed});
+    b->Args({message_count, 256, speed});
+  }
+}
+}
+
+static void BM_EndToEnd_SaturateCpu(benchmark::State& state) {
+  BenchmarkCommon(state);
+}
+
+BENCHMARK(BM_EndToEnd_SaturateCpu)
     ->Unit(benchmark::kMicrosecond)
     ->UseRealTime()
-    ->RangeMultiplier(2)
-    ->Ranges({{16, 1024 * 1024}, {8, 2048}});
+    ->Apply(SaturateCpuArgs);
+
+static void BM_EndToEnd_ConstantRate(benchmark::State& state) {
+  BenchmarkCommon(state);
 }
+
+BENCHMARK(BM_EndToEnd_ConstantRate)
+    ->Unit(benchmark::kMicrosecond)
+    ->UseRealTime()
+    ->Apply(ConstantRateArgs);
+}  // namespace perfetto
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
index acaeb12..dbf91c2 100644
--- a/test/end_to_end_integrationtest.cc
+++ b/test/end_to_end_integrationtest.cc
@@ -86,7 +86,7 @@
 
   // Create the buffer for ftrace.
   auto* ds_config = trace_config.add_data_sources()->mutable_config();
-  ds_config->set_name("com.google.perfetto.ftrace");
+  ds_config->set_name("linux.ftrace");
   ds_config->set_target_buffer(0);
 
   // Setup the config for ftrace.
@@ -183,9 +183,10 @@
                               std::vector<TracePacket> packets, bool has_more) {
     for (auto& packet : packets) {
       ASSERT_TRUE(packet.Decode());
+      ASSERT_TRUE(packet->has_for_testing() || packet->has_clock_snapshot() ||
+                  packet->has_trace_config());
       if (packet->has_clock_snapshot() || packet->has_trace_config())
         continue;
-      ASSERT_TRUE(packet->has_for_testing());
       ASSERT_EQ(protos::TracePacket::kTrustedUid,
                 packet->optional_trusted_uid_case());
       ASSERT_EQ(packet->for_testing().seq_value(), rnd_engine());
diff --git a/test/fake_producer.cc b/test/fake_producer.cc
index 9d28744..a81f656 100644
--- a/test/fake_producer.cc
+++ b/test/fake_producer.cc
@@ -21,6 +21,7 @@
 
 #include "gtest/gtest.h"
 #include "perfetto/base/logging.h"
+#include "perfetto/base/time.h"
 #include "perfetto/base/utils.h"
 #include "perfetto/trace/test_event.pbzero.h"
 #include "perfetto/trace/trace_packet.pbzero.h"
@@ -65,6 +66,8 @@
   rnd_engine_ = std::minstd_rand0(source_config.for_testing().seed());
   message_count_ = source_config.for_testing().message_count();
   message_size_ = source_config.for_testing().message_size();
+  max_messages_per_second_ =
+      source_config.for_testing().max_messages_per_second();
   task_runner_->PostTask(on_create_data_source_instance_);
 }
 
@@ -82,10 +85,34 @@
         static_cast<char*>(malloc(message_size_)));
     memset(payload.get(), '.', message_size_);
     payload.get()[message_size_ - 1] = 0;
-    for (size_t i = 0; i < message_count_; i++) {
-      auto handle = trace_writer_->NewTracePacket();
-      handle->set_for_testing()->set_seq_value(rnd_engine_());
-      handle->set_for_testing()->set_str(payload.get(), message_size_);
+
+    base::TimeMillis start = base::GetWallTimeMs();
+    int64_t iterations = 0;
+    size_t messages_to_emit = message_count_;
+    while (messages_to_emit > 0) {
+      size_t messages_in_minibatch =
+          max_messages_per_second_ == 0
+              ? messages_to_emit
+              : std::min(max_messages_per_second_, messages_to_emit);
+      PERFETTO_DCHECK(messages_to_emit >= messages_in_minibatch);
+
+      for (size_t i = 0; i < messages_in_minibatch; i++) {
+        auto handle = trace_writer_->NewTracePacket();
+        handle->set_for_testing()->set_seq_value(rnd_engine_());
+        handle->set_for_testing()->set_str(payload.get(), message_size_);
+      }
+      messages_to_emit -= messages_in_minibatch;
+
+      // Pause until the second boundary to make sure that we are adhering to
+      // the speed limitation.
+      if (max_messages_per_second_ > 0) {
+        int64_t expected_time_taken = ++iterations * 1000;
+        base::TimeMillis time_taken = base::GetWallTimeMs() - start;
+        while (time_taken.count() < expected_time_taken) {
+          usleep((expected_time_taken - time_taken.count()) * 1000);
+          time_taken = base::GetWallTimeMs() - start;
+        }
+      }
     }
     trace_writer_->Flush(callback);
   });
diff --git a/test/fake_producer.h b/test/fake_producer.h
index 152dd04..2495518 100644
--- a/test/fake_producer.h
+++ b/test/fake_producer.h
@@ -61,6 +61,7 @@
   std::minstd_rand0 rnd_engine_;
   size_t message_size_ = 0;
   size_t message_count_ = 0;
+  size_t max_messages_per_second_ = 0;
   std::function<void()> on_create_data_source_instance_;
   std::unique_ptr<Service::ProducerEndpoint> endpoint_;
   std::unique_ptr<TraceWriter> trace_writer_;
diff --git a/tools/run_android_test b/tools/run_android_test
index bb92156..83f029d 100755
--- a/tools/run_android_test
+++ b/tools/run_android_test
@@ -114,6 +114,7 @@
   parser = argparse.ArgumentParser()
   parser.add_argument('--no-cleanup', '-n', action='store_true')
   parser.add_argument('--no-data-deps', '-x', action='store_true')
+  parser.add_argument('--env', '-e', action='append')
   parser.add_argument('out_dir', help='out/android/')
   parser.add_argument('test_name', help='perfetto_unittests')
   parser.add_argument('cmd_args', nargs=argparse.REMAINDER)
@@ -138,10 +139,10 @@
 
   # LLVM sanitizers require to sideload a libclangrtXX.so on the device.
   sanitizer_libs = os.path.join(args.out_dir, 'sanitizer_libs')
-  env = ''
+  env = ' '.join(args.env if args.env is not None else []) + ' '
   if os.path.exists(sanitizer_libs):
     AdbCall('push', sanitizer_libs, target_dir)
-    env = 'LD_LIBRARY_PATH="%s/sanitizer_libs" ' % (target_dir)
+    env += 'LD_LIBRARY_PATH="%s/sanitizer_libs" ' % (target_dir)
   cmd = 'cd %s;' % target_dir;
   binary = env + './%s' % args.test_name
   cmd += binary
diff --git a/tools/tmux b/tools/tmux
index 568fc78..1e4b3d4 100755
--- a/tools/tmux
+++ b/tools/tmux
@@ -164,8 +164,12 @@
 tmux select-pane -t 2
 
 tmux -2 attach-session -t demo
-reset
-TRACE=$HOME/Downloads/trace.json
-echo -e "\n\x1b[32mPulling trace into $TRACE\x1b[0m"
-pull trace $TMPDIR/trace.protobuf
-$OUT/trace_to_text systrace < $TMPDIR/trace.protobuf > $TRACE
+
+reset_tracing
+
+TRACE=$HOME/Downloads/trace
+pull trace /tmp/trace.protobuf
+echo -e "\n\x1b[32mPulling trace into $TRACE.pbtext\x1b[0m"
+$OUT/trace_to_text text < /tmp/trace.protobuf > $TRACE.pbtext
+echo -e "\n\x1b[32mPulling trace into $TRACE.json\x1b[0m"
+$OUT/trace_to_text systrace < /tmp/trace.protobuf > $TRACE.json
diff --git a/tools/trace_to_text/ftrace_event_formatter.cc b/tools/trace_to_text/ftrace_event_formatter.cc
index 54e8a79..bdf7d88 100644
--- a/tools/trace_to_text/ftrace_event_formatter.cc
+++ b/tools/trace_to_text/ftrace_event_formatter.cc
@@ -379,7 +379,7 @@
   sprintf(line,
           "sched_switch: prev_comm=%s "
           "prev_pid=%d prev_prio=%d prev_state=%s ==> next_comm=%s next_pid=%d "
-          "next_prio=%d\\n",
+          "next_prio=%d",
           sched_switch.prev_comm().c_str(), sched_switch.prev_pid(),
           sched_switch.prev_prio(),
           GetSchedSwitchFlag(sched_switch.prev_state()),
@@ -392,7 +392,7 @@
   char line[2048];
   sprintf(line,
           "sched_wakeup: comm=%s "
-          "pid=%d prio=%d success=%d target_cpu=%03d\\n",
+          "pid=%d prio=%d success=%d target_cpu=%03d",
           sched_wakeup.comm().c_str(), sched_wakeup.pid(), sched_wakeup.prio(),
           sched_wakeup.success(), sched_wakeup.target_cpu());
   return std::string(line);
@@ -401,24 +401,31 @@
 std::string FormatSchedBlockedReason(
     const SchedBlockedReasonFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_blocked_reason: pid=%d iowait=%d caller=%llxS\\n",
+  sprintf(line, "sched_blocked_reason: pid=%d iowait=%d caller=%llxS",
           event.pid(), event.io_wait(), event.caller());
   return std::string(line);
 }
 
 std::string FormatPrint(const PrintFtraceEvent& print) {
-  char line[2048];
-  std::string msg = print.buf();
+  std::string line = "tracing_mark_write: ";
+  size_t dst = line.size();
+  line.resize(2048);
+  const std::string& msg = print.buf();
+
   // Remove any newlines in the message. It's not entirely clear what the right
   // behaviour is here. Maybe we should escape them instead?
-  msg.erase(std::remove(msg.begin(), msg.end(), '\n'), msg.end());
-  sprintf(line, "tracing_mark_write: %s\\n", msg.c_str());
-  return std::string(line);
+  for (size_t src = 0; src < msg.size() && dst < line.size() - 1; src++) {
+    char c = msg[src];
+    if (c != '\n')
+      line[dst++] = c;
+  }
+  line.resize(dst);
+  return line;
 }
 
 std::string FormatCpuFrequency(const CpuFrequencyFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "cpu_frequency: state=%" PRIu32 " cpu_id=%" PRIu32 "\\n",
+  sprintf(line, "cpu_frequency: state=%" PRIu32 " cpu_id=%" PRIu32,
           event.state(), event.cpu_id());
   return std::string(line);
 }
@@ -428,21 +435,21 @@
   char line[2048];
   sprintf(line,
           "cpu_frequency_limits: min_freq=%" PRIu32 "max_freq=%" PRIu32
-          " cpu_id=%" PRIu32 "\\n",
+          " cpu_id=%" PRIu32,
           event.min_freq(), event.max_freq(), event.cpu_id());
   return std::string(line);
 }
 
 std::string FormatCpuIdle(const CpuIdleFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "cpu_idle: state=%" PRIu32 " cpu_id=%" PRIu32 "\\n",
-          event.state(), event.cpu_id());
+  sprintf(line, "cpu_idle: state=%" PRIu32 " cpu_id=%" PRIu32, event.state(),
+          event.cpu_id());
   return std::string(line);
 }
 
 std::string FormatClockSetRate(const ClockSetRateFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "clock_set_rate: %s state=%llu cpu_id=%llu\\n",
+  sprintf(line, "clock_set_rate: %s state=%llu cpu_id=%llu",
           event.name().empty() ? "todo" : event.name().c_str(), event.state(),
           event.cpu_id());
   return std::string(line);
@@ -450,7 +457,7 @@
 
 std::string FormatClockEnable(const ClockEnableFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "clock_enable: %s state=%llu cpu_id=%llu\\n",
+  sprintf(line, "clock_enable: %s state=%llu cpu_id=%llu",
           event.name().empty() ? "todo" : event.name().c_str(), event.state(),
           event.cpu_id());
   return std::string(line);
@@ -458,7 +465,7 @@
 
 std::string FormatClockDisable(const ClockDisableFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "clock_disable: %s state=%llu cpu_id=%llu\\n",
+  sprintf(line, "clock_disable: %s state=%llu cpu_id=%llu",
           event.name().empty() ? "todo" : event.name().c_str(), event.state(),
           event.cpu_id());
   return std::string(line);
@@ -466,27 +473,26 @@
 
 std::string FormatTracingMarkWrite(const TracingMarkWriteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "tracing_mark_write: %s|%d|%s\\n",
-          event.trace_begin() ? "B" : "E", event.pid(),
-          event.trace_name().c_str());
+  sprintf(line, "tracing_mark_write: %s|%d|%s", event.trace_begin() ? "B" : "E",
+          event.pid(), event.trace_name().c_str());
   return std::string(line);
 }
 
 std::string FormatBinderLocked(const BinderLockedFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "binder_locked: tag=%s\\n", event.tag().c_str());
+  sprintf(line, "binder_locked: tag=%s", event.tag().c_str());
   return std::string(line);
 }
 
 std::string FormatBinderUnlock(const BinderUnlockFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "binder_unlock: tag=%s\\n", event.tag().c_str());
+  sprintf(line, "binder_unlock: tag=%s", event.tag().c_str());
   return std::string(line);
 }
 
 std::string FormatBinderLock(const BinderLockFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "binder_lock: tag=%s\\n", event.tag().c_str());
+  sprintf(line, "binder_lock: tag=%s", event.tag().c_str());
   return std::string(line);
 }
 
@@ -494,7 +500,7 @@
   char line[2048];
   sprintf(line,
           "binder_transaction: transaction=%d dest_node=%d dest_proc=%d "
-          "dest_thread=%d reply=%d flags=0x%x code=0x%x\\n",
+          "dest_thread=%d reply=%d flags=0x%x code=0x%x",
           event.debug_id(), event.target_node(), event.to_proc(),
           event.to_thread(), event.reply(), event.flags(), event.code());
   return std::string(line);
@@ -503,7 +509,7 @@
 std::string FormatBinderTransactionReceived(
     const BinderTransactionReceivedFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "binder_transaction_received: transaction=%d\\n",
+  sprintf(line, "binder_transaction_received: transaction=%d",
           event.debug_id());
   return std::string(line);
 }
@@ -511,7 +517,7 @@
 std::string FormatExt4SyncFileEnter(const Ext4SyncFileEnterFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_sync_file_enter: dev %d,%d ino %lu parent %lu datasync %d \\n",
+          "ext4_sync_file_enter: dev %d,%d ino %lu parent %lu datasync %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.parent(), event.datasync());
   return std::string(line);
@@ -519,7 +525,7 @@
 
 std::string FormatExt4SyncFileExit(const Ext4SyncFileExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_sync_file_exit: dev %d,%d ino %lu ret %d\\n",
+  sprintf(line, "ext4_sync_file_exit: dev %d,%d ino %lu ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.ret());
   return std::string(line);
@@ -528,7 +534,7 @@
 std::string FormatExt4DaWriteBegin(const Ext4DaWriteBeginFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_da_write_begin: dev %d,%d ino %lu pos %lld len %u flags %u\\n",
+          "ext4_da_write_begin: dev %d,%d ino %lu pos %lld len %u flags %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.len(), event.flags());
   return std::string(line);
@@ -537,7 +543,7 @@
 std::string FormatExt4DaWriteEnd(const Ext4DaWriteEndFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_da_write_end: dev %d,%d ino %lu pos %lld len %u copied %u\\n",
+          "ext4_da_write_end: dev %d,%d ino %lu pos %lld len %u copied %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.len(), event.copied());
   return std::string(line);
@@ -545,7 +551,7 @@
 
 std::string FormatBlockRqIssue(const BlockRqIssueFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_issue: %d,%d %s %u (%s) %llu + %u [%s]\\n",
+  sprintf(line, "block_rq_issue: %d,%d %s %u (%s) %llu + %u [%s]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           event.bytes(), event.cmd().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
@@ -555,29 +561,28 @@
 
 std::string FormatI2cRead(const I2cReadFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "i2c_read: i2c-%d #%u a=%03x f=%04x l=%u\\n",
-          event.adapter_nr(), event.msg_nr(), event.addr(), event.flags(),
-          event.len());
+  sprintf(line, "i2c_read: i2c-%d #%u a=%03x f=%04x l=%u", event.adapter_nr(),
+          event.msg_nr(), event.addr(), event.flags(), event.len());
   return std::string(line);
 }
 
 std::string FormatI2cResult(const I2cResultFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "i2c_result: i2c-%d n=%u ret=%d\\n", event.adapter_nr(),
+  sprintf(line, "i2c_result: i2c-%d n=%u ret=%d", event.adapter_nr(),
           event.nr_msgs(), event.ret());
   return std::string(line);
 }
 
 std::string FormatIrqHandlerEntry(const IrqHandlerEntryFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "irq_handler_entry: irq=%d name=%s\\n", event.irq(),
+  sprintf(line, "irq_handler_entry: irq=%d name=%s", event.irq(),
           event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatIrqHandlerExit(const IrqHandlerExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "irq_handler_exit: irq=%d ret=%s\\n", event.irq(),
+  sprintf(line, "irq_handler_exit: irq=%d ret=%s", event.irq(),
           event.ret() ? "handled" : "unhandled");
   return std::string(line);
 }
@@ -585,7 +590,7 @@
 std::string FormatMmVmscanKswapdWake(
     const MmVmscanKswapdWakeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_vmscan_kswapd_wake: nid=%d order=%d\\n", event.nid(),
+  sprintf(line, "mm_vmscan_kswapd_wake: nid=%d order=%d", event.nid(),
           event.order());
   return std::string(line);
 }
@@ -593,77 +598,76 @@
 std::string FormatMmVmscanKswapdSleep(
     const MmVmscanKswapdSleepFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_vmscan_kswapd_sleep: nid=%d\\n", event.nid());
+  sprintf(line, "mm_vmscan_kswapd_sleep: nid=%d", event.nid());
   return std::string(line);
 }
 
 std::string FormatRegulatorEnable(const RegulatorEnableFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_enable: name=%s\\n", event.name().c_str());
+  sprintf(line, "regulator_enable: name=%s", event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatRegulatorEnableDelay(
     const RegulatorEnableDelayFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_enable_delay: name=%s\\n", event.name().c_str());
+  sprintf(line, "regulator_enable_delay: name=%s", event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatRegulatorEnableComplete(
     const RegulatorEnableCompleteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_enable_complete: name=%s\\n", event.name().c_str());
+  sprintf(line, "regulator_enable_complete: name=%s", event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatRegulatorDisable(const RegulatorDisableFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_disable: name=%s\\n", event.name().c_str());
+  sprintf(line, "regulator_disable: name=%s", event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatRegulatorDisableComplete(
     const RegulatorDisableCompleteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_disable_complete: name=%s\\n", event.name().c_str());
+  sprintf(line, "regulator_disable_complete: name=%s", event.name().c_str());
   return std::string(line);
 }
 
 std::string FormatRegulatorSetVoltage(
     const RegulatorSetVoltageFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_set_voltage: name=%s (%d-%d)\\n",
-          event.name().c_str(), event.min(), event.max());
+  sprintf(line, "regulator_set_voltage: name=%s (%d-%d)", event.name().c_str(),
+          event.min(), event.max());
   return std::string(line);
 }
 
 std::string FormatRegulatorSetVoltageComplete(
     const RegulatorSetVoltageCompleteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "regulator_set_voltage_complete: name=%s, val=%u\\n",
+  sprintf(line, "regulator_set_voltage_complete: name=%s, val=%u",
           event.name().c_str(), event.val());
   return std::string(line);
 }
 
 std::string FormatSchedCpuHotplug(const SchedCpuHotplugFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_cpu_hotplug: cpu %d %s error=%d\\n",
-          event.affected_cpu(), event.status() ? "online" : "offline",
-          event.error());
+  sprintf(line, "sched_cpu_hotplug: cpu %d %s error=%d", event.affected_cpu(),
+          event.status() ? "online" : "offline", event.error());
   return std::string(line);
 }
 
 std::string FormatSyncTimeline(const SyncTimelineFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sync_timeline: name=%s value=%s\\n", event.name().c_str(),
+  sprintf(line, "sync_timeline: name=%s value=%s", event.name().c_str(),
           event.value().c_str());
   return std::string(line);
 }
 
 std::string FormatSyncWait(const SyncWaitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sync_wait: %s name=%s state=%d\\n",
+  sprintf(line, "sync_wait: %s name=%s state=%d",
           event.begin() ? "begin" : "end", event.name().c_str(),
           event.status());
   return std::string(line);
@@ -671,28 +675,28 @@
 
 std::string FormatSyncPt(const SyncPtFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sync_pt: name=%s value=%s\\n", event.timeline().c_str(),
+  sprintf(line, "sync_pt: name=%s value=%s", event.timeline().c_str(),
           event.value().c_str());
   return std::string(line);
 }
 
 std::string FormatSoftirqRaise(const SoftirqRaiseFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "softirq_raise: vec=%u [action=%s]\\n", event.vec(),
+  sprintf(line, "softirq_raise: vec=%u [action=%s]", event.vec(),
           SoftirqArray[event.vec()]);
   return std::string(line);
 }
 
 std::string FormatSoftirqEntry(const SoftirqEntryFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "softirq_entry: vec=%u [action=%s]\\n", event.vec(),
+  sprintf(line, "softirq_entry: vec=%u [action=%s]", event.vec(),
           SoftirqArray[event.vec()]);
   return std::string(line);
 }
 
 std::string FormatSoftirqExit(const SoftirqExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "softirq_exit: vec=%u [action=%s]\\n", event.vec(),
+  sprintf(line, "softirq_exit: vec=%u [action=%s]", event.vec(),
           SoftirqArray[event.vec()]);
   return std::string(line);
 }
@@ -700,18 +704,16 @@
 std::string FormatI2cWrite(const I2cWriteFtraceEvent& event) {
   char line[2048];
   // TODO(hjd): Check event.buf().
-  sprintf(line, "i2c_write: i2c-%d #%u a=%03x f=%04x l=%u\\n",
-          event.adapter_nr(), event.msg_nr(), event.addr(), event.flags(),
-          event.len());
+  sprintf(line, "i2c_write: i2c-%d #%u a=%03x f=%04x l=%u", event.adapter_nr(),
+          event.msg_nr(), event.addr(), event.flags(), event.len());
   return std::string(line);
 }
 
 std::string FormatI2cReply(const I2cReplyFtraceEvent& event) {
   char line[2048];
   // TODO(hjd): Check event.buf().
-  sprintf(line, "i2c_reply: i2c-%d #%u a=%03x f=%04x l=%u\\n",
-          event.adapter_nr(), event.msg_nr(), event.addr(), event.flags(),
-          event.len());
+  sprintf(line, "i2c_reply: i2c-%d #%u a=%03x f=%04x l=%u", event.adapter_nr(),
+          event.msg_nr(), event.addr(), event.flags(), event.len());
   return std::string(line);
 }
 
@@ -719,7 +721,7 @@
 std::string FormatMmVmscanDirectReclaimBegin(
     const MmVmscanDirectReclaimBeginFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_vmscan_direct_reclaim_begin: order=%d may_writepage=%d\\n",
+  sprintf(line, "mm_vmscan_direct_reclaim_begin: order=%d may_writepage=%d",
           event.order(), event.may_writepage());
   return std::string(line);
 }
@@ -727,7 +729,7 @@
 std::string FormatMmVmscanDirectReclaimEnd(
     const MmVmscanDirectReclaimEndFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_vmscan_direct_reclaim_end: nr_reclaimed=%llu\\n",
+  sprintf(line, "mm_vmscan_direct_reclaim_end: nr_reclaimed=%llu",
           event.nr_reclaimed());
   return std::string(line);
 }
@@ -736,7 +738,7 @@
   char line[2048];
   sprintf(line,
           "lowmemory_kill: %s (%d), page cache %lldkB (limit %lldkB), free "
-          "%lldKb\\n",
+          "%lldKb",
           event.comm().c_str(), event.pid(), event.pagecache_size(),
           event.pagecache_limit(), event.free());
   return std::string(line);
@@ -745,7 +747,7 @@
 std::string FormatWorkqueueExecuteStart(
     const WorkqueueExecuteStartFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "workqueue_execute_start: work struct %llx: function %llxf\\n",
+  sprintf(line, "workqueue_execute_start: work struct %llx: function %llxf",
           event.work(), event.function());
   return std::string(line);
 }
@@ -753,7 +755,7 @@
 std::string FormatWorkqueueExecuteEnd(
     const WorkqueueExecuteEndFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "workqueue_execute_end: work struct %llx\\n", event.work());
+  sprintf(line, "workqueue_execute_end: work struct %llx", event.work());
   return std::string(line);
 }
 
@@ -763,7 +765,7 @@
   sprintf(
       line,
       "workqueue_queue_work: work struct=%llx function=%llxf workqueue=%llx "
-      "req_cpu=%u cpu=%u\\n",
+      "req_cpu=%u cpu=%u",
       event.work(), event.function(), event.workqueue(), event.req_cpu(),
       event.cpu());
   return std::string(line);
@@ -772,7 +774,7 @@
 std::string FormatWorkqueueActivateWork(
     const WorkqueueActivateWorkFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "workqueue_activate_work: work struct %llx\\n", event.work());
+  sprintf(line, "workqueue_activate_work: work struct %llx", event.work());
   return std::string(line);
 }
 
@@ -780,7 +782,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_begin: zone_start=0x%llx migrate_pfn=0x%llx "
-          "free_pfn=0x%llx zone_end=0x%llx, mode=%s\\n",
+          "free_pfn=0x%llx zone_end=0x%llx, mode=%s",
           event.zone_start(), event.migrate_pfn(), event.free_pfn(),
           event.zone_end(), event.sync() ? "sync" : "async");
   return std::string(line);
@@ -791,7 +793,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_defer_compaction: node=%d zone=%-8s order=%d "
-          "order_failed=%d consider=%u limit=%lu\\n",
+          "order_failed=%d consider=%u limit=%lu",
           event.nid(), MmCompactionSuitableArray[event.idx()], event.order(),
           event.order_failed(), event.considered(), 1UL << event.defer_shift());
   return std::string(line);
@@ -802,7 +804,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_deferred: node=%d zone=%-8s order=%d order_failed=%d "
-          "consider=%u limit=%lu\\n",
+          "consider=%u limit=%lu",
           event.nid(), MmCompactionSuitableArray[event.idx()], event.order(),
           event.order_failed(), event.considered(), 1UL << event.defer_shift());
   return std::string(line);
@@ -813,7 +815,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_defer_reset: node=%d zone=%-8s order=%d "
-          "order_failed=%d consider=%u limit=%lu\\n",
+          "order_failed=%d consider=%u limit=%lu",
           event.nid(), MmCompactionSuitableArray[event.idx()], event.order(),
           event.order_failed(), event.considered(), 1UL << event.defer_shift());
   return std::string(line);
@@ -823,7 +825,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_end: zone_start=0x%llx migrate_pfn=0x%llx "
-          "free_pfn=0x%llx zone_end=0x%llx, mode=%s status=%s\\n",
+          "free_pfn=0x%llx zone_end=0x%llx, mode=%s status=%s",
           event.zone_start(), event.migrate_pfn(), event.free_pfn(),
           event.zone_end(), event.sync() ? "sync" : "aysnc",
           MmCompactionRetArray[event.status()]);
@@ -833,7 +835,7 @@
 std::string FormatMmCompactionFinished(
     const MmCompactionFinishedFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_compaction_finished: node=%d zone=%-8s order=%d ret=%s\\n",
+  sprintf(line, "mm_compaction_finished: node=%d zone=%-8s order=%d ret=%s",
           event.nid(), MmCompactionSuitableArray[event.idx()], event.order(),
           MmCompactionRetArray[event.ret()]);
   return std::string(line);
@@ -844,7 +846,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_isolate_freepages: range=(0x%llx ~ 0x%llx) "
-          "nr_scanned=%llu nr_taken=%llu\\n",
+          "nr_scanned=%llu nr_taken=%llu",
           event.start_pfn(), event.end_pfn(), event.nr_scanned(),
           event.nr_taken());
   return std::string(line);
@@ -855,7 +857,7 @@
   char line[2048];
   sprintf(line,
           "mm_compaction_isolate_migratepages: range=(0x%llx ~ 0x%llx) "
-          "nr_scanned=%llu nr_taken=%llu\\n",
+          "nr_scanned=%llu nr_taken=%llu",
           event.start_pfn(), event.end_pfn(), event.nr_scanned(),
           event.nr_taken());
   return std::string(line);
@@ -864,7 +866,7 @@
 std::string FormatMmCompactionKcompactdSleep(
     const MmCompactionKcompactdSleepFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_compaction_kcompactd_sleep: nid=%d\\n", event.nid());
+  sprintf(line, "mm_compaction_kcompactd_sleep: nid=%d", event.nid());
   return std::string(line);
 }
 
@@ -872,7 +874,7 @@
     const MmCompactionKcompactdWakeFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "mm_compaction_kcompactd_wake: nid=%d order=%d classzone_idx=%-8s\\n",
+          "mm_compaction_kcompactd_wake: nid=%d order=%d classzone_idx=%-8s",
           event.nid(), event.order(),
           MmCompactionSuitableArray[event.classzone_idx()]);
   return std::string(line);
@@ -881,8 +883,7 @@
 std::string FormatMmCompactionMigratepages(
     const MmCompactionMigratepagesFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "mm_compaction_migratepages: nr_migrated=%llu nr_failed=%llu\\n",
+  sprintf(line, "mm_compaction_migratepages: nr_migrated=%llu nr_failed=%llu",
           event.nr_migrated(), event.nr_failed());
   return std::string(line);
 }
@@ -890,7 +891,7 @@
 std::string FormatMmCompactionSuitable(
     const MmCompactionSuitableFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "mm_compaction_suitable: node=%d zone=%-8s order=%d ret=%s\\n",
+  sprintf(line, "mm_compaction_suitable: node=%d zone=%-8s order=%d ret=%s",
           event.nid(), MmCompactionSuitableArray[event.idx()], event.order(),
           MmCompactionRetArray[event.ret()]);
   return std::string(line);
@@ -899,48 +900,46 @@
 std::string FormatMmCompactionTryToCompactPages(
     const MmCompactionTryToCompactPagesFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "mm_compaction_try_to_compact_pages: order=%d gfp_mask=0x%x mode=%d\\n",
-      event.order(), event.gfp_mask(),
-      event.mode());  // convert to int?
+  sprintf(line,
+          "mm_compaction_try_to_compact_pages: order=%d gfp_mask=0x%x mode=%d",
+          event.order(), event.gfp_mask(),
+          event.mode());  // convert to int?
   return std::string(line);
 }
 
 std::string FormatMmCompactionWakeupKcompactd(
     const MmCompactionWakeupKcompactdFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "mm_compaction_wakeup_kcompactd: nid=%d order=%d classzone_idx=%-8s\\n",
-      event.nid(), event.order(),
-      MmCompactionSuitableArray[event.classzone_idx()]);
+  sprintf(line,
+          "mm_compaction_wakeup_kcompactd: nid=%d order=%d classzone_idx=%-8s",
+          event.nid(), event.order(),
+          MmCompactionSuitableArray[event.classzone_idx()]);
   return std::string(line);
 }
 
 std::string FormatSuspendResume(const SuspendResumeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "suspend_resume: %s[%u] %s\\n", event.action().c_str(),
+  sprintf(line, "suspend_resume: %s[%u] %s", event.action().c_str(),
           event.val(), event.start() ? "begin" : "end");
   return std::string(line);
 }
 
 std::string FormatSchedWakeupNew(const SchedWakeupNewFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_wakeup_new: comm=%s pid=%d prio=%d target_cpu=%03d\\n",
+  sprintf(line, "sched_wakeup_new: comm=%s pid=%d prio=%d target_cpu=%03d",
           event.comm().c_str(), event.pid(), event.prio(), event.target_cpu());
   return std::string(line);
 }
 
 std::string FormatSchedProcessExec(const SchedProcessExecFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_process_exec: filename=%s pid=%d old_pid=%d\\n",
+  sprintf(line, "sched_process_exec: filename=%s pid=%d old_pid=%d",
           event.filename().c_str(), event.pid(), event.old_pid());
   return std::string(line);
 }
 std::string FormatSchedProcessExit(const SchedProcessExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_process_exit: comm=%s pid=%d tgid=%d prio=%d\\n",
+  sprintf(line, "sched_process_exit: comm=%s pid=%d tgid=%d prio=%d",
           event.comm().c_str(), event.pid(), event.tgid(), event.prio());
   return std::string(line);
 }
@@ -948,27 +947,27 @@
   char line[2048];
   sprintf(line,
           "sched_process_fork: parent_comm=%s parent_pid=%d child_comm=%s "
-          "child_pid=%d\\n",
+          "child_pid=%d",
           event.parent_comm().c_str(), event.parent_pid(),
           event.child_comm().c_str(), event.child_pid());
   return std::string(line);
 }
 std::string FormatSchedProcessFree(const SchedProcessFreeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_process_free: comm=%s pid=%d prio=%d\\n",
+  sprintf(line, "sched_process_free: comm=%s pid=%d prio=%d",
           event.comm().c_str(), event.pid(), event.prio());
   return std::string(line);
 }
 std::string FormatSchedProcessHang(const SchedProcessHangFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_process_hang: comm=%s pid=%d\\n", event.comm().c_str(),
+  sprintf(line, "sched_process_hang: comm=%s pid=%d", event.comm().c_str(),
           event.pid());
   return std::string(line);
 }
 
 std::string FormatSchedProcessWait(const SchedProcessWaitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "sched_process_wait: comm=%s pid=%d\\n", event.comm().c_str(),
+  sprintf(line, "sched_process_wait: comm=%s pid=%d", event.comm().c_str(),
           event.pid());
   return std::string(line);
 }
@@ -976,7 +975,7 @@
 std::string FormatTaskNewtask(const TaskNewtaskFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "task_newtask: comm=%s pid=%d clone_flags=%llu oom_score_adj=%d\\n",
+          "task_newtask: comm=%s pid=%d clone_flags=%llu oom_score_adj=%d",
           event.comm().c_str(), event.pid(), event.clone_flags(),
           event.oom_score_adj());
   return std::string(line);
@@ -984,7 +983,7 @@
 
 std::string FormatTaskRename(const TaskRenameFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "task_rename: pid=%d oldcomm=%s newcomm=%s oom_score_adj=%d\\n",
+  sprintf(line, "task_rename: pid=%d oldcomm=%s newcomm=%s oom_score_adj=%d",
           event.pid(), event.newcomm().c_str(), event.oldcomm().c_str(),
           event.oom_score_adj());
   return std::string(line);
@@ -992,7 +991,7 @@
 
 std::string FormatBlockBioBackmerge(const BlockBioBackmergeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_bio_backmerge: %d,%d %s %llu + %u [%s]\\n",
+  sprintf(line, "block_bio_backmerge: %d,%d %s %llu + %u [%s]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
@@ -1003,7 +1002,7 @@
   char line[2048];
   sprintf(line,
           "block_bio_bounce:"
-          "%d,%d %s %llu + %u [%s]\\n",
+          "%d,%d %s %llu + %u [%s]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
@@ -1012,7 +1011,7 @@
 
 std::string FormatBlockBioComplete(const BlockBioCompleteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_bio_complete: %d,%d %s %llu + %u [%d]\\n",
+  sprintf(line, "block_bio_complete: %d,%d %s %llu + %u [%d]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.error());
@@ -1022,7 +1021,7 @@
 std::string FormatBlockBioFrontmerge(
     const BlockBioFrontmergeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_bio_frontmerge: %d,%d %s %llu + %u [%s]\\n",
+  sprintf(line, "block_bio_frontmerge: %d,%d %s %llu + %u [%s]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
@@ -1031,8 +1030,8 @@
 
 std::string FormatBlockBioQueue(const BlockBioQueueFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_bio_queue: %d,%d %s %llu + %u [%s]\\n",
-          major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
+  sprintf(line, "block_bio_queue: %d,%d %s %llu + %u [%s]", major(event.dev()),
+          minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
   return std::string(line);
@@ -1040,7 +1039,7 @@
 
 std::string FormatBlockBioRemap(const BlockBioRemapFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_bio_remap:  %d,%d %s %llu + %u <- (%d,%d) %llu\\n",
+  sprintf(line, "block_bio_remap:  %d,%d %s %llu + %u <- (%d,%d) %llu",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           major(event.dev()), minor(event.dev()),
@@ -1050,7 +1049,7 @@
 
 std::string FormatBlockDirtyBuffer(const BlockDirtyBufferFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_dirty_buffer: %d,%d sector=%llu size=%zu\\n",
+  sprintf(line, "block_dirty_buffer: %d,%d sector=%llu size=%zu",
           major(event.dev()), minor(event.dev()),
           static_cast<unsigned long long>(event.sector()),
           static_cast<size_t>(event.size()));
@@ -1059,7 +1058,7 @@
 
 std::string FormatBlockGetrq(const BlockGetrqFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_getrq: %d,%d %s %llu + %u [%s]\\n", major(event.dev()),
+  sprintf(line, "block_getrq: %d,%d %s %llu + %u [%s]", major(event.dev()),
           minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
@@ -1068,13 +1067,13 @@
 
 std::string FormatBlockPlug(const BlockPlugFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_plug: comm=[%s]\\n", event.comm().c_str());
+  sprintf(line, "block_plug: comm=[%s]", event.comm().c_str());
   return std::string(line);
 }
 
 std::string FormatBlockRqAbort(const BlockRqAbortFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_abort: %d,%d %s (%s) %llu + %u [%d]\\n",
+  sprintf(line, "block_rq_abort: %d,%d %s (%s) %llu + %u [%d]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           event.cmd().c_str(), static_cast<unsigned long long>(event.sector()),
           event.nr_sector(), event.errors());
@@ -1083,7 +1082,7 @@
 
 std::string FormatBlockRqComplete(const BlockRqCompleteFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_complete: %d,%d %s (%s) %llu + %u [%d]\\n",
+  sprintf(line, "block_rq_complete: %d,%d %s (%s) %llu + %u [%d]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           event.cmd().c_str(), static_cast<unsigned long long>(event.sector()),
           event.nr_sector(), event.errors());
@@ -1092,7 +1091,7 @@
 
 std::string FormatBlockRqInsert(const BlockRqInsertFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_insert: %d,%d %s %u (%s) %llu + %u [%s]\\n",
+  sprintf(line, "block_rq_insert: %d,%d %s %u (%s) %llu + %u [%s]",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           event.bytes(), event.cmd().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
@@ -1102,7 +1101,7 @@
 
 std::string FormatBlockRqRemap(const BlockRqRemapFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_remap: %d,%d %s %llu + %u <- (%d,%d) %llu %u\\n",
+  sprintf(line, "block_rq_remap: %d,%d %s %llu + %u <- (%d,%d) %llu %u",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           major(event.dev()), minor(event.dev()),
@@ -1112,7 +1111,7 @@
 
 std::string FormatBlockRqRequeue(const BlockRqRequeueFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_rq_requeue: %d,%d %s (%s) %llu + %u [%d\\n",
+  sprintf(line, "block_rq_requeue: %d,%d %s (%s) %llu + %u [%d",
           major(event.dev()), minor(event.dev()), event.rwbs().c_str(),
           event.cmd().c_str(), static_cast<unsigned long long>(event.sector()),
           event.nr_sector(), event.errors());
@@ -1121,7 +1120,7 @@
 
 std::string FormatBlockSleeprq(const BlockSleeprqFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_sleeprq: %d,%d %s %llu + %u [%s]\\n", major(event.dev()),
+  sprintf(line, "block_sleeprq: %d,%d %s %llu + %u [%s]", major(event.dev()),
           minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()), event.nr_sector(),
           event.comm().c_str());
@@ -1130,7 +1129,7 @@
 
 std::string FormatBlockSplit(const BlockSplitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_split: %d,%d %s %llu / %llu [%s]\\n", major(event.dev()),
+  sprintf(line, "block_split: %d,%d %s %llu / %llu [%s]", major(event.dev()),
           minor(event.dev()), event.rwbs().c_str(),
           static_cast<unsigned long long>(event.sector()),
           (unsigned long long)event.new_sector(), event.comm().c_str());
@@ -1139,7 +1138,7 @@
 
 std::string FormatBlockTouchBuffer(const BlockTouchBufferFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_touch_buffer: %d,%d sector=%llu size=%zu\\n",
+  sprintf(line, "block_touch_buffer: %d,%d sector=%llu size=%zu",
           major(event.dev()), minor(event.dev()),
           static_cast<unsigned long long>(event.sector()),
           static_cast<size_t>(event.size()));
@@ -1148,8 +1147,7 @@
 
 std::string FormatBlockUnplug(const BlockUnplugFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "block_unplug: [%s] %d\\n", event.comm().c_str(),
-          event.nr_rq());
+  sprintf(line, "block_unplug: [%s] %d", event.comm().c_str(), event.nr_rq());
   return std::string(line);
 }
 
@@ -1157,7 +1155,7 @@
   char line[2048];
   sprintf(line,
           "ext4_alloc_da_blocks: dev %d,%d ino %lu data_blocks %u meta_blocks "
-          "%u \\n",
+          "%u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.data_blocks(), event.meta_blocks());
   return std::string(line);
@@ -1168,7 +1166,7 @@
   char line[2048];
   sprintf(line,
           "ext4_allocate_blocks: dev %d,%d ino %lu flags %s len %u block %llu "
-          "lblk %u goal %llu lleft %u lright %u pleft %llu pright %llu\\n",
+          "lblk %u goal %llu lleft %u lright %u pleft %llu pright %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           GetExt4HintFlag(event.flags()), event.len(), event.block(),
           event.logical(), event.goal(), event.lleft(), event.lright(),
@@ -1178,7 +1176,7 @@
 
 std::string FormatExt4AllocateInode(const Ext4AllocateInodeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_allocate_inode: dev %d,%d ino %lu dir %lu mode 0%o\\n",
+  sprintf(line, "ext4_allocate_inode: dev %d,%d ino %lu dir %lu mode 0%o",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.dir(), event.mode());
   return std::string(line);
@@ -1187,8 +1185,7 @@
 std::string FormatExt4BeginOrderedTruncate(
     const Ext4BeginOrderedTruncateFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "ext4_begin_ordered_truncate: dev %d,%d ino %lu new_size %lld\\n",
+  sprintf(line, "ext4_begin_ordered_truncate: dev %d,%d ino %lu new_size %lld",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.new_size());
   return std::string(line);
@@ -1196,8 +1193,7 @@
 
 std::string FormatExt4CollapseRange(const Ext4CollapseRangeFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "ext4_collapse_range: dev %d,%d ino %lu offset %lld len %lld\\n",
+  sprintf(line, "ext4_collapse_range: dev %d,%d ino %lu offset %lld len %lld",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.offset(), event.len());
   return std::string(line);
@@ -1209,7 +1205,7 @@
   sprintf(line,
           "ext4_da_release_space: dev %d,%d ino %lu mode 0%o i_blocks %llu "
           "freed_blocks %d reserved_data_blocks %d reserved_meta_blocks %d "
-          "allocated_meta_blocks %d\\n",
+          "allocated_meta_blocks %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.mode(), event.i_blocks(), event.freed_blocks(),
           event.reserved_data_blocks(), event.reserved_meta_blocks(),
@@ -1222,7 +1218,7 @@
   char line[2048];
   sprintf(line,
           "ext4_da_reserve_space:dev %d,%d ino %lu mode 0%o i_blocks %llu "
-          "reserved_data_blocks %d reserved_meta_blocks %d \\n",
+          "reserved_data_blocks %d reserved_meta_blocks %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.mode(), event.i_blocks(), event.reserved_data_blocks(),
           event.reserved_meta_blocks());
@@ -1235,7 +1231,7 @@
   sprintf(line,
           "ext4_da_update_reserve_space: dev %d,%d ino %lu mode 0%o i_blocks "
           "%llu used_blocks %d reserved_data_blocks %d reserved_meta_blocks %d "
-          "allocated_meta_blocks %d quota_claim %d\\n",
+          "allocated_meta_blocks %d quota_claim %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.mode(), event.i_blocks(), event.used_blocks(),
           event.reserved_data_blocks(), event.reserved_meta_blocks(),
@@ -1247,7 +1243,7 @@
   char line[2048];
   sprintf(line,
           "ext4_da_write_pages: dev %d,%d ino %lu first_page %lu nr_to_write "
-          "%ld sync_mode %d\\n",
+          "%ld sync_mode %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.first_page(), (long)event.nr_to_write(),
           event.sync_mode());
@@ -1259,7 +1255,7 @@
     const Ext4DaWritePagesExtentFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_da_write_pages_extent: dev %d,%d ino %lu lblk %llu len %u \\n",
+          "ext4_da_write_pages_extent: dev %d,%d ino %lu lblk %llu len %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.len());
   return std::string(line);
@@ -1267,7 +1263,7 @@
 
 std::string FormatExt4DiscardBlocks(const Ext4DiscardBlocksFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_discard_blocks: dev %d,%d blk %llu count %llu\\n",
+  sprintf(line, "ext4_discard_blocks: dev %d,%d blk %llu count %llu",
           major(event.dev()), minor(event.dev()), event.blk(), event.count());
   return std::string(line);
 }
@@ -1275,14 +1271,14 @@
 std::string FormatExt4DiscardPreallocations(
     const Ext4DiscardPreallocationsFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_discard_preallocations: dev %d,%d ino %lu\\n",
+  sprintf(line, "ext4_discard_preallocations: dev %d,%d ino %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino());
   return std::string(line);
 }
 
 std::string FormatExt4DropInode(const Ext4DropInodeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_drop_inode: dev %d,%d ino %lu drop %d\\n",
+  sprintf(line, "ext4_drop_inode: dev %d,%d ino %lu drop %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.drop());
   return std::string(line);
@@ -1292,7 +1288,7 @@
 std::string FormatExt4EsCacheExtent(const Ext4EsCacheExtentFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_es_cache_extent: dev %d,%d ino %lu es [%u/%u) mapped %llu \\n",
+          "ext4_es_cache_extent: dev %d,%d ino %lu es [%u/%u) mapped %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.len(), event.pblk());
   return std::string(line);
@@ -1301,11 +1297,10 @@
 std::string FormatExt4EsFindDelayedExtentRangeEnter(
     const Ext4EsFindDelayedExtentRangeEnterFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_es_find_delayed_extent_range_enter: dev %d,%d ino %lu lblk %u\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      event.lblk());
+  sprintf(line,
+          "ext4_es_find_delayed_extent_range_enter: dev %d,%d ino %lu lblk %u",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          event.lblk());
   return std::string(line);
 }
 
@@ -1315,7 +1310,7 @@
   char line[2048];
   sprintf(line,
           "ext4_es_find_delayed_extent_range_exit: dev %d,%d ino %lu es "
-          "[%u/%u) mapped %llu\\n",
+          "[%u/%u) mapped %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.len(), event.pblk());
   return std::string(line);
@@ -1326,7 +1321,7 @@
     const Ext4EsInsertExtentFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_es_insert_extent: dev %d,%d ino %lu es [%u/%u) mapped %llu \\n",
+          "ext4_es_insert_extent: dev %d,%d ino %lu es [%u/%u) mapped %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.len(), event.pblk());
   return std::string(line);
@@ -1335,7 +1330,7 @@
 std::string FormatExt4EsLookupExtentEnter(
     const Ext4EsLookupExtentEnterFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_es_lookup_extent_enter: dev %d,%d ino %lu lblk %u\\n",
+  sprintf(line, "ext4_es_lookup_extent_enter: dev %d,%d ino %lu lblk %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk());
   return std::string(line);
@@ -1345,19 +1340,18 @@
 std::string FormatExt4EsLookupExtentExit(
     const Ext4EsLookupExtentExitFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_es_lookup_extent_exit: dev %d,%d ino %lu found %d [%u/%u) %llu\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      event.found(), event.lblk(), event.len(),
-      event.found() ? event.pblk() : 0);
+  sprintf(line,
+          "ext4_es_lookup_extent_exit: dev %d,%d ino %lu found %d [%u/%u) %llu",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          event.found(), event.lblk(), event.len(),
+          event.found() ? event.pblk() : 0);
   return std::string(line);
 }
 
 std::string FormatExt4EsRemoveExtent(
     const Ext4EsRemoveExtentFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_es_remove_extent: dev %d,%d ino %lu es [%lld/%lld)\\n",
+  sprintf(line, "ext4_es_remove_extent: dev %d,%d ino %lu es [%lld/%lld)",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.len());
   return std::string(line);
@@ -1367,7 +1361,7 @@
   char line[2048];
   sprintf(line,
           "ext4_es_shrink: dev %d,%d nr_shrunk %d, scan_time %llu nr_skipped "
-          "%d retried %d\\n",
+          "%d retried %d",
           major(event.dev()), minor(event.dev()), event.nr_shrunk(),
           event.scan_time(), event.nr_skipped(), event.retried());
   return std::string(line);
@@ -1375,7 +1369,7 @@
 
 std::string FormatExt4EsShrinkCount(const Ext4EsShrinkCountFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_es_shrink_count: dev %d,%d nr_to_scan %d cache_cnt %d\\n",
+  sprintf(line, "ext4_es_shrink_count: dev %d,%d nr_to_scan %d cache_cnt %d",
           major(event.dev()), minor(event.dev()), event.nr_to_scan(),
           event.cache_cnt());
   return std::string(line);
@@ -1385,7 +1379,7 @@
     const Ext4EsShrinkScanEnterFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_es_shrink_scan_enter: dev %d,%d nr_to_scan %d cache_cnt %d\\n",
+          "ext4_es_shrink_scan_enter: dev %d,%d nr_to_scan %d cache_cnt %d",
           major(event.dev()), minor(event.dev()), event.nr_to_scan(),
           event.cache_cnt());
   return std::string(line);
@@ -1394,8 +1388,7 @@
 std::string FormatExt4EsShrinkScanExit(
     const Ext4EsShrinkScanExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "ext4_es_shrink_scan_exit: dev %d,%d nr_shrunk %d cache_cnt %d\\n",
+  sprintf(line, "ext4_es_shrink_scan_exit: dev %d,%d nr_shrunk %d cache_cnt %d",
           major(event.dev()), minor(event.dev()), event.nr_shrunk(),
           event.cache_cnt());
   return std::string(line);
@@ -1403,7 +1396,7 @@
 
 std::string FormatExt4EvictInode(const Ext4EvictInodeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_evict_inode: dev %d,%d ino %lu nlink %d\\n",
+  sprintf(line, "ext4_evict_inode: dev %d,%d ino %lu nlink %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.nlink());
   return std::string(line);
@@ -1414,7 +1407,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ext_convert_to_initialized_enter: dev %d,%d ino %lu m_lblk %u "
-          "m_len %u u_lblk %u u_len %u u_pblk %llu\\n",
+          "m_len %u u_lblk %u u_len %u u_pblk %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.m_lblk(), event.m_len(), event.u_lblk(), event.u_len(),
           event.u_pblk());
@@ -1427,7 +1420,7 @@
   sprintf(line,
           "ext4_ext_convert_to_initialized_fastpath: dev %d,%d ino %lu m_lblk "
           "%u m_len %u u_lblk %u u_len %u u_pblk %llu i_lblk %u i_len %u "
-          "i_pblk %llu\\n",
+          "i_pblk %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.m_lblk(), event.m_len(), event.u_lblk(), event.u_len(),
           event.u_pblk(), event.i_lblk(), event.i_len(), event.i_pblk());
@@ -1439,7 +1432,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ext_handle_unwritten_extents: dev %d,%d ino %lu m_lblk %u "
-          "m_pblk %llu m_len %u flags %s allocated %d newblock %llu\\n",
+          "m_pblk %llu m_len %u flags %s allocated %d newblock %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.lblk(), (unsigned long long)event.pblk(), event.len(),
           GetExt4ExtFlag(event.flags()), (unsigned int)event.allocated(),
@@ -1449,7 +1442,7 @@
 
 std::string FormatExt4ExtInCache(const Ext4ExtInCacheFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_ext_in_cache: dev %d,%d ino %lu lblk %u ret %d\\n",
+  sprintf(line, "ext4_ext_in_cache: dev %d,%d ino %lu lblk %u ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.lblk(), event.ret());
   return std::string(line);
@@ -1457,7 +1450,7 @@
 
 std::string FormatExt4ExtLoadExtent(const Ext4ExtLoadExtentFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_ext_load_extent: dev %d,%d ino %lu lblk %u pblk %llu\\n",
+  sprintf(line, "ext4_ext_load_extent: dev %d,%d ino %lu lblk %u pblk %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.pblk());
   return std::string(line);
@@ -1468,7 +1461,7 @@
   char line[2048];
   sprintf(
       line,
-      "ext4_ext_map_blocks_enter: dev %d,%d ino %lu lblk %u len %u flags %s\\n",
+      "ext4_ext_map_blocks_enter: dev %d,%d ino %lu lblk %u len %u flags %s",
       major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
       event.lblk(), event.len(), GetExt4ExtFlag(event.flags()));
   return std::string(line);
@@ -1479,7 +1472,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ext_map_blocks_exit: dev %d,%d ino %lu lblk %u pblk %llu len "
-          "%u flags %x ret %d\\n",
+          "%u flags %x ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.pblk(), event.len(), event.flags(), event.ret());
   return std::string(line);
@@ -1487,22 +1480,21 @@
 
 std::string FormatExt4ExtPutInCache(const Ext4ExtPutInCacheFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_ext_put_in_cache: dev %d,%d ino %lu lblk %u len %u start %llu\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      (unsigned)event.lblk(), event.len(), (unsigned long long)event.start());
+  sprintf(line,
+          "ext4_ext_put_in_cache: dev %d,%d ino %lu lblk %u len %u start %llu",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          (unsigned)event.lblk(), event.len(),
+          (unsigned long long)event.start());
   return std::string(line);
 }
 
 std::string FormatExt4ExtRemoveSpace(
     const Ext4ExtRemoveSpaceFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_ext_remove_space: dev %d,%d ino %lu since %u end %u depth %d\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      (unsigned)event.start(), (unsigned)event.end(), event.depth());
+  sprintf(line,
+          "ext4_ext_remove_space: dev %d,%d ino %lu since %u end %u depth %d",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          (unsigned)event.start(), (unsigned)event.end(), event.depth());
   return std::string(line);
 }
 
@@ -1511,7 +1503,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ext_remove_space_done: dev %d,%d ino %lu since %u end %u depth "
-          "%d partial %lld remaining_entries %u\\n",
+          "%d partial %lld remaining_entries %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.start(), (unsigned)event.end(), event.depth(),
           (long long)event.partial(), (unsigned short)event.eh_entries());
@@ -1520,7 +1512,7 @@
 
 std::string FormatExt4ExtRmIdx(const Ext4ExtRmIdxFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_ext_rm_idx: dev %d,%d ino %lu index_pblk %llu\\n",
+  sprintf(line, "ext4_ext_rm_idx: dev %d,%d ino %lu index_pblk %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long long)event.pblk());
   return std::string(line);
@@ -1530,7 +1522,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ext_rm_leaf: dev %d,%d ino %lu start_lblk %u last_extent "
-          "[%u(%llu), %u]partial_cluster %lld\\n",
+          "[%u(%llu), %u]partial_cluster %lld",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.start(), (unsigned)event.ee_lblk(),
           (unsigned long long)event.ee_pblk(), (unsigned short)event.ee_len(),
@@ -1541,7 +1533,7 @@
 std::string FormatExt4ExtShowExtent(const Ext4ExtShowExtentFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_ext_show_extent: dev %d,%d ino %lu lblk %u pblk %llu len %u\\n",
+          "ext4_ext_show_extent: dev %d,%d ino %lu lblk %u pblk %llu len %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.lblk(), (unsigned long long)event.pblk(),
           (unsigned short)event.len());
@@ -1553,7 +1545,7 @@
   char line[2048];
   sprintf(
       line,
-      "ext4_fallocate_enter: dev %d,%d ino %lu offset %lld len %lld mode %s\\n",
+      "ext4_fallocate_enter: dev %d,%d ino %lu offset %lld len %lld mode %s",
       major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
       event.offset(), event.len(), GetExt4ModeFlag(event.mode()));
   return std::string(line);
@@ -1562,7 +1554,7 @@
 std::string FormatExt4FallocateExit(const Ext4FallocateExitFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_fallocate_exit: dev %d,%d ino %lu pos %lld blocks %u ret %d\\n",
+          "ext4_fallocate_exit: dev %d,%d ino %lu pos %lld blocks %u ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.blocks(), event.ret());
   return std::string(line);
@@ -1573,7 +1565,7 @@
   char line[2048];
   sprintf(line,
           "ext4_find_delalloc_range: dev %d,%d ino %lu from %u to %u reverse "
-          "%d found %d (blk = %u)\\n",
+          "%d found %d (blk = %u)",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.from(), (unsigned)event.to(), event.reverse(),
           event.found(), (unsigned)event.found_blk());
@@ -1582,11 +1574,10 @@
 
 std::string FormatExt4Forget(const Ext4ForgetFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_forget: dev %d,%d ino %lu mode 0%o is_metadata %d block %llu\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      event.mode(), event.is_metadata(), event.block());
+  sprintf(line,
+          "ext4_forget: dev %d,%d ino %lu mode 0%o is_metadata %d block %llu",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          event.mode(), event.is_metadata(), event.block());
   return std::string(line);
 }
 
@@ -1594,7 +1585,7 @@
   char line[2048];
   sprintf(line,
           "ext4_free_blocks: dev %d,%d ino %lu mode 0%o block %llu count %lu "
-          "flags %s\\n",
+          "flags %s",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.mode(), event.block(), (unsigned long)event.count(),
           GetExt4FreeBlocksFlag(event.flags()));
@@ -1605,7 +1596,7 @@
   char line[2048];
   sprintf(line,
           "ext4_free_inode: dev %d,%d ino %lu mode 0%o uid %u gid %u blocks "
-          "%llu\\n",
+          "%llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.mode(), event.uid(), event.gid(), event.blocks());
   return std::string(line);
@@ -1616,7 +1607,7 @@
   char line[2048];
   sprintf(line,
           "ext4_get_implied_cluster_alloc_exit: dev %d,%d m_lblk %u m_pblk "
-          "%llu m_len %u m_flags %u ret %d\\n",
+          "%llu m_len %u m_flags %u ret %d",
           major(event.dev()), minor(event.dev()), event.lblk(),
           (unsigned long long)event.pblk(), event.len(), event.flags(),
           event.ret());
@@ -1626,11 +1617,10 @@
 std::string FormatExt4GetReservedClusterAlloc(
     const Ext4GetReservedClusterAllocFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_get_reserved_cluster_alloc: dev %d,%d ino %lu lblk %u len %u\\n",
-      major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
-      (unsigned)event.lblk(), event.len());
+  sprintf(line,
+          "ext4_get_reserved_cluster_alloc: dev %d,%d ino %lu lblk %u len %u",
+          major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
+          (unsigned)event.lblk(), event.len());
   return std::string(line);
 }
 
@@ -1639,7 +1629,7 @@
   char line[2048];
   sprintf(
       line,
-      "ext4_ind_map_blocks_enter: dev %d,%d ino %lu lblk %u len %u flags %u\\n",
+      "ext4_ind_map_blocks_enter: dev %d,%d ino %lu lblk %u len %u flags %u",
       major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
       event.lblk(), event.len(), event.flags());
   return std::string(line);
@@ -1650,7 +1640,7 @@
   char line[2048];
   sprintf(line,
           "ext4_ind_map_blocks_exit: dev %d,%d ino %lu lblk %u pblk %llu len "
-          "%u flags %x ret %d\\n",
+          "%u flags %x ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.lblk(), event.pblk(), event.len(), event.flags(), event.ret());
   return std::string(line);
@@ -1658,7 +1648,7 @@
 
 std::string FormatExt4InsertRange(const Ext4InsertRangeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_insert_range: dev %d,%d ino %lu offset %lld len %lld\\n",
+  sprintf(line, "ext4_insert_range: dev %d,%d ino %lu offset %lld len %lld",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.offset(), event.len());
   return std::string(line);
@@ -1669,7 +1659,7 @@
   char line[2048];
   sprintf(line,
           "ext4_invalidatepage: dev %d,%d ino %lu page_index %lu offset %u "
-          "length %u\\n",
+          "length %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.index(), event.offset(), event.length());
   return std::string(line);
@@ -1677,19 +1667,17 @@
 
 std::string FormatExt4JournalStart(const Ext4JournalStartFtraceEvent& event) {
   char line[2048];
-  sprintf(
-      line,
-      "ext4_journal_start: dev %d,%d blocks, %d rsv_blocks, %d caller %pS\\n",
-      major(event.dev()), minor(event.dev()), event.blocks(),
-      event.rsv_blocks(), (void*)event.ip());
+  sprintf(line,
+          "ext4_journal_start: dev %d,%d blocks, %d rsv_blocks, %d caller %pS",
+          major(event.dev()), minor(event.dev()), event.blocks(),
+          event.rsv_blocks(), (void*)event.ip());
   return std::string(line);
 }
 
 std::string FormatExt4JournalStartReserved(
     const Ext4JournalStartReservedFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "ext4_journal_start_reserved: dev %d,%d blocks, %d caller %pS\\n",
+  sprintf(line, "ext4_journal_start_reserved: dev %d,%d blocks, %d caller %pS",
           major(event.dev()), minor(event.dev()), event.blocks(),
           (void*)event.ip());
   return std::string(line);
@@ -1700,7 +1688,7 @@
   char line[2048];
   sprintf(line,
           "ext4_journalled_invalidatepage: dev %d,%d ino %lu page_index %lu "
-          "offset %u length %u\\n",
+          "offset %u length %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.index(), event.offset(), event.length());
   return std::string(line);
@@ -1711,7 +1699,7 @@
   char line[2048];
   sprintf(line,
           "ext4_journalled_write_end: dev %d,%d ino %lu pos %lld len %u copied "
-          "%u\\n",
+          "%u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.len(), event.copied());
   return std::string(line);
@@ -1719,7 +1707,7 @@
 
 std::string FormatExt4LoadInode(const Ext4LoadInodeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_load_inode: dev %d,%d ino %ld\\n", major(event.dev()),
+  sprintf(line, "ext4_load_inode: dev %d,%d ino %ld", major(event.dev()),
           minor(event.dev()), (unsigned long)event.ino());
   return std::string(line);
 }
@@ -1727,7 +1715,7 @@
 std::string FormatExt4LoadInodeBitmap(
     const Ext4LoadInodeBitmapFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_load_inode_bitmap: dev %d,%d group %u\\n",
+  sprintf(line, "ext4_load_inode_bitmap: dev %d,%d group %u",
           major(event.dev()), minor(event.dev()), event.group());
   return std::string(line);
 }
@@ -1735,7 +1723,7 @@
 std::string FormatExt4MarkInodeDirty(
     const Ext4MarkInodeDirtyFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mark_inode_dirty: dev %d,%d ino %lu caller %pS\\n",
+  sprintf(line, "ext4_mark_inode_dirty: dev %d,%d ino %lu caller %pS",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (void*)event.ip());
   return std::string(line);
@@ -1743,15 +1731,15 @@
 
 std::string FormatExt4MbBitmapLoad(const Ext4MbBitmapLoadFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mb_bitmap_load: dev %d,%d group %u\\n",
-          major(event.dev()), minor(event.dev()), event.group());
+  sprintf(line, "ext4_mb_bitmap_load: dev %d,%d group %u", major(event.dev()),
+          minor(event.dev()), event.group());
   return std::string(line);
 }
 
 std::string FormatExt4MbBuddyBitmapLoad(
     const Ext4MbBuddyBitmapLoadFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mb_buddy_bitmap_load: dev %d,%d group %u\\n",
+  sprintf(line, "ext4_mb_buddy_bitmap_load: dev %d,%d group %u",
           major(event.dev()), minor(event.dev()), event.group());
   return std::string(line);
 }
@@ -1759,7 +1747,7 @@
 std::string FormatExt4MbDiscardPreallocations(
     const Ext4MbDiscardPreallocationsFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mb_discard_preallocations: dev %d,%d needed %d\\n",
+  sprintf(line, "ext4_mb_discard_preallocations: dev %d,%d needed %d",
           major(event.dev()), minor(event.dev()), event.needed());
   return std::string(line);
 }
@@ -1768,7 +1756,7 @@
   char line[2048];
   sprintf(line,
           "ext4_mb_new_group_pa: dev %d,%d ino %lu pstart %llu len %u lstart "
-          "%llu\\n",
+          "%llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pa_pstart(), event.pa_len(), event.pa_lstart());
   return std::string(line);
@@ -1778,7 +1766,7 @@
   char line[2048];
   sprintf(line,
           "ext4_mb_new_inode_pa: dev %d,%d ino %lu pstart %llu len %u lstart "
-          "%llu\\n",
+          "%llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pa_pstart(), event.pa_len(), event.pa_lstart());
   return std::string(line);
@@ -1787,7 +1775,7 @@
 std::string FormatExt4MbReleaseGroupPa(
     const Ext4MbReleaseGroupPaFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mb_release_group_pa: dev %d,%d pstart %llu len %u\\n",
+  sprintf(line, "ext4_mb_release_group_pa: dev %d,%d pstart %llu len %u",
           major(event.dev()), minor(event.dev()), event.pa_pstart(),
           event.pa_len());
   return std::string(line);
@@ -1797,7 +1785,7 @@
     const Ext4MbReleaseInodePaFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_mb_release_inode_pa: dev %d,%d ino %lu block %llu count %u\\n",
+          "ext4_mb_release_inode_pa: dev %d,%d ino %lu block %llu count %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.block(), event.count());
   return std::string(line);
@@ -1808,7 +1796,7 @@
   sprintf(line,
           "ext4_mballoc_alloc: dev %d,%d inode %lu orig %u/%d/%u@%u goal "
           "%u/%d/%u@%u result %u/%d/%u@%u blks %u grps %u cr %u flags %s tail "
-          "%u broken %u\\n",
+          "%u broken %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.orig_group(), event.orig_start(), event.orig_len(),
           event.orig_logical(), event.goal_group(), event.goal_start(),
@@ -1823,7 +1811,7 @@
 std::string FormatExt4MballocDiscard(
     const Ext4MballocDiscardFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mballoc_discard: dev %d,%d inode %lu extent %u/%d/%d \\n",
+  sprintf(line, "ext4_mballoc_discard: dev %d,%d inode %lu extent %u/%d/%d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.result_group(), event.result_start(), event.result_len());
   return std::string(line);
@@ -1831,7 +1819,7 @@
 
 std::string FormatExt4MballocFree(const Ext4MballocFreeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_mballoc_free: dev %d,%d inode %lu extent %u/%d/%d \\n",
+  sprintf(line, "ext4_mballoc_free: dev %d,%d inode %lu extent %u/%d/%d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.result_group(), event.result_start(), event.result_len());
   return std::string(line);
@@ -1842,7 +1830,7 @@
   char line[2048];
   sprintf(line,
           "ext4_mballoc_prealloc: dev %d,%d inode %lu orig %u/%d/%u@%u result "
-          "%u/%d/%u@%u\\n",
+          "%u/%d/%u@%u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.orig_group(), event.orig_start(), event.orig_len(),
           event.orig_logical(), event.result_group(), event.result_start(),
@@ -1855,7 +1843,7 @@
   char line[2048];
   sprintf(line,
           "ext4_other_inode_update_time: dev %d,%d orig_ino %lu ino %lu mode "
-          "0%o uid %u gid %u\\n",
+          "0%o uid %u gid %u",
           major(event.dev()), minor(event.dev()),
           (unsigned long)event.orig_ino(), (unsigned long)event.ino(),
           event.mode(), event.uid(), event.gid());
@@ -1865,7 +1853,7 @@
 std::string FormatExt4PunchHole(const Ext4PunchHoleFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_punch_hole: dev %d,%d ino %lu offset %lld len %lld mode %s\\n",
+          "ext4_punch_hole: dev %d,%d ino %lu offset %lld len %lld mode %s",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.offset(), event.len(), GetExt4ModeFlag(event.mode()));
   return std::string(line);
@@ -1874,14 +1862,14 @@
 std::string FormatExt4ReadBlockBitmapLoad(
     const Ext4ReadBlockBitmapLoadFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_read_block_bitmap_load: dev %d,%d group %u\\n",
+  sprintf(line, "ext4_read_block_bitmap_load: dev %d,%d group %u",
           major(event.dev()), minor(event.dev()), event.group());
   return std::string(line);
 }
 
 std::string FormatExt4Readpage(const Ext4ReadpageFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_readpage: dev %d,%d ino %lu page_index %lu\\n",
+  sprintf(line, "ext4_readpage: dev %d,%d ino %lu page_index %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.index());
   return std::string(line);
@@ -1889,7 +1877,7 @@
 
 std::string FormatExt4Releasepage(const Ext4ReleasepageFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_releasepage: dev %d,%d ino %lu page_index %lu\\n",
+  sprintf(line, "ext4_releasepage: dev %d,%d ino %lu page_index %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.index());
   return std::string(line);
@@ -1899,7 +1887,7 @@
   char line[2048];
   sprintf(line,
           "ext4_remove_blocks: dev %d,%d ino %lu extent [%u(%llu), %u]from %u "
-          "to %u partial_cluster %lld\\n",
+          "to %u partial_cluster %lld",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned)event.ee_lblk(), (unsigned long long)event.ee_pblk(),
           (unsigned short)event.ee_len(), (unsigned)event.from(),
@@ -1911,7 +1899,7 @@
   char line[2048];
   sprintf(line,
           "ext4_request_blocks: dev %d,%d ino %lu flags %s len %u lblk %u goal "
-          "%llu lleft %u lright %u pleft %llu pright %llu \\n",
+          "%llu lleft %u lright %u pleft %llu pright %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           GetExt4HintFlag(event.flags()), event.len(), event.logical(),
           event.goal(), event.lleft(), event.lright(), event.pleft(),
@@ -1921,7 +1909,7 @@
 
 std::string FormatExt4RequestInode(const Ext4RequestInodeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_request_inode: dev %d,%d dir %lu mode 0%o\\n",
+  sprintf(line, "ext4_request_inode: dev %d,%d dir %lu mode 0%o",
           major(event.dev()), minor(event.dev()), (unsigned long)event.dir(),
           event.mode());
   return std::string(line);
@@ -1929,14 +1917,14 @@
 
 std::string FormatExt4SyncFs(const Ext4SyncFsFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_sync_fs: dev %d,%d wait %d\\n", major(event.dev()),
+  sprintf(line, "ext4_sync_fs: dev %d,%d wait %d", major(event.dev()),
           minor(event.dev()), event.wait());
   return std::string(line);
 }
 
 std::string FormatExt4TrimAllFree(const Ext4TrimAllFreeFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_trim_all_free: dev %d,%d group %u, start %d, len %d\\n",
+  sprintf(line, "ext4_trim_all_free: dev %d,%d group %u, start %d, len %d",
           event.dev_major(), event.dev_minor(), event.group(), event.start(),
           event.len());
   return std::string(line);
@@ -1944,7 +1932,7 @@
 
 std::string FormatExt4TrimExtent(const Ext4TrimExtentFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_trim_extent: dev %d,%d group %u, start %d, len %d\\n",
+  sprintf(line, "ext4_trim_extent: dev %d,%d group %u, start %d, len %d",
           event.dev_major(), event.dev_minor(), event.group(), event.start(),
           event.len());
   return std::string(line);
@@ -1952,7 +1940,7 @@
 
 std::string FormatExt4TruncateEnter(const Ext4TruncateEnterFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_truncate_enter: dev %d,%d ino %lu blocks %llu\\n",
+  sprintf(line, "ext4_truncate_enter: dev %d,%d ino %lu blocks %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.blocks());
   return std::string(line);
@@ -1960,7 +1948,7 @@
 
 std::string FormatExt4TruncateExit(const Ext4TruncateExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_truncate_exit: dev %d,%d ino %lu blocks %llu\\n",
+  sprintf(line, "ext4_truncate_exit: dev %d,%d ino %lu blocks %llu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.blocks());
   return std::string(line);
@@ -1968,7 +1956,7 @@
 
 std::string FormatExt4UnlinkEnter(const Ext4UnlinkEnterFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_unlink_enter: dev %d,%d ino %lu size %lld parent %lu\\n",
+  sprintf(line, "ext4_unlink_enter: dev %d,%d ino %lu size %lld parent %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.size(), (unsigned long)event.parent());
   return std::string(line);
@@ -1976,7 +1964,7 @@
 
 std::string FormatExt4UnlinkExit(const Ext4UnlinkExitFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_unlink_exit: dev %d,%d ino %lu ret %d\\n",
+  sprintf(line, "ext4_unlink_exit: dev %d,%d ino %lu ret %d",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.ret());
   return std::string(line);
@@ -1984,8 +1972,7 @@
 
 std::string FormatExt4WriteBegin(const Ext4WriteBeginFtraceEvent& event) {
   char line[2048];
-  sprintf(line,
-          "ext4_write_begin: dev %d,%d ino %lu pos %lld len %u flags %u\\n",
+  sprintf(line, "ext4_write_begin: dev %d,%d ino %lu pos %lld len %u flags %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.len(), event.flags());
   return std::string(line);
@@ -1993,7 +1980,7 @@
 
 std::string FormatExt4WriteEnd(const Ext4WriteEndFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_write_end: %d,%d ino %lu pos %lld len %u copied %u\\n",
+  sprintf(line, "ext4_write_end: %d,%d ino %lu pos %lld len %u copied %u",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.pos(), event.len(), event.copied());
   return std::string(line);
@@ -2001,7 +1988,7 @@
 
 std::string FormatExt4Writepage(const Ext4WritepageFtraceEvent& event) {
   char line[2048];
-  sprintf(line, "ext4_writepage: dev %d,%d ino %lu page_index %lu\\n",
+  sprintf(line, "ext4_writepage: dev %d,%d ino %lu page_index %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (unsigned long)event.index());
   return std::string(line);
@@ -2012,7 +1999,7 @@
   sprintf(line,
           "ext4_writepages: dev %d,%d ino %lu nr_to_write %ld pages_skipped "
           "%ld range_start %lld range_end %lld sync_mode %d for_kupdate %d "
-          "range_cyclic %d writeback_index %lu\\n",
+          "range_cyclic %d writeback_index %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           (long)event.nr_to_write(), (long)event.pages_skipped(),
           event.range_start(), event.range_end(), event.sync_mode(),
@@ -2026,7 +2013,7 @@
   char line[2048];
   sprintf(line,
           "ext4_writepages_result: dev %d,%d ino %lu ret %d pages_written %d "
-          "pages_skipped %ld sync_mode %d writeback_index %lu \\n",
+          "pages_skipped %ld sync_mode %d writeback_index %lu",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.ret(), event.pages_written(), (long)event.pages_skipped(),
           event.sync_mode(), (unsigned long)event.writeback_index());
@@ -2036,7 +2023,7 @@
 std::string FormatExt4ZeroRange(const Ext4ZeroRangeFtraceEvent& event) {
   char line[2048];
   sprintf(line,
-          "ext4_zero_range: dev %d,%d ino %lu offset %lld len %lld mode %s\\n ",
+          "ext4_zero_range: dev %d,%d ino %lu offset %lld len %lld mode %s",
           major(event.dev()), minor(event.dev()), (unsigned long)event.ino(),
           event.offset(), event.len(), GetExt4ModeFlag(event.mode()));
   return std::string(line);
diff --git a/tools/trace_to_text/main.cc b/tools/trace_to_text/main.cc
index 2f0c96b..bd29756 100644
--- a/tools/trace_to_text/main.cc
+++ b/tools/trace_to_text/main.cc
@@ -164,7 +164,9 @@
   }
 }
 
-int TraceToSystrace(std::istream* input, std::ostream* output) {
+int TraceToSystrace(std::istream* input,
+                    std::ostream* output,
+                    bool wrap_in_json) {
   std::multimap<uint64_t, std::string> sorted;
 
   ForEachPacketInTrace(input, [&sorted](const protos::TracePacket& packet) {
@@ -181,22 +183,25 @@
     }
   });
 
-  *output << kTraceHeader;
-  *output << kFtraceHeader;
+  if (wrap_in_json) {
+    *output << kTraceHeader;
+    *output << kFtraceHeader;
+  }
 
   fprintf(stderr, "\n");
   size_t total_events = sorted.size();
   size_t written_events = 0;
   for (auto it = sorted.begin(); it != sorted.end(); it++) {
-    *output << it->second;
-    if (written_events++ % 100 == 0) {
+    *output << it->second << (wrap_in_json ? "\\n" : "\n");
+    if (written_events++ % 100 == 0 && !isatty(STDOUT_FILENO)) {
       fprintf(stderr, "Writing trace: %.2f %%\r",
               written_events * 100.0 / total_events);
       fflush(stderr);
     }
   }
 
-  *output << kTraceFooter;
+  if (wrap_in_json)
+    *output << kTraceFooter;
 
   return 0;
 }
@@ -289,10 +294,10 @@
                    ftrace_inodes.begin(), ftrace_inodes.end(),
                    std::inserter(intersect, intersect.begin()));
 
-  sprintf(line, "Unresolved inodes: %" PRIu64 "\n",
+  sprintf(line, "Unresolved inodes: %zu\n",
           ftrace_inodes.size() - intersect.size());
 
-  sprintf(line, "Unexpected inodes from filesystem: %" PRIu64 "\n",
+  sprintf(line, "Unexpected inodes from filesystem: %zu\n",
           resolved_inodes.size() - intersect.size());
   *output << std::string(line);
 
@@ -404,7 +409,7 @@
 namespace {
 
 int Usage(int argc, char** argv) {
-  printf("Usage: %s [systrace|text|summary] < trace.proto > trace.txt\n",
+  printf("Usage: %s [systrace|json|text|summary] < trace.proto > trace.txt\n",
          argv[0]);
   return 1;
 }
@@ -417,15 +422,15 @@
 
   std::string format(argv[1]);
 
-  bool is_systrace = format == "systrace";
-  bool is_text = format == "text";
-  bool is_summary = format == "summary";
-
-  if (is_systrace)
-    return perfetto::TraceToSystrace(&std::cin, &std::cout);
-  if (is_text)
+  if (format == "json")
+    return perfetto::TraceToSystrace(&std::cin, &std::cout,
+                                     /*wrap_in_json=*/true);
+  if (format == "systrace")
+    return perfetto::TraceToSystrace(&std::cin, &std::cout,
+                                     /*wrap_in_json=*/false);
+  if (format == "text")
     return perfetto::TraceToText(&std::cin, &std::cout);
-  if (is_summary)
+  if (format == "summary")
     return perfetto::TraceToSummary(&std::cin, &std::cout);
   return Usage(argc, argv);
 }