Merge "Fix PDK build"
diff --git a/gn/standalone/libc++/BUILD.gn b/gn/standalone/libc++/BUILD.gn
index 9b1515a..a8ccba1 100644
--- a/gn/standalone/libc++/BUILD.gn
+++ b/gn/standalone/libc++/BUILD.gn
@@ -37,8 +37,6 @@
       "dl",  # libdl: dynamic linking.
       "gcc_eh",  # gcc exception handling, required by libunwind.
     ]
-  } else {
-    libs = [ "atomic" ]
   }
 }
 
diff --git a/include/perfetto/ftrace_reader/ftrace_controller.h b/include/perfetto/ftrace_reader/ftrace_controller.h
index ce9c6cb..7de9e53 100644
--- a/include/perfetto/ftrace_reader/ftrace_controller.h
+++ b/include/perfetto/ftrace_reader/ftrace_controller.h
@@ -42,6 +42,9 @@
 
 const size_t kMaxSinks = 32;
 
+// Method of last resort to reset ftrace state.
+void HardResetFtraceState();
+
 class FtraceController;
 class ProtoTranslationTable;
 class CpuReader;
diff --git a/src/ftrace_reader/end_to_end_integrationtest.cc b/src/ftrace_reader/end_to_end_integrationtest.cc
index 8f4bee6..09e8336 100644
--- a/src/ftrace_reader/end_to_end_integrationtest.cc
+++ b/src/ftrace_reader/end_to_end_integrationtest.cc
@@ -166,6 +166,6 @@
   std::string output_as_text;
   printf("%s\n", output_as_text.c_str());
 }
-#endif  // BUILDFLAG(PERFETTO_OS_ANDROID)
+#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
 
 }  // namespace perfetto
diff --git a/src/ftrace_reader/ftrace_controller.cc b/src/ftrace_reader/ftrace_controller.cc
index ee9252c..053eae6 100644
--- a/src/ftrace_reader/ftrace_controller.cc
+++ b/src/ftrace_reader/ftrace_controller.cc
@@ -22,6 +22,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
+#include <unistd.h>
 
 #include <array>
 #include <string>
@@ -107,8 +108,39 @@
   return status == 0;
 }
 
+void WriteToFile(const char* path, const char* str) {
+  int fd = open(path, O_WRONLY);
+  if (fd == -1)
+    return;
+  perfetto::base::ignore_result(write(fd, str, strlen(str)));
+  perfetto::base::ignore_result(close(fd));
+}
+
+void ClearFile(const char* path) {
+  int fd = open(path, O_WRONLY | O_TRUNC);
+  if (fd == -1)
+    return;
+  perfetto::base::ignore_result(close(fd));
+}
+
 }  // namespace
 
+// TODO(fmayer): Actually call this on shutdown.
+// Method of last resort to reset ftrace state.
+// We don't know what state the rest of the system and process is so as far
+// as possible avoid allocations.
+void HardResetFtraceState() {
+  WriteToFile("/sys/kernel/debug/tracing/tracing_on", "0");
+  WriteToFile("/sys/kernel/debug/tracing/buffer_size_kb", "4");
+  WriteToFile("/sys/kernel/debug/tracing/events/enable", "0");
+  ClearFile("/sys/kernel/debug/tracing/trace");
+
+  WriteToFile("/sys/kernel/tracing/tracing_on", "0");
+  WriteToFile("/sys/kernel/tracing/buffer_size_kb", "4");
+  WriteToFile("/sys/kernel/tracing/events/enable", "0");
+  ClearFile("/sys/kernel/tracing/trace");
+}
+
 // static
 // TODO(taylori): Add a test for tracing paths in integration tests.
 std::unique_ptr<FtraceController> FtraceController::Create(
diff --git a/src/ftrace_reader/ftrace_procfs_integrationtest.cc b/src/ftrace_reader/ftrace_procfs_integrationtest.cc
index 620cd87..e6f698e 100644
--- a/src/ftrace_reader/ftrace_procfs_integrationtest.cc
+++ b/src/ftrace_reader/ftrace_procfs_integrationtest.cc
@@ -22,6 +22,7 @@
 #include "ftrace_procfs.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
+#include "perfetto/ftrace_reader/ftrace_controller.h"
 
 using testing::HasSubstr;
 using testing::Not;
@@ -60,16 +61,31 @@
 
 }  // namespace
 
