summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTreehugger Robot2018-04-20 21:15:45 -0500
committerGerrit Code Review2018-04-20 21:15:45 -0500
commit3e378800b82c9db6cb66719bc43cd7734c8a5305 (patch)
treef97643829527acae997038acd501d8b9ac3d8296
parenta7112f4c9b6a2952dfc2874a05ddfce975ae6e2f (diff)
parent5d1c14f41bac357c730aa47d705c1f1da7625280 (diff)
downloadplatform-system-core-3e378800b82c9db6cb66719bc43cd7734c8a5305.tar.gz
platform-system-core-3e378800b82c9db6cb66719bc43cd7734c8a5305.tar.xz
platform-system-core-3e378800b82c9db6cb66719bc43cd7734c8a5305.zip
Merge changes I4b017701,I28aff510
* changes: libdebuggerd: clone registers before we Unwind with them. libunwindstack: add Regs::Clone.
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp4
-rw-r--r--libunwindstack/RegsArm.cpp4
-rw-r--r--libunwindstack/RegsArm64.cpp4
-rw-r--r--libunwindstack/RegsMips.cpp4
-rw-r--r--libunwindstack/RegsMips64.cpp4
-rw-r--r--libunwindstack/RegsX86.cpp4
-rw-r--r--libunwindstack/RegsX86_64.cpp4
-rw-r--r--libunwindstack/include/unwindstack/Regs.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsArm.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsArm64.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsMips.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsMips64.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsX86.h2
-rw-r--r--libunwindstack/include/unwindstack/RegsX86_64.h2
-rw-r--r--libunwindstack/tests/RegsFake.h4
-rw-r--r--libunwindstack/tests/RegsTest.cpp35
16 files changed, 80 insertions, 1 deletions
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 55d6204ac..2b7529217 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -422,8 +422,10 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory,
422 422
423 dump_registers(log, thread_info.registers.get()); 423 dump_registers(log, thread_info.registers.get());
424 424
425 // Unwind will mutate the registers, so make a copy first.
426 std::unique_ptr<Regs> regs_copy(thread_info.registers->Clone());
425 std::vector<backtrace_frame_data_t> frames; 427 std::vector<backtrace_frame_data_t> frames;
426 if (!Backtrace::Unwind(thread_info.registers.get(), map, &frames, 0, nullptr)) { 428 if (!Backtrace::Unwind(regs_copy.get(), map, &frames, 0, nullptr)) {
427 _LOG(log, logtype::THREAD, "Failed to unwind"); 429 _LOG(log, logtype::THREAD, "Failed to unwind");
428 return false; 430 return false;
429 } 431 }
diff --git a/libunwindstack/RegsArm.cpp b/libunwindstack/RegsArm.cpp
index 27cab4384..de22bdea9 100644
--- a/libunwindstack/RegsArm.cpp
+++ b/libunwindstack/RegsArm.cpp
@@ -197,4 +197,8 @@ bool RegsArm::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem
197 return true; 197 return true;
198} 198}
199 199
200Regs* RegsArm::Clone() {
201 return new RegsArm(*this);
202}
203
200} // namespace unwindstack 204} // namespace unwindstack
diff --git a/libunwindstack/RegsArm64.cpp b/libunwindstack/RegsArm64.cpp
index 4a2a6c4db..a68f6e04a 100644
--- a/libunwindstack/RegsArm64.cpp
+++ b/libunwindstack/RegsArm64.cpp
@@ -148,4 +148,8 @@ bool RegsArm64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_m
148 return true; 148 return true;
149} 149}
150 150
151Regs* RegsArm64::Clone() {
152 return new RegsArm64(*this);
153}
154
151} // namespace unwindstack 155} // namespace unwindstack
diff --git a/libunwindstack/RegsMips.cpp b/libunwindstack/RegsMips.cpp
index c87e69b90..2e6908c26 100644
--- a/libunwindstack/RegsMips.cpp
+++ b/libunwindstack/RegsMips.cpp
@@ -173,4 +173,8 @@ bool RegsMips::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_me
173 return true; 173 return true;
174} 174}
175 175
176Regs* RegsMips::Clone() {
177 return new RegsMips(*this);
178}
179
176} // namespace unwindstack 180} // namespace unwindstack
diff --git a/libunwindstack/RegsMips64.cpp b/libunwindstack/RegsMips64.cpp
index 236a9223b..0b835a152 100644
--- a/libunwindstack/RegsMips64.cpp
+++ b/libunwindstack/RegsMips64.cpp
@@ -160,4 +160,8 @@ bool RegsMips64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_
160 return true; 160 return true;
161} 161}
162 162
163Regs* RegsMips64::Clone() {
164 return new RegsMips64(*this);
165}
166
163} // namespace unwindstack 167} // namespace unwindstack
diff --git a/libunwindstack/RegsX86.cpp b/libunwindstack/RegsX86.cpp
index f7e06145e..9bb39d10e 100644
--- a/libunwindstack/RegsX86.cpp
+++ b/libunwindstack/RegsX86.cpp
@@ -179,4 +179,8 @@ bool RegsX86::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_mem
179 return false; 179 return false;
180} 180}
181 181
182Regs* RegsX86::Clone() {
183 return new RegsX86(*this);
184}
185
182} // namespace unwindstack 186} // namespace unwindstack
diff --git a/libunwindstack/RegsX86_64.cpp b/libunwindstack/RegsX86_64.cpp
index 7d6ad86cf..ebad3f421 100644
--- a/libunwindstack/RegsX86_64.cpp
+++ b/libunwindstack/RegsX86_64.cpp
@@ -168,4 +168,8 @@ bool RegsX86_64::StepIfSignalHandler(uint64_t rel_pc, Elf* elf, Memory* process_
168 return true; 168 return true;
169} 169}
170 170
171Regs* RegsX86_64::Clone() {
172 return new RegsX86_64(*this);
173}
174
171} // namespace unwindstack 175} // namespace unwindstack
diff --git a/libunwindstack/include/unwindstack/Regs.h b/libunwindstack/include/unwindstack/Regs.h
index 4bac47313..878ced30c 100644
--- a/libunwindstack/include/unwindstack/Regs.h
+++ b/libunwindstack/include/unwindstack/Regs.h
@@ -73,6 +73,8 @@ class Regs {
73 73
74 uint16_t total_regs() { return total_regs_; } 74 uint16_t total_regs() { return total_regs_; }
75 75
76 virtual Regs* Clone() = 0;
77
76 static ArchEnum CurrentArch(); 78 static ArchEnum CurrentArch();
77 static Regs* RemoteGet(pid_t pid); 79 static Regs* RemoteGet(pid_t pid);
78 static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext); 80 static Regs* CreateFromUcontext(ArchEnum arch, void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsArm.h b/libunwindstack/include/unwindstack/RegsArm.h
index 31e6797fa..44f67443f 100644
--- a/libunwindstack/include/unwindstack/RegsArm.h
+++ b/libunwindstack/include/unwindstack/RegsArm.h
@@ -50,6 +50,8 @@ class RegsArm : public RegsImpl<uint32_t> {
50 void set_pc(uint64_t pc) override; 50 void set_pc(uint64_t pc) override;
51 void set_sp(uint64_t sp) override; 51 void set_sp(uint64_t sp) override;
52 52
53 Regs* Clone() override final;
54
53 static Regs* Read(void* data); 55 static Regs* Read(void* data);
54 56
55 static Regs* CreateFromUcontext(void* ucontext); 57 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsArm64.h b/libunwindstack/include/unwindstack/RegsArm64.h
index 0c45ebab8..a72f91ff2 100644
--- a/libunwindstack/include/unwindstack/RegsArm64.h
+++ b/libunwindstack/include/unwindstack/RegsArm64.h
@@ -50,6 +50,8 @@ class RegsArm64 : public RegsImpl<uint64_t> {
50 void set_pc(uint64_t pc) override; 50 void set_pc(uint64_t pc) override;
51 void set_sp(uint64_t sp) override; 51 void set_sp(uint64_t sp) override;
52 52
53 Regs* Clone() override final;
54
53 static Regs* Read(void* data); 55 static Regs* Read(void* data);
54 56
55 static Regs* CreateFromUcontext(void* ucontext); 57 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsMips.h b/libunwindstack/include/unwindstack/RegsMips.h
index 709f9e2c7..c9dd202aa 100644
--- a/libunwindstack/include/unwindstack/RegsMips.h
+++ b/libunwindstack/include/unwindstack/RegsMips.h
@@ -50,6 +50,8 @@ class RegsMips : public RegsImpl<uint32_t> {
50 void set_pc(uint64_t pc) override; 50 void set_pc(uint64_t pc) override;
51 void set_sp(uint64_t sp) override; 51 void set_sp(uint64_t sp) override;
52 52
53 Regs* Clone() override final;
54
53 static Regs* Read(void* data); 55 static Regs* Read(void* data);
54 56
55 static Regs* CreateFromUcontext(void* ucontext); 57 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsMips64.h b/libunwindstack/include/unwindstack/RegsMips64.h
index 1de83ea9d..7c42812b7 100644
--- a/libunwindstack/include/unwindstack/RegsMips64.h
+++ b/libunwindstack/include/unwindstack/RegsMips64.h
@@ -50,6 +50,8 @@ class RegsMips64 : public RegsImpl<uint64_t> {
50 void set_pc(uint64_t pc) override; 50 void set_pc(uint64_t pc) override;
51 void set_sp(uint64_t sp) override; 51 void set_sp(uint64_t sp) override;
52 52
53 Regs* Clone() override final;
54
53 static Regs* Read(void* data); 55 static Regs* Read(void* data);
54 56
55 static Regs* CreateFromUcontext(void* ucontext); 57 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsX86.h b/libunwindstack/include/unwindstack/RegsX86.h
index 586c9d85c..d19e4499b 100644
--- a/libunwindstack/include/unwindstack/RegsX86.h
+++ b/libunwindstack/include/unwindstack/RegsX86.h
@@ -53,6 +53,8 @@ class RegsX86 : public RegsImpl<uint32_t> {
53 void set_pc(uint64_t pc) override; 53 void set_pc(uint64_t pc) override;
54 void set_sp(uint64_t sp) override; 54 void set_sp(uint64_t sp) override;
55 55
56 Regs* Clone() override final;
57
56 static Regs* Read(void* data); 58 static Regs* Read(void* data);
57 59
58 static Regs* CreateFromUcontext(void* ucontext); 60 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/include/unwindstack/RegsX86_64.h b/libunwindstack/include/unwindstack/RegsX86_64.h
index 061f479a0..dc9a220c3 100644
--- a/libunwindstack/include/unwindstack/RegsX86_64.h
+++ b/libunwindstack/include/unwindstack/RegsX86_64.h
@@ -53,6 +53,8 @@ class RegsX86_64 : public RegsImpl<uint64_t> {
53 void set_pc(uint64_t pc) override; 53 void set_pc(uint64_t pc) override;
54 void set_sp(uint64_t sp) override; 54 void set_sp(uint64_t sp) override;
55 55
56 Regs* Clone() override final;
57
56 static Regs* Read(void* data); 58 static Regs* Read(void* data);
57 59
58 static Regs* CreateFromUcontext(void* ucontext); 60 static Regs* CreateFromUcontext(void* ucontext);
diff --git a/libunwindstack/tests/RegsFake.h b/libunwindstack/tests/RegsFake.h
index ede16b32b..d6ca9b7b5 100644
--- a/libunwindstack/tests/RegsFake.h
+++ b/libunwindstack/tests/RegsFake.h
@@ -58,6 +58,8 @@ class RegsFake : public Regs {
58 void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; } 58 void FakeSetReturnAddress(uint64_t return_address) { fake_return_address_ = return_address; }
59 void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; } 59 void FakeSetReturnAddressValid(bool valid) { fake_return_address_valid_ = valid; }
60 60
61 Regs* Clone() override { return nullptr; }
62
61 private: 63 private:
62 ArchEnum fake_arch_ = ARCH_UNKNOWN; 64 ArchEnum fake_arch_ = ARCH_UNKNOWN;
63 uint64_t fake_pc_ = 0; 65 uint64_t fake_pc_ = 0;
@@ -83,6 +85,8 @@ class RegsImplFake : public RegsImpl<TypeParam> {
83 bool SetPcFromReturnAddress(Memory*) override { return false; } 85 bool SetPcFromReturnAddress(Memory*) override { return false; }
84 bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; } 86 bool StepIfSignalHandler(uint64_t, Elf*, Memory*) override { return false; }
85 87
88 Regs* Clone() override { return nullptr; }
89
86 private: 90 private:
87 uint64_t fake_pc_ = 0; 91 uint64_t fake_pc_ = 0;
88 uint64_t fake_sp_ = 0; 92 uint64_t fake_sp_ = 0;
diff --git a/libunwindstack/tests/RegsTest.cpp b/libunwindstack/tests/RegsTest.cpp
index d15823e1c..90c3fe619 100644
--- a/libunwindstack/tests/RegsTest.cpp
+++ b/libunwindstack/tests/RegsTest.cpp
@@ -286,4 +286,39 @@ TEST_F(RegsTest, machine_type) {
286 EXPECT_EQ(ARCH_MIPS64, mips64_regs.Arch()); 286 EXPECT_EQ(ARCH_MIPS64, mips64_regs.Arch());
287} 287}
288 288
289template <typename RegisterType>
290void clone_test(Regs* regs) {
291 RegisterType* register_values = reinterpret_cast<RegisterType*>(regs->RawData());
292 int num_regs = regs->total_regs();
293 for (int i = 0; i < num_regs; ++i) {
294 register_values[i] = i;
295 }
296
297 std::unique_ptr<Regs> clone(regs->Clone());
298 ASSERT_EQ(regs->total_regs(), clone->total_regs());
299 RegisterType* clone_values = reinterpret_cast<RegisterType*>(clone->RawData());
300 for (int i = 0; i < num_regs; ++i) {
301 EXPECT_EQ(register_values[i], clone_values[i]);
302 EXPECT_NE(&register_values[i], &clone_values[i]);
303 }
304}
305
306TEST_F(RegsTest, clone) {
307 std::vector<std::unique_ptr<Regs>> regs;
308 regs.emplace_back(new RegsArm());
309 regs.emplace_back(new RegsArm64());
310 regs.emplace_back(new RegsX86());
311 regs.emplace_back(new RegsX86_64());
312 regs.emplace_back(new RegsMips());
313 regs.emplace_back(new RegsMips64());
314
315 for (auto& r : regs) {
316 if (r->Is32Bit()) {
317 clone_test<uint32_t>(r.get());
318 } else {
319 clone_test<uint64_t>(r.get());
320 }
321 }
322}
323
289} // namespace unwindstack 324} // namespace unwindstack