diff options
author | Treehugger Robot | 2018-04-20 21:15:45 -0500 |
---|---|---|
committer | Gerrit Code Review | 2018-04-20 21:15:45 -0500 |
commit | 3e378800b82c9db6cb66719bc43cd7734c8a5305 (patch) | |
tree | f97643829527acae997038acd501d8b9ac3d8296 | |
parent | a7112f4c9b6a2952dfc2874a05ddfce975ae6e2f (diff) | |
parent | 5d1c14f41bac357c730aa47d705c1f1da7625280 (diff) | |
download | platform-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.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsArm.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsArm64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsMips.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsMips64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsX86.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/RegsX86_64.cpp | 4 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/Regs.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsArm.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsArm64.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsMips.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsMips64.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsX86.h | 2 | ||||
-rw-r--r-- | libunwindstack/include/unwindstack/RegsX86_64.h | 2 | ||||
-rw-r--r-- | libunwindstack/tests/RegsFake.h | 4 | ||||
-rw-r--r-- | libunwindstack/tests/RegsTest.cpp | 35 |
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 | ||
200 | Regs* 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 | ||
151 | Regs* 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 | ||
176 | Regs* 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 | ||
163 | Regs* 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 | ||
182 | Regs* 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 | ||
171 | Regs* 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 | ||
289 | template <typename RegisterType> | ||
290 | void 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(®ister_values[i], &clone_values[i]); | ||
303 | } | ||
304 | } | ||
305 | |||
306 | TEST_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 |