summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2020-09-23 15:51:46 -0700
committerChristopher Ferris <cferris@google.com>2020-09-24 18:46:23 -0700
commit1d2a2a492f49beded338c91be01a6bd39478deaf (patch)
treeefd610ed831aa7c61ebdf0772c444212e60d4995
parentfb162c7404514efe0b553d9b44ebff574df4d167 (diff)
downloadunwinding-1d2a2a492f49beded338c91be01a6bd39478deaf.tar.gz
Add arch member into Unwinder object.
This simplifies some of the logic and removes the need to pass an Arch value to functions that should already know about the arch it is operating on. Includes fixes for debuggerd/libbacktrace. Added new unit tests to cover new cases. Test: All unit tests pass. Test: Faked unwinder failing to verify debuggerd error messages display Test: properly in backtrace and tombstone. Change-Id: I439fcae0695befcfb1cb4c0a786cc74949d33425
-rw-r--r--libbacktrace/BacktraceCurrent.cpp12
-rw-r--r--libbacktrace/UnwindStack.cpp9
-rw-r--r--libunwindstack/Android.bp2
-rw-r--r--libunwindstack/Unwinder.cpp52
-rw-r--r--libunwindstack/include/unwindstack/Arch.h47
-rw-r--r--libunwindstack/include/unwindstack/Elf.h11
-rw-r--r--libunwindstack/include/unwindstack/Error.h21
-rw-r--r--libunwindstack/include/unwindstack/Regs.h7
-rw-r--r--libunwindstack/include/unwindstack/Unwinder.h42
-rw-r--r--libunwindstack/tests/UnwindOfflineTest.cpp8
-rw-r--r--libunwindstack/tests/UnwindTest.cpp3
-rw-r--r--libunwindstack/tests/UnwinderTest.cpp21
-rw-r--r--libunwindstack/tests/VerifyBionicTerminationTest.cpp1
-rw-r--r--libunwindstack/tests/fuzz/UnwinderFuzz.cpp2
-rw-r--r--libunwindstack/tools/unwind.cpp5
-rw-r--r--libunwindstack/tools/unwind_for_offline.cpp4
16 files changed, 184 insertions, 63 deletions
diff --git a/libbacktrace/BacktraceCurrent.cpp b/libbacktrace/BacktraceCurrent.cpp
index 038b59e..a506575 100644
--- a/libbacktrace/BacktraceCurrent.cpp
+++ b/libbacktrace/BacktraceCurrent.cpp
@@ -37,6 +37,12 @@
#include "ThreadEntry.h"
bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
+#if defined(__aarch64__)
+ // Tagged pointer after Android R would lead top byte to have random values
+ // https://source.android.com/devices/tech/debug/tagged-pointers
+ ptr &= (1ULL << 56) - 1;
+#endif
+
if (!VerifyReadWordArgs(ptr, out_value)) {
return false;
}
@@ -54,6 +60,12 @@ bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
}
size_t BacktraceCurrent::Read(uint64_t addr, uint8_t* buffer, size_t bytes) {
+#if defined(__aarch64__)
+ // Tagged pointer after Android R would lead top byte to have random values
+ // https://source.android.com/devices/tech/debug/tagged-pointers
+ addr &= (1ULL << 56) - 1;
+#endif
+
backtrace_map_t map;
FillInMap(addr, &map);
if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) {
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index 624711f..82ff21c 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -52,11 +52,11 @@ bool Backtrace::Unwind(unwindstack::Regs* regs, BacktraceMap* back_map,
unwinder.SetResolveNames(stack_map->ResolveNames());
stack_map->SetArch(regs->Arch());
if (stack_map->GetJitDebug() != nullptr) {
- unwinder.SetJitDebug(stack_map->GetJitDebug(), regs->Arch());
+ unwinder.SetJitDebug(stack_map->GetJitDebug());
}
#if !defined(NO_LIBDEXFILE_SUPPORT)
if (stack_map->GetDexFiles() != nullptr) {
- unwinder.SetDexFiles(stack_map->GetDexFiles(), regs->Arch());
+ unwinder.SetDexFiles(stack_map->GetDexFiles());
}
#endif
unwinder.Unwind(skip_names, &stack_map->GetSuffixesToIgnore());
@@ -180,5 +180,10 @@ bool UnwindStackPtrace::Unwind(size_t num_ignore_frames, void* context) {
}
size_t UnwindStackPtrace::Read(uint64_t addr, uint8_t* buffer, size_t bytes) {
+#if defined(__aarch64__)
+ // Tagged pointer after Android R would lead top byte to have random values
+ // https://source.android.com/devices/tech/debug/tagged-pointers
+ addr &= (1ULL << 56) - 1;
+#endif
return memory_->Read(addr, buffer, bytes);
}
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 8cc780a..75a419c 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -131,7 +131,6 @@ cc_library {
support_system_process: true,
},
defaults: ["libunwindstack_defaults"],
-
srcs: ["DexFile.cpp"],
cflags: ["-DDEXFILE_SUPPORT"],
shared_libs: ["libdexfile_support"],
@@ -168,6 +167,7 @@ cc_library_static {
defaults: ["libunwindstack_defaults"],
visibility: [
+ "//external/gwp_asan",
"//system/core/debuggerd",
"//system/core/init",
"//system/core/libbacktrace",
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp
index 57806c1..bcdbde8 100644
--- a/libunwindstack/Unwinder.cpp
+++ b/libunwindstack/Unwinder.cpp
@@ -27,6 +27,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <unwindstack/DexFiles.h>
#include <unwindstack/Elf.h>
#include <unwindstack/JitDebug.h>
#include <unwindstack/MapInfo.h>
@@ -34,7 +35,7 @@
#include <unwindstack/Memory.h>
#include <unwindstack/Unwinder.h>
-#include <unwindstack/DexFiles.h>
+#include "Check.h"
// Use the demangler from libc++.
extern "C" char* __cxa_demangle(const char*, char*, size_t*, int* status);
@@ -142,14 +143,12 @@ static bool ShouldStop(const std::vector<std::string>* map_suffixes_to_ignore,
void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
const std::vector<std::string>* map_suffixes_to_ignore) {
+ CHECK(arch_ != ARCH_UNKNOWN);
+ ClearErrors();
+
frames_.clear();
- warnings_ = WARNING_NONE;
- last_error_.code = ERROR_NONE;
- last_error_.address = 0;
elf_from_memory_not_file_ = false;
- ArchEnum arch = regs_->Arch();
-
bool return_address_attempt = false;
bool adjust_pc = false;
for (; frames_.size() < max_frames_;) {
@@ -169,7 +168,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
if (ShouldStop(map_suffixes_to_ignore, map_info->name)) {
break;
}
- elf = map_info->GetElf(process_memory_, arch);
+ elf = map_info->GetElf(process_memory_, arch_);
// If this elf is memory backed, and there is a valid file, then set
// an indicator that we couldn't open the file.
if (!elf_from_memory_not_file_ && map_info->memory_backed_elf && !map_info->name.empty() &&
@@ -183,7 +182,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
step_pc = rel_pc;
}
if (adjust_pc) {
- pc_adjustment = GetPcAdjustment(rel_pc, elf, arch);
+ pc_adjustment = GetPcAdjustment(rel_pc, elf, arch_);
} else {
pc_adjustment = 0;
}
@@ -311,7 +310,7 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
std::string Unwinder::FormatFrame(const FrameData& frame) const {
std::string data;
- if (regs_->Is32Bit()) {
+ if (ArchIs32Bit(arch_)) {
data += android::base::StringPrintf(" #%02zu pc %08" PRIx64, frame.num, frame.rel_pc);
} else {
data += android::base::StringPrintf(" #%02zu pc %016" PRIx64, frame.num, frame.rel_pc);
@@ -362,23 +361,33 @@ std::string Unwinder::FormatFrame(size_t frame_num) const {
return FormatFrame(frames_[frame_num]);
}
-void Unwinder::SetJitDebug(JitDebug* jit_debug, ArchEnum arch) {
- jit_debug->SetArch(arch);
+void Unwinder::SetJitDebug(JitDebug* jit_debug) {
+ CHECK(arch_ != ARCH_UNKNOWN);
+ jit_debug->SetArch(arch_);
jit_debug_ = jit_debug;
}
-void Unwinder::SetDexFiles(DexFiles* dex_files, ArchEnum arch) {
- dex_files->SetArch(arch);
+void Unwinder::SetDexFiles(DexFiles* dex_files) {
+ CHECK(arch_ != ARCH_UNKNOWN);
+ dex_files->SetArch(arch_);
dex_files_ = dex_files;
}
-bool UnwinderFromPid::Init(ArchEnum arch) {
+bool UnwinderFromPid::Init() {
+ CHECK(arch_ != ARCH_UNKNOWN);
+ if (initted_) {
+ return true;
+ }
+ initted_ = true;
+
if (pid_ == getpid()) {
maps_ptr_.reset(new LocalMaps());
} else {
maps_ptr_.reset(new RemoteMaps(pid_));
}
if (!maps_ptr_->Parse()) {
+ ClearErrors();
+ last_error_.code = ERROR_INVALID_MAP;
return false;
}
maps_ = maps_ptr_.get();
@@ -387,16 +396,24 @@ bool UnwinderFromPid::Init(ArchEnum arch) {
jit_debug_ptr_.reset(new JitDebug(process_memory_));
jit_debug_ = jit_debug_ptr_.get();
- SetJitDebug(jit_debug_, arch);
+ SetJitDebug(jit_debug_);
#if defined(DEXFILE_SUPPORT)
dex_files_ptr_.reset(new DexFiles(process_memory_));
dex_files_ = dex_files_ptr_.get();
- SetDexFiles(dex_files_, arch);
+ SetDexFiles(dex_files_);
#endif
return true;
}
+void UnwinderFromPid::Unwind(const std::vector<std::string>* initial_map_names_to_skip,
+ const std::vector<std::string>* map_suffixes_to_ignore) {
+ if (!Init()) {
+ return;
+ }
+ Unwinder::Unwind(initial_map_names_to_skip, map_suffixes_to_ignore);
+}
+
FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc, ArchEnum arch, Maps* maps,
JitDebug* jit_debug,
std::shared_ptr<Memory> process_memory,
@@ -449,8 +466,7 @@ FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc, ArchEnum arch, Maps* maps,
}
FrameData Unwinder::BuildFrameFromPcOnly(uint64_t pc) {
- return BuildFrameFromPcOnly(pc, regs_ ? regs_->Arch() : ARCH_UNKNOWN, maps_, jit_debug_,
- process_memory_, resolve_names_);
+ return BuildFrameFromPcOnly(pc, arch_, maps_, jit_debug_, process_memory_, resolve_names_);
}
} // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/Arch.h b/libunwindstack/include/unwindstack/Arch.h
new file mode 100644
index 0000000..7060004
--- /dev/null
+++ b/libunwindstack/include/unwindstack/Arch.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef _LIBUNWINDSTACK_ARCH_H
+#define _LIBUNWINDSTACK_ARCH_H
+
+#include <stddef.h>
+
+namespace unwindstack {
+
+enum ArchEnum : uint8_t {
+ ARCH_UNKNOWN = 0,
+ ARCH_ARM,
+ ARCH_ARM64,
+ ARCH_X86,
+ ARCH_X86_64,
+ ARCH_MIPS,
+ ARCH_MIPS64,
+};
+
+static inline bool ArchIs32Bit(ArchEnum arch) {
+ switch (arch) {
+ case ARCH_ARM:
+ case ARCH_X86:
+ case ARCH_MIPS:
+ return true;
+ default:
+ return false;
+ }
+}
+
+} // namespace unwindstack
+
+#endif // _LIBUNWINDSTACK_ARCH_H
diff --git a/libunwindstack/include/unwindstack/Elf.h b/libunwindstack/include/unwindstack/Elf.h
index 472ed92..97614b1 100644
--- a/libunwindstack/include/unwindstack/Elf.h
+++ b/libunwindstack/include/unwindstack/Elf.h
@@ -25,6 +25,7 @@
#include <unordered_map>
#include <utility>
+#include <unwindstack/Arch.h>
#include <unwindstack/ElfInterface.h>
#include <unwindstack/Memory.h>
@@ -38,16 +39,6 @@ namespace unwindstack {
struct MapInfo;
class Regs;
-enum ArchEnum : uint8_t {
- ARCH_UNKNOWN = 0,
- ARCH_ARM,
- ARCH_ARM64,
- ARCH_X86,
- ARCH_X86_64,
- ARCH_MIPS,
- ARCH_MIPS64,
-};
-
class Elf {
public:
Elf(Memory* memory) : memory_(memory) {}
diff --git a/libunwindstack/include/unwindstack/Error.h b/libunwindstack/include/unwindstack/Error.h
index 66fefe7..0be4572 100644
--- a/libunwindstack/include/unwindstack/Error.h
+++ b/libunwindstack/include/unwindstack/Error.h
@@ -39,6 +39,27 @@ enum ErrorCode : uint8_t {
ERROR_INVALID_ELF, // Unwind in an invalid elf.
};
+static inline const char* GetErrorCodeString(ErrorCode error) {
+ switch (error) {
+ case ERROR_NONE:
+ return "None";
+ case ERROR_MEMORY_INVALID:
+ return "Memory Invalid";
+ case ERROR_UNWIND_INFO:
+ return "Unwind Info";
+ case ERROR_UNSUPPORTED:
+ return "Unsupported";
+ case ERROR_INVALID_MAP:
+ return "Invalid Map";
+ case ERROR_MAX_FRAMES_EXCEEDED:
+ return "Maximum Frames Exceeded";
+ case ERROR_REPEATED_FRAME:
+ return "Repeated Frame";
+ case ERROR_INVALID_ELF:
+ return "Invalid Elf";
+ }
+}
+
struct ErrorData {
ErrorCode code;
uint64_t address; // Only valid when code is ERROR_MEMORY_INVALID.
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h
index 5f42565..1a2a704 100644
--- a/libunwindstack/include/unwindstack/Regs.h
+++ b/libunwindstack/include/unwindstack/Regs.h
@@ -24,11 +24,12 @@
#include <string>
#include <vector>
+#include <unwindstack/Arch.h>
+
namespace unwindstack {
// Forward declarations.
class Elf;
-enum ArchEnum : uint8_t;
class Memory;
class Regs {
@@ -52,7 +53,7 @@ class Regs {
virtual ArchEnum Arch() = 0;
- virtual bool Is32Bit() = 0;
+ bool Is32Bit() { return ArchIs32Bit(Arch()); }
virtual void* RawData() = 0;
virtual uint64_t pc() = 0;
@@ -96,8 +97,6 @@ class RegsImpl : public Regs {
: Regs(total_regs, return_loc), regs_(total_regs) {}
virtual ~RegsImpl() = default;
- bool Is32Bit() override { return sizeof(AddressType) == sizeof(uint32_t); }
-
inline AddressType& operator[](size_t reg) { return regs_[reg]; }
void* RawData() override { return regs_.data(); }
diff --git a/libunwindstack/include/unwindstack/Unwinder.h b/libunwindstack/include/unwindstack/Unwinder.h
index 3df8aad..b274c4c 100644
--- a/libunwindstack/include/unwindstack/Unwinder.h
+++ b/libunwindstack/include/unwindstack/Unwinder.h
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+#include <unwindstack/Arch.h>
#include <unwindstack/DexFiles.h>
#include <unwindstack/Error.h>
#include <unwindstack/JitDebug.h>
@@ -35,7 +36,6 @@ namespace unwindstack {
// Forward declarations.
class Elf;
-enum ArchEnum : uint8_t;
struct FrameData {
size_t num;
@@ -64,7 +64,11 @@ struct FrameData {
class Unwinder {
public:
Unwinder(size_t max_frames, Maps* maps, Regs* regs, std::shared_ptr<Memory> process_memory)
- : max_frames_(max_frames), maps_(maps), regs_(regs), process_memory_(process_memory) {
+ : max_frames_(max_frames),
+ maps_(maps),
+ regs_(regs),
+ process_memory_(process_memory),
+ arch_(regs->Arch()) {
frames_.reserve(max_frames);
}
Unwinder(size_t max_frames, Maps* maps, std::shared_ptr<Memory> process_memory)
@@ -74,8 +78,8 @@ class Unwinder {
virtual ~Unwinder() = default;
- void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
- const std::vector<std::string>* map_suffixes_to_ignore = nullptr);
+ virtual void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
+ const std::vector<std::string>* map_suffixes_to_ignore = nullptr);
size_t NumFrames() const { return frames_.size(); }
@@ -90,9 +94,14 @@ class Unwinder {
std::string FormatFrame(size_t frame_num) const;
std::string FormatFrame(const FrameData& frame) const;
- void SetJitDebug(JitDebug* jit_debug, ArchEnum arch);
+ void SetArch(ArchEnum arch) { arch_ = arch; };
+
+ void SetJitDebug(JitDebug* jit_debug);
- void SetRegs(Regs* regs) { regs_ = regs; }
+ void SetRegs(Regs* regs) {
+ regs_ = regs;
+ arch_ = regs_ != nullptr ? regs->Arch() : ARCH_UNKNOWN;
+ }
Maps* GetMaps() { return maps_; }
std::shared_ptr<Memory>& GetProcessMemory() { return process_memory_; }
@@ -107,11 +116,12 @@ class Unwinder {
void SetDisplayBuildID(bool display_build_id) { display_build_id_ = display_build_id; }
- void SetDexFiles(DexFiles* dex_files, ArchEnum arch);
+ void SetDexFiles(DexFiles* dex_files);
bool elf_from_memory_not_file() { return elf_from_memory_not_file_; }
ErrorCode LastErrorCode() { return last_error_.code; }
+ const char* LastErrorCodeString() { return GetErrorCodeString(last_error_.code); }
uint64_t LastErrorAddress() { return last_error_.address; }
uint64_t warnings() { return warnings_; }
@@ -126,6 +136,15 @@ class Unwinder {
protected:
Unwinder(size_t max_frames) : max_frames_(max_frames) { frames_.reserve(max_frames); }
+ Unwinder(size_t max_frames, ArchEnum arch) : max_frames_(max_frames), arch_(arch) {
+ frames_.reserve(max_frames);
+ }
+
+ void ClearErrors() {
+ warnings_ = WARNING_NONE;
+ last_error_.code = ERROR_NONE;
+ last_error_.address = 0;
+ }
void FillInDexFrame();
FrameData* FillInFrame(MapInfo* map_info, Elf* elf, uint64_t rel_pc, uint64_t pc_adjustment);
@@ -145,20 +164,27 @@ class Unwinder {
bool elf_from_memory_not_file_ = false;
ErrorData last_error_;
uint64_t warnings_;
+ ArchEnum arch_ = ARCH_UNKNOWN;
};
class UnwinderFromPid : public Unwinder {
public:
UnwinderFromPid(size_t max_frames, pid_t pid) : Unwinder(max_frames), pid_(pid) {}
+ UnwinderFromPid(size_t max_frames, pid_t pid, ArchEnum arch)
+ : Unwinder(max_frames, arch), pid_(pid) {}
virtual ~UnwinderFromPid() = default;
- bool Init(ArchEnum arch);
+ bool Init();
+
+ void Unwind(const std::vector<std::string>* initial_map_names_to_skip = nullptr,
+ const std::vector<std::string>* map_suffixes_to_ignore = nullptr) override;
private:
pid_t pid_;
std::unique_ptr<Maps> maps_ptr_;
std::unique_ptr<JitDebug> jit_debug_ptr_;
std::unique_ptr<DexFiles> dex_files_ptr_;
+ bool initted_ = false;
};
} // namespace unwindstack
diff --git a/libunwindstack/tests/UnwindOfflineTest.cpp b/libunwindstack/tests/UnwindOfflineTest.cpp
index c2bd836..0c6f9f8 100644
--- a/libunwindstack/tests/UnwindOfflineTest.cpp
+++ b/libunwindstack/tests/UnwindOfflineTest.cpp
@@ -314,7 +314,7 @@ TEST_F(UnwindOfflineTest, jit_debug_x86) {
JitDebug jit_debug(process_memory_);
Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+ unwinder.SetJitDebug(&jit_debug);
unwinder.Unwind();
std::string frame_info(DumpFrames(unwinder));
@@ -616,7 +616,7 @@ TEST_F(UnwindOfflineTest, jit_debug_arm) {
JitDebug jit_debug(process_memory_);
Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+ unwinder.SetJitDebug(&jit_debug);
unwinder.Unwind();
std::string frame_info(DumpFrames(unwinder));
@@ -939,7 +939,7 @@ static void OfflineUnwind(void* data) {
std::unique_ptr<Regs> regs_copy(leak_data->regs->Clone());
JitDebug jit_debug(leak_data->process_memory);
Unwinder unwinder(128, leak_data->maps, regs_copy.get(), leak_data->process_memory);
- unwinder.SetJitDebug(&jit_debug, regs_copy->Arch());
+ unwinder.SetJitDebug(&jit_debug);
unwinder.Unwind();
ASSERT_EQ(76U, unwinder.NumFrames());
}
@@ -1062,7 +1062,7 @@ TEST_F(UnwindOfflineTest, art_quick_osr_stub_arm) {
JitDebug jit_debug(process_memory_);
Unwinder unwinder(128, maps_.get(), regs_.get(), process_memory_);
- unwinder.SetJitDebug(&jit_debug, regs_->Arch());
+ unwinder.SetJitDebug(&jit_debug);
unwinder.Unwind();
std::string frame_info(DumpFrames(unwinder));
diff --git a/libunwindstack/tests/UnwindTest.cpp b/libunwindstack/tests/UnwindTest.cpp
index f76a101..b11d213 100644
--- a/libunwindstack/tests/UnwindTest.cpp
+++ b/libunwindstack/tests/UnwindTest.cpp
@@ -170,7 +170,6 @@ extern "C" void InnerFunction(TestTypeEnum test_type) {
unwinder.reset(new Unwinder(512, maps.get(), regs.get(), process_memory));
} else {
UnwinderFromPid* unwinder_from_pid = new UnwinderFromPid(512, getpid());
- ASSERT_TRUE(unwinder_from_pid->Init(regs->Arch()));
unwinder_from_pid->SetRegs(regs.get());
unwinder.reset(unwinder_from_pid);
}
@@ -283,7 +282,6 @@ TEST_F(UnwindTest, unwind_from_pid_remote) {
ASSERT_TRUE(regs.get() != nullptr);
UnwinderFromPid unwinder(512, pid);
- ASSERT_TRUE(unwinder.Init(regs->Arch()));
unwinder.SetRegs(regs.get());
VerifyUnwind(&unwinder, kFunctionOrder);
@@ -335,7 +333,6 @@ static void RemoteUnwindFromPid(void* data) {
ASSERT_TRUE(regs.get() != nullptr);
UnwinderFromPid unwinder(512, *pid);
- ASSERT_TRUE(unwinder.Init(regs->Arch()));
unwinder.SetRegs(regs.get());
VerifyUnwind(&unwinder, kFunctionOrder);
diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp
index 915f248..8bae242 100644
--- a/libunwindstack/tests/UnwinderTest.cpp
+++ b/libunwindstack/tests/UnwinderTest.cpp
@@ -1182,7 +1182,7 @@ TEST_F(UnwinderTest, dex_pc_not_in_map_valid_dex_files) {
DexFiles dex_files(process_memory_);
Unwinder unwinder(64, maps_.get(), &regs_, process_memory_);
- unwinder.SetDexFiles(&dex_files, ARCH_ARM);
+ unwinder.SetDexFiles(&dex_files);
unwinder.Unwind();
EXPECT_EQ(ERROR_NONE, unwinder.LastErrorCode());
EXPECT_EQ(WARNING_DEX_PC_NOT_IN_MAP, unwinder.warnings());
@@ -1735,7 +1735,7 @@ TEST_F(UnwinderTest, build_frame_pc_in_jit) {
regs.FakeSetArch(ARCH_ARM);
JitDebug jit_debug(process_memory_);
Unwinder unwinder(10, maps_.get(), &regs, process_memory_);
- unwinder.SetJitDebug(&jit_debug, ARCH_ARM);
+ unwinder.SetJitDebug(&jit_debug);
FrameData frame = unwinder.BuildFrameFromPcOnly(0x100310);
EXPECT_EQ(0x10030eU, frame.pc);
@@ -1751,4 +1751,21 @@ TEST_F(UnwinderTest, build_frame_pc_in_jit) {
EXPECT_EQ(0xeU, frame.function_offset);
}
+TEST_F(UnwinderTest, unwinder_from_pid_init_error) {
+ UnwinderFromPid unwinder(10, getpid());
+ ASSERT_DEATH(unwinder.Init(), "");
+}
+
+TEST_F(UnwinderTest, set_jit_debug_error) {
+ Unwinder unwinder(10, maps_.get(), process_memory_);
+ JitDebug jit_debug(process_memory_);
+ ASSERT_DEATH(unwinder.SetJitDebug(&jit_debug), "");
+}
+
+TEST_F(UnwinderTest, set_dex_files_error) {
+ Unwinder unwinder(10, maps_.get(), process_memory_);
+ DexFiles dex_files(process_memory_);
+ ASSERT_DEATH(unwinder.SetDexFiles(&dex_files), "");
+}
+
} // namespace unwindstack
diff --git a/libunwindstack/tests/VerifyBionicTerminationTest.cpp b/libunwindstack/tests/VerifyBionicTerminationTest.cpp
index eb2b01d..3e67dc9 100644
--- a/libunwindstack/tests/VerifyBionicTerminationTest.cpp
+++ b/libunwindstack/tests/VerifyBionicTerminationTest.cpp
@@ -94,7 +94,6 @@ TEST(VerifyBionicTermination, local_terminate) {
std::unique_ptr<Regs> regs(Regs::CreateFromLocal());
UnwinderFromPid unwinder(512, getpid());
- ASSERT_TRUE(unwinder.Init(regs->Arch()));
unwinder.SetRegs(regs.get());
RegsGetLocal(regs.get());
diff --git a/libunwindstack/tests/fuzz/UnwinderFuzz.cpp b/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
index 2f4986a..1600547 100644
--- a/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
+++ b/libunwindstack/tests/fuzz/UnwinderFuzz.cpp
@@ -85,7 +85,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Create instance
Unwinder unwinder(max_frames, maps.get(), regs.get(), memory);
- unwinder.SetJitDebug(jit_debug_ptr.get(), arch);
+ unwinder.SetJitDebug(jit_debug_ptr.get());
unwinder.SetResolveNames(data_provider.ConsumeBool());
// Call unwind
PerformUnwind(&data_provider, &unwinder);
diff --git a/libunwindstack/tools/unwind.cpp b/libunwindstack/tools/unwind.cpp
index 1812e50..ae45f06 100644
--- a/libunwindstack/tools/unwind.cpp
+++ b/libunwindstack/tools/unwind.cpp
@@ -90,11 +90,6 @@ void DoUnwind(pid_t pid) {
printf("\n");
unwindstack::UnwinderFromPid unwinder(1024, pid);
- if (!unwinder.Init(regs->Arch())) {
- printf("Failed to init unwinder object.\n");
- return;
- }
-
unwinder.SetRegs(regs);
unwinder.Unwind();
diff --git a/libunwindstack/tools/unwind_for_offline.cpp b/libunwindstack/tools/unwind_for_offline.cpp
index 64b58a8..c44a121 100644
--- a/libunwindstack/tools/unwind_for_offline.cpp
+++ b/libunwindstack/tools/unwind_for_offline.cpp
@@ -248,10 +248,6 @@ int SaveData(pid_t pid) {
// Do an unwind so we know how much of the stack to save, and what
// elf files are involved.
unwindstack::UnwinderFromPid unwinder(1024, pid);
- if (!unwinder.Init(regs->Arch())) {
- printf("Unable to init unwinder object.\n");
- return 1;
- }
unwinder.SetRegs(regs);
uint64_t sp = regs->sp();
unwinder.Unwind();