[go: nahoru, domu]

Reland "android: Remove the legacy orderfile instrumentation."

This reverts commit 2b33f7e21ffa29e67a02d27161c0e03486287744.

Reason for reland: The initial CL wasn't related to
                   crbug.com/814627.

Original change's description:
> Revert "android: Remove the legacy orderfile instrumentation."
> 
> This reverts commit 5ecdb8cf939ff1d3b53a34e45e283e0975ba8283.
> 
> Reason for revert: Speculative revert for crbug.com/814627
> 
> Original change's description:
> > android: Remove the legacy orderfile instrumentation.
> > 
> > Bug: 813597
> > Change-Id: Ie4838ed3b816b483b3b44325f4159856c3b81d4e
> > Reviewed-on: https://chromium-review.googlesource.com/925424
> > Reviewed-by: Egor Pasko <pasko@chromium.org>
> > Reviewed-by: agrieve <agrieve@chromium.org>
> > Reviewed-by: Matthew Cary <mattcary@chromium.org>
> > Commit-Queue: Benoit L <lizeb@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#538082}
> 
> TBR=pasko@chromium.org,agrieve@chromium.org,lizeb@chromium.org,mattcary@chromium.org
> 
> Change-Id: I161ebcdaf105d561d4b4ad5ebb21a065ebc9be14
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: 813597
> Reviewed-on: https://chromium-review.googlesource.com/931381
> Reviewed-by: Tien-Ren Chen <trchen@chromium.org>
> Commit-Queue: Tien-Ren Chen <trchen@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#538414}

TBR=pasko@chromium.org,trchen@chromium.org,agrieve@chromium.org,lizeb@chromium.org,mattcary@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 813597
Change-Id: I22daf61b6441336d9158124be3cc71959e426613
Reviewed-on: https://chromium-review.googlesource.com/951422
Reviewed-by: Benoit L <lizeb@chromium.org>
Reviewed-by: Egor Pasko <pasko@chromium.org>
Reviewed-by: Matthew Cary <mattcary@chromium.org>
Commit-Queue: Benoit L <lizeb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541111}
diff --git a/BUILD.gn b/BUILD.gn
index 0f2e28a..37cf59b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -309,7 +309,6 @@
       "//tools/android/customtabs_benchmark:customtabs_benchmark_apk",
       "//tools/android/errorprone_plugin:errorprone_plugin_java",
       "//tools/android/kerberos/SpnegoAuthenticator:spnego_authenticator_apk",