-// TODO(lalitm): reenable these thests (see b/72306171).
-TEST(FtraceProcfsIntegrationTest, DISABLED_CreateWithGoodPath) {
+// TODO(lalitm): reenable these tests (see b/72306171).
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_CreateWithGoodPath CreateWithGoodPath
+#else
+#define MAYBE_CreateWithGoodPath DISABLED_CreateWithGoodPath
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_CreateWithGoodPath) {
   EXPECT_TRUE(FtraceProcfs::Create(kTracingPath));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_CreateWithBadPath) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_CreateWithBadPath CreateWithBadPath
+#else
+#define MAYBE_CreateWithBadPath DISABLED_CreateWithBadath
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_CreateWithBadPath) {
   EXPECT_FALSE(FtraceProcfs::Create(kTracingPath + std::string("bad_path")));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_ClearTrace) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_ClearTrace ClearTrace
+#else
+#define MAYBE_ClearTrace DISABLED_ClearTrace
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_ClearTrace) {
   FtraceProcfs ftrace(kTracingPath);
   ResetFtrace(&ftrace);
   ftrace.WriteTraceMarker("Hello, World!");
@@ -77,14 +93,24 @@
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello, World!")));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_TraceMarker) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_TraceMarker TraceMarker
+#else
+#define MAYBE_TraceMarker DISABLED_TraceMarker
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_TraceMarker) {
   FtraceProcfs ftrace(kTracingPath);
   ResetFtrace(&ftrace);
   ftrace.WriteTraceMarker("Hello, World!");
   EXPECT_THAT(GetTraceOutput(), HasSubstr("Hello, World!"));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_EnableDisableEvent) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_EnableDisableEvent EnableDisableEvent
+#else
+#define MAYBE_EnableDisableEvent DISABLED_EnableDisableEvent
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_EnableDisableEvent) {
   FtraceProcfs ftrace(kTracingPath);
   ResetFtrace(&ftrace);
   ftrace.EnableEvent("sched", "sched_switch");
@@ -97,7 +123,12 @@
   EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("sched_switch")));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_EnableDisableTracing) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_EnableDisableTracing EnableDisableTracing
+#else
+#define MAYBE_EnableDisableTracing DISABLED_EnableDisableTracing
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_EnableDisableTracing) {
   FtraceProcfs ftrace(kTracingPath);
   ResetFtrace(&ftrace);
   EXPECT_TRUE(ftrace.IsTracingEnabled());
@@ -113,25 +144,45 @@
   EXPECT_THAT(GetTraceOutput(), HasSubstr("After"));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_ReadFormatFile) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_ReadFormatFile ReadFormatFile
+#else
+#define MAYBE_ReadFormatFile DISABLED_ReadFormatFile
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_ReadFormatFile) {
   FtraceProcfs ftrace(kTracingPath);
   std::string format = ftrace.ReadEventFormat("ftrace", "print");
   EXPECT_THAT(format, HasSubstr("name: print"));
   EXPECT_THAT(format, HasSubstr("field:char buf"));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_ReadAvailableEvents) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_ReadAvailableEvents ReadAvailableEvents
+#else
+#define MAYBE_ReadAvailableEvents DISABLED_ReadAvailableEvents
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_ReadAvailableEvents) {
   FtraceProcfs ftrace(kTracingPath);
   std::string format = ftrace.ReadAvailableEvents();
   EXPECT_THAT(format, HasSubstr("sched:sched_switch"));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_CanOpenTracePipeRaw) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_CanOpenTracePipeRaw CanOpenTracePipeRaw
+#else
+#define MAYBE_CanOpenTracePipeRaw DISABLED_CanOpenTracePipeRaw
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_CanOpenTracePipeRaw) {
   FtraceProcfs ftrace(kTracingPath);
   EXPECT_TRUE(ftrace.OpenPipeForCpu(0));
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_Clock) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_Clock Clock
+#else
+#define MAYBE_Clock DISABLED_Clock
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_Clock) {
   FtraceProcfs ftrace(kTracingPath);
   std::set<std::string> clocks = ftrace.AvailableClocks();
   EXPECT_THAT(clocks, Contains("local"));
@@ -143,7 +194,12 @@
   EXPECT_EQ(ftrace.GetClock(), "local");
 }
 
-TEST(FtraceProcfsIntegrationTest, DISABLED_CanSetBufferSize) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_CanSetBufferSize CanSetBufferSize
+#else
+#define MAYBE_CanSetBufferSize DISABLED_CanSetBufferSize
+#endif
+TEST(FtraceProcfsIntegrationTest, MAYBE_CanSetBufferSize) {
   FtraceProcfs ftrace(kTracingPath);
   EXPECT_TRUE(ftrace.SetCpuBufferSizeInPages(4ul));
   EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");  // (4096 * 4) / 1024
@@ -151,4 +207,26 @@
   EXPECT_EQ(ReadFile("buffer_size_kb"), "20\n");  // (4096 * 5) / 1024
 }
 
