Add extra frame when dex_pc is non-zero.

Use the art dex file library to read the dex data.

Add unit tests for the UnwindDexFile code.

Bug: 72070049

Test: All unit tests continue to pass.
Test: Dumped the backtrace of the 137-cfi test while running in interpreter
Test: mode and verified that the stack trace is correct. Did this on host
Test: and for arm/arm64.

Change-Id: Ia6f343318c5dd6968a954015a7d59fdf101575b0
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 60c7952..11ff84a 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -26,11 +26,20 @@
 #include <unwindstack/MapInfo.h>
 #include <unwindstack/Maps.h>
 
+#include "UnwindDexFile.h"
 #include "UnwindStackMap.h"
 
 //-------------------------------------------------------------------------
 UnwindStackMap::UnwindStackMap(pid_t pid) : BacktraceMap(pid) {}
 
+UnwindStackMap::~UnwindStackMap() {
+#ifndef NO_LIBDEXFILE
+  for (auto& entry : dex_files_) {
+    delete entry.second;
+  }
+#endif
+}
+
 bool UnwindStackMap::Build() {
   if (pid_ == 0) {
     pid_ = getpid();
@@ -118,6 +127,26 @@
   return process_memory_;
 }
 
+#ifdef NO_LIBDEXFILE
+UnwindDexFile* UnwindStackMap::GetDexFile(uint64_t, unwindstack::MapInfo*) {
+  return nullptr;
+}
+#else
+UnwindDexFile* UnwindStackMap::GetDexFile(uint64_t dex_file_offset, unwindstack::MapInfo* info) {
+  // Lock while we get the data.
+  std::lock_guard<std::mutex> guard(dex_lock_);
+  UnwindDexFile* dex_file;
+  auto entry = dex_files_.find(dex_file_offset);
+  if (entry == dex_files_.end()) {
+    dex_file = UnwindDexFile::Create(dex_file_offset, process_memory_.get(), info);
+    dex_files_[dex_file_offset] = dex_file;
+  } else {
+    dex_file = entry->second;
+  }
+  return dex_file;
+}
+#endif
+
 //-------------------------------------------------------------------------
 // BacktraceMap create function.
 //-------------------------------------------------------------------------