-      "//tools/cygprofile:cygprofile_unittests",
       "//ui/android:ui_junit_tests",
     ]
     deps -= [
diff --git a/base/android/library_loader/library_prefetcher.cc b/base/android/library_loader/library_prefetcher.cc
index dda25778a..fefbb5e 100644
--- a/base/android/library_loader/library_prefetcher.cc
+++ b/base/android/library_loader/library_prefetcher.cc
@@ -184,9 +184,9 @@
 
 // static
 bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary() {
-  // Avoid forking with cygprofile instrumentation because the latter performs
-  // memory allocations.
 #if defined(CYGPROFILE_INSTRUMENTATION)
+  // Avoid forking with cygprofile instrumentation because the child process
+  // would create a dump as well.
   return false;
 #endif
 
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn
index 4e73318..fabde6c 100644
--- a/build/config/android/BUILD.gn
+++ b/build/config/android/BUILD.gn
@@ -216,11 +216,7 @@
 
 config("cygprofile_instrumentation") {
   defines = [ "CYGPROFILE_INSTRUMENTATION=1" ]
-  if (use_lightweight_order_profiling) {
-    cflags = [ "-finstrument-function-entry-bare" ]
-  } else {
-    cflags = [ "-finstrument-functions-after-inlining" ]
-  }
+  cflags = [ "-finstrument-function-entry-bare" ]
 }
 
 config("no_cygprofile_instrumentation") {
diff --git a/build/config/android/abi.gni b/build/config/android/abi.gni
index 24bef19..877c3f74 100644
--- a/build/config/android/abi.gni
+++ b/build/config/android/abi.gni
@@ -12,11 +12,6 @@
   # functions are called at startup.
   use_order_profiling = false
 
-  # Use a lightweight variant of order profiling. Does nothing without
-  # use_order_profiling set above. Will either replace use_order_profiling
-  # or be removed.
-  use_lightweight_order_profiling = false
-
   # Builds secondary abi for APKs, supports build 32-bit arch as secondary
   # abi in 64-bit Monochrome and WebView.
   build_apk_secondary_abi = true
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index efd4954c..bdff8d3 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -778,8 +778,8 @@
       deps += [ "//tools/cygprofile" ]
     }
 
-    # See crbug.com/705088, crbug.com/717815.
-    if (target_cpu == "arm" && (is_asan || use_order_profiling)) {
+    # See crbug.com/705088.
+    if (target_cpu == "arm" && is_asan) {
       ldflags = [ "-Wl,--long-plt" ]
     }
 
diff --git a/tools/cygprofile/BUILD.gn b/tools/cygprofile/BUILD.gn
index f5f9016..0ba8b6a 100644
--- a/tools/cygprofile/BUILD.gn
+++ b/tools/cygprofile/BUILD.gn
@@ -5,8 +5,9 @@
 import("//build/config/android/config.gni")
 
 if (target_cpu == "arm") {
-  static_library("lightweight_cygprofile") {
+  static_library("cygprofile") {
     sources = [
+      "delayed_dumper.cc",
       "lightweight_cygprofile.cc",
       "lightweight_cygprofile.h",
     ]
@@ -17,71 +18,8 @@
     configs -= [ "//build/config/android:default_cygprofile_instrumentation" ]
     configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
   }
-}
 
-static_library("cygprofile") {
-  deps = [
-    # This adds uninstrumented symbols to the static library from base.
-    # These symbols are likely *not* to be used because there are many other
-    # duplicates in other objects/libraries.
-    "//base",
-  ]
-
-  if (use_lightweight_order_profiling) {
-    assert(use_order_profiling)
-    assert(target_cpu == "arm")
-    sources = [
-      "delayed_dumper.cc",
-    ]
-    deps += [ ":lightweight_cygprofile" ]
-  } else {
-    sources = [
-      "cygprofile.cc",
-      "cygprofile.h",
-    ]
-  }
-
-  configs -= [ "//build/config/android:default_cygprofile_instrumentation" ]
-  configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
-}
-
-executable("cygprofile_unittests") {
-  testonly = true
-
-  sources = [
-    "cygprofile_unittest.cc",
-  ]
-
-  configs -= [ "//build/config/android:default_cygprofile_instrumentation" ]
-  configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
-
-  deps = [
-    ":cygprofile",
-    "//base",
-    "//testing/gtest",
-  ]
-}
-
-executable("cygprofile_perftests") {
-  testonly = true
-
-  sources = [
-    "cygprofile_perftest.cc",
-  ]
-
-  configs -= [ "//build/config/android:default_cygprofile_instrumentation" ]
-  configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
-
-  deps = [
-    ":cygprofile",
-    "//base",
-    "//testing/gtest",
-    "//testing/perf",
-  ]
-}
-
-if (target_cpu == "arm") {
-  executable("lightweight_cygprofile_perftests") {
+  executable("cygprofile_perftests") {
     testonly = true
 
     sources = [
@@ -92,7 +30,7 @@
     configs += [ "//build/config/android:no_cygprofile_instrumentation" ]
 
     deps = [
-      ":lightweight_cygprofile",
+      ":cygprofile",
       "//base",
       "//testing/gtest",
       "//testing/perf",
diff --git a/tools/cygprofile/cyglog_to_orderfile.py b/tools/cygprofile/cyglog_to_orderfile.py
index 0fb2e90..aecb101 100755
--- a/tools/cygprofile/cyglog_to_orderfile.py
+++ b/tools/cygprofile/cyglog_to_orderfile.py
@@ -13,7 +13,6 @@
 import multiprocessing
 import os
 import re
-import string
 import sys
 import tempfile
 
@@ -123,6 +122,7 @@
     symbol_infos_nested = pool.map(
         symbol_extractor.SymbolInfosFromBinary, obj_files)
     pool.close()
+    pool.join()
     result = []
     for symbol_infos in symbol_infos_nested:
       result += symbol_infos
@@ -201,47 +201,6 @@
       raise _SymbolNotFoundException(offset)
 
 
-def _ParseLogLines(log_file_lines):
-  """Parses a merged cyglog produced by mergetraces.py.
-
-  Args:
-    log_file_lines: array of lines in log file produced by profiled run
-
-    Below is an example of a small log file:
-    5086e000-52e92000 r-xp 00000000 b3:02 51276      libchromeview.so
-    secs       usecs      pid:threadid    func
-    START
-    1314897086 795828     3587:1074648168 0x509e105c
-    1314897086 795874     3587:1074648168 0x509e0eb4
-    1314897086 796326     3587:1074648168 0x509e0e3c
-    1314897086 796552     3587:1074648168 0x509e07bc
-    END
-
-  Returns:
-    An ordered list of callee offsets.
-  """
-  call_lines = []
-  vm_start = 0
-  line = log_file_lines[0]
-  assert 'r-xp' in line
-  end_index = line.find('-')
-  vm_start = int(line[:end_index], 16)
-  for line in log_file_lines[3:]:
-    fields = line.split()
-    if len(fields) == 4:
-      call_lines.append(fields)
-    else:
-      assert fields[0] == 'END'
-  # Convert strings to int in fields.
-  call_info = []
-  for call_line in call_lines:
-    addr = int(call_line[3], 16)
-    if vm_start < addr:
-      addr -= vm_start
-      call_info.append(addr)
-  return call_info
-
-
 def _WarnAboutDuplicates(offsets):
   """Warns about duplicate offsets.
 
@@ -275,9 +234,7 @@
   parser.add_argument('--target-arch', required=False,
                       choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'],
                       help='The target architecture for libchrome.so')
-  parser.add_argument('--merged-cyglog', type=str, required=False,
-                      help='Path to the merged cyglog')
-  parser.add_argument('--reached-offsets', type=str, required=False,
+  parser.add_argument('--reached-offsets', type=str, required=True,
                       help='Path to the reached offsets')
   parser.add_argument('--native-library', type=str, required=True,
                       help='Path to the unstripped instrumented library')
@@ -290,20 +247,13 @@
   parser = _CreateArgumentParser()
   args = parser.parse_args()
 
-  assert bool(args.merged_cyglog) ^ bool(args.reached_offsets)
-
   if not args.target_arch:
     args.arch = cygprofile_utils.DetectArchitecture()
   symbol_extractor.SetArchitecture(args.target_arch)
 
   obj_dir = cygprofile_utils.GetObjDir(args.native_library)
 
-  offsets = []
-  if args.merged_cyglog:
-    log_file_lines = map(string.rstrip, open(args.merged_cyglog).readlines())
-    offsets = _ParseLogLines(log_file_lines)
-  else:
-    offsets = _ReadReachedOffsets(args.reached_offsets)
+  offsets = _ReadReachedOffsets(args.reached_offsets)
   assert offsets
   _WarnAboutDuplicates(offsets)
 
diff --git a/tools/cygprofile/cyglog_to_orderfile_unittest.py b/tools/cygprofile/cyglog_to_orderfile_unittest.py
index 37722570..2aae4d4 100755
--- a/tools/cygprofile/cyglog_to_orderfile_unittest.py
+++ b/tools/cygprofile/cyglog_to_orderfile_unittest.py
@@ -76,17 +76,6 @@
     if failure_items:
       raise self.failureException('\n'.join(failure_items))
 
-  def testParseLogLines(self):
-    lines = """5086e000-52e92000 r-xp 00000000 b3:02 51276      libchromeview.so
-secs       usecs      pid:threadid    func
-START
-1314897086 795828     3587:1074648168 0x509e105c
-1314897086 795874     3587:1074648168 0x509e0eb4
-END""".split('\n')
-    offsets = cyglog_to_orderfile._ParseLogLines(lines)
-    self.assertListEqual(
-        offsets, [0x509e105c - 0x5086e000, 0x509e0eb4 - 0x5086e000])
-
   def testWarnAboutDuplicates(self):
     offsets = [0x1, 0x2, 0x3]
     self.assertTrue(cyglog_to_orderfile._WarnAboutDuplicates(offsets))
diff --git a/tools/cygprofile/cygprofile.cc b/tools/cygprofile/cygprofile.cc
deleted file mode 100644
index 7c04fed..0000000
--- a/tools/cygprofile/cygprofile.cc
+++ /dev/null
@@ -1,400 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tools/cygprofile/cygprofile.h"
-
-#include <fcntl.h>
-#include <pthread.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include <cstdio>
-#include <fstream>
-#include <string>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/containers/hash_tables.h"
-#include "base/files/scoped_file.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/stl_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_piece.h"
-#include "base/strings/stringprintf.h"
-#include "base/synchronization/lock.h"
-
-namespace cygprofile {
-namespace {
-
-// Allow 8 MBytes of data for each thread log.
-const size_t kMaxBufferSize = 8 * 1024 * 1024 / sizeof(LogEntry);
-
-// Have the background internal thread do its flush every 15 sec.
-const int kFlushThreadIdleTimeSec = 15;
-
-const char kLogFileNamePrefix[] = "/data/local/tmp/chrome/cyglog/";
-
-// "cyglog.PID.LWP.PPID"
-const char kLogFilenameFormat[] = "%scyglog.%d.%d-%d";
-
-// Magic value of above to prevent instrumentation. Used when ThreadLog is being
-// constructed (to prevent reentering by malloc, for example) and by the flush
-// log thread (to prevent it from being logged0.
-ThreadLog* const kMagicBeingConstructed = reinterpret_cast<ThreadLog*>(1);
-
-// Per-thread pointer to the current log object.
-pthread_key_t g_tls_slot;
-
-// Used to initialize the tls slot, once per the entire process.
-pthread_once_t g_tls_slot_initializer_once = PTHREAD_ONCE_INIT;
-
-// This variable is to prevent re-entrancy in the __cyg_profile_func_enter()
-// while the TLS slot itself is being initialized. Volatile here is required
-// to avoid compiler optimizations as this need to be read in a re-entrant way.
-// This variable is written by one thread only, which is the first thread that
-// happens to run the TLSSlotInitializer(). In practice this will happen very
-// early in the startup process, as soon as the first instrumented function is
-// called.
-volatile bool g_tls_slot_being_initialized = false;
-
-// Initializes the global TLS slot. This is invoked only once per process.
-static void TLSSlotInitializer()
-{
-    g_tls_slot_being_initialized = true;
-    PCHECK(0 == pthread_key_create(&g_tls_slot, NULL));
-    g_tls_slot_being_initialized = false;
-}
-
-// Returns light-weight process ID. On Linux, this is a system-wide unique
-// thread id.
-pid_t GetTID() {
-  return syscall(__NR_gettid);
-}
-
-timespec GetCurrentTime() {
-  timespec timestamp;
-  clock_gettime(CLOCK_MONOTONIC, &timestamp);
-  return timestamp;
-}
-
-// Sleeps for |sec| seconds.
-void SleepSec(int sec) {
-  for (int secs_to_sleep = sec; secs_to_sleep != 0;)
-    secs_to_sleep = sleep(secs_to_sleep);
-}
-
-// Exposes the string header that will appear at the top of every trace file.
-// This string contains memory mapping information for the mapped
-// library/executable which is used offline during symbolization. Note that
-// this class is meant to be instantiated once per process and lazily (during
-// the first flush).
-struct ImmutableFileHeaderLine {
-  ImmutableFileHeaderLine() : value(MakeFileHeaderLine()) {}
-
-  const std::string value;
-
- private:
-  // Returns whether the integer representation of the hexadecimal address
-  // stored in |line| at position |start_offset| was successfully stored in
-  // |result|.
-  static bool ParseAddress(const std::string& line,
-                           size_t start_offset,
-                           size_t length,
-                           uint64_t* result) {
-    if (start_offset >= line.length())
-      return false;
-
-    uint64_t address;
-    const bool ret = HexStringToUInt64(
-        base::StringPiece(line.c_str() + start_offset, length), &address);
-    if (!ret)
-      return false;
-
-    *result = address;
-    return true;
-  }
-
-  // Parses /proc/self/maps and returns a two line string such as:
-  // 758c6000-79f4b000 r-xp 00000000 b3:17 309475 libchrome.2009.0.so
-  // secs    usecs   pid:threadid    func
-  static std::string MakeFileHeaderLine() {
-    std::ifstream mapsfile("/proc/self/maps");
-    CHECK(mapsfile.good());
-    std::string result;
-
-    for (std::string line; std::getline(mapsfile, line); ) {
-      if (line.find("r-xp") == std::string::npos)
-        continue;
-
-      const size_t address_length = line.find('-');
-      uint64_t start_address = 0;
-      CHECK(ParseAddress(line, 0, address_length, &start_address));
-
-      uint64_t end_address = 0;
-      CHECK(ParseAddress(line, address_length + 1, address_length,
-                         &end_address));
-
-      const uintptr_t current_func_addr = reinterpret_cast<uintptr_t>(
-          &MakeFileHeaderLine);
-      if (current_func_addr >= start_address &&
-          current_func_addr < end_address) {
-        result.swap(line);
-        break;
-      }
-    }
-    CHECK(!result.empty());
-    result.append("\nsecs\tusecs\tpid:threadid\tfunc\n");
-    return result;
-  }
-};
-
-base::LazyInstance<ThreadLogsManager>::Leaky g_logs_manager =
-    LAZY_INSTANCE_INITIALIZER;
-
-base::LazyInstance<ImmutableFileHeaderLine>::Leaky g_file_header_line =
-    LAZY_INSTANCE_INITIALIZER;
-
-}  // namespace
-
-// Custom thread implementation that joins on destruction. Note that
-// base::Thread has non-trivial dependencies on e.g. AtExitManager which makes
-// it hard to use it early.
-class Thread {
- public:
-  Thread(const base::Closure& thread_callback)
-      : thread_callback_(thread_callback) {
-    PCHECK(0 == pthread_create(&handle_, NULL, &Thread::EntryPoint, this));
-  }
-
-  ~Thread() {
-    PCHECK(0 == pthread_join(handle_, NULL));
-  }
-
- private:
-  static void* EntryPoint(void* data) {
-    // Disable logging on this thread. Although this routine is not instrumented
-    // (cygprofile.gyp provides that), the called routines are and thus will
-    // call instrumentation.
-    pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer);
-    ThreadLog* thread_log = reinterpret_cast<ThreadLog*>(
-        pthread_getspecific(g_tls_slot));
-    CHECK(thread_log == NULL);  // Must be 0 as this is a new thread.
-    PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed));
-
-    Thread* const instance = reinterpret_cast<Thread*>(data);
-    instance->thread_callback_.Run();
-    return NULL;
-  }
-
-  const base::Closure thread_callback_;
-  pthread_t handle_;
-
-  DISALLOW_COPY_AND_ASSIGN(Thread);
-};
-
-// Single log entry recorded for each function call.
-LogEntry::LogEntry(const void* address, pid_t pid, pid_t tid)
-    : time(GetCurrentTime()), pid(pid), tid(tid), address(address) {}
-
-ThreadLog::ThreadLog()
-    : pid_(getpid()),
-      tid_(GetTID()),
-      in_use_(false),
-      flush_callback_(
-          base::Bind(&ThreadLog::FlushInternal, base::Unretained(this))) {}
-
-ThreadLog::ThreadLog(const FlushCallback& flush_callback)
-    : pid_(getpid()),
-      tid_(GetTID()),
-      in_use_(false),
-      flush_callback_(flush_callback) {}
-
-ThreadLog::~ThreadLog() {
-  PCHECK(0 == pthread_setspecific(g_tls_slot, NULL));
-}
-
-void ThreadLog::AddEntry(void* address) {
-  if (in_use_)
-    return;
-  in_use_ = true;
-
-  DCHECK_EQ(tid_, GetTID());
-  bool did_insert = called_functions_.insert(address).second;
-
-  if (did_insert) {
-    base::AutoLock auto_lock(lock_);
-    entries_.emplace_back(address, pid_, tid_);
-    // Crash in a quickly understandable way instead of crashing (or maybe not
-    // though) due to OOM.
-    CHECK_LE(entries_.size(), kMaxBufferSize);
-  }
-
-  in_use_ = false;
-}
-
-void ThreadLog::TakeEntries(std::vector<LogEntry>* destination) {
-  base::AutoLock auto_lock(lock_);
-  destination->swap(entries_);
-  base::STLClearObject(&entries_);
-}
-
-void ThreadLog::Flush(std::vector<LogEntry>* entries) const {
-  flush_callback_.Run(entries);
-}
-
-void ThreadLog::FlushInternal(std::vector<LogEntry>* entries) const {
-  const std::string log_filename(
-      base::StringPrintf(
-          kLogFilenameFormat, kLogFileNamePrefix, getpid(), tid_, getppid()));
-  const base::ScopedFILE file(fopen(log_filename.c_str(), "a"));
-  CHECK(file.get());
-
-  const long offset = ftell(file.get());
-  if (offset == 0)
-    fprintf(file.get(), "%s", g_file_header_line.Get().value.c_str());
-
-  for (std::vector<LogEntry>::const_iterator it = entries->begin();
-       it != entries->end(); ++it) {
-    fprintf(file.get(), "%ld %ld\t%d:%d\t%p\n", it->time.tv_sec,
-            it->time.tv_nsec / 1000, it->pid, it->tid, it->address);
-  }
-
-  base::STLClearObject(entries);
-}
-
-ThreadLogsManager::ThreadLogsManager()
-    : wait_callback_(base::Bind(&SleepSec, kFlushThreadIdleTimeSec)) {
-}
-
-ThreadLogsManager::ThreadLogsManager(const base::Closure& wait_callback,
-                                     const base::Closure& notify_callback)
-
-    : wait_callback_(wait_callback),
-      notify_callback_(notify_callback) {
-}
-
-ThreadLogsManager::~ThreadLogsManager() {
-  // Note that the internal thread does some work until it sees |flush_thread_|
-  // = NULL.
-  std::unique_ptr<Thread> flush_thread;
-  {
-    base::AutoLock auto_lock(lock_);
-    flush_thread_.swap(flush_thread);
-  }
-  flush_thread.reset();  // Joins the flush thread.
-}
-
-void ThreadLogsManager::AddLog(std::unique_ptr<ThreadLog> new_log) {
-  base::AutoLock auto_lock(lock_);
-
-  if (logs_.empty())
-    StartInternalFlushThread_Locked();
-
-  logs_.push_back(std::move(new_log));
-}
-
-void ThreadLogsManager::StartInternalFlushThread_Locked() {
-  lock_.AssertAcquired();
-  CHECK(!flush_thread_);
-  // Note that the |flush_thread_| joins at destruction which guarantees that it
-  // will never outlive |this|, i.e. it's safe not to use ref-counting.
-  flush_thread_.reset(
-      new Thread(base::Bind(&ThreadLogsManager::FlushAllLogsOnFlushThread,
-                            base::Unretained(this))));
-}
-
-// Type used below for flushing.
-struct LogData {
-  LogData(ThreadLog* thread_log) : thread_log(thread_log) {}
-
-  ThreadLog* const thread_log;
-  std::vector<LogEntry> entries;
-};
-
-void ThreadLogsManager::FlushAllLogsOnFlushThread() {
-  while (true) {
-    {
-      base::AutoLock auto_lock(lock_);
-      // The |flush_thread_| field is reset during destruction.
-      if (!flush_thread_)
-        return;
-    }
-    // Sleep for a few secs and then flush all thread's buffers. There is a
-    // danger that, when quitting Chrome, this thread may see unallocated data
-    // and segfault. We do not care because we need logs when Chrome is working.
-    wait_callback_.Run();
-
-    // Copy the ThreadLog pointers to avoid acquiring both the logs manager's
-    // lock and the one for individual thread logs.
-    std::vector<ThreadLog*> thread_logs_copy;
-    {
-      base::AutoLock auto_lock(lock_);
-      for (const auto& log : logs_)
-        thread_logs_copy.push_back(log.get());
-    }
-
-    // Move the logs' data before flushing them so that the mutexes are not
-    // acquired for too long.
-    std::vector<LogData> logs;
-    for (std::vector<ThreadLog*>::const_iterator it =
-             thread_logs_copy.begin();
-         it != thread_logs_copy.end(); ++it) {
-      ThreadLog* const thread_log = *it;
-      LogData log_data(thread_log);
-      logs.push_back(log_data);
-      thread_log->TakeEntries(&logs.back().entries);
-    }
-
-    for (std::vector<LogData>::iterator it = logs.begin();
-         it != logs.end(); ++it) {
-      if (!it->entries.empty())
-        it->thread_log->Flush(&it->entries);
-    }
-
-    if (!notify_callback_.is_null())
-      notify_callback_.Run();
-  }
-}
-
-extern "C" {
-
-// The GCC compiler callbacks, called on every function invocation providing
-// addresses of caller and callee codes.
-void __cyg_profile_func_enter(void* this_fn, void* call_site)
-    __attribute__((no_instrument_function));
-void __cyg_profile_func_exit(void* this_fn, void* call_site)
-    __attribute__((no_instrument_function));
-
-void __cyg_profile_func_enter(void* this_fn, void* callee_unused) {
-  // Avoid re-entrancy while initializing the TLS slot (once per process).
-  if (g_tls_slot_being_initialized)
-    return;
-
-  pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer);
-  ThreadLog* thread_log = reinterpret_cast<ThreadLog*>(
-      pthread_getspecific(g_tls_slot));
-
-  if (thread_log == NULL) {
-    PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed));
-    thread_log = new ThreadLog();
-    CHECK(thread_log);
-    g_logs_manager.Pointer()->AddLog(base::WrapUnique(thread_log));
-    PCHECK(0 == pthread_setspecific(g_tls_slot, thread_log));
-  }
-
-  if (thread_log != kMagicBeingConstructed)
-    thread_log->AddEntry(this_fn);
-}
-
-void __cyg_profile_func_exit(void* this_fn, void* call_site) {}
-
-}  // extern "C"
-}  // namespace cygprofile
diff --git a/tools/cygprofile/cygprofile.h b/tools/cygprofile/cygprofile.h
deleted file mode 100644
index 97684e78..0000000
--- a/tools/cygprofile/cygprofile.h
+++ /dev/null
@@ -1,169 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// Tool to log the execution of the process (Chrome). Writes logs containing
-// time and address of the callback being called for the first time.
-//
-// For performance reasons logs are buffered. Every thread has its own buffer
-// and log file so the contention between threads is minimal. As a side-effect,
-// functions called might be mentioned in many thread logs.
-//
-// A special thread is created in the process to periodically flush logs for all
-// threads in case the thread had stopped before flushing its logs.
-//
-// Also note that the instrumentation code is self-activated. It begins to
-// record the log data when it is called first, including the run-time startup.
-// Have it in mind when modifying it, in particular do not use global objects
-// with constructors as they are called during startup (too late for us).
-
-#ifndef TOOLS_CYGPROFILE_CYGPROFILE_H_
-#define TOOLS_CYGPROFILE_CYGPROFILE_H_
-
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include <memory>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/containers/hash_tables.h"
-#include "base/macros.h"
-#include "base/synchronization/lock.h"
-#include "build/build_config.h"
-
-#if !defined(OS_ANDROID)
-// This is only supported on Android thanks to the fact that on Android
-// processes (other than the system's zygote) don't fork.
-//
-// To make cygprofile truly work (i.e. without any deadlock) on Chrome
-// platforms that use fork(), cygprofile.cc should be written in a way that
-// guarantees that:
-// - No lock is acquired by a foreign thread during fork(). In particular this
-// means that cygprofile.cc should not perform any heap allocation (since heap
-// allocators, including TCMalloc generally use locks).
-// - Only cygprofile.cc uses pthread_atfork() in the whole process. Unlike POSIX
-// signals, pthread_atfork() doesn't provide a way to install multiple handlers.
-// Calling pthread_atfork() in cygprofile.cc would override any handler that
-// could have been installed previously.
-//
-// Chrome happens to violate the first requirement at least once by having its
-// process launcher thread fork. However the child process in that case, when
-// it's not instrumented with cygprofile, directly calls exec(). This is safe
-// since the child process doesn't try to release a lock acquired by another
-// thread in the parent process which would lead to a deadlock. This problem was
-// actually observed by trying to port the current version of cygprofile.cc to
-// Linux.
-#error This is only supported on Android.
-#endif
-
-// The following is only exposed for testing.
-namespace cygprofile {
-
-class Thread;
-
-// Single log entry recorded for each function call.
-struct LogEntry {
-  LogEntry(const void* address, pid_t pid, pid_t tid);
-
-  const timespec time;
-  const pid_t pid;
-  const pid_t tid;
-  const void* const address;
-};
-
-// Per-thread function calls log.
-class ThreadLog {
- public:
-  // Callback invoked for flushing that can be provided for testing.
-  typedef base::Callback<void (std::vector<LogEntry>*)> FlushCallback;
-
-  ThreadLog();
-
-  // Used for testing.
-  ThreadLog(const FlushCallback& flush_callback);
-
-  ~ThreadLog();
-
-  // Must only be called from the thread this ThreadLog instance is watching.
-  void AddEntry(void* address);
-
-  // Can be called from any thread.
-  void TakeEntries(std::vector<LogEntry>* output);
-
-  // Flushes the provided vector of entries to a file and clears it. Note that
-  // this can be called from any thread.
-  void Flush(std::vector<LogEntry>* entries) const;
-
- private:
-  // Default implementation (that can be overridden for testing) of the method
-  // above.
-  void FlushInternal(std::vector<LogEntry>* entries) const;
-
-  // Process ID, as returned by getpid().
-  const pid_t pid_;
-
-  // Thread identifier as Linux kernel shows it.  LWP (light-weight process) is
-  // a unique ID of the thread in the system, unlike pthread_self() which is the
-  // same for fork()-ed threads.
-  const pid_t tid_;
-
-  // Current thread is inside the instrumentation routine.
-  bool in_use_;
-
-  // Callback used to flush entries.
-  const FlushCallback flush_callback_;
-
-  // Keeps track of all functions that have been logged on this thread so we do
-  // not record duplicates.
-  base::hash_set<void*> called_functions_;
-
-  // A lock that guards |entries_| usage between per-thread instrumentation
-  // routine and timer flush callback. So the contention could happen only
-  // during the flush, every 15 secs.
-  base::Lock lock_;
-
-  std::vector<LogEntry> entries_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadLog);
-};
-
-// Manages a list of per-thread logs.
-class ThreadLogsManager {
- public:
-  ThreadLogsManager();
-
-  // Used for testing. The provided callbacks are used for testing to
-  // synchronize the internal thread with the unit test running on the main
-  // thread.
-  ThreadLogsManager(const base::Closure& wait_callback,
-                    const base::Closure& notify_callback);
-
-  ~ThreadLogsManager();
-
-  // Can be called from any thread.
-  void AddLog(std::unique_ptr<ThreadLog> new_log);
-
- private:
-  void StartInternalFlushThread_Locked();
-
-  // Flush thread's entry point.
-  void FlushAllLogsOnFlushThread();
-
-  // Used to make the internal thread sleep before each flush iteration.
-  const base::Closure wait_callback_;
-  // Used to trigger a notification when a flush happened on the internal
-  // thread.
-  const base::Closure notify_callback_;
-
-  // Protects the state below.
-  base::Lock lock_;
-  std::unique_ptr<Thread> flush_thread_;
-  std::vector<std::unique_ptr<ThreadLog>> logs_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadLogsManager);
-};
-
-}  // namespace cygprofile
-
-#endif  // TOOLS_CYGPROFILE_CYGPROFILE_H_
diff --git a/tools/cygprofile/cygprofile_perftest.cc b/tools/cygprofile/cygprofile_perftest.cc
deleted file mode 100644
index ae8fe3e7..0000000
--- a/tools/cygprofile/cygprofile_perftest.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tools/cygprofile/cygprofile.h"
-
-#include <cstdint>
-#include <vector>
-
-#include "base/strings/stringprintf.h"
-#include "base/time/time.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-
-namespace cygprofile {
-
-namespace {
-
-void AddEntryCost(int iterations, int addresses_count) {
-  // This is intentionally leaky. ThreadLog() destructor would call abort(),
-  // limiting us to a single test. Leaking ThreadLog is fine as long as we clean
-  // up the entries.
-  auto* thread_log = new ThreadLog();
-
-  auto tick = base::TimeTicks::Now();
-  for (int i = 0; i < iterations; i++) {
-    for (int address = 0; address < addresses_count; address++) {
-      thread_log->AddEntry(reinterpret_cast<void*>(address));
-    }
-  }
-  auto tock = base::TimeTicks::Now();
-  double nanos = static_cast<double>((tock - tick).InNanoseconds());
-  auto ns_per_call =
-      nanos / (iterations * static_cast<double>(addresses_count));
-  auto modifier = base::StringPrintf("_%d_%d", iterations, addresses_count);
-  perf_test::PrintResult("AddEntryCostPerCall", modifier, "", ns_per_call, "ns",
-                         true);
-
-  // Entries cleanup, see comment at the beginning of the function.
-  std::vector<LogEntry> entries;
-  thread_log->TakeEntries(&entries);
-}
-}  // namespace
-
-TEST(CygprofilePerfTest, CreateEntries_10_10000) {
-  AddEntryCost(10, 10000);
-}
-
-TEST(CygprofilePerfTest, CreateEntries_100_10000) {
-  AddEntryCost(100, 10000);
-}
-
-TEST(CygprofilePerfTest, CreateEntries_10_100000) {
-  AddEntryCost(10, 100000);
-}
-
-TEST(CygprofilePerfTest, CreateEntries_100_1000000) {
-  AddEntryCost(100, 100000);
-}
-
-}  // namespace cygprofile
-
-// Custom runner implementation since base's one requires JNI on Android.
-int main(int argc, char** argv) {
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/tools/cygprofile/cygprofile_unittest.cc b/tools/cygprofile/cygprofile_unittest.cc
deleted file mode 100644
index 5be4804..0000000
--- a/tools/cygprofile/cygprofile_unittest.cc
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tools/cygprofile/cygprofile.h"
-
-#include <stdint.h>
-#include <sys/time.h>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/logging.h"
-#include "base/synchronization/waitable_event.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cygprofile {
-namespace {
-
-void FlushEntries(std::vector<LogEntry>* destination,
-                  std::vector<LogEntry>* entries) {
-  CHECK_EQ(0U, destination->size());
-  // Move the provided |entries| vector to the provided |destination| so that
-  // the unit test that triggered the flush can check it.
-  destination->swap(*entries);
-}
-
-// Flush callback that should not be invoked.
-void CheckFlushDoesNotHappen(std::vector<LogEntry>* entries) {
-  NOTREACHED();
-}
-
-uint64_t GetUsecSecTimeFromTimeSpec(struct timespec timespec) {
-  return timespec.tv_sec * 1000 * 1000 + timespec.tv_nsec / 1000;
-}
-
-TEST(CygprofileTest, ThreadLogBasic) {
-  ThreadLog thread_log(base::Bind(&CheckFlushDoesNotHappen));
-
-  thread_log.AddEntry(reinterpret_cast<void*>(0x2));
-  thread_log.AddEntry(reinterpret_cast<void*>(0x1));
-
-  std::vector<LogEntry> entries;
-  thread_log.TakeEntries(&entries);
-
-  ASSERT_EQ(2U, entries.size());
-  // The entries should appear in their insertion order.
-  const LogEntry& first_entry = entries[0];
-  ASSERT_EQ(reinterpret_cast<uintptr_t>(first_entry.address), 2U);
-  ASSERT_EQ(getpid(), first_entry.pid);
-  ASSERT_LT(0, first_entry.tid);
-
-  const LogEntry& second_entry = entries[1];
-  ASSERT_EQ(1U, reinterpret_cast<uintptr_t>(second_entry.address));
-  ASSERT_EQ(first_entry.pid, second_entry.pid);
-  ASSERT_EQ(first_entry.tid, second_entry.tid);
-
-  ASSERT_GE(GetUsecSecTimeFromTimeSpec(second_entry.time),
-            GetUsecSecTimeFromTimeSpec(first_entry.time));
-}
-
-TEST(CygprofileTest, ManagerBasic) {
-  base::WaitableEvent wait_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-  base::WaitableEvent notify_event(
-      base::WaitableEvent::ResetPolicy::MANUAL,
-      base::WaitableEvent::InitialState::NOT_SIGNALED);
-
-  ThreadLogsManager manager(
-      base::Bind(&base::WaitableEvent::Wait, base::Unretained(&wait_event)),
-      base::Bind(&base::WaitableEvent::Signal,
-                 base::Unretained(&notify_event)));
-
-  std::vector<LogEntry> entries;
-  std::unique_ptr<ThreadLog> thread_log(
-      new ThreadLog(base::Bind(&FlushEntries, base::Unretained(&entries))));
-
-  thread_log->AddEntry(reinterpret_cast<void*>(0x2));
-  thread_log->AddEntry(reinterpret_cast<void*>(0x3));
-
-  // This should make the manager spawn its internal flush thread which will
-  // wait for a notification before it starts doing some work.
-  manager.AddLog(std::move(thread_log));
-
-  EXPECT_EQ(0U, entries.size());
-  // This will wake up the internal thread.
-  wait_event.Signal();
-  // Now it's our turn to wait until it performed the flush.
-  notify_event.Wait();
-
-  // The flush should have moved the data to the local vector of entries.
-  EXPECT_EQ(2U, entries.size());
-  ASSERT_EQ(2U, reinterpret_cast<uintptr_t>(entries[0].address));
-  ASSERT_EQ(3U, reinterpret_cast<uintptr_t>(entries[1].address));
-}
-
-}  // namespace
-}  // namespace cygprofile
-
-// Custom runner implementation since base's one requires JNI on Android.
-int main(int argc, char** argv) {
-  testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/tools/cygprofile/mergetraces.py b/tools/cygprofile/mergetraces.py
deleted file mode 100755
index 2ac8393..0000000
--- a/tools/cygprofile/mergetraces.py
+++ /dev/null
@@ -1,254 +0,0 @@
-#!/usr/bin/python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Use: ../mergetraces.py `ls cyglog.* -Sr` > merged_cyglog
-
-""""Merge multiple logs files from different processes into a single log.
-
-Given two log files of execution traces, merge the traces into a single trace.
-Merging will use timestamps (i.e. the first two columns of logged calls) to
-create a single log that is an ordered trace of calls by both processes.
-"""
-
-import optparse
-import string
-import sys
-
-
-def ParseLogLines(lines):
-  """Parse log file lines.
-
-  Args:
-    lines: lines from log file produced by profiled run
-
-    Below is an example of a small log file:
-    5086e000-52e92000 r-xp 00000000 b3:02 51276      libchromeview.so
-    secs       usecs      pid:threadid    func
-    START
-    1314897086 795828     3587:1074648168 0x509e105c
-    1314897086 795874     3587:1074648168 0x509e0eb4
-    1314897086 796326     3587:1074648168 0x509e0e3c
-    1314897086 796552     3587:1074648168 0x509e07bc
-    END
-
-  Returns:
-    tuple conisiting of 1) an ordered list of the logged calls, as an array of
-    fields, 2) the virtual start address of the library, used to compute the
-    offset of the symbol in the library and 3) the virtual end address
-  """
-  call_lines = []
-  vm_start = 0
-  vm_end = 0
-  dash_index = lines[0].find ('-')
-  space_index = lines[0].find (' ')
-  vm_start = int (lines[0][:dash_index], 16)
-  vm_end = int (lines[0][dash_index+1:space_index], 16)
-  for line in lines[2:]:
-    line = line.strip()
-    fields = line.split()
-    call_lines.append (fields)
-
-  return (call_lines, vm_start, vm_end)
-
-
-def HasDuplicates(calls):
-  """Makes sure that calls are only logged once.
-
-  Args:
-    calls: list of calls logged
-
-  Returns:
-    boolean indicating if calls has duplicate calls
-  """
-  seen = set([])
-  for call in calls:
-    if call[3] in seen:
-      return True
-    seen.add(call[3])
-  return False
-
-def CheckTimestamps(calls):
-  """Prints warning to stderr if the call timestamps are not in order.
-
-  Args:
-    calls: list of calls logged
-  """
-  index = 0
-  last_timestamp_secs = -1
-  last_timestamp_us = -1
-  while (index < len (calls)):
-    timestamp_secs = int (calls[index][0])
-    timestamp_us = int (calls[index][1])
-    timestamp = (timestamp_secs * 1000000) + timestamp_us
-    last_timestamp = (last_timestamp_secs * 1000000) + last_timestamp_us
-    if (timestamp < last_timestamp):
-      raise Exception("last_timestamp: " + str(last_timestamp_secs)
-                       + " " + str(last_timestamp_us) + " timestamp: "
-                       + str(timestamp_secs) + " " + str(timestamp_us) + "\n")
-    last_timestamp_secs = timestamp_secs
-    last_timestamp_us = timestamp_us
-    index = index + 1
-
-
-def Convert(call_lines, start_address, end_address):
-  """Converts the call addresses to static offsets and removes invalid calls.
-
-  Removes profiled calls not in shared library using start and end virtual
-  addresses, converts strings to integer values, coverts virtual addresses to
-  address in shared library.
-
-  Returns:
-     list of calls as tuples (sec, usec, pid:tid, callee)
-  """
-  converted_calls = []
-  call_addresses = set()
-  for fields in call_lines:
-    secs = int (fields[0])
-    usecs = int (fields[1])
-    callee = int (fields[3], 16)
-    # Eliminate repetitions of the same function.
-    if callee in call_addresses:
-      continue
-    # Eliminate small addresses. It should be safe to do so because these point
-    # before the .text section (it is in .plt or earlier).
-    # TODO(pasko): understand why __cyg_profile_func_enter may output a small
-    # offset sometimes.
-    if callee < start_address + 4096:
-      sys.stderr.write('WARNING: ignoring small address: %s' %
-          hex(callee - start_address))
-      call_addresses.add(callee)
-      continue
-    if start_address <= callee < end_address:
-      converted_calls.append((secs, usecs, fields[2], (callee - start_address)))
-      call_addresses.add(callee)
-  return converted_calls
-
-
-def Timestamp(trace_entry):
-  return int (trace_entry[0]) * 1000000 + int(trace_entry[1])
-
-
-def AddTrace (tracemap, trace):
-  """Adds a trace to the tracemap.
-
-  Adds entries in the trace to the tracemap. All new calls will be added to
-  the tracemap. If the calls already exist in the tracemap then they will be
-  replaced if they happened sooner in the new trace.
-
-  Args:
-    tracemap: the tracemap
-    trace: the trace
-
-  """
-  for trace_entry in trace:
-    call = trace_entry[3]
-    if (not call in tracemap) or (
-        Timestamp(tracemap[call]) > Timestamp(trace_entry)):
-      tracemap[call] = trace_entry
-
-
-def GroupByProcessAndThreadId(input_trace):
-  """Returns an array of traces grouped by pid and tid.
-
-  This is used to make the order of functions not depend on thread scheduling
-  which can be greatly impacted when profiling is done with cygprofile. As a
-  result each thread has its own contiguous segment of code (ordered by
-  timestamp) and processes also have their code isolated (i.e. not interleaved).
-  """
-  def MakeTimestamp(sec, usec):
-    return sec * 1000000 + usec
-
-  def PidAndTidFromString(pid_and_tid):
-    strings = pid_and_tid.split(':')
-    return (int(strings[0]), int(strings[1]))
-
-  tid_to_pid_map = {}
-  pid_first_seen = {}
-  tid_first_seen = {}
-
-  for (sec, usec, pid_and_tid, _) in input_trace:
-    (pid, tid) = PidAndTidFromString(pid_and_tid)
-
-    # Make sure that thread IDs are unique since this is a property we rely on.
-    if tid_to_pid_map.setdefault(tid, pid) != pid:
-      raise Exception(
-          'Seen PIDs %d and %d for TID=%d. Thread-IDs must be unique' % (
-              tid_to_pid_map[tid], pid, tid))
-
-    if not pid in pid_first_seen:
-      pid_first_seen[pid] = MakeTimestamp(sec, usec)
-    if not tid in tid_first_seen:
-      tid_first_seen[tid] = MakeTimestamp(sec, usec)
-
-  def CompareEvents(event1, event2):
-    (sec1, usec1, pid_and_tid, _) = event1
-    (pid1, tid1) = PidAndTidFromString(pid_and_tid)
-    (sec2, usec2, pid_and_tid, _) = event2
-    (pid2, tid2) = PidAndTidFromString(pid_and_tid)
-
-    pid_cmp = cmp(pid_first_seen[pid1], pid_first_seen[pid2])
-    if pid_cmp != 0:
-      return pid_cmp
-    tid_cmp = cmp(tid_first_seen[tid1], tid_first_seen[tid2])
-    if tid_cmp != 0:
-      return tid_cmp
-    return cmp(MakeTimestamp(sec1, usec1), MakeTimestamp(sec2, usec2))
-
-  return sorted(input_trace, cmp=CompareEvents)
-
-
-def Main():
-  """Merge two traces for code in specified library and write to stdout.
-
-  Merges the two traces and coverts the virtual addresses to the offsets in the
-  library.  First line of merged trace has dummy virtual address of 0-ffffffff
-  so that symbolizing the addresses uses the addresses in the log, since the
-  addresses have already been converted to static offsets.
-  """
-  parser = optparse.OptionParser('usage: %prog trace1 ... traceN')
-  (_, args) = parser.parse_args()
-  if len(args) <= 1:
-    parser.error('expected at least the following args: trace1 trace2')
-
-  step = 0
-
-  # Maps function addresses to their corresponding trace entry.
-  tracemap = dict()
-
-  for trace_file in args:
-    step += 1
-    sys.stderr.write("    " + str(step) + "/" + str(len(args)) +
-                     ": " + trace_file + ":\n")
-
-    trace_lines = map(string.rstrip, open(trace_file).readlines())
-    (trace_calls, trace_start, trace_end) = ParseLogLines(trace_lines)
-    CheckTimestamps(trace_calls)
-    sys.stderr.write("Len: " + str(len(trace_calls)) +
-                     ". Start: " + hex(trace_start) +
-                     ", end: " + hex(trace_end) + '\n')
-
-    trace_calls = Convert(trace_calls, trace_start, trace_end)
-    sys.stderr.write("Converted len: " + str(len(trace_calls)) + "\n")
-
-    AddTrace(tracemap, trace_calls)
-    sys.stderr.write("Merged len: " + str(len(tracemap)) + "\n")
-
-  # Extract the resulting trace from the tracemap
-  merged_trace = []
-  for call in tracemap:
-    merged_trace.append(tracemap[call])
-  merged_trace.sort(key=Timestamp)
-
-  grouped_trace = GroupByProcessAndThreadId(merged_trace)
-
-  print "0-ffffffff r-xp 00000000 xx:00 00000 ./"
-  print "secs\tusecs\tpid:threadid\tfunc"
-  for call in grouped_trace:
-    print (str(call[0]) + "\t" + str(call[1]) + "\t" + call[2] + "\t" +
-           hex(call[3]))
-
-
-if __name__ == '__main__':
-  Main()
diff --git a/tools/cygprofile/mergetraces_unittest.py b/tools/cygprofile/mergetraces_unittest.py
deleted file mode 100644
index de88137..0000000
--- a/tools/cygprofile/mergetraces_unittest.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mergetraces
-
-class GroupByProcessAndThreadIdTestBasic(unittest.TestCase):
-  def runTest(self):
-    # (sec, usec, 'pid:tid', function address).
-    input_trace = [
-        (100, 10, '2000:2001', 0x5),
-        (100, 11, '2000:2001', 0x3),
-        (100, 13, '2000:1999', 0x8),
-        (100, 14, '2000:2000', 0x7),
-        (120, 13, '2001:2003', 0x9),
-        (150, 12, '2001:2004', 0x6),
-        (180, 11, '2000:2000', 0x1),
-    ]
-
-    # Functions should be grouped by thread-id and PIDs should not be
-    # interleaved.
-    expected_trace = [
-        (100, 10, '2000:2001', 0x5),
-        (100, 11, '2000:2001', 0x3),
-        (100, 13, '2000:1999', 0x8),
-        (100, 14, '2000:2000', 0x7),
-        (180, 11, '2000:2000', 0x1),
-        (120, 13, '2001:2003', 0x9),
-        (150, 12, '2001:2004', 0x6),
-    ]
-
-    grouped_trace = mergetraces.GroupByProcessAndThreadId(input_trace)
-
-    self.assertEqual(grouped_trace, expected_trace)
-
-class GroupByProcessAndThreadIdFailsWithNonUniqueTIDs(unittest.TestCase):
-  def runTest(self):
-    # (sec, usec, 'pid:tid', function address).
-    input_trace = [
-        (100, 10, '1999:2001', 0x5),
-        (100, 10, '1988:2001', 0x5),
-    ]
-
-    try:
-      mergetraces.GroupByProcessAndThreadId(input_trace)
-    except Exception:
-      return
-
-    self.fail('Multiple processes should not have a same thread-ID.')
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py
index 147a067..96348a5 100755
--- a/tools/cygprofile/orderfile_generator_backend.py
+++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -250,7 +250,7 @@
   """Handles compilation of clank."""
 
   def __init__(self, out_dir, step_recorder, arch, jobs, max_load, use_goma,
-               goma_dir, lightweight_instrumentation):
+               goma_dir):
     self._out_dir = out_dir
     self._step_recorder = step_recorder
     self._arch = arch
@@ -258,7 +258,6 @@
     self._max_load = max_load
     self._use_goma = use_goma
     self._goma_dir = goma_dir
-    self._lightweight_instrumentation = lightweight_instrumentation
     lib_chrome_so_dir = 'lib.unstripped'
     self.lib_chrome_so = os.path.join(
         self._out_dir, 'Release', lib_chrome_so_dir, 'libchrome.so')
@@ -288,8 +287,6 @@
         'use_goma=' + str(self._use_goma).lower(),
         'use_order_profiling=' + str(instrumented).lower(),
     ]
-    if instrumented and self._lightweight_instrumentation:
-      args.append('use_lightweight_order_profiling=true')
     if self._goma_dir:
       args += ['goma_dir="%s"' % self._goma_dir]
 
@@ -420,8 +417,6 @@
   generates an updated orderfile.
   """
   _CLANK_REPO = os.path.join(constants.DIR_SOURCE_ROOT, 'clank')
-  _MERGE_TRACES_SCRIPT = os.path.join(
-      constants.DIR_SOURCE_ROOT, 'tools', 'cygprofile', 'mergetraces.py')
   _CYGLOG_TO_ORDERFILE_SCRIPT = os.path.join(
       constants.DIR_SOURCE_ROOT, 'tools', 'cygprofile',
       'cyglog_to_orderfile.py')
@@ -460,18 +455,12 @@
     if options.profile:
       output_directory = os.path.join(self._instrumented_out_dir, 'Release')
       host_cyglog_dir = os.path.join(output_directory, 'cyglog_data')
-      # Only override the defaults when using lightweight instrumentation,
-      # as the regular profiling code is likely too slow for these.
       urls = [profile_android_startup.AndroidProfileTool.TEST_URL]
       use_wpr = True
       simulate_user = False
-      if options.simulate_user and not options.lightweight_instrumentation:
-        logging.error(
-            '--simulate-user required --lightweight-instrumentation, ignoring.')
-      if options.lightweight_instrumentation:
-        urls = options.urls
-        use_wpr = not options.no_wpr
-        simulate_user = options.simulate_user
+      urls = options.urls
+      use_wpr = not options.no_wpr
+      simulate_user = options.simulate_user
       self._profiler = profile_android_startup.AndroidProfileTool(
           output_directory, host_cyglog_dir, use_wpr, urls, simulate_user)
 
@@ -486,27 +475,6 @@
     assert os.path.isdir(constants.DIR_SOURCE_ROOT), 'No src directory found'
     symbol_extractor.SetArchitecture(options.arch)
 
-  def _RunCygprofileUnitTests(self):
-    """Builds, deploys and runs cygprofile_unittests."""
-    # There an no unittests (yet) for the lightweight instrumentation.
-    # TODO(lizeb): Fix this.
-    if self._options.lightweight_instrumentation:
-      return
-    tools_compiler = ClankCompiler(
-        os.path.dirname(constants.GetOutDirectory()),
-        self._step_recorder, self._options.arch, self._options.jobs,
-        self._options.max_load, self._options.use_goma, self._options.goma_dir,
-        self._options.lightweight_instrumentation)
-    tools_compiler.Build(instrumented=False, target='android_tools')
-    self._compiler.Build(instrumented=True, target='cygprofile_unittests')
-
-    self._step_recorder.BeginStep('Deploy and run cygprofile_unittests')
-    exit_code = self._profiler.RunCygprofileTests()
-
-    if exit_code != 0:
-      self._step_recorder.FailStep(
-          'cygprofile_unittests exited with non-0 status: %d' % exit_code)
-
   @staticmethod
   def _RemoveBlanks(src_file, dest_file):
     """A utility to remove blank lines from a file.
@@ -537,20 +505,14 @@
           self._compiler.chrome_apk,
           constants.PACKAGE_INFO['chrome'])
       self._step_recorder.BeginStep('Process cyglog')
-      if self._options.lightweight_instrumentation:
-        assert os.path.exists(self._compiler.lib_chrome_so)
-        offsets = process_profiles.GetReachedOffsetsFromDumpFiles(
-            files, self._compiler.lib_chrome_so)
-        if not offsets:
-          raise Exception('No profiler offsets found in {}'.format(
-                          '\n'.join(files)))
-        with open(self._MERGED_CYGLOG_FILENAME, 'w') as f:
-          f.write('\n'.join(map(str, offsets)))
-      else:
-        with open(self._MERGED_CYGLOG_FILENAME, 'w') as merged_cyglog:
-          self._step_recorder.RunCommand([self._MERGE_TRACES_SCRIPT] + files,
-                                         constants.DIR_SOURCE_ROOT,
-                                         stdout=merged_cyglog)
+      assert os.path.exists(self._compiler.lib_chrome_so)
+      offsets = process_profiles.GetReachedOffsetsFromDumpFiles(
+          files, self._compiler.lib_chrome_so)
+      if not offsets:
+        raise Exception('No profiler offsets found in {}'.format(
+            '\n'.join(files)))
+      with open(self._MERGED_CYGLOG_FILENAME, 'w') as f:
+        f.write('\n'.join(map(str, offsets)))
     except Exception:
       for f in files:
         self._SaveForDebugging(f)
@@ -564,10 +526,7 @@
           '--target-arch=' + self._options.arch,
           '--native-library=' + self._compiler.lib_chrome_so,
           '--output=' + self._GetUnpatchedOrderfileFilename()]
-      if self._options.lightweight_instrumentation:
-        command_args.append('--reached-offsets=' + self._MERGED_CYGLOG_FILENAME)
-      else:
-        command_args.append('--merged-cyglog=' + self._MERGED_CYGLOG_FILENAME)
+      command_args.append('--reached-offsets=' + self._MERGED_CYGLOG_FILENAME)
       self._step_recorder.RunCommand(
           [self._CYGLOG_TO_ORDERFILE_SCRIPT] + command_args)
     except CommandError:
@@ -688,13 +647,9 @@
             self._instrumented_out_dir,
             self._step_recorder, self._options.arch, self._options.jobs,
             self._options.max_load, self._options.use_goma,
-            self._options.goma_dir,
-            self._options.lightweight_instrumentation)
-        self._RunCygprofileUnitTests()
-        if self._options.lightweight_instrumentation:
-          _EnsureOrderfileStartsWithAnchorSection(self._GetPathToOrderfile())
-        self._compiler.CompileChromeApk(
-            True, self._options.lightweight_instrumentation)
+            self._options.goma_dir)
+        _EnsureOrderfileStartsWithAnchorSection(self._GetPathToOrderfile())
+        self._compiler.CompileChromeApk(True)
         self._GenerateAndProcessProfile()
         self._MaybeArchiveOrderfile(self._GetUnpatchedOrderfileFilename())
         profile_uploaded = True
@@ -710,8 +665,7 @@
         self._compiler = ClankCompiler(
             self._uninstrumented_out_dir, self._step_recorder,
             self._options.arch, self._options.jobs, self._options.max_load,
-            self._options.use_goma, self._options.goma_dir,
-            self._options.lightweight_instrumentation)
+            self._options.use_goma, self._options.goma_dir)
         self._compiler.CompileLibchrome(False)
         self._PatchOrderfile()
         # Because identical code folding is a bit different with and without
@@ -748,10 +702,6 @@
   """Creates and returns the argument parser."""
   parser = argparse.ArgumentParser()
   parser.add_argument(
-      '--regular-instrumentation', action='store_false',
-      dest='lightweight_instrumentation',
-      help='Use the regular instrumentation path')
-  parser.add_argument(
       '--buildbot', action='store_true',
       help='If true, the script expects to be run on a buildbot')
   parser.add_argument(
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py
index ba96bce8..c71fb53 100755
--- a/tools/cygprofile/profile_android_startup.py
+++ b/tools/cygprofile/profile_android_startup.py
@@ -393,6 +393,9 @@
       cyglog_dir = os.path.join(self._host_cyglog_dir, 'cyglog')
       files = os.listdir(cyglog_dir)
 
+    if len(files) == 0:
+      raise NoCyglogDataError('No cyglog data was collected')
+
     return [os.path.join(cyglog_dir, x) for x in files]