diff options
author | Christopher Ferris <cferris@google.com> | 2018-10-12 16:33:42 -0700 |
---|---|---|
committer | Christopher Ferris <cferris@google.com> | 2018-10-12 16:36:35 -0700 |
commit | fa3148bb3a542f8922ce9c3b2fca36020432eea4 (patch) | |
tree | c00a8e3c95f509394c5a1f3f4d5dcdceb427a7b5 | |
parent | eb069a28d6b1d6a6a74e7bebeecd91140128821a (diff) | |
download | unwinding-fa3148bb3a542f8922ce9c3b2fca36020432eea4.tar.gz |
Fix problem adding too many frames.
When adding a frame with a dex pc, two frames will be added total. However,
if there is only enough room for a single frame, two get added any way.
Only add a single frame in this case, and add a unit test for this case.
Test: Passes unit tests.
Change-Id: If320584b126967a042c623d8fdf3f51dbc1c2251
-rw-r--r-- | libunwindstack/Unwinder.cpp | 6 | ||||
-rw-r--r-- | libunwindstack/tests/UnwinderTest.cpp | 27 |
2 files changed, 33 insertions, 0 deletions
diff --git a/libunwindstack/Unwinder.cpp b/libunwindstack/Unwinder.cpp index 099cc9e..ee1cd1a 100644 --- a/libunwindstack/Unwinder.cpp +++ b/libunwindstack/Unwinder.cpp @@ -190,6 +190,12 @@ void Unwinder::Unwind(const std::vector<std::string>* initial_map_names_to_skip, FillInDexFrame(); // Clear the dex pc so that we don't repeat this frame later. regs_->set_dex_pc(0); + + // Make sure there is enough room for the real frame. + if (frames_.size() == max_frames_) { + last_error_.code = ERROR_MAX_FRAMES_EXCEEDED; + break; + } } FillInFrame(map_info, elf, rel_pc, step_pc, pc_adjustment); diff --git a/libunwindstack/tests/UnwinderTest.cpp b/libunwindstack/tests/UnwinderTest.cpp index 4369030..831d3b5 100644 --- a/libunwindstack/tests/UnwinderTest.cpp +++ b/libunwindstack/tests/UnwinderTest.cpp @@ -946,6 +946,33 @@ TEST_F(UnwinderTest, dex_pc_multiple_frames) { EXPECT_EQ(PROT_READ | PROT_WRITE, frame->map_flags); } +TEST_F(UnwinderTest, dex_pc_max_frames) { + ElfInterfaceFake::FakePushFunctionData(FunctionData("Frame0", 0)); + regs_.set_pc(0x1000); + regs_.set_sp(0x10000); + regs_.FakeSetDexPc(0xa3400); + + Unwinder unwinder(1, &maps_, ®s_, process_memory_); + unwinder.Unwind(); + EXPECT_EQ(ERROR_MAX_FRAMES_EXCEEDED, unwinder.LastErrorCode()); + + ASSERT_EQ(1U, unwinder.NumFrames()); + + auto* frame = &unwinder.frames()[0]; + EXPECT_EQ(0U, frame->num); + EXPECT_EQ(0x400U, frame->rel_pc); + EXPECT_EQ(0xa3400U, frame->pc); + EXPECT_EQ(0x10000U, frame->sp); + EXPECT_EQ("", frame->function_name); + EXPECT_EQ(0U, frame->function_offset); + EXPECT_EQ("/fake/fake.vdex", frame->map_name); + EXPECT_EQ(0U, frame->map_offset); + EXPECT_EQ(0xa3000U, frame->map_start); + EXPECT_EQ(0xa4000U, frame->map_end); + EXPECT_EQ(0U, frame->map_load_bias); + EXPECT_EQ(PROT_READ | PROT_WRITE | PROT_EXEC, frame->map_flags); +} + // Verify format frame code. TEST_F(UnwinderTest, format_frame_static) { FrameData frame; |