diff --git a/sandboxed_api/examples/stringop/lib/stringop.cc b/sandboxed_api/examples/stringop/lib/stringop.cc index 805f3f3..decac6e 100644 --- a/sandboxed_api/examples/stringop/lib/stringop.cc +++ b/sandboxed_api/examples/stringop/lib/stringop.cc @@ -79,17 +79,20 @@ extern "C" const void* get_raw_c_string() { return "Ten chars."; } extern "C" void nop() {} -// The "no tail-call" annotation and the additional indirection ensure that this -// function shows up in the violation stack trace. Otherwise, depending on -// optimization level and optimizer aggressiveness, functions may be inlined, -// hoisted or omitted (in case of tail calls). +// The "no tail-call" annotation and the additional indirection ensure that +// either this function or its calling function shows up in the violation stack +// trace. Otherwise, depending on optimization level and optimizer +// aggressiveness, functions may be inlined, hoisted or omitted (in case of tail +// calls). static ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL void ViolateIndirect() { ptrace((__ptrace_request)990, 991, 992, 993); - ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); } -extern "C" void violate() { +// Using block syntax here, because SAPI's libclang based header generator won't +// parse the attribute annotations otherwise. +extern "C" { +ABSL_ATTRIBUTE_NOINLINE ABSL_ATTRIBUTE_NO_TAIL_CALL void violate() { ViolateIndirect(); - ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +} } diff --git a/sandboxed_api/sapi_test.cc b/sandboxed_api/sapi_test.cc index d2bade6..d440c7b 100644 --- a/sandboxed_api/sapi_test.cc +++ b/sandboxed_api/sapi_test.cc @@ -143,7 +143,15 @@ TEST(SapiTest, HasStackTraces) { StringopApi api(sandbox.get()); EXPECT_THAT(api.violate(), StatusIs(absl::StatusCode::kUnavailable)); const auto& result = sandbox->AwaitResult(); - EXPECT_THAT(result.GetStackTrace(), HasSubstr("ViolateIndirect")); + EXPECT_THAT( + result.GetStackTrace(), + // Check that at least one expected function is present in the stack + // trace. + // Note: Typically, in optimized builds, on x86-64, only + // "ViolateIndirect()" will be present in the stack trace. On POWER, all + // stack frames are generated, but libunwind will be unable to track + // "ViolateIndirect()" on the stack and instead show its IP as zero. + AnyOf(HasSubstr("ViolateIndirect"), HasSubstr("violate"))); EXPECT_THAT(result.final_status(), Eq(sandbox2::Result::VIOLATION)); }