mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Test stack unwinding more thoroughly
Check unwinding recursive calls. Verify we can unwind in absence of unwind tables. PiperOrigin-RevId: 513506498 Change-Id: Ib87240b7481dae3a4513c944e17a7924a54926e9
This commit is contained in:
parent
0033c4563f
commit
a613dda7f2
@ -54,9 +54,11 @@ using ::testing::IsEmpty;
|
|||||||
using ::testing::StartsWith;
|
using ::testing::StartsWith;
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
std::string arg = "1";
|
std::string testname = "CrashMe";
|
||||||
|
int testno = 1;
|
||||||
|
int testmode = 1;
|
||||||
int final_status = Result::SIGNALED;
|
int final_status = Result::SIGNALED;
|
||||||
std::string function_name = "CrashMe";
|
std::string function_name = testname;
|
||||||
std::string full_function_description = "CrashMe(char)";
|
std::string full_function_description = "CrashMe(char)";
|
||||||
std::function<void(PolicyBuilder*)> modify_policy;
|
std::function<void(PolicyBuilder*)> modify_policy;
|
||||||
absl::Duration wall_time_limit = absl::ZeroDuration();
|
absl::Duration wall_time_limit = absl::ZeroDuration();
|
||||||
@ -67,7 +69,8 @@ class StackTraceTest : public ::testing::TestWithParam<TestCase> {};
|
|||||||
// Test that symbolization of stack traces works.
|
// Test that symbolization of stack traces works.
|
||||||
void SymbolizationWorksCommon(TestCase param) {
|
void SymbolizationWorksCommon(TestCase param) {
|
||||||
const std::string path = GetTestSourcePath("sandbox2/testcases/symbolize");
|
const std::string path = GetTestSourcePath("sandbox2/testcases/symbolize");
|
||||||
std::vector<std::string> args = {path, param.arg};
|
std::vector<std::string> args = {path, absl::StrCat(param.testno),
|
||||||
|
absl::StrCat(param.testmode)};
|
||||||
|
|
||||||
auto policybuilder = PolicyBuilder()
|
auto policybuilder = PolicyBuilder()
|
||||||
// Don't restrict the syscalls at all.
|
// Don't restrict the syscalls at all.
|
||||||
@ -87,6 +90,20 @@ void SymbolizationWorksCommon(TestCase param) {
|
|||||||
// Check that demangling works as well.
|
// Check that demangling works as well.
|
||||||
EXPECT_THAT(result.stack_trace(),
|
EXPECT_THAT(result.stack_trace(),
|
||||||
Contains(StartsWith(param.full_function_description)));
|
Contains(StartsWith(param.full_function_description)));
|
||||||
|
EXPECT_THAT(result.stack_trace(), Contains(StartsWith("RunTest")));
|
||||||
|
EXPECT_THAT(result.stack_trace(), Contains(StartsWith("main")));
|
||||||
|
if (param.testmode == 2) {
|
||||||
|
EXPECT_THAT(result.stack_trace(),
|
||||||
|
Contains(StartsWith("RecurseA")).Times(5));
|
||||||
|
EXPECT_THAT(result.stack_trace(),
|
||||||
|
Contains(StartsWith("RecurseB")).Times(5));
|
||||||
|
} else if (param.testmode == 3) {
|
||||||
|
EXPECT_THAT(result.stack_trace(), Contains(StartsWith("LibRecurse")));
|
||||||
|
EXPECT_THAT(result.stack_trace(),
|
||||||
|
Contains(StartsWith("LibRecurseA")).Times(5));
|
||||||
|
EXPECT_THAT(result.stack_trace(),
|
||||||
|
Contains(StartsWith("LibRecurseB")).Times(5));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SymbolizationWorksWithModifiedPolicy(
|
void SymbolizationWorksWithModifiedPolicy(
|
||||||
@ -206,21 +223,21 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
Instantiation, StackTraceTest,
|
Instantiation, StackTraceTest,
|
||||||
::testing::Values(
|
::testing::Values(
|
||||||
TestCase{
|
TestCase{
|
||||||
.arg = "1",
|
.testname = "CrashMe",
|
||||||
|
.testno = 1,
|
||||||
.final_status = Result::SIGNALED,
|
.final_status = Result::SIGNALED,
|
||||||
.function_name = "CrashMe",
|
|
||||||
.full_function_description = "CrashMe(char)",
|
.full_function_description = "CrashMe(char)",
|
||||||
},
|
},
|
||||||
TestCase{
|
TestCase{
|
||||||
.arg = "2",
|
.testname = "ViolatePolicy",
|
||||||
|
.testno = 2,
|
||||||
.final_status = Result::VIOLATION,
|
.final_status = Result::VIOLATION,
|
||||||
.function_name = "ViolatePolicy",
|
|
||||||
.full_function_description = "ViolatePolicy(int)",
|
.full_function_description = "ViolatePolicy(int)",
|
||||||
},
|
},
|
||||||
TestCase{
|
TestCase{
|
||||||
.arg = "3",
|
.testname = "ExitNormally",
|
||||||
|
.testno = 3,
|
||||||
.final_status = Result::OK,
|
.final_status = Result::OK,
|
||||||
.function_name = "ExitNormally",
|
|
||||||
.full_function_description = "ExitNormally(int)",
|
.full_function_description = "ExitNormally(int)",
|
||||||
.modify_policy =
|
.modify_policy =
|
||||||
[](PolicyBuilder* builder) {
|
[](PolicyBuilder* builder) {
|
||||||
@ -228,14 +245,30 @@ INSTANTIATE_TEST_SUITE_P(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
TestCase{
|
TestCase{
|
||||||
.arg = "4",
|
.testname = "SleepForXSeconds",
|
||||||
|
.testno = 4,
|
||||||
.final_status = Result::TIMEOUT,
|
.final_status = Result::TIMEOUT,
|
||||||
.function_name = "SleepForXSeconds",
|
|
||||||
.full_function_description = "SleepForXSeconds(int)",
|
.full_function_description = "SleepForXSeconds(int)",
|
||||||
.wall_time_limit = absl::Seconds(1),
|
.wall_time_limit = absl::Seconds(1),
|
||||||
|
},
|
||||||
|
TestCase{
|
||||||
|
.testname = "ViolatePolicyRecursive",
|
||||||
|
.testno = 2,
|
||||||
|
.testmode = 2,
|
||||||
|
.final_status = Result::VIOLATION,
|
||||||
|
.function_name = "ViolatePolicy",
|
||||||
|
.full_function_description = "ViolatePolicy(int)",
|
||||||
|
},
|
||||||
|
TestCase{
|
||||||
|
.testname = "ViolatePolicyRecursiveLib",
|
||||||
|
.testno = 2,
|
||||||
|
.testmode = 3,
|
||||||
|
.final_status = Result::VIOLATION,
|
||||||
|
.function_name = "ViolatePolicy",
|
||||||
|
.full_function_description = "ViolatePolicy(int)",
|
||||||
}),
|
}),
|
||||||
[](const ::testing::TestParamInfo<TestCase>& info) {
|
[](const ::testing::TestParamInfo<TestCase>& info) {
|
||||||
return info.param.function_name;
|
return info.param.testname;
|
||||||
});
|
});
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@ -163,6 +163,22 @@ cc_binary(
|
|||||||
features = ["fully_static_link"],
|
features = ["fully_static_link"],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "symbolize_lib",
|
||||||
|
testonly = True,
|
||||||
|
srcs = ["symbolize_lib.cc"],
|
||||||
|
hdrs = ["symbolize_lib.h"],
|
||||||
|
copts = sapi_platform_copts([
|
||||||
|
"-fno-omit-frame-pointer",
|
||||||
|
"-fno-unwind-tables",
|
||||||
|
"-fno-asynchronous-unwind-tables",
|
||||||
|
]),
|
||||||
|
features = ["fully_static_link"],
|
||||||
|
deps = [
|
||||||
|
"@com_google_absl//absl/base:core_headers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "symbolize",
|
name = "symbolize",
|
||||||
testonly = True,
|
testonly = True,
|
||||||
@ -170,6 +186,7 @@ cc_binary(
|
|||||||
copts = sapi_platform_copts(),
|
copts = sapi_platform_copts(),
|
||||||
features = ["fully_static_link"],
|
features = ["fully_static_link"],
|
||||||
deps = [
|
deps = [
|
||||||
|
":symbolize_lib",
|
||||||
"//sandboxed_api/util:raw_logging",
|
"//sandboxed_api/util:raw_logging",
|
||||||
"@com_google_absl//absl/base:core_headers",
|
"@com_google_absl//absl/base:core_headers",
|
||||||
"@com_google_absl//absl/strings",
|
"@com_google_absl//absl/strings",
|
||||||
|
@ -213,6 +213,24 @@ target_link_libraries(sandbox2_testcase_symbolize PRIVATE
|
|||||||
absl::strings
|
absl::strings
|
||||||
sapi::base
|
sapi::base
|
||||||
sapi::raw_logging
|
sapi::raw_logging
|
||||||
|
sandbox2::testcase_symbolize_lib
|
||||||
|
)
|
||||||
|
|
||||||
|
# sandboxed_api/sandbox2/testcases:symbolize_lib
|
||||||
|
add_library(sandbox2_testcase_symbolize_lib
|
||||||
|
symbolize_lib.cc
|
||||||
|
symbolize_lib.h
|
||||||
|
)
|
||||||
|
add_library(sandbox2::testcase_symbolize_lib ALIAS sandbox2_testcase_symbolize_lib)
|
||||||
|
target_link_libraries(sandbox2_testcase_symbolize_lib PRIVATE
|
||||||
|
-static
|
||||||
|
absl::core_headers
|
||||||
|
sapi::base
|
||||||
|
)
|
||||||
|
target_compile_options(sandbox2_testcase_symbolize_lib PRIVATE
|
||||||
|
-fno-omit-frame-pointer
|
||||||
|
-fno-unwind-tables
|
||||||
|
-fno-asynchronous-unwind-tables
|
||||||
)
|
)
|
||||||
|
|
||||||
# sandboxed_api/sandbox2/testcases:starve
|
# sandboxed_api/sandbox2/testcases:starve
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "absl/base/attributes.h"
|
#include "absl/base/attributes.h"
|
||||||
#include "absl/strings/numbers.h"
|
#include "absl/strings/numbers.h"
|
||||||
|
#include "sandboxed_api/sandbox2/testcases/symbolize_lib.h"
|
||||||
#include "sandboxed_api/util/raw_logging.h"
|
#include "sandboxed_api/util/raw_logging.h"
|
||||||
|
|
||||||
// Sometimes we don't have debug info to properly unwind through libc (a frame
|
// Sometimes we don't have debug info to properly unwind through libc (a frame
|
||||||
@ -63,10 +64,9 @@ void SleepForXSeconds(int x = 0) {
|
|||||||
IndirectLibcCall([x]() { sleep(x); });
|
IndirectLibcCall([x]() { sleep(x); });
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
SAPI_RAW_CHECK(argc >= 2, "Not enough arguments");
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
int testno;
|
void RunTest(int testno) {
|
||||||
SAPI_RAW_CHECK(absl::SimpleAtoi(argv[1], &testno), "testno not a number");
|
|
||||||
switch (testno) {
|
switch (testno) {
|
||||||
case 1:
|
case 1:
|
||||||
CrashMe();
|
CrashMe();
|
||||||
@ -83,5 +83,46 @@ int main(int argc, char* argv[]) {
|
|||||||
default:
|
default:
|
||||||
SAPI_RAW_LOG(FATAL, "Unknown test case: %d", testno);
|
SAPI_RAW_LOG(FATAL, "Unknown test case: %d", testno);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
|
void RecurseA(int testno, int n);
|
||||||
|
|
||||||
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
|
void RecurseB(int testno, int n) {
|
||||||
|
if (n > 1) {
|
||||||
|
return RecurseA(testno, n - 1);
|
||||||
|
}
|
||||||
|
return RunTest(testno);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RecurseA(int testno, int n) {
|
||||||
|
if (n > 1) {
|
||||||
|
return RecurseB(testno, n - 1);
|
||||||
|
}
|
||||||
|
return RunTest(testno);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
SAPI_RAW_CHECK(argc >= 3, "Not enough arguments");
|
||||||
|
int testno;
|
||||||
|
int testmode;
|
||||||
|
SAPI_RAW_CHECK(absl::SimpleAtoi(argv[1], &testno), "testno not a number");
|
||||||
|
SAPI_RAW_CHECK(absl::SimpleAtoi(argv[2], &testmode), "testmode not a number");
|
||||||
|
switch (testmode) {
|
||||||
|
case 1:
|
||||||
|
RunTest(testno);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
RecurseA(testno, 10);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
LibRecurse(&RunTest, testno, 10);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
SAPI_RAW_LOG(FATAL, "Unknown test mode: %d", testmode);
|
||||||
|
}
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
25
sandboxed_api/sandbox2/testcases/symbolize_lib.cc
Normal file
25
sandboxed_api/sandbox2/testcases/symbolize_lib.cc
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "sandboxed_api/sandbox2/testcases/symbolize_lib.h"
|
||||||
|
|
||||||
|
#include "absl/base/attributes.h"
|
||||||
|
|
||||||
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
|
void LibRecurseA(void (*cb)(int), int data, int n);
|
||||||
|
|
||||||
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
|
void LibRecurseB(void (*cb)(int), int data, int n) {
|
||||||
|
if (n > 1) {
|
||||||
|
return LibRecurseA(cb, data, n - 1);
|
||||||
|
}
|
||||||
|
return cb(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibRecurseA(void (*cb)(int), int data, int n) {
|
||||||
|
if (n > 1) {
|
||||||
|
return LibRecurseB(cb, data, n - 1);
|
||||||
|
}
|
||||||
|
return cb(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibRecurse(void (*cb)(int), int data, int n) { LibRecurseA(cb, data, n); }
|
10
sandboxed_api/sandbox2/testcases/symbolize_lib.h
Normal file
10
sandboxed_api/sandbox2/testcases/symbolize_lib.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef SANDBOXED_API_SANDBOX2_TESTCASES_SYMBOLIZE_LIB_H_
|
||||||
|
#define SANDBOXED_API_SANDBOX2_TESTCASES_SYMBOLIZE_LIB_H_
|
||||||
|
|
||||||
|
#include "absl/base/attributes.h"
|
||||||
|
|
||||||
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
|
ABSL_ATTRIBUTE_NO_TAIL_CALL
|
||||||
|
void LibRecurse(void (*cb)(int), int data, int n);
|
||||||
|
|
||||||
|
#endif // SANDBOXED_API_SANDBOX2_TESTCASES_SYMBOLIZE_LIB_H_
|
Loading…
x
Reference in New Issue
Block a user