[libcxx-commits] [PATCH] D126611: [libunwind] Ensure test/libunwind_01.pass is not completely inlined
Alexander Richardson via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Sun May 29 04:22:45 PDT 2022
arichardson created this revision.
arichardson added reviewers: libunwind, ldionne.
Herald added subscribers: libcxx-commits, jrtc27.
Herald added projects: libunwind, All.
Herald added 1 blocking reviewer(s): libunwind.
arichardson requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
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
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D126611
Files:
libunwind/test/libunwind_01.pass.cpp
Index: libunwind/test/libunwind_01.pass.cpp
===================================================================
--- libunwind/test/libunwind_01.pass.cpp
+++ 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 @@
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 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,12 +157,13 @@
#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();
test_fpreg_get_set();
+ fprintf(stderr, "Success!\n");
return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D126611.432778.patch
Type: text/x-patch
Size: 1865 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220529/dea39ce2/attachment.bin>
More information about the libcxx-commits
mailing list