src/profiling: move proc-fd based unwinding helpers into src/p/common/

These are the classes I'm intending to share (including UnwindingMetadata).
Will replicate DoUnwind for now though (as it's a bit more tightly bound to
heapprofd's types and requirements).

Bug: 144281346
Change-Id: I1686fefc52d32d1ebeb142bca8e598a4c8b330ca
diff --git a/Android.bp b/Android.bp
index dc0bc6c..1dbff86 100644
--- a/Android.bp
+++ b/Android.bp
@@ -110,6 +110,8 @@
     ":perfetto_src_base_unix_socket",
     ":perfetto_src_ipc_client",
     ":perfetto_src_ipc_common",
+    ":perfetto_src_profiling_common_unwind_support",
+    ":perfetto_src_profiling_common_utils",
     ":perfetto_src_profiling_memory_daemon",
     ":perfetto_src_profiling_memory_proc_utils",
     ":perfetto_src_profiling_memory_ring_buffer",
@@ -1341,6 +1343,8 @@
     ":perfetto_src_ipc_common",
     ":perfetto_src_ipc_host",
     ":perfetto_src_perfetto_cmd_perfetto_atoms",
+    ":perfetto_src_profiling_common_unwind_support",
+    ":perfetto_src_profiling_common_utils",
     ":perfetto_src_profiling_memory_client",
     ":perfetto_src_profiling_memory_daemon",
     ":perfetto_src_profiling_memory_end_to_end_tests",
@@ -5592,6 +5596,22 @@
   ],
 }
 
+// GN: //src/profiling/common:unwind_support
+filegroup {
+  name: "perfetto_src_profiling_common_unwind_support",
+  srcs: [
+    "src/profiling/common/unwind_support.cc",
+  ],
+}
+
+// GN: //src/profiling/common:utils
+filegroup {
+  name: "perfetto_src_profiling_common_utils",
+  srcs: [
+    "src/profiling/common/utils.cc",
+  ],
+}
+
 // GN: //src/profiling:deobfuscator
 filegroup {
   name: "perfetto_src_profiling_deobfuscator",
@@ -5619,7 +5639,6 @@
     "src/profiling/memory/page_idle_checker.cc",
     "src/profiling/memory/system_property.cc",
     "src/profiling/memory/unwinding.cc",
-    "src/profiling/memory/utils.cc",
   ],
 }
 
@@ -6961,6 +6980,8 @@
     ":perfetto_src_perfetto_cmd_protos_gen",
     ":perfetto_src_perfetto_cmd_trigger_producer",
     ":perfetto_src_perfetto_cmd_unittests",
+    ":perfetto_src_profiling_common_unwind_support",
+    ":perfetto_src_profiling_common_utils",
     ":perfetto_src_profiling_deobfuscator",
     ":perfetto_src_profiling_memory_client",
     ":perfetto_src_profiling_memory_daemon",
