@@ -90,30 +90,48 @@ TEST_F(StackWalkValidationTest, sameStack_FarApart) {
9090 * - This violates the fp > prev_fp invariant
9191 */
9292TEST_F (StackWalkValidationTest, FPChainProgression_ValidChain) {
93- // Simulate a valid FP chain where each frame is at a higher address
94- MockFrame frame3 = { 0 , nullptr }; // Oldest frame (null FP = end )
95- MockFrame frame2 = {( uintptr_t )&frame3, ( void *) 0x400000 };
96- MockFrame frame1 = {( uintptr_t )&frame2, ( void *) 0x400100 } ;
93+ // Allocate frames in a buffer with controlled layout
94+ // Frame layout must simulate: frame1 (low addr) -> frame2 -> frame3 (high addr )
95+ // where each frame's saved_fp points to the next higher frame
96+ alignas ( sizeof ( uintptr_t )) char buffer[ 3 * sizeof (MockFrame)] ;
9797
98- uintptr_t fp = (uintptr_t )&frame1;
98+ MockFrame* frame1 = (MockFrame*)(buffer);
99+ MockFrame* frame2 = (MockFrame*)(buffer + sizeof (MockFrame));
100+ MockFrame* frame3 = (MockFrame*)(buffer + 2 * sizeof (MockFrame));
101+
102+ // Verify ordering: frame1 < frame2 < frame3
103+ ASSERT_LT ((uintptr_t )frame1, (uintptr_t )frame2);
104+ ASSERT_LT ((uintptr_t )frame2, (uintptr_t )frame3);
105+
106+ // Setup chain: frame1 -> frame2 -> frame3 -> null
107+ frame3->saved_fp = 0 ; // Oldest frame (null FP = end)
108+ frame3->return_addr = nullptr ;
109+
110+ frame2->saved_fp = (uintptr_t )frame3;
111+ frame2->return_addr = (void *)0x400000 ;
112+
113+ frame1->saved_fp = (uintptr_t )frame2;
114+ frame1->return_addr = (void *)0x400100 ;
115+
116+ uintptr_t fp = (uintptr_t )frame1;
99117
100118 // Walk the chain and verify progression
101119 uintptr_t prev_fp = fp;
102- fp = *(uintptr_t *)fp; // Read saved FP
120+ fp = *(uintptr_t *)fp; // Read saved FP from frame1
103121
104- // Valid: next FP should be greater than current
122+ // Valid: next FP (frame2) should be greater than current (frame1)
105123 EXPECT_GT (fp, prev_fp);
106124 EXPECT_TRUE (aligned (fp));
107125
108126 prev_fp = fp;
109- fp = *(uintptr_t *)fp;
127+ fp = *(uintptr_t *)fp; // Read saved FP from frame2
110128
111- // Valid: next FP should still be greater
129+ // Valid: next FP (frame3) should be greater than current (frame2)
112130 EXPECT_GT (fp, prev_fp);
113131
114132 // Final frame has null FP (chain terminator)
115133 prev_fp = fp;
116- fp = *(uintptr_t *)fp;
134+ fp = *(uintptr_t *)fp; // Read saved FP from frame3
117135 EXPECT_EQ (fp, 0u );
118136}
119137
0 commit comments