diff --git a/tools/jvmti-agents/README.md b/tools/jvmti-agents/README.md
index 69d4921..b093289 100644
--- a/tools/jvmti-agents/README.md
+++ b/tools/jvmti-agents/README.md
@@ -12,6 +12,7 @@
 * [libjitload](./jit-load)
 * [liblistextensions](./list-extensions)
 * [libforceredefine](./simple-force-redefine)
+* [libsimpleprofile](./simple-profile)
 * [litifast](./ti-fast)
 * [libtitrace](./titrace)
 * [libwrapagentproperties](./wrapagentproperties)
\ No newline at end of file
diff --git a/tools/jvmti-agents/simple-profile/Android.bp b/tools/jvmti-agents/simple-profile/Android.bp
new file mode 100644
index 0000000..f524cac
--- /dev/null
+++ b/tools/jvmti-agents/simple-profile/Android.bp
@@ -0,0 +1,92 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+// Build variants {target,host} x {debug,ndebug} x {32,64}
+
+cc_defaults {
+    name: "simpleprofile-base-defaults",
+    host_supported: true,
+    srcs: ["simple_profile.cc"],
+    defaults: ["art_defaults"],
+
+    // Note that this tool needs to be built for both 32-bit and 64-bit since it requires
+    // to be same ISA as what it is attached to.
+    compile_multilib: "both",
+
+    target: {
+        android: {
+        },
+        host: {
+        },
+    },
+    header_libs: [
+        "jni_headers",
+        "libopenjdkjvmti_headers",
+        "libnativehelper_header_only",
+    ],
+}
+
+cc_defaults {
+    name: "simpleprofile-defaults",
+    shared_libs: [
+        "libbase",
+    ],
+}
+
+cc_defaults {
+    name: "simpleprofile-static-defaults",
+    host_supported: false,
+    defaults: ["simpleprofile-base-defaults"],
+
+    shared_libs: [
+        "liblog",
+    ],
+    static_libs: [
+        "libbase_ndk",
+    ],
+    sdk_version: "current",
+    stl: "c++_static",
+}
+
+art_cc_library {
+    name: "libsimpleprofiles",
+    defaults: ["simpleprofile-static-defaults"],
+}
+
+art_cc_library {
+    name: "libsimpleprofileds",
+    defaults: [
+        "art_debug_defaults",
+        "simpleprofile-static-defaults",
+    ],
+    shared_libs: [],
+}
+
+art_cc_library {
+    name: "libsimpleprofile",
+    defaults: ["simpleprofile-defaults"],
+    shared_libs: [
+    ],
+}
+
+art_cc_library {
+    name: "libsimpleprofiled",
+    defaults: [
+        "art_debug_defaults",
+        "simpleprofile-defaults",
+    ],
+    shared_libs: [],
+}
diff --git a/tools/jvmti-agents/simple-profile/README.md b/tools/jvmti-agents/simple-profile/README.md
new file mode 100644
index 0000000..4a069fb
--- /dev/null
+++ b/tools/jvmti-agents/simple-profile/README.md
@@ -0,0 +1,63 @@
+# simpleprofile
+
+simpleprofile is a JVMTI agent that lets one get simple JSON profiles with JVMTI
+
+# Usage
+### Build
+>    `m libsimpleprofile`  # or 'm libsimpleprofiled' with debugging checks enabled
+
+For binaries with NDK shared libraries only.
+>    `m libsimpleprofiled` # or `m libsimpleprofileds` with debugging checks enabled.
+
+The libraries will be built for 32-bit, 64-bit, host and target. Below examples
+assume you want to use the 64-bit version.
+
+### Command Line
+
+The agent is loaded using -agentpath like normal. It takes arguments in the
+following format:
+>     `file-output[,dump_on_shutdown][,dump_on_main_stop]`
+
+
+#### ART
+>    `art -Xplugin:$ANDROID_HOST_OUT/lib64/libopenjdkjvmti.so '-agentpath:libsimpleprofiled.so=/proc/self/fd/2,dump_on_main_stop' -cp tmp/java/helloworld.dex -Xint helloworld`
+
+* `-Xplugin` and `-agentpath` need to be used, otherwise the agent will fail during init.
+* If using `libartd.so`, make sure to use the debug version of jvmti.
+
+#### Device
+```
+% adb root
+% adb shell setenforce 0
+% adb push $OUT/system/lib64/libsimpleprofileds.so /data/local/tmp/libsimpleprofileds.so
+% adb shell
+blueline:/data/data/com.google.android.apps.maps # cp /data/local/tmp/libsimpleprofileds.so .
+blueline:/data/data/com.google.android.apps.maps # ps -A | grep maps
+u0_a178        9143    927 15691440 190132 SyS_epoll_wait     0 S com.google.android.apps.maps
+blueline:/data/data/com.google.android.apps.maps # cmd activity attach-agent com.google.android.apps.maps $PWD/libsimpleprofileds.so=$PWD/maps.json
+blueline:/data/data/com.google.android.apps.maps # # Do things on the app.
+blueline:/data/data/com.google.android.apps.maps # kill -3 9143
+blueline:/data/data/com.google.android.apps.maps # wc -l maps.json
+17901 maps.json
+blueline:/data/data/com.google.android.apps.maps # ^D
+% adb pull /data/data/com.google.android.apps.maps/maps.json
+```
+
+#### RI
+>    `java '-agentpath:libsimpleprofiled.so=/proc/self/fd/2,dump_on_main_stop' -cp tmp/helloworld/classes helloworld`
+
+### Output
+A normal run will look something like this:
+
+    % ./test/run-test --64 --host --dev --with-agent $ANDROID_HOST_OUT/lib64/libsimpleprofiled.so=dump_on_main_stop,/proc/self/fd/1 001-HelloWorld
+    <normal output removed>
+    Hello, world!
+    ...
+    {"class_name":"Ljava/util/HashMap$KeySet;","method_name":"iterator","method_descriptor":"()Ljava/util/Iterator;","count":6},
+    {"class_name":"Ljava/util/HashMap$KeyIterator;","method_name":"<init>","method_descriptor":"(Ljava/util/HashMap;)V","count":6},
+    {"class_name":"Ljava/util/HashMap$HashIterator;","method_name":"<init>","method_descriptor":"(Ljava/util/HashMap;)V","count":6},
+    {"class_name":"Ljava/lang/String;","method_name":"equals","method_descriptor":"(Ljava/lang/Object;)Z","count":128},
+    {"class_name":"Ljava/util/Collections$UnmodifiableCollection$1;","method_name":"next","method_descriptor":"()Ljava/lang/Object;","count":38},
+    {"class_name":"Ljava/util/HashMap$KeyIterator;","method_name":"next","method_descriptor":"()Ljava/lang/Object;","count":38},
+    {"class_name":"Lsun/misc/Cleaner;","method_name":"add","method_descriptor":"(Lsun/misc/Cleaner;)Lsun/misc/Cleaner;","count":1},
+    ...
diff --git a/tools/jvmti-agents/simple-profile/simple_profile.cc b/tools/jvmti-agents/simple-profile/simple_profile.cc
new file mode 100644
index 0000000..5ead97e
--- /dev/null
+++ b/tools/jvmti-agents/simple-profile/simple_profile.cc
@@ -0,0 +1,523 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <android-base/logging.h>
+#include <fcntl.h>
+#include <jni.h>
+#include <jvmti.h>
+
+#include <atomic>
+#include <cstring>
+#include <iomanip>
+#include <iostream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "android-base/unique_fd.h"
+#include "nativehelper/scoped_local_ref.h"
+
+namespace simple_profile {
+
+static constexpr jint kArtTiVersion = JVMTI_VERSION_1_2 | 0x40000000;
+
+#define CHECK_JVMTI(a) CHECK_EQ(JVMTI_ERROR_NONE, a)
+
+struct DataDefinition {
+  std::string_view class_name;
+  std::string_view method_name;
+  std::string_view method_descriptor;
+  uint64_t count;
+};
+
+std::ostream& operator<<(std::ostream& os, const DataDefinition& dd) {
+  return os << "{\"class_name\":\"" << dd.class_name << "\",\"method_name\":\"" << dd.method_name
+            << "\",\"method_descriptor\":\"" << dd.method_descriptor << "\",\"count\":" << dd.count
+            << "}";
+}
+
+class SimpleProfileData {
+ public:
+  SimpleProfileData(
+      jvmtiEnv* env, std::string out_fd_name, int fd, bool dump_on_shutdown, bool dump_on_main_stop)
+      : dump_id_(0),
+        out_fd_name_(out_fd_name),
+        out_fd_(fd),
+        shutdown_(false),
+        dump_on_shutdown_(dump_on_shutdown || dump_on_main_stop),
+        dump_on_main_stop_(dump_on_main_stop) {
+    CHECK_JVMTI(env->CreateRawMonitor("simple_profile_mon", &mon_));
+    method_counts_.reserve(10000);
+  }
+
+  void Dump(jvmtiEnv* jvmti);
+  void Enter(jvmtiEnv* jvmti, JNIEnv* env, jmethodID meth);
+
+  void RunDumpLoop(jvmtiEnv* jvmti, JNIEnv* env);
+
+  static SimpleProfileData* GetProfileData(jvmtiEnv* env) {
+    void* data;
+    CHECK_JVMTI(env->GetEnvironmentLocalStorage(&data));
+    return static_cast<SimpleProfileData*>(data);
+  }
+
+  void FinishInitialization(jvmtiEnv* jvmti, JNIEnv* jni, jthread cur);
+  void Shutdown(jvmtiEnv* jvmti, JNIEnv* jni);
+
+ private:
+  void DoDump(jvmtiEnv* jvmti, JNIEnv* jni, std::unordered_map<jmethodID, uint64_t> copy);
+
+  jlong dump_id_;
+  jrawMonitorID mon_;
+  std::string out_fd_name_;
+  int out_fd_;
+  std::unordered_map<jmethodID, uint64_t> method_counts_;
+  bool shutdown_;
+  bool dump_on_shutdown_;
+  bool dump_on_main_stop_;
+};
+
+struct ScopedJvmtiMonitor {
+ public:
+  ScopedJvmtiMonitor(jvmtiEnv* env, jrawMonitorID mon) : jvmti_(env), mon_(mon) {
+    CHECK_JVMTI(jvmti_->RawMonitorEnter(mon_));
+  }
+
+  ~ScopedJvmtiMonitor() {
+    CHECK_JVMTI(jvmti_->RawMonitorExit(mon_));
+  }
+
+  void Notify() {
+    CHECK_JVMTI(jvmti_->RawMonitorNotifyAll(mon_));
+  }
+
+  void Wait() {
+    CHECK_JVMTI(jvmti_->RawMonitorWait(mon_, 0));
+  }
+
+ private:
+  jvmtiEnv* jvmti_;
+  jrawMonitorID mon_;
+};
+
+void SimpleProfileData::Enter(jvmtiEnv* jvmti, JNIEnv* env, jmethodID meth) {
+  ScopedJvmtiMonitor sjm(jvmti, mon_);
+  // Keep all classes from being unloaded to allow us to know we can get the method info later.
+  jclass tmp;
+  CHECK_JVMTI(jvmti->GetMethodDeclaringClass(meth, &tmp));
+  ScopedLocalRef<jclass> klass(env, tmp);
+  jlong tag;
+  CHECK_JVMTI(jvmti->GetTag(klass.get(), &tag));
+  if (tag == 0) {
+    CHECK_JVMTI(jvmti->SetTag(klass.get(), 1u));
+    env->NewGlobalRef(klass.get());
+  }
+  method_counts_.insert({ meth, 0u }).first->second++;
+}
+
+void SimpleProfileData::Dump(jvmtiEnv* jvmti) {
+  ScopedJvmtiMonitor sjm(jvmti, mon_);
+  dump_id_++;
+  sjm.Notify();
+}
+
+void SimpleProfileData::RunDumpLoop(jvmtiEnv* jvmti, JNIEnv* env) {
+  jlong current_id = 0;
+  do {
+    std::unordered_map<jmethodID, uint64_t> copy;
+    {
+      ScopedJvmtiMonitor sjm(jvmti, mon_);
+      while (!shutdown_ && current_id == dump_id_) {
+        sjm.Wait();
+      }
+      if (shutdown_) {
+        break;
+      }
+      current_id = dump_id_;
+      copy = method_counts_;
+    }
+    DoDump(jvmti, env, std::move(copy));
+  } while (true);
+}
+
+void SimpleProfileData::Shutdown(jvmtiEnv* jvmti, JNIEnv* jni) {
+  std::unordered_map<jmethodID, uint64_t> copy;
+  {
+    ScopedJvmtiMonitor sjm(jvmti, mon_);
+    if (shutdown_) {
+      return;
+    }
+    shutdown_ = true;
+    copy = method_counts_;
+    sjm.Notify();
+  }
+  if (dump_on_shutdown_) {
+    DoDump(jvmti, jni, std::move(copy));
+  }
+}
+
+void SimpleProfileData::FinishInitialization(jvmtiEnv* jvmti, JNIEnv* env, jthread cur) {
+  // Finish up startup.
+  // Create a Thread object.
+  std::string name = std::string("profile dump Thread: ") + this->out_fd_name_;
+  ScopedLocalRef<jobject> thread_name(env, env->NewStringUTF(name.c_str()));
+  CHECK_NE(thread_name.get(), nullptr);
+
+  ScopedLocalRef<jclass> thread_klass(env, env->FindClass("java/lang/Thread"));
+  CHECK_NE(thread_klass.get(), nullptr);
+  ScopedLocalRef<jobject> thread(env, env->AllocObject(thread_klass.get()));
+  CHECK_NE(thread.get(), nullptr);
+  jmethodID initID = env->GetMethodID(thread_klass.get(), "<init>", "(Ljava/lang/String;)V");
+  jmethodID setDaemonId = env->GetMethodID(thread_klass.get(), "setDaemon", "(Z)V");
+  CHECK_NE(initID, nullptr);
+  CHECK_NE(setDaemonId, nullptr);
+  env->CallNonvirtualVoidMethod(thread.get(), thread_klass.get(), initID, thread_name.get());
+  env->CallVoidMethod(thread.get(), setDaemonId, JNI_TRUE);
+  CHECK(!env->ExceptionCheck());
+
+  CHECK_JVMTI(jvmti->RunAgentThread(
+      thread.get(),
+      [](jvmtiEnv* jvmti, JNIEnv* jni, void* unused_data ATTRIBUTE_UNUSED) {
+        SimpleProfileData* data = SimpleProfileData::GetProfileData(jvmti);
+        data->RunDumpLoop(jvmti, jni);
+      },
+      nullptr,
+      JVMTI_THREAD_NORM_PRIORITY));
+
+  CHECK_JVMTI(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_METHOD_ENTRY, nullptr));
+  CHECK_JVMTI(
+      jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DATA_DUMP_REQUEST, nullptr));
+  if (dump_on_main_stop_) {
+    CHECK_JVMTI(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, cur));
+  }
+  CHECK_JVMTI(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, nullptr));
+}
+
+class ScopedClassInfo {
+ public:
+  ScopedClassInfo(jvmtiEnv* jvmti_env, jclass c)
+      : jvmti_env_(jvmti_env), class_(c), name_(nullptr), generic_(nullptr) {}
+
+  ~ScopedClassInfo() {
+    if (class_ != nullptr) {
+      jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(name_));
+      jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(generic_));
+    }
+  }
+
+  bool Init() {
+    if (class_ == nullptr) {
+      name_ = const_cast<char*>("<NONE>");
+      generic_ = const_cast<char*>("<NONE>");
+      return true;
+    } else {
+      return jvmti_env_->GetClassSignature(class_, &name_, &generic_) == JVMTI_ERROR_NONE;
+    }
+  }
+
+  jclass GetClass() const {
+    return class_;
+  }
+  const char* GetName() const {
+    return name_;
+  }
+  // Generic type parameters, whatever is in the <> for a class
+  const char* GetGeneric() const {
+    return generic_;
+  }
+
+ private:
+  jvmtiEnv* jvmti_env_;
+  jclass class_;
+  char* name_;
+  char* generic_;
+};
+
+class ScopedMethodInfo {
+ public:
+  ScopedMethodInfo(jvmtiEnv* jvmti_env, JNIEnv* env, jmethodID method)
+      : jvmti_env_(jvmti_env),
+        env_(env),
+        method_(method),
+        declaring_class_(nullptr),
+        class_info_(nullptr),
+        name_(nullptr),
+        signature_(nullptr),
+        generic_(nullptr) {}
+
+  ~ScopedMethodInfo() {
+    env_->DeleteLocalRef(declaring_class_);
+    jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(name_));
+    jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(signature_));
+    jvmti_env_->Deallocate(reinterpret_cast<unsigned char*>(generic_));
+  }
+
+  bool Init() {
+    if (jvmti_env_->GetMethodDeclaringClass(method_, &declaring_class_) != JVMTI_ERROR_NONE) {
+      LOG(INFO) << "No decl";
+      return false;
+    }
+    class_info_.reset(new ScopedClassInfo(jvmti_env_, declaring_class_));
+    return class_info_->Init() &&
+           (jvmti_env_->GetMethodName(method_, &name_, &signature_, &generic_) == JVMTI_ERROR_NONE);
+  }
+
+  const ScopedClassInfo& GetDeclaringClassInfo() const {
+    return *class_info_;
+  }
+
+  jclass GetDeclaringClass() const {
+    return declaring_class_;
+  }
+
+  const char* GetName() const {
+    return name_;
+  }
+
+  const char* GetSignature() const {
+    return signature_;
+  }
+
+  const char* GetGeneric() const {
+    return generic_;
+  }
+
+ private:
+  jvmtiEnv* jvmti_env_;
+  JNIEnv* env_;
+  jmethodID method_;
+  jclass declaring_class_;
+  std::unique_ptr<ScopedClassInfo> class_info_;
+  char* name_;
+  char* signature_;
+  char* generic_;
+
+  friend std::ostream& operator<<(std::ostream& os, ScopedMethodInfo const& method);
+};
+
+std::ostream& operator<<(std::ostream& os, const ScopedMethodInfo* method) {
+  return os << *method;
+}
+
+std::ostream& operator<<(std::ostream& os, ScopedMethodInfo const& method) {
+  return os << method.GetDeclaringClassInfo().GetName() << "->" << method.GetName()
+            << method.GetSignature();
+}
+
+void SimpleProfileData::DoDump(jvmtiEnv* jvmti,
+                               JNIEnv* jni,
+                               std::unordered_map<jmethodID, uint64_t> copy) {
+  std::ostringstream oss;
+  oss << "[";
+  bool is_first = true;
+  for (auto [meth, cnt] : copy) {
+    ScopedMethodInfo smi(jvmti, jni, meth);
+    if (!smi.Init()) {
+      continue;
+    }
+    if (!is_first) {
+      oss << "," << std::endl;
+    }
+    is_first = false;
+    oss << DataDefinition {
+      .class_name = smi.GetDeclaringClassInfo().GetName(),
+      .method_name = smi.GetName(),
+      .method_descriptor = smi.GetSignature(),
+      .count = cnt,
+    };
+  }
+  oss << "]";
+  CHECK_GE(TEMP_FAILURE_RETRY(write(out_fd_, oss.str().c_str(), oss.str().size())), 0)
+      << strerror(errno) << out_fd_ << " " << out_fd_name_;
+  fsync(out_fd_);
+}
+
+static void DataDumpCb(jvmtiEnv* jvmti_env) {
+  SimpleProfileData* data = SimpleProfileData::GetProfileData(jvmti_env);
+  data->Dump(jvmti_env);
+}
+
+static void MethodEntryCB(jvmtiEnv* jvmti_env,
+                          JNIEnv* env,
+                          jthread thread ATTRIBUTE_UNUSED,
+                          jmethodID method) {
+  SimpleProfileData* data = SimpleProfileData::GetProfileData(jvmti_env);
+  data->Enter(jvmti_env, env, method);
+}
+
+static void VMInitCB(jvmtiEnv* jvmti, JNIEnv* env, jthread thr) {
+  SimpleProfileData* data = SimpleProfileData::GetProfileData(jvmti);
+  data->FinishInitialization(jvmti, env, thr);
+}
+static void VMDeathCB(jvmtiEnv* jvmti, JNIEnv* env) {
+  SimpleProfileData* data = SimpleProfileData::GetProfileData(jvmti);
+  data->Shutdown(jvmti, env);
+}
+
+// Fills targets with the breakpoints to add.
+// Lname/of/Klass;->methodName(Lsig/of/Method)Lreturn/Type;@location,<...>
+static bool ParseArgs(const std::string& start_options,
+                      /*out*/ std::string* fd_name,
+                      /*out*/ int* fd,
+                      /*out*/ bool* dump_on_shutdown,
+                      /*out*/ bool* dump_on_main_stop) {
+  std::istringstream iss(start_options);
+  std::string item;
+  *dump_on_main_stop = false;
+  *dump_on_shutdown = false;
+  bool has_fd = false;
+  while (std::getline(iss, item, ',')) {
+    if (item == "dump_on_shutdown") {
+      *dump_on_shutdown = true;
+    } else if (item == "dump_on_main_stop") {
+      *dump_on_main_stop = true;
+    } else if (has_fd) {
+      LOG(ERROR) << "Too many args!";
+      return false;
+    } else {
+      has_fd = true;
+      *fd_name = item;
+      *fd = TEMP_FAILURE_RETRY(open(fd_name->c_str(), O_WRONLY | O_CLOEXEC | O_CREAT, 00666));
+      CHECK_GE(*fd, 0) << strerror(errno);
+    }
+  }
+  return has_fd;
+}
+
+enum class StartType {
+  OnAttach,
+  OnLoad,
+};
+
+static jint SetupJvmtiEnv(JavaVM* vm, jvmtiEnv** jvmti) {
+  jint res = 0;
+  res = vm->GetEnv(reinterpret_cast<void**>(jvmti), JVMTI_VERSION_1_1);
+
+  if (res != JNI_OK || *jvmti == nullptr) {
+    LOG(ERROR) << "Unable to access JVMTI, error code " << res;
+    return vm->GetEnv(reinterpret_cast<void**>(jvmti), kArtTiVersion);
+  }
+  return res;
+}
+
+static jint AgentStart(StartType start,
+                       JavaVM* vm,
+                       const char* options,
+                       void* reserved ATTRIBUTE_UNUSED) {
+  if (options == nullptr) {
+    options = "";
+  }
+  jvmtiEnv* jvmti = nullptr;
+  jvmtiError error = JVMTI_ERROR_NONE;
+  {
+    jint res = 0;
+    res = SetupJvmtiEnv(vm, &jvmti);
+
+    if (res != JNI_OK || jvmti == nullptr) {
+      LOG(ERROR) << "Unable to access JVMTI, error code " << res;
+      return JNI_ERR;
+    }
+  }
+
+  int fd;
+  std::string fd_name;
+  bool dump_on_shutdown;
+  bool dump_on_main_stop;
+  if (!ParseArgs(options,
+                 /*out*/ &fd_name,
+                 /*out*/ &fd,
+                 /*out*/ &dump_on_shutdown,
+                 /*out*/ &dump_on_main_stop)) {
+    LOG(ERROR) << "failed to get output file from " << options << "!";
+    return JNI_ERR;
+  }
+
+  void* data_mem = nullptr;
+  error = jvmti->Allocate(sizeof(SimpleProfileData), reinterpret_cast<unsigned char**>(&data_mem));
+  if (error != JVMTI_ERROR_NONE) {
+    LOG(ERROR) << "Unable to alloc memory for breakpoint target data";
+    return JNI_ERR;
+  }
+
+  SimpleProfileData* data =
+      new (data_mem) SimpleProfileData(jvmti, fd_name, fd, dump_on_shutdown, dump_on_main_stop);
+  error = jvmti->SetEnvironmentLocalStorage(data);
+  if (error != JVMTI_ERROR_NONE) {
+    LOG(ERROR) << "Unable to set local storage";
+    return JNI_ERR;
+  }
+
+  jvmtiCapabilities caps {};
+  caps.can_generate_method_entry_events = JNI_TRUE;
+  caps.can_tag_objects = JNI_TRUE;
+  error = jvmti->AddCapabilities(&caps);
+  if (error != JVMTI_ERROR_NONE) {
+    LOG(ERROR) << "Unable to set caps";
+    return JNI_ERR;
+  }
+
+  jvmtiEventCallbacks callbacks {};
+  callbacks.MethodEntry = &MethodEntryCB;
+  callbacks.VMInit = &VMInitCB;
+  callbacks.DataDumpRequest = &DataDumpCb;
+  callbacks.VMDeath = &VMDeathCB;
+  callbacks.ThreadEnd = [](jvmtiEnv* env, JNIEnv* jni, jthread thr ATTRIBUTE_UNUSED) {
+    VMDeathCB(env, jni);
+  };
+
+  error = jvmti->SetEventCallbacks(&callbacks, static_cast<jint>(sizeof(callbacks)));
+
+  if (error != JVMTI_ERROR_NONE) {
+    LOG(ERROR) << "Unable to set event callbacks.";
+    return JNI_ERR;
+  }
+
+  if (start == StartType::OnAttach) {
+    JNIEnv* env = nullptr;
+    jint res = 0;
+    res = vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_2);
+    if (res != JNI_OK || env == nullptr) {
+      LOG(ERROR) << "Unable to get jnienv";
+      return JNI_ERR;
+    }
+    jthread temp;
+    ScopedLocalRef<jthread> cur(env, nullptr);
+    CHECK_JVMTI(jvmti->GetCurrentThread(&temp));
+    cur.reset(temp);
+    VMInitCB(jvmti, env, cur.get());
+  } else {
+    error = jvmti->SetEventNotificationMode(
+        JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, nullptr /* all threads */);
+    if (error != JVMTI_ERROR_NONE) {
+      LOG(ERROR) << "Unable to set event vminit";
+      return JNI_ERR;
+    }
+  }
+  return JNI_OK;
+}
+
+// Late attachment (e.g. 'am attach-agent').
+extern "C" JNIEXPORT jint JNICALL Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
+  return AgentStart(StartType::OnAttach, vm, options, reserved);
+}
+
+// Early attachment
+extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* jvm, char* options, void* reserved) {
+  return AgentStart(StartType::OnLoad, jvm, options, reserved);
+}
+
+}  // namespace simple_profile