diff --git a/src/profiling/common/BUILD.gn b/src/profiling/common/BUILD.gn
new file mode 100644
index 0000000..767f969
--- /dev/null
+++ b/src/profiling/common/BUILD.gn
@@ -0,0 +1,36 @@
+# 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.
+
+import("../../../gn/perfetto.gni")
+
+source_set("unwind_support") {
+  public_deps = [ "../../../gn:libunwindstack" ]
+  deps = [
+    ":utils",
+    "../../../gn:default_deps",
+    "../../../src/base",
+  ]
+  sources = [
+    "unwind_support.cc",
+    "unwind_support.h",
+  ]
+}
+
+source_set("utils") {
+  deps = [ "../../../gn:default_deps" ]
+  sources = [
+    "utils.cc",
+    "utils.h",
+  ]
+}
diff --git a/src/profiling/common/unwind_support.cc b/src/profiling/common/unwind_support.cc
new file mode 100644
index 0000000..1d0d9f9
--- /dev/null
+++ b/src/profiling/common/unwind_support.cc
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2018 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 "src/profiling/common/unwind_support.h"
+
+#include <inttypes.h>
+
+#include <procinfo/process_map.h>
+#include <unwindstack/Maps.h>
+#include <unwindstack/Memory.h>
+
+#include "perfetto/ext/base/file_utils.h"
+#include "src/profiling/common/utils.h"
+
+namespace perfetto {
+namespace profiling {
+
+StackOverlayMemory::StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
+                                       uint64_t sp,
+                                       uint8_t* stack,
+                                       size_t size)
+    : mem_(std::move(mem)), sp_(sp), stack_end_(sp + size), stack_(stack) {}
+
+size_t StackOverlayMemory::Read(uint64_t addr, void* dst, size_t size) {
+  if (addr >= sp_ && addr + size <= stack_end_ && addr + size > sp_) {
+    size_t offset = static_cast<size_t>(addr - sp_);
+    memcpy(dst, stack_ + offset, size);
+    return size;
+  }
+
+  return mem_->Read(addr, dst, size);
+}
+
+FDMemory::FDMemory(base::ScopedFile mem_fd) : mem_fd_(std::move(mem_fd)) {}
+
+size_t FDMemory::Read(uint64_t addr, void* dst, size_t size) {
+  ssize_t rd = ReadAtOffsetClobberSeekPos(*mem_fd_, dst, size,
+                                          static_cast<off64_t>(addr));
+  if (rd == -1) {
+    PERFETTO_DPLOG("read of %zu at offset %" PRIu64, size, addr);
+    return 0;
+  }
+  return static_cast<size_t>(rd);
+}
+
+FileDescriptorMaps::FileDescriptorMaps(base::ScopedFile fd)
+    : fd_(std::move(fd)) {}
+
+bool FileDescriptorMaps::Parse() {
+  // If the process has already exited, lseek or ReadFileDescriptor will
+  // return false.
+  if (lseek(*fd_, 0, SEEK_SET) == -1)
+    return false;
+
+  std::string content;
+  if (!base::ReadFileDescriptor(*fd_, &content))
+    return false;
+
+  unwindstack::MapInfo* prev_map = nullptr;
+  unwindstack::MapInfo* prev_real_map = nullptr;
+  return android::procinfo::ReadMapFileContent(
+      &content[0], [&](uint64_t start, uint64_t end, uint16_t flags,
+                       uint64_t pgoff, ino_t, const char* name) {
+        // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
+        if (strncmp(name, "/dev/", 5) == 0 &&
+            strncmp(name + 5, "ashmem/", 7) != 0) {
+          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
+        }
+        maps_.emplace_back(new unwindstack::MapInfo(
+            prev_map, prev_real_map, start, end, pgoff, flags, name));
+        prev_map = maps_.back().get();
+        if (!prev_map->IsBlank()) {
+          prev_real_map = prev_map;
+        }
+      });
+}
+
+void FileDescriptorMaps::Reset() {
+  maps_.clear();
+}
+
+}  // namespace profiling
+}  // namespace perfetto
diff --git a/src/profiling/common/unwind_support.h b/src/profiling/common/unwind_support.h
new file mode 100644
index 0000000..f840273
--- /dev/null
+++ b/src/profiling/common/unwind_support.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#ifndef SRC_PROFILING_COMMON_UNWIND_SUPPORT_H_
+#define SRC_PROFILING_COMMON_UNWIND_SUPPORT_H_
+
+// defines PERFETTO_BUILDFLAG
+#include "perfetto/base/build_config.h"
+
+#include <unwindstack/Maps.h>
+#include <unwindstack/Unwinder.h>
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+#include <unwindstack/DexFiles.h>
+#include <unwindstack/JitDebug.h>
+#endif
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/time.h"
+#include "perfetto/ext/base/scoped_file.h"
+
+namespace perfetto {
+namespace profiling {
+
+// Read /proc/[pid]/maps from an open file descriptor.
+// TODO(fmayer): Figure out deduplication to other maps.
+class FileDescriptorMaps : public unwindstack::Maps {
+ public:
+  FileDescriptorMaps(base::ScopedFile fd);
+
+  FileDescriptorMaps(const FileDescriptorMaps&) = delete;
+  FileDescriptorMaps& operator=(const FileDescriptorMaps&) = delete;
+
+  FileDescriptorMaps(FileDescriptorMaps&& m) : Maps(std::move(m)) {
+    fd_ = std::move(m.fd_);
+  }
+
+  FileDescriptorMaps& operator=(FileDescriptorMaps&& m) {
+    if (&m != this)
+      fd_ = std::move(m.fd_);
+    Maps::operator=(std::move(m));
+    return *this;
+  }
+
+  virtual ~FileDescriptorMaps() override = default;
+
+  bool Parse() override;
+  void Reset();
+
+ private:
+  base::ScopedFile fd_;
+};
+
+class FDMemory : public unwindstack::Memory {
+ public:
+  FDMemory(base::ScopedFile mem_fd);
+  size_t Read(uint64_t addr, void* dst, size_t size) override;
+
+ private:
+  base::ScopedFile mem_fd_;
+};
+
+// Overlays size bytes pointed to by stack for addresses in [sp, sp + size).
+// Addresses outside of that range are read from mem_fd, which should be an fd
+// that opened /proc/[pid]/mem.
+class StackOverlayMemory : public unwindstack::Memory {
+ public:
+  StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
+                     uint64_t sp,
+                     uint8_t* stack,
+                     size_t size);
+  size_t Read(uint64_t addr, void* dst, size_t size) override;
+
+ private:
+  std::shared_ptr<unwindstack::Memory> mem_;
+  uint64_t sp_;
+  uint64_t stack_end_;
+  uint8_t* stack_;
+};
+
+struct UnwindingMetadata {
+  UnwindingMetadata(pid_t p, base::ScopedFile maps_fd, base::ScopedFile mem)
+      : pid(p),
+        maps(std::move(maps_fd)),
+        fd_mem(std::make_shared<FDMemory>(std::move(mem)))
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+        ,
+        jit_debug(std::unique_ptr<unwindstack::JitDebug>(
+            new unwindstack::JitDebug(fd_mem))),
+        dex_files(std::unique_ptr<unwindstack::DexFiles>(
+            new unwindstack::DexFiles(fd_mem)))
+#endif
+  {
+    bool parsed = maps.Parse();
+    PERFETTO_DCHECK(parsed);
+  }
+  void ReparseMaps() {
+    reparses++;
+    maps.Reset();
+    maps.Parse();
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+    jit_debug = std::unique_ptr<unwindstack::JitDebug>(
+        new unwindstack::JitDebug(fd_mem));
+    dex_files = std::unique_ptr<unwindstack::DexFiles>(
+        new unwindstack::DexFiles(fd_mem));
+#endif
+  }
+  pid_t pid;
+  FileDescriptorMaps maps;
+  // The API of libunwindstack expects shared_ptr for Memory.
+  std::shared_ptr<unwindstack::Memory> fd_mem;
+  uint64_t reparses = 0;
+  base::TimeMillis last_maps_reparse_time{0};
+#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
+  std::unique_ptr<unwindstack::JitDebug> jit_debug;
+  std::unique_ptr<unwindstack::DexFiles> dex_files;
+#endif
+};
+
+}  // namespace profiling
+}  // namespace perfetto
+
+#endif  // SRC_PROFILING_COMMON_UNWIND_SUPPORT_H_
diff --git a/src/profiling/memory/utils.cc b/src/profiling/common/utils.cc
similarity index 97%
rename from src/profiling/memory/utils.cc
rename to src/profiling/common/utils.cc
index b424192..019eb1b 100644
--- a/src/profiling/memory/utils.cc
+++ b/src/profiling/common/utils.cc
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "src/profiling/memory/utils.h"
+#include "src/profiling/common/utils.h"
 
 namespace perfetto {
 namespace profiling {
diff --git a/src/profiling/memory/utils.h b/src/profiling/common/utils.h
similarity index 88%
rename from src/profiling/memory/utils.h
rename to src/profiling/common/utils.h
index 5e375c9..01fbf99 100644
--- a/src/profiling/memory/utils.h
+++ b/src/profiling/common/utils.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef SRC_PROFILING_MEMORY_UTILS_H_
-#define SRC_PROFILING_MEMORY_UTILS_H_
+#ifndef SRC_PROFILING_COMMON_UTILS_H_
+#define SRC_PROFILING_COMMON_UTILS_H_
 
 #include <unistd.h>
 
@@ -31,7 +31,7 @@
                                     void* buf,
                                     size_t count,
                                     off64_t addr);
-}
+}  // namespace profiling
 }  // namespace perfetto
 
