33 #include <gtest/gtest.h>
37 std::string
env(
const char* n) {
const char* v = getenv(n);
return v ? v :
""; }
39 std::string r =
env(
"CCTLIB_ROOT");
40 return r.empty() ?
"../.." : r;
45 const std::vector<std::string>& toolArgs,
46 const std::string& victim,
47 std::string* stderrOut) {
48 std::string pin =
pin_root() +
"/pin";
49 std::vector<char*> argv;
50 argv.push_back(
const_cast<char*
>(pin.c_str()));
51 argv.push_back(
const_cast<char*
>(
"-t"));
52 argv.push_back(
const_cast<char*
>(tool.c_str()));
53 for (
auto&
a : toolArgs) argv.push_back(
const_cast<char*
>(
a.c_str()));
54 argv.push_back(
const_cast<char*
>(
"--"));
55 argv.push_back(
const_cast<char*
>(victim.c_str()));
56 argv.push_back(
nullptr);
58 char errPath[] =
"/tmp/cct_shape_exc_stderr_XXXXXX";
59 int errFd = mkstemp(errPath);
60 if (errFd < 0)
return -1;
63 if (pid < 0) { close(errFd);
return -1; }
65 int devnull = open(
"/dev/null", O_WRONLY);
66 if (devnull >= 0) { dup2(devnull, 1); close(devnull); }
67 dup2(errFd, 2); close(errFd);
68 execv(pin.c_str(), argv.data());
72 if (waitpid(pid, &
status, 0) < 0) { close(errFd); unlink(errPath);
return -1; }
75 lseek(errFd, 0, SEEK_SET);
79 while ((n = read(errFd,
buf,
sizeof(
buf))) > 0) {
80 stderrOut->append(
buf, n);
87 return -128 - WTERMSIG(
status);
108 {
"exc_simple_throw",
true },
109 {
"exc_deep_unwind",
false },
110 {
"exc_rethrow",
true },
111 {
"exc_catchall",
false },
112 {
"exc_dtor_cleanup",
false },
113 {
"exc_stress_loop",
true },
114 {
"exc_polymorphic",
false },
115 {
"exc_recurse_trycatch",
false },
116 {
"exc_none_tn",
true },
117 {
"exc_uncaught_tn",
false },
118 {
"exc_ctor_throw",
false },
119 {
"exc_catch_and_resume",
false },
120 {
"sig_longjmp",
false },
121 {
"sig_sigsegv_recover",
false },
129 ASSERT_FALSE(
pin_root().empty()) <<
"PIN_ROOT required";
130 ASSERT_EQ(0, chdir(root_.c_str())) <<
"chdir(" << root_ <<
") failed";
135 const auto& v = GetParam();
136 if (v.expensive &&
env(
"CCTLIB_EXPENSIVE_SHAPE").empty()) {
137 GTEST_SKIP() << v.name <<
" gated behind CCTLIB_EXPENSIVE_SHAPE=1 "
138 <<
"(slow under Pin+cctlib; runs in nightly / on-demand)";
140 std::string tool = root_ +
"/clients/obj-intel64/cct_shape_check.so";
141 std::string victim = root_ +
"/tests/gtest/obj/apps/exceptions/" + v.name;
142 ASSERT_EQ(0, access(tool.c_str(), F_OK)) << tool <<
" missing";
143 ASSERT_EQ(0, access(victim.c_str(), F_OK)) << victim <<
" missing";
148 <<
"victim=" << v.name <<
" rc=" << rc
149 <<
"\n---- cct_shape_check stderr ----\n" << errText
150 <<
"---- end stderr ----";
156 [](
const testing::TestParamInfo<ExceptionShape::ParamType>& info) {
157 return std::string(info.param.name);
static uint64_t buf[ITERS]
TEST_P(ExceptionShape, CctShapeSurvivesUnwind)
INSTANTIATE_TEST_SUITE_P(Victims, ExceptionShape, ::testing::ValuesIn(kVictims), [](const testing::TestParamInfo< ExceptionShape::ParamType > &info) { return std::string(info.param.name);})
std::string env(const char *n)
int run_pin_capture(const std::string &tool, const std::vector< std::string > &toolArgs, const std::string &victim, std::string *stderrOut)
const VictimSpec kVictims[]
std::string cctlib_root()