10f53df86Swlei; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/callback-external-addr.perfscript --binary=%S/Inputs/callback-external-addr.perfbin --output=%t --skip-symbolization 20f53df86Swlei; RUN: FileCheck %s --input-file %t --check-prefix=CHECK-UNWINDER 30f53df86Swlei 4*bfcb2c11Swlei; RUN: llvm-profgen --format=text --perfscript=%S/Inputs/callback-external-addr.perfscript --binary=%S/Inputs/callback-external-addr.perfbin --output=%t --profile-summary-cold-count=0 --csspgo-preinliner=0 --gen-cs-nested-profile=0 5*bfcb2c11Swlei; RUN: FileCheck %s --input-file %t 6*bfcb2c11Swlei 70f53df86Swlei; Test if call stack is correctly truncated. 80f53df86Swlei; CHECK-UNWINDER-NOT: main:3 @ bar 90f53df86Swlei; CHECK-UNWINDER-NOT: main:3 @ foo 100f53df86Swlei; CHECK-UNWINDER-NOT: qux:3 @ baz 110f53df86Swlei; CHECK-UNWINDER-NOT: qux:3 @ bar 120f53df86Swlei 130f53df86Swlei; Test if return to wrong internal target 140f53df86Swlei; CHECK-UNWINDER-NOT: baz:0 @ bar 150f53df86Swlei; CHECK-UNWINDER-NOT: bar:0 @ baz 160f53df86Swlei; CHECK-UNWINDER-NOT: baz:0 @ main 170f53df86Swlei; CHECK-UNWINDER-NOT: bar:0 @ foo 180f53df86Swlei; CHECK-UNWINDER-NOT: baz:0 @ qux 190f53df86Swlei 200f53df86Swlei; Test for callback return from internal address to external address. 210f53df86Swlei; [foo:2 @ qux:2 @ callBeforeReturn] and [foo:2 @ qux:4 @ callAfterReturn] should exist 220f53df86Swlei; which means the callback return won't interrupt the previous call stack 230f53df86Swlei 24*bfcb2c11Swlei 25*bfcb2c11Swlei; CHECK-UNWINDER: [] 26*bfcb2c11Swlei; CHECK-UNWINDER: 0 27*bfcb2c11Swlei; CHECK-UNWINDER: 5 28*bfcb2c11Swlei; CHECK-UNWINDER: ffffffffffc00001->690:13 29*bfcb2c11Swlei; CHECK-UNWINDER: ffffffffffc00001->6a0:7 30*bfcb2c11Swlei; CHECK-UNWINDER: ffffffffffc00001->715:7 31*bfcb2c11Swlei; CHECK-UNWINDER: ffffffffffc00001->730:5 32*bfcb2c11Swlei; CHECK-UNWINDER: ffffffffffc00001->7b0:5 330f53df86Swlei; CHECK-UNWINDER: [bar] 340f53df86Swlei; CHECK-UNWINDER: 1 35*bfcb2c11Swlei; CHECK-UNWINDER: 690-69e:13 360f53df86Swlei; CHECK-UNWINDER: 0 370f53df86Swlei; CHECK-UNWINDER: [baz] 380f53df86Swlei; CHECK-UNWINDER: 1 390f53df86Swlei; CHECK-UNWINDER: 6a0-6ae:7 400f53df86Swlei; CHECK-UNWINDER: 0 410f53df86Swlei; CHECK-UNWINDER: [foo] 420f53df86Swlei; CHECK-UNWINDER: 2 430f53df86Swlei; CHECK-UNWINDER: 730-747:5 440f53df86Swlei; CHECK-UNWINDER: 74c-751:5 450f53df86Swlei; CHECK-UNWINDER: 1 460f53df86Swlei; CHECK-UNWINDER: 747->6d0:5 470f53df86Swlei; CHECK-UNWINDER: [foo:2 @ qux] 480f53df86Swlei; CHECK-UNWINDER: 4 490f53df86Swlei; CHECK-UNWINDER: 6d0-6e7:5 500f53df86Swlei; CHECK-UNWINDER: 6ec-710:6 510f53df86Swlei; CHECK-UNWINDER: 715-71b:7 520f53df86Swlei; CHECK-UNWINDER: 720-72b:6 530f53df86Swlei; CHECK-UNWINDER: 3 540f53df86Swlei; CHECK-UNWINDER: 6e7->6b0:6 550f53df86Swlei; CHECK-UNWINDER: 71b->6c0:7 560f53df86Swlei; CHECK-UNWINDER: 72b->74c:6 570f53df86Swlei; CHECK-UNWINDER: [foo:2 @ qux:2 @ callBeforeReturn] 580f53df86Swlei; CHECK-UNWINDER: 1 590f53df86Swlei; CHECK-UNWINDER: 6b0-6be:6 600f53df86Swlei; CHECK-UNWINDER: 1 610f53df86Swlei; CHECK-UNWINDER: 6be->6ec:7 620f53df86Swlei; CHECK-UNWINDER: [foo:2 @ qux:4 @ callAfterReturn] 630f53df86Swlei; CHECK-UNWINDER: 1 640f53df86Swlei; CHECK-UNWINDER: 6c0-6ce:7 650f53df86Swlei; CHECK-UNWINDER: 1 660f53df86Swlei; CHECK-UNWINDER: 6ce->720:7 670f53df86Swlei; CHECK-UNWINDER: [main] 680f53df86Swlei; CHECK-UNWINDER: 2 690f53df86Swlei; CHECK-UNWINDER: 77d-7ab:5 700f53df86Swlei; CHECK-UNWINDER: 7b0-7bf:5 710f53df86Swlei; CHECK-UNWINDER: 1 720f53df86Swlei; CHECK-UNWINDER: 7bf->77d:5 730f53df86Swlei 74*bfcb2c11Swlei; CHECK: [foo:2 @ qux]:132:5 75*bfcb2c11Swlei; CHECK: 0: 5 76*bfcb2c11Swlei; CHECK: 1: 5 77*bfcb2c11Swlei; CHECK: 2: 6 callBeforeReturn:6 78*bfcb2c11Swlei; CHECK: 3: 7 79*bfcb2c11Swlei; CHECK: 4: 7 callAfterReturn:7 80*bfcb2c11Swlei; CHECK: 5: 6 81*bfcb2c11Swlei; CHECK: [bar]:91:13 82*bfcb2c11Swlei; CHECK: 0: 13 83*bfcb2c11Swlei; CHECK: 1: 13 84*bfcb2c11Swlei; CHECK: [main]:65:0 85*bfcb2c11Swlei; CHECK: 2.1: 5 86*bfcb2c11Swlei; CHECK: 2.2: 5 87*bfcb2c11Swlei; CHECK: 3: 5 88*bfcb2c11Swlei; CHECK: [foo]:60:5 89*bfcb2c11Swlei; CHECK: 0: 5 90*bfcb2c11Swlei; CHECK: 1: 5 91*bfcb2c11Swlei; CHECK: 2: 5 qux:5 92*bfcb2c11Swlei; CHECK: [baz]:49:7 93*bfcb2c11Swlei; CHECK: 0: 7 94*bfcb2c11Swlei; CHECK: 1: 7 95*bfcb2c11Swlei; CHECK: [foo:2 @ qux:4 @ callAfterReturn]:49:7 96*bfcb2c11Swlei; CHECK: 0: 7 97*bfcb2c11Swlei; CHECK: 1: 7 98*bfcb2c11Swlei; CHECK: [foo:2 @ qux:2 @ callBeforeReturn]:42:6 99*bfcb2c11Swlei; CHECK: 0: 6 100*bfcb2c11Swlei; CHECK: 1: 6 101*bfcb2c11Swlei 1020f53df86Swlei; libcallback.c 1030f53df86Swlei; clang -shared -fPIC -o libcallback.so libcallback.c 1040f53df86Swlei 1050f53df86Swleiint callback(int *cnt, int (*func1)(int), int (*func2)(int), int p) { 1060f53df86Swlei (*cnt)++; 1070f53df86Swlei return func1(p) + func2(p); 1080f53df86Swlei} 1090f53df86Swlei 1100f53df86Swlei; test.c 1110f53df86Swlei; clang test.c -O0 -g -fno-optimize-sibling-calls -fdebug-info-for-profiling -L $PWD -lcallback -fno-inline 1120f53df86Swlei 1130f53df86Swlei#include <stdio.h> 1140f53df86Swlei 1150f53df86Swleiint callbackCnt = 0; 1160f53df86Swlei 1170f53df86Swleiint callback(int *cnt, int (*func1)(int), int (*func2)(int), int p); 1180f53df86Swlei 1190f53df86Swleiint bar(int p) { 1200f53df86Swlei return p + 1; 1210f53df86Swlei} 1220f53df86Swlei 1230f53df86Swleiint baz(int p) { 1240f53df86Swlei return p - 1; 1250f53df86Swlei} 1260f53df86Swlei 1270f53df86Swleiint callBeforeReturn(int p) { 1280f53df86Swlei return p + 10; 1290f53df86Swlei} 1300f53df86Swlei 1310f53df86Swleiint callAfterReturn(int p) { 1320f53df86Swlei return p - 10; 1330f53df86Swlei} 1340f53df86Swlei 1350f53df86Swleiint qux(int p) { 1360f53df86Swlei p += 10; 1370f53df86Swlei int ret = callBeforeReturn(p); 1380f53df86Swlei ret = callback(&callbackCnt, bar, baz, ret); 1390f53df86Swlei ret = callAfterReturn(ret); 1400f53df86Swlei return ret; 1410f53df86Swlei} 1420f53df86Swlei 1430f53df86Swleiint foo (int p) { 1440f53df86Swlei p -= 10; 1450f53df86Swlei return qux(p); 1460f53df86Swlei} 1470f53df86Swlei 1480f53df86Swleiint main(void) { 1490f53df86Swlei int sum = 0; 1500f53df86Swlei for (int i = 0; i < 1000 * 1000; i++) { 1510f53df86Swlei sum += callback(&callbackCnt, foo, bar, i); 1520f53df86Swlei } 1530f53df86Swlei printf("callback count=%d, sum=%d\n", callbackCnt, sum); 1540f53df86Swlei} 155