-#endif  // SRC_PROFILING_MEMORY_UTILS_H_
+#endif  // SRC_PROFILING_COMMON_UTILS_H_
diff --git a/src/profiling/memory/BUILD.gn b/src/profiling/memory/BUILD.gn
index 6c4ef75..76b9dc7 100644
--- a/src/profiling/memory/BUILD.gn
+++ b/src/profiling/memory/BUILD.gn
@@ -140,6 +140,8 @@
     "../../base:unix_socket",
     "../../tracing/core",
     "../../tracing/ipc/producer",
+    "../common:unwind_support",
+    "../common:utils",
   ]
   public_deps = [
     "../../../gn:libunwindstack",
@@ -165,8 +167,6 @@
     "unwinding.cc",
     "unwinding.h",
     "unwound_messages.h",
-    "utils.cc",
-    "utils.h",
   ]
 }
 
@@ -202,6 +202,8 @@
     "../../base",
     "../../base:test_support",
     "../../tracing/core",
+    "../common:unwind_support",
+    "../common:utils",
   ]
   sources = [
     "bookkeeping_unittest.cc",
@@ -248,6 +250,8 @@
     "../../../gn:default_deps",
     "../../base",
     "../../tracing/core",
+    "../common:unwind_support",
+    "../common:utils",
   ]
 }
 
