CCTLib
Calling-context and data-object attribution library for Intel Pin
sig_longjmp.cpp
Go to the documentation of this file.
1 // setjmp/longjmp: non-C++ stack unwinding. cctlib has separate hooks for
2 // setjmp/longjmp (CaptureSigSetJmpCtxt/HoldLongJmpBuf/RestoreSigLongJmpCtxt).
3 // This test ensures the exception-path resolver changes don't regress that
4 // path. ITERS bounded so the CCT fits under Pin's Fini stack budget.
5 //
6 // sjlj_try_marker (before go_deep) and sjlj_landing_marker (post-longjmp
7 // on the setjmp-returns-nonzero path) verify both are direct children of
8 // main -- setjmp/longjmp's re-anchor must not leave the landing block
9 // dangling under go_deep's or __longjmp's subtree.
10 #include <cstdint>
11 #include <cstdio>
12 #include <setjmp.h>
13 #define ITERS 500
14 static volatile uint64_t sink;
15 static uint64_t buf[ITERS];
16 static jmp_buf jb;
17 
18 extern "C" __attribute__((noinline)) void sjlj_try_marker(int i) {
19  __asm__ __volatile__("" ::: "memory"); sink ^= (uint64_t)i;
20 }
21 extern "C" __attribute__((noinline)) void sjlj_landing_marker(int i) {
22  __asm__ __volatile__("" ::: "memory"); sink ^= (uint64_t)i << 8;
23 }
24 
25 static void go_deep(int i, int depth) {
26  volatile uint64_t local = 0;
27  if (depth == 0) {
28  buf[i] = 0xEE;
29  longjmp(jb, i + 1); // never returns
30  }
31  go_deep(i, depth - 1);
32  (void)local;
33 }
34 
35 int main(int argc, char** argv) {
36  (void)argc; (void)argv;
37  int jumps = 0;
38  for (int i = 0; i < ITERS; ++i) {
39  int rc = setjmp(jb);
40  if (rc == 0) {
41  sjlj_try_marker(i);
42  go_deep(i, 8);
43  } else {
44  sjlj_landing_marker(i);
45  buf[i] ^= 0x77;
46  ++jumps;
47  }
48  }
49  for (int i = 0; i < ITERS; ++i) sink ^= buf[i];
50  fprintf(stderr, "sig_longjmp: jumps=%d iters=%d sink=%llx\n",
51  jumps, ITERS, (unsigned long long)sink);
52  return jumps == ITERS ? 0 : 1;
53 }
static void go_deep(int i, int depth)
Definition: sig_longjmp.cpp:25
#define ITERS
Definition: sig_longjmp.cpp:13
static jmp_buf jb
Definition: sig_longjmp.cpp:16
int main(int argc, char **argv)
Definition: sig_longjmp.cpp:35
static uint64_t buf[ITERS]
Definition: sig_longjmp.cpp:15
__attribute__((noinline)) void sjlj_try_marker(int i)
Definition: sig_longjmp.cpp:18
static volatile uint64_t sink
Definition: sig_longjmp.cpp:14