[libunwind] 8df257a - [libunwind] Ensure test/libunwind_01.pass is not completely inlined

Alex Richardson via cfe-commits cfe-commits at lists.llvm.org
Mon Jun 20 02:06:03 PDT 2022


Author: Alex Richardson
Date: 2022-06-20T09:05:49Z
New Revision: 8df257a6d0b0b32e05e89874eff4c8ddd2a2a2a9

URL: https://github.com/llvm/llvm-project/commit/8df257a6d0b0b32e05e89874eff4c8ddd2a2a2a9
DIFF: https://github.com/llvm/llvm-project/commit/8df257a6d0b0b32e05e89874eff4c8ddd2a2a2a9.diff

LOG: [libunwind] Ensure test/libunwind_01.pass is not completely inlined

By adding noinline and calling fprintf before returning we ensure that
every function will have a distinct call frame and that the return address
will always be saved instead of saving the target in main as the result.

Before this change all backtraces were always backtrace -> main -> _start,
i.e. always exactly three entries. This happenend because all calls were
inlined in main() and the test just happenend to pass because there is at
least _start before main.

I found this while fixing some bugs in libunwind for CHERI and noticed that
the test was passing even though the code was completely broken.

Obtained from: https://github.com/CTSRD-CHERI/llvm-project

Reviewed By: #libunwind, ldionne, MaskRay

Differential Revision: https://reviews.llvm.org/D126611

Added: 
    

Modified: 
    libunwind/test/libunwind_01.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libunwind/test/libunwind_01.pass.cpp b/libunwind/test/libunwind_01.pass.cpp
index bbfaffd153cc2..4661ac9df8219 100644
--- a/libunwind/test/libunwind_01.pass.cpp
+++ b/libunwind/test/libunwind_01.pass.cpp
@@ -15,6 +15,7 @@
 
 #include <libunwind.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 
 void backtrace(int lower_bound) {
@@ -24,9 +25,17 @@ void backtrace(int lower_bound) {
   unw_cursor_t cursor;
   unw_init_local(&cursor, &context);
 
+  char buffer[1024];
+  unw_word_t offset = 0;
+
   int n = 0;
   do {
-    ++n;
+    n++;
+    if (unw_get_proc_name(&cursor, buffer, sizeof(buffer), &offset) == 0) {
+      fprintf(stderr, "Frame %d: %s+%p\n", n, buffer, (void*)offset);
+    } else {
+      fprintf(stderr, "Frame %d: Could not get name for cursor\n", n);
+    }
     if (n > 100) {
       abort();
     }
@@ -37,18 +46,24 @@ void backtrace(int lower_bound) {
   }
 }
 
-void test1(int i) {
+__attribute__((noinline)) void test1(int i) {
+  fprintf(stderr, "starting %s\n", __func__);
   backtrace(i);
+  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved
 }
 
-void test2(int i, int j) {
+__attribute__((noinline)) void test2(int i, int j) {
+  fprintf(stderr, "starting %s\n", __func__);
   backtrace(i);
   test1(j);
+  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved
 }
 
-void test3(int i, int j, int k) {
+__attribute__((noinline)) void test3(int i, int j, int k) {
+  fprintf(stderr, "starting %s\n", __func__);
   backtrace(i);
   test2(j, k);
+  fprintf(stderr, "finished %s\n", __func__); // ensure return address is saved
 }
 
 void test_no_info() {
@@ -142,9 +157,9 @@ void test_fpreg_get_set() {}
 #endif
 
 int main(int, char**) {
-  test1(1);
-  test2(1, 2);
-  test3(1, 2, 3);
+  test1(3);
+  test2(3, 4);
+  test3(3, 4, 5);
   test_no_info();
   test_reg_names();
   test_reg_get_set();


        


More information about the cfe-commits mailing list