diff --git a/src/profiling/memory/page_idle_checker.cc b/src/profiling/memory/page_idle_checker.cc
index 7e639b5..56eec2d 100644
--- a/src/profiling/memory/page_idle_checker.cc
+++ b/src/profiling/memory/page_idle_checker.cc
@@ -16,7 +16,7 @@
 
 #include "src/profiling/memory/page_idle_checker.h"
 #include "perfetto/ext/base/utils.h"
-#include "src/profiling/memory/utils.h"
+#include "src/profiling/common/utils.h"
 
 #include <inttypes.h>
 #include <vector>
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index 339077b..587bea4 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -51,7 +51,7 @@
 #include "perfetto/ext/base/string_utils.h"
 #include "perfetto/ext/base/thread_task_runner.h"
 
-#include "src/profiling/memory/utils.h"
+#include "src/profiling/common/utils.h"
 #include "src/profiling/memory/wire_protocol.h"
 
 namespace perfetto {
@@ -117,70 +117,6 @@
   return ret;
 }
 
-StackOverlayMemory::StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
-                                       uint64_t sp,
-                                       uint8_t* stack,
-                                       size_t size)
-    : mem_(std::move(mem)), sp_(sp), stack_end_(sp + size), stack_(stack) {}
-
-size_t StackOverlayMemory::Read(uint64_t addr, void* dst, size_t size) {
-  if (addr >= sp_ && addr + size <= stack_end_ && addr + size > sp_) {
-    size_t offset = static_cast<size_t>(addr - sp_);
-    memcpy(dst, stack_ + offset, size);
-    return size;
-  }
-
-  return mem_->Read(addr, dst, size);
-}
-
-FDMemory::FDMemory(base::ScopedFile mem_fd) : mem_fd_(std::move(mem_fd)) {}
-
-size_t FDMemory::Read(uint64_t addr, void* dst, size_t size) {
-  ssize_t rd = ReadAtOffsetClobberSeekPos(*mem_fd_, dst, size,
-                                          static_cast<off64_t>(addr));
-  if (rd == -1) {
-    PERFETTO_DPLOG("read of %zu at offset %" PRIu64, size, addr);
-    return 0;
-  }
-  return static_cast<size_t>(rd);
-}
-
-FileDescriptorMaps::FileDescriptorMaps(base::ScopedFile fd)
-    : fd_(std::move(fd)) {}
-
-bool FileDescriptorMaps::Parse() {
-  // If the process has already exited, lseek or ReadFileDescriptor will
-  // return false.
-  if (lseek(*fd_, 0, SEEK_SET) == -1)
-    return false;
-
-  std::string content;
-  if (!base::ReadFileDescriptor(*fd_, &content))
-    return false;
-
-  unwindstack::MapInfo* prev_map = nullptr;
-  unwindstack::MapInfo* prev_real_map = nullptr;
-  return android::procinfo::ReadMapFileContent(
-      &content[0], [&](uint64_t start, uint64_t end, uint16_t flags,
-                       uint64_t pgoff, ino_t, const char* name) {
-        // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
-        if (strncmp(name, "/dev/", 5) == 0 &&
-            strncmp(name + 5, "ashmem/", 7) != 0) {
-          flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
-        }
-        maps_.emplace_back(
-            new unwindstack::MapInfo(prev_map, prev_real_map, start, end, pgoff, flags, name));
-        prev_map = maps_.back().get();
-        if (!prev_map->IsBlank()) {
-          prev_real_map = prev_map;
-        }
-      });
-}
-
-void FileDescriptorMaps::Reset() {
-  maps_.clear();
-}
-
 bool DoUnwind(WireMessage* msg, UnwindingMetadata* metadata, AllocRecord* out) {
   AllocMetadata* alloc_metadata = msg->alloc_header;
   std::unique_ptr<unwindstack::Regs> regs(CreateRegsFromRawData(
diff --git a/src/profiling/memory/unwinding.h b/src/profiling/memory/unwinding.h
index a702c64..b1692a6 100644
--- a/src/profiling/memory/unwinding.h
+++ b/src/profiling/memory/unwinding.h
@@ -17,20 +17,13 @@
 #ifndef SRC_PROFILING_MEMORY_UNWINDING_H_
 #define SRC_PROFILING_MEMORY_UNWINDING_H_
 
-#include "perfetto/base/build_config.h"
-
-#include <unwindstack/Maps.h>
-#include <unwindstack/Unwinder.h>
-
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-#include <unwindstack/DexFiles.h>
-#include <unwindstack/JitDebug.h>
-#endif
+#include <unwindstack/Regs.h>
 
 #include "perfetto/base/time.h"
 #include "perfetto/ext/base/scoped_file.h"
 #include "perfetto/ext/base/thread_task_runner.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
+#include "src/profiling/common/unwind_support.h"
 #include "src/profiling/memory/bookkeeping.h"
 #include "src/profiling/memory/unwound_messages.h"
 #include "src/profiling/memory/wire_protocol.h"
@@ -42,101 +35,6 @@
     unwindstack::ArchEnum arch,
     void* raw_data);
 
-// Read /proc/[pid]/maps from an open file descriptor.
-// TODO(fmayer): Figure out deduplication to other maps.
-class FileDescriptorMaps : public unwindstack::Maps {
- public:
-  FileDescriptorMaps(base::ScopedFile fd);
-
-  FileDescriptorMaps(const FileDescriptorMaps&) = delete;
-  FileDescriptorMaps& operator=(const FileDescriptorMaps&) = delete;
-
-  FileDescriptorMaps(FileDescriptorMaps&& m) : Maps(std::move(m)) {
-    fd_ = std::move(m.fd_);
-  }
-
-  FileDescriptorMaps& operator=(FileDescriptorMaps&& m) {
-    if (&m != this)
-      fd_ = std::move(m.fd_);
-    Maps::operator=(std::move(m));
-    return *this;
-  }
-
-  virtual ~FileDescriptorMaps() override = default;
-
-  bool Parse() override;
-  void Reset();
-
- private:
-  base::ScopedFile fd_;
-};
-
-class FDMemory : public unwindstack::Memory {
- public:
-  FDMemory(base::ScopedFile mem_fd);
-  size_t Read(uint64_t addr, void* dst, size_t size) override;
-
- private:
-  base::ScopedFile mem_fd_;
-};
-
-// Overlays size bytes pointed to by stack for addresses in [sp, sp + size).
-// Addresses outside of that range are read from mem_fd, which should be an fd
-// that opened /proc/[pid]/mem.
-class StackOverlayMemory : public unwindstack::Memory {
- public:
-  StackOverlayMemory(std::shared_ptr<unwindstack::Memory> mem,
-                     uint64_t sp,
-                     uint8_t* stack,
-                     size_t size);
-  size_t Read(uint64_t addr, void* dst, size_t size) override;
-
- private:
-  std::shared_ptr<unwindstack::Memory> mem_;
-  uint64_t sp_;
-  uint64_t stack_end_;
-  uint8_t* stack_;
-};
-
-struct UnwindingMetadata {
-  UnwindingMetadata(pid_t p, base::ScopedFile maps_fd, base::ScopedFile mem)
-      : pid(p),
-        maps(std::move(maps_fd)),
-        fd_mem(std::make_shared<FDMemory>(std::move(mem)))
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-        ,
-        jit_debug(std::unique_ptr<unwindstack::JitDebug>(
-            new unwindstack::JitDebug(fd_mem))),
-        dex_files(std::unique_ptr<unwindstack::DexFiles>(
-            new unwindstack::DexFiles(fd_mem)))
-#endif
-  {
-    bool parsed = maps.Parse();
-    PERFETTO_DCHECK(parsed);
-  }
-  void ReparseMaps() {
-    reparses++;
-    maps.Reset();
-    maps.Parse();
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-    jit_debug = std::unique_ptr<unwindstack::JitDebug>(
-        new unwindstack::JitDebug(fd_mem));
-    dex_files = std::unique_ptr<unwindstack::DexFiles>(
-        new unwindstack::DexFiles(fd_mem));
-#endif
-  }
-  pid_t pid;
-  FileDescriptorMaps maps;
-  // The API of libunwindstack expects shared_ptr for Memory.
-  std::shared_ptr<unwindstack::Memory> fd_mem;
-  uint64_t reparses = 0;
-  base::TimeMillis last_maps_reparse_time{0};
-#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
-  std::unique_ptr<unwindstack::JitDebug> jit_debug;
-  std::unique_ptr<unwindstack::DexFiles> dex_files;
-#endif
-};
-
 bool DoUnwind(WireMessage*, UnwindingMetadata* metadata, AllocRecord* out);
 
 class UnwindingWorker : public base::UnixSocket::EventListener {
diff --git a/src/profiling/memory/unwinding_fuzzer.cc b/src/profiling/memory/unwinding_fuzzer.cc
index c2046b0..29991ba 100644
--- a/src/profiling/memory/unwinding_fuzzer.cc
+++ b/src/profiling/memory/unwinding_fuzzer.cc
@@ -19,6 +19,7 @@
 
 #include "perfetto/ext/base/utils.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
+#include "src/profiling/common/unwind_support.h"
 #include "src/profiling/memory/shared_ring_buffer.h"
 #include "src/profiling/memory/unwinding.h"
 #include "src/profiling/memory/unwound_messages.h"
diff --git a/src/profiling/memory/unwinding_unittest.cc b/src/profiling/memory/unwinding_unittest.cc
index b52a7ce..893bf8e 100644
--- a/src/profiling/memory/unwinding_unittest.cc
+++ b/src/profiling/memory/unwinding_unittest.cc
@@ -23,6 +23,7 @@
 #include <unwindstack/RegsGetLocal.h>
 
 #include "perfetto/ext/base/scoped_file.h"
+#include "src/profiling/common/unwind_support.h"
 #include "src/profiling/memory/client.h"
 #include "src/profiling/memory/wire_protocol.h"
 #include "test/gtest_and_gmock.h"