+TEST(FtraceProcfsIntegrationTest, DISABLED_FtraceControllerHardReset) {
+  FtraceProcfs ftrace(kTracingPath);
+  ResetFtrace(&ftrace);
+
+  ftrace.SetCpuBufferSizeInPages(4ul);
+  ftrace.EnableTracing();
+  ftrace.EnableEvent("sched", "sched_switch");
+  ftrace.WriteTraceMarker("Hello, World!");
+
+  EXPECT_EQ(ReadFile("buffer_size_kb"), "16\n");
+  EXPECT_EQ(ReadFile("tracing_on"), "1\n");
+  EXPECT_EQ(ReadFile("events/enable"), "X\n");
+  EXPECT_THAT(GetTraceOutput(), HasSubstr("Hello"));
+
+  HardResetFtraceState();
+
+  EXPECT_EQ(ReadFile("buffer_size_kb"), "4\n");
+  EXPECT_EQ(ReadFile("tracing_on"), "0\n");
+  EXPECT_EQ(ReadFile("events/enable"), "0\n");
+  EXPECT_THAT(GetTraceOutput(), Not(HasSubstr("Hello")));
+}
+
 }  // namespace perfetto
diff --git a/src/traced/probes/ftrace_producer.h b/src/traced/probes/ftrace_producer.h
index 27c292a..95c9a99 100644
--- a/src/traced/probes/ftrace_producer.h
+++ b/src/traced/probes/ftrace_producer.h
@@ -60,8 +60,11 @@
 
    private:
     std::unique_ptr<FtraceSink> sink_ = nullptr;
-    TraceWriter::TracePacketHandle trace_packet_;
     std::unique_ptr<TraceWriter> writer_;
+
+    // Keep this after the TraceWriter because TracePackets must not outlive
+    // their originating writer.
+    TraceWriter::TracePacketHandle trace_packet_;
   };
 
   enum State {
diff --git a/src/tracing/core/trace_writer_impl.cc b/src/tracing/core/trace_writer_impl.cc
index f38128e..3bd4199 100644
--- a/src/tracing/core/trace_writer_impl.cc
+++ b/src/tracing/core/trace_writer_impl.cc
@@ -18,6 +18,7 @@
 
 #include <string.h>
 
+#include <algorithm>
 #include <type_traits>
 #include <utility>
 
diff --git a/test/AndroidTest.xml b/test/AndroidTest.xml
index 3f2a230..8f529af 100644
--- a/test/AndroidTest.xml
+++ b/test/AndroidTest.xml
@@ -21,10 +21,7 @@
         <option name="push" value="perfetto_unittests->/data/local/tmp/perfetto_unittests" />
         <option name="push" value="perfetto_integrationtests->/data/local/tmp/perfetto_integrationtests" />
     </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
-        <option name="run-command" value="setprop persist.traced.enable 1" />
-        <option name="teardown-command" value="setprop persist.traced.enable 0" />
-    </target_preparer>
+    <option name="post-boot-command" value="setprop persist.traced.enable 1" />
     <test class="com.android.tradefed.testtype.GTest" >
       <option name="native-test-device-path" value="/data/local/tmp/perfetto_unittests" />
       <option name="module-name" value="perfetto_unittests" />
diff --git a/test/end_to_end_integrationtest.cc b/test/end_to_end_integrationtest.cc
index f881cc3..deb1a59 100644
--- a/test/end_to_end_integrationtest.cc
+++ b/test/end_to_end_integrationtest.cc
@@ -113,16 +113,19 @@
   };
 };
 
-// TODO(lalitm): reenable this when we have a solution for running ftrace
-// on travis.
-TEST_F(PerfettoTest, DISABLED_TestFtraceProducer) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#define MAYBE_TestFtraceProducer TestFtraceProducer
+#else
+#define MAYBE_TestFtraceProducer DISABLED_TestFtraceProducer
+#endif
+TEST_F(PerfettoTest, MAYBE_TestFtraceProducer) {
   base::TestTaskRunner task_runner;
   auto finish = task_runner.CreateCheckpoint("no.more.packets");
 
   // Setip the TraceConfig for the consumer.
   TraceConfig trace_config;
   trace_config.add_buffers()->set_size_kb(4096 * 10);
-  trace_config.set_duration_ms(200);
+  trace_config.set_duration_ms(3000);
 
   // Create the buffer for ftrace.
   auto* ds_config = trace_config.add_data_sources()->mutable_config();