Merge "debuggerd_fallback: don't recursively abort."
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 0e32e47..711a12a 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -128,6 +128,22 @@
   return true;
 }
 
+bool Backtrace::UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+                              const backtrace_stackinfo_t& stack,
+                              std::vector<backtrace_frame_data_t>* frames,
+                              BacktraceUnwindError* error) {
+  UnwindStackOfflineMap* offline_map = reinterpret_cast<UnwindStackOfflineMap*>(back_map);
+  // Create the process memory from the stack data since this will almost
+  // always be different each unwind.
+  if (!offline_map->CreateProcessMemory(stack)) {
+    if (error != nullptr) {
+      error->error_code = BACKTRACE_UNWIND_ERROR_SETUP_FAILED;
+    }
+    return false;
+  }
+  return Backtrace::Unwind(regs, back_map, frames, 0U, nullptr, error);
+}
+
 UnwindStackCurrent::UnwindStackCurrent(pid_t pid, pid_t tid, BacktraceMap* map)
     : BacktraceCurrent(pid, tid, map) {}
 
@@ -221,12 +237,12 @@
 Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid,
                                     const std::vector<backtrace_map_t>& maps,
                                     const backtrace_stackinfo_t& stack) {
-  BacktraceMap* map = BacktraceMap::CreateOffline(pid, maps, stack);
-  if (map == nullptr) {
+  std::unique_ptr<UnwindStackOfflineMap> map(
+      reinterpret_cast<UnwindStackOfflineMap*>(BacktraceMap::CreateOffline(pid, maps)));
+  if (map.get() == nullptr || !map->CreateProcessMemory(stack)) {
     return nullptr;
   }
-
-  return new UnwindStackOffline(arch, pid, tid, map, false);
+  return new UnwindStackOffline(arch, pid, tid, map.release(), false);
 }
 
 Backtrace* Backtrace::CreateOffline(ArchEnum arch, pid_t pid, pid_t tid, BacktraceMap* map) {
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 6dcc621..9c6fed4 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -127,12 +127,7 @@
   return false;
 }
 
-bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps,
-                                  const backtrace_stackinfo_t& stack) {
-  if (stack.start >= stack.end) {
-    return false;
-  }
-
+bool UnwindStackOfflineMap::Build(const std::vector<backtrace_map_t>& backtrace_maps) {
   for (const backtrace_map_t& map : backtrace_maps) {
     maps_.push_back(map);
   }
@@ -145,6 +140,13 @@
   for (const backtrace_map_t& map : maps_) {
     maps->Add(map.start, map.end, map.offset, map.flags, map.name, map.load_bias);
   }
+  return true;
+}
+
+bool UnwindStackOfflineMap::CreateProcessMemory(const backtrace_stackinfo_t& stack) {
+  if (stack.start >= stack.end) {
+    return false;
+  }
 
   // Create the process memory from the stack data.
   uint64_t size = stack.end - stack.start;
@@ -154,7 +156,6 @@
   std::shared_ptr<unwindstack::Memory> shared_memory(memory);
 
   process_memory_.reset(new unwindstack::MemoryRange(shared_memory, 0, size, stack.start));
-
   return true;
 }
 
@@ -182,10 +183,9 @@
 //-------------------------------------------------------------------------
 // BacktraceMap create offline function.
 //-------------------------------------------------------------------------
-BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
-                                          const backtrace_stackinfo_t& stack) {
+BacktraceMap* BacktraceMap::CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps) {
   UnwindStackOfflineMap* map = new UnwindStackOfflineMap(pid);
-  if (!map->Build(maps, stack)) {
+  if (!map->Build(maps)) {
     delete map;
     return nullptr;
   }
diff --git a/libbacktrace/UnwindStackMap.h b/libbacktrace/UnwindStackMap.h
index 94cbfb2..ec0d9c1 100644
--- a/libbacktrace/UnwindStackMap.h
+++ b/libbacktrace/UnwindStackMap.h
@@ -76,7 +76,9 @@
 
   bool Build() override;
 
-  bool Build(const std::vector<backtrace_map_t>& maps, const backtrace_stackinfo_t& stack);
+  bool Build(const std::vector<backtrace_map_t>& maps);
+
+  bool CreateProcessMemory(const backtrace_stackinfo_t& stack);
 };
 
 #endif  // _LIBBACKTRACE_UNWINDSTACK_MAP_H
diff --git a/libbacktrace/include/backtrace/Backtrace.h b/libbacktrace/include/backtrace/Backtrace.h
index 7a37015..a088207 100644
--- a/libbacktrace/include/backtrace/Backtrace.h
+++ b/libbacktrace/include/backtrace/Backtrace.h
@@ -151,6 +151,11 @@
                      std::vector<backtrace_frame_data_t>* frames, size_t num_ignore_frames,
                      std::vector<std::string>* skip_names, BacktraceUnwindError* error = nullptr);
 
+  static bool UnwindOffline(unwindstack::Regs* regs, BacktraceMap* back_map,
+                            const backtrace_stackinfo_t& stack_info,
+                            std::vector<backtrace_frame_data_t>* frames,
+                            BacktraceUnwindError* error = nullptr);
+
   // Get the function name and offset into the function given the pc.
   // If the string is empty, then no valid function name was found,
   // or the pc is not in any valid map.
diff --git a/libbacktrace/include/backtrace/BacktraceMap.h b/libbacktrace/include/backtrace/BacktraceMap.h
index da54472..473d195 100644
--- a/libbacktrace/include/backtrace/BacktraceMap.h
+++ b/libbacktrace/include/backtrace/BacktraceMap.h
@@ -64,8 +64,7 @@
   // is unsupported.
   static BacktraceMap* Create(pid_t pid, bool uncached = false);
 
-  static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps,
-                                     const backtrace_stackinfo_t& stack);
+  static BacktraceMap* CreateOffline(pid_t pid, const std::vector<backtrace_map_t>& maps);
 
   virtual ~BacktraceMap();
 
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index a993d41..5ea981f 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -202,16 +202,6 @@
                                            CAP_MASK_LONG(CAP_NET_RAW),
                                               "vendor/bin/hw/android.hardware.wifi@1.0-service" },
 
-    // A non-privileged zygote that spawns isolated processes for web rendering.
-    { 0750,  AID_ROOT,      AID_ROOT,      CAP_MASK_LONG(CAP_SETUID) |
-                                           CAP_MASK_LONG(CAP_SETGID) |
-                                           CAP_MASK_LONG(CAP_SETPCAP),
-                                              "system/bin/webview_zygote32" },
-    { 0750,  AID_ROOT,      AID_ROOT,      CAP_MASK_LONG(CAP_SETUID) |
-                                           CAP_MASK_LONG(CAP_SETGID) |
-                                           CAP_MASK_LONG(CAP_SETPCAP),
-                                              "system/bin/webview_zygote64" },
-
     // generic defaults
     { 00755, AID_ROOT,      AID_ROOT,      0, "bin/*" },
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
diff --git a/libunwindstack/DexFiles.cpp b/libunwindstack/DexFiles.cpp
index c5f8138..430f6c5 100644
--- a/libunwindstack/DexFiles.cpp
+++ b/libunwindstack/DexFiles.cpp
@@ -77,7 +77,8 @@
 
 uint64_t DexFiles::ReadEntryPtr32(uint64_t addr) {
   uint32_t entry;
-  if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+  const uint32_t field_offset = 12;  // offset of first_entry_ in the descriptor struct.
+  if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
     return 0;
   }
   return entry;
@@ -85,7 +86,8 @@
 
 uint64_t DexFiles::ReadEntryPtr64(uint64_t addr) {
   uint64_t entry;
-  if (!memory_->ReadFully(addr, &entry, sizeof(entry))) {
+  const uint32_t field_offset = 16;  // offset of first_entry_ in the descriptor struct.
+  if (!memory_->ReadFully(addr + field_offset, &entry, sizeof(entry))) {
     return 0;
   }
   return entry;
@@ -122,7 +124,7 @@
   initialized_ = true;
   entry_addr_ = 0;
 
-  const std::string dex_debug_name("__art_debug_dexfiles");
+  const std::string dex_debug_name("__dex_debug_descriptor");
   for (MapInfo* info : *maps) {
     if (!(info->flags & PROT_EXEC) || !(info->flags & PROT_READ) || info->offset != 0) {
       continue;
diff --git a/libunwindstack/tests/DexFilesTest.cpp b/libunwindstack/tests/DexFilesTest.cpp
index dca5605..d029bb0 100644
--- a/libunwindstack/tests/DexFilesTest.cpp
+++ b/libunwindstack/tests/DexFilesTest.cpp
@@ -63,7 +63,7 @@
     elf->FakeSetValid(true);
     ElfInterfaceFake* interface = new ElfInterfaceFake(memory);
     elf->FakeSetInterface(interface);
-    interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+    interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
     map_info->elf.reset(elf);
 
     // Global variable not set by default.
@@ -74,7 +74,7 @@
     elf->FakeSetValid(true);
     interface = new ElfInterfaceFake(memory);
     elf->FakeSetInterface(interface);
-    interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+    interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
     map_info->elf.reset(elf);
 
     // Global variable set in this map.
@@ -85,10 +85,12 @@
     elf->FakeSetValid(true);
     interface = new ElfInterfaceFake(memory);
     elf->FakeSetInterface(interface);
-    interface->FakeSetGlobalVariable("__art_debug_dexfiles", 0x800);
+    interface->FakeSetGlobalVariable("__dex_debug_descriptor", 0x800);
     map_info->elf.reset(elf);
   }
 
+  void WriteDescriptor32(uint64_t addr, uint32_t head);
+  void WriteDescriptor64(uint64_t addr, uint64_t head);
   void WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev, uint32_t dex_file);
   void WriteEntry64(uint64_t entry_addr, uint64_t next, uint64_t prev, uint64_t dex_file);
   void WriteDex(uint64_t dex_file);
@@ -105,6 +107,16 @@
   std::unique_ptr<BufferMaps> maps_;
 };
 
+void DexFilesTest::WriteDescriptor32(uint64_t addr, uint32_t head) {
+  //   void* first_entry_
+  memory_->SetData32(addr + 12, head);
+}
+
+void DexFilesTest::WriteDescriptor64(uint64_t addr, uint64_t head) {
+  //   void* first_entry_
+  memory_->SetData64(addr + 16, head);
+}
+
 void DexFilesTest::WriteEntry32(uint64_t entry_addr, uint32_t next, uint32_t prev,
                                 uint32_t dex_file) {
   // Format of the 32 bit DEXFileEntry structure:
@@ -146,7 +158,7 @@
   uint64_t method_offset = 0x124;
   MapInfo* info = maps_->Get(kMapDexFiles);
 
-  memory_->SetData32(0xf800, 0x200000);
+  WriteDescriptor32(0xf800, 0x200000);
   WriteEntry32(0x200000, 0, 0, 0x300000);
   WriteDex(0x300000);
 
@@ -161,7 +173,7 @@
   MapInfo* info = maps_->Get(kMapDexFiles);
 
   dex_files_->SetArch(ARCH_ARM64);
-  memory_->SetData64(0xf800, 0x200000);
+  WriteDescriptor64(0xf800, 0x200000);
   WriteEntry64(0x200000, 0, 0, 0x301000);
   WriteDex(0x301000);
 
@@ -175,7 +187,7 @@
   uint64_t method_offset = 0x124;
   MapInfo* info = maps_->Get(kMapDexFiles);
 
-  memory_->SetData32(0xf800, 0x200000);
+  WriteDescriptor32(0xf800, 0x200000);
   WriteEntry32(0x200000, 0x200100, 0, 0x100000);
   WriteEntry32(0x200100, 0, 0x200000, 0x300000);
   WriteDex(0x300000);
@@ -191,7 +203,7 @@
   MapInfo* info = maps_->Get(kMapDexFiles);
 
   dex_files_->SetArch(ARCH_ARM64);
-  memory_->SetData64(0xf800, 0x200000);
+  WriteDescriptor64(0xf800, 0x200000);
   WriteEntry64(0x200000, 0x200100, 0, 0x100000);
   WriteEntry64(0x200100, 0, 0x200000, 0x300000);
   WriteDex(0x300000);
@@ -206,7 +218,7 @@
   uint64_t method_offset = 0x124;
   MapInfo* info = maps_->Get(kMapDexFiles);
 
-  memory_->SetData32(0xf800, 0x200000);
+  WriteDescriptor32(0xf800, 0x200000);
   WriteEntry32(0x200000, 0, 0, 0x300000);
   WriteDex(0x300000);
 
@@ -226,7 +238,7 @@
   uint64_t method_offset = 0x124;
   MapInfo* info = maps_->Get(kMapDexFiles);
 
-  memory_->SetData32(0xf800, 0x200000);
+  WriteDescriptor32(0xf800, 0x200000);
   WriteEntry32(0x200000, 0x200100, 0, 0x100000);
   WriteEntry32(0x200100, 0, 0x200000, 0x300000);
   WriteDex(0x300000);
@@ -259,9 +271,9 @@
   MapInfo* info = maps_->Get(kMapDexFiles);
 
   // First global variable found, but value is zero.
-  memory_->SetData32(0xc800, 0);
+  WriteDescriptor32(0xc800, 0);
 
-  memory_->SetData32(0xf800, 0x200000);
+  WriteDescriptor32(0xf800, 0x200000);
   WriteEntry32(0x200000, 0, 0, 0x300000);
   WriteDex(0x300000);
 
@@ -274,7 +286,7 @@
   dex_files_->SetArch(ARCH_ARM);
   method_name = "fail";
   method_offset = 0x123;
-  memory_->SetData32(0xc800, 0x100000);
+  WriteDescriptor32(0xc800, 0x100000);
   dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
   EXPECT_EQ("fail", method_name);
   EXPECT_EQ(0x123U, method_offset);
@@ -286,9 +298,9 @@
   MapInfo* info = maps_->Get(kMapDexFiles);
 
   // First global variable found, but value is zero.
-  memory_->SetData64(0xc800, 0);
+  WriteDescriptor64(0xc800, 0);
 
-  memory_->SetData64(0xf800, 0x200000);
+  WriteDescriptor64(0xf800, 0x200000);
   WriteEntry64(0x200000, 0, 0, 0x300000);
   WriteDex(0x300000);
 
@@ -302,7 +314,7 @@
   dex_files_->SetArch(ARCH_ARM64);
   method_name = "fail";
   method_offset = 0x123;
-  memory_->SetData32(0xc800, 0x100000);
+  WriteDescriptor64(0xc800, 0x100000);
   dex_files_->GetMethodInformation(maps_.get(), info, 0x300100, &method_name, &method_offset);
   EXPECT_EQ("fail", method_name);
   EXPECT_EQ(0x123U, method_offset);