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
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 @@
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 @@
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;