46 lines · cpp
1// Test program to verify libunwind ret injection feature for execution flow2// rebalancing.3//4// This test creates a multi-frame call stack and throws a C++ exception to5// trigger libunwind's two-phase exception handling. The test verifies that6// libunwind correctly injects the right amount of 'ret' instructions to7// rebalance the execution flow when returning to the landing pad, which is8// important for Apple Processor Trace analysis.9 10#include <cstdio>11#include <exception>12#include <stdexcept>13 14// Marker functions with noinline to ensure they appear in the stack.15static void __attribute__((noinline)) func_d() {16 printf("In func_d, about to throw exception\n");17 throw std::runtime_error("test exception");18}19 20static void __attribute__((noinline)) func_c() {21 printf("In func_c\n");22 func_d();23}24 25static void __attribute__((noinline)) func_b() {26 printf("In func_b\n");27 func_c();28}29 30static void __attribute__((noinline)) func_a() {31 printf("In func_a\n");32 func_b();33}34 35int main(int argc, char *argv[]) {36 try {37 printf("In main, about to call func_a\n");38 func_a();39 printf("ERROR: Should not reach here\n");40 return 1;41 } catch (const std::exception &e) {42 printf("Caught exception in main: %s\n", e.what());43 return 0;44 }45}46