CCTLib
Calling-context and data-object attribution library for Intel Pin
exc_simple_throw.cpp
Go to the documentation of this file.
1 // Basic C++ exception: single throw, single catch, three-level unwind.
2 // Exercises cctlib's exception path with the simplest possible pattern.
3 //
4 // simple_try_marker (called just before the throw inside the try block)
5 // and simple_catch_marker (called inside the catch handler) let the
6 // shape-check tool assert that both are direct children of main -- NOT
7 // rooted somewhere under __cxa_throw's subtree.
8 #include <cstdint>
9 #include <cstdio>
10 #define N 5000
11 static volatile uint64_t sink;
12 static uint64_t buf[N];
13 
14 extern "C" __attribute__((noinline)) void simple_try_marker(int i) {
15  __asm__ __volatile__("" ::: "memory");
16  sink ^= (uint64_t)i;
17 }
18 extern "C" __attribute__((noinline)) void simple_catch_marker(int i) {
19  __asm__ __volatile__("" ::: "memory");
20  sink ^= (uint64_t)i << 8;
21 }
22 
23 static void inner(int i) {
24  buf[i] = 0xAA;
25  throw i;
26 }
27 static void middle(int i) { inner(i); buf[i] = 0xBB; /* never reached */ }
28 static void outer(int i) { middle(i); buf[i] = 0xCC; /* never reached */ }
29 
30 int main(int argc, char** argv) {
31  (void)argc; (void)argv;
32  int caught = 0;
33  for (int i = 0; i < N; ++i) buf[i] = 0x11; // prime
34  for (int i = 0; i < N; ++i) {
35  try {
36  simple_try_marker(i); // in-try, non-throwing marker
37  outer(i);
38  } catch (int v) {
39  simple_catch_marker(i); // in-catch marker
40  caught += v == i;
41  buf[i] = 0xDD; // post-unwind write, tool must record correctly
42  }
43  }
44  for (int i = 0; i < N; ++i) sink ^= buf[i];
45  fprintf(stderr, "exc_simple_throw: caught=%d expected=%d sink=%llx\n",
46  caught, N, (unsigned long long)sink);
47  return caught == N ? 0 : 1;
48 }
#define N
int main(int argc, char **argv)
__attribute__((noinline)) void simple_try_marker(int i)
static void inner(int i)
static uint64_t buf[N]
static void middle(int i)
static void outer(int i)
static volatile uint64_t sink