CCTLib
Calling-context and data-object attribution library for Intel Pin
exc_polymorphic.cpp
Go to the documentation of this file.
1 // Polymorphic catch: throw derived, catch by base reference. Exercises
2 // libstdc++'s __cxa_throw + type-info matching path.
3 //
4 // poly_try_marker / poly_catch_marker verify catch-body attribution
5 // under the type-info-matching personality path.
6 #include <cstdint>
7 #include <cstdio>
8 #include <stdexcept>
9 #define ITERS 1000
10 static volatile uint64_t sink;
11 static uint64_t buf[ITERS];
12 
13 extern "C" __attribute__((noinline)) void poly_try_marker(int i) {
14  __asm__ __volatile__("" ::: "memory"); sink ^= (uint64_t)i;
15 }
16 extern "C" __attribute__((noinline)) void poly_catch_marker(int i) {
17  __asm__ __volatile__("" ::: "memory"); sink ^= (uint64_t)i << 8;
18 }
19 
20 struct Base : std::exception { const char* what() const noexcept override { return "Base"; } };
21 struct Mid : Base { const char* what() const noexcept override { return "Mid"; } };
22 struct Leaf : Mid { const char* what() const noexcept override { return "Leaf"; } };
23 
24 static void thrower(int i) {
25  buf[i] = 0x55;
26  switch (i % 3) {
27  case 0: throw Base{};
28  case 1: throw Mid{};
29  case 2: throw Leaf{};
30  }
31 }
32 
33 int main(int argc, char** argv) {
34  (void)argc; (void)argv;
35  int caught = 0;
36  for (int i = 0; i < ITERS; ++i) {
37  try {
38  poly_try_marker(i);
39  thrower(i);
40  } catch (const std::exception& e) {
41  poly_catch_marker(i);
42  buf[i] ^= 0x99;
43  caught += (e.what() != nullptr);
44  }
45  }
46  for (int i = 0; i < ITERS; ++i) sink ^= buf[i];
47  fprintf(stderr, "exc_polymorphic: caught=%d iters=%d sink=%llx\n",
48  caught, ITERS, (unsigned long long)sink);
49  return caught == ITERS ? 0 : 1;
50 }
#define ITERS
int main(int argc, char **argv)
static uint64_t buf[ITERS]
__attribute__((noinline)) void poly_try_marker(int i)
static void thrower(int i)
static volatile uint64_t sink
const char * what() const noexcept override
const char * what() const noexcept override
const char * what() const noexcept override