From 5b01e8ce80821816a8283c90f262ab0a3cb94de0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CRian?= <“rianquinn@gmail.com”> Date: Mon, 5 Sep 2016 07:07:26 -0600 Subject: [PATCH] Bad Alloc Testing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch provides some small updates to enable catching and handling when memory runs out (std::bad_alloc). Specifically, when this happens, we can no longer use std::cout which does many allocations in the process. Instead we exit gracefully with an error code. Signed-off-by: “Rian <“rianquinn@gmail.com”> --- bfunwind/include/misc.h | 4 +-- bfvmm/src/entry/test/test.cpp | 2 ++ bfvmm/src/entry/test/test.h | 6 ++-- bfvmm/src/entry/test/test_entry.cpp | 36 ++++++++++++++++++++++++ bfvmm/src/misc/test/test_error_codes.cpp | 2 ++ common/common_target.mk | 2 ++ include/error_codes.h | 8 ++++++ include/guard_exceptions.h | 4 +++ tools/scripts/setup_ubuntu.sh | 17 ++++++----- 9 files changed, 68 insertions(+), 13 deletions(-) diff --git a/bfunwind/include/misc.h b/bfunwind/include/misc.h index 153d013e..85a96f61 100644 --- a/bfunwind/include/misc.h +++ b/bfunwind/include/misc.h @@ -25,13 +25,13 @@ #include #include -inline uint64_t abs(int64_t value) +inline uint64_t bfabs(int64_t value) { return value >= 0 ? static_cast(value) : static_cast(-value); } inline uint64_t add_offset(uint64_t value, int64_t offset) { - auto abs_offset = abs(offset); + auto abs_offset = bfabs(offset); if (offset >= 0) return value + abs_offset; diff --git a/bfvmm/src/entry/test/test.cpp b/bfvmm/src/entry/test/test.cpp index db4a59c9..4148885f 100644 --- a/bfvmm/src/entry/test/test.cpp +++ b/bfvmm/src/entry/test/test.cpp @@ -43,10 +43,12 @@ entry_ut::list() this->test_start_vmm_success(); this->test_start_vmm_throws_general_exception(); this->test_start_vmm_throws_standard_exception(); + this->test_start_vmm_throws_bad_alloc(); this->test_start_vmm_throws_any_exception(); this->test_stop_vmm_success(); this->test_stop_vmm_throws_general_exception(); this->test_stop_vmm_throws_standard_exception(); + this->test_stop_vmm_throws_bad_alloc(); this->test_stop_vmm_throws_any_exception(); return true; diff --git a/bfvmm/src/entry/test/test.h b/bfvmm/src/entry/test/test.h index d585ee9b..dccb1ca5 100644 --- a/bfvmm/src/entry/test/test.h +++ b/bfvmm/src/entry/test/test.h @@ -42,15 +42,13 @@ private: void test_start_vmm_success(); void test_start_vmm_throws_general_exception(); void test_start_vmm_throws_standard_exception(); + void test_start_vmm_throws_bad_alloc(); void test_start_vmm_throws_any_exception(); void test_stop_vmm_success(); void test_stop_vmm_throws_general_exception(); void test_stop_vmm_throws_standard_exception(); + void test_stop_vmm_throws_bad_alloc(); void test_stop_vmm_throws_any_exception(); - void test_add_mdl_success(); - void test_add_mdl_throws_general_exception(); - void test_add_mdl_throws_standard_exception(); - void test_add_mdl_throws_any_exception(); }; diff --git a/bfvmm/src/entry/test/test_entry.cpp b/bfvmm/src/entry/test/test_entry.cpp index ad740466..3844b387 100644 --- a/bfvmm/src/entry/test/test_entry.cpp +++ b/bfvmm/src/entry/test/test_entry.cpp @@ -81,6 +81,24 @@ entry_ut::test_start_vmm_throws_standard_exception() }); } +void +entry_ut::test_start_vmm_throws_bad_alloc() +{ + MockRepository mocks; + auto vcm = mocks.Mock(); + mocks.OnCallFunc(vcpu_manager::instance).Return(vcm); + + mocks.OnCall(vcm, vcpu_manager::create_vcpu); + mocks.OnCall(vcm, vcpu_manager::delete_vcpu); + mocks.OnCall(vcm, vcpu_manager::run_vcpu).Throw(std::bad_alloc()); + mocks.OnCall(vcm, vcpu_manager::hlt_vcpu); + + RUN_UNITTEST_WITH_MOCKS(mocks, [&] + { + EXPECT_NO_EXCEPTION(start_vmm(0)); + }); +} + void entry_ut::test_start_vmm_throws_any_exception() { @@ -153,6 +171,24 @@ entry_ut::test_stop_vmm_throws_standard_exception() }); } +void +entry_ut::test_stop_vmm_throws_bad_alloc() +{ + MockRepository mocks; + auto vcm = mocks.Mock(); + mocks.OnCallFunc(vcpu_manager::instance).Return(vcm); + + mocks.OnCall(vcm, vcpu_manager::create_vcpu); + mocks.OnCall(vcm, vcpu_manager::delete_vcpu); + mocks.OnCall(vcm, vcpu_manager::run_vcpu); + mocks.OnCall(vcm, vcpu_manager::hlt_vcpu).Throw(std::bad_alloc()); + + RUN_UNITTEST_WITH_MOCKS(mocks, [&] + { + EXPECT_NO_EXCEPTION(stop_vmm(0)); + }); +} + void entry_ut::test_stop_vmm_throws_any_exception() { diff --git a/bfvmm/src/misc/test/test_error_codes.cpp b/bfvmm/src/misc/test/test_error_codes.cpp index 873b0354..5c7f803c 100644 --- a/bfvmm/src/misc/test/test_error_codes.cpp +++ b/bfvmm/src/misc/test/test_error_codes.cpp @@ -68,6 +68,8 @@ misc_ut::test_error_codes_valid() EXPECT_TRUE(ec_to_str(BF_ERROR_VMM_CORRUPTED) == STRINGIFY_MACRO(BF_ERROR_VMM_CORRUPTED)); EXPECT_TRUE(ec_to_str(BF_ERROR_UNKNOWN) == STRINGIFY_MACRO(BF_ERROR_UNKNOWN)); + EXPECT_TRUE(ec_to_str(BF_BAD_ALLOC) == STRINGIFY_MACRO(BF_BAD_ALLOC)); + EXPECT_TRUE(ec_to_str(BF_IOCTL_FAILURE) == STRINGIFY_MACRO(BF_IOCTL_FAILURE)); } diff --git a/common/common_target.mk b/common/common_target.mk index 7a12d0b6..ee50c007 100644 --- a/common/common_target.mk +++ b/common/common_target.mk @@ -243,6 +243,8 @@ ifeq ($(DYNAMIC_ANALYSIS_ENABLED), true) NATIVE_LDFLAGS+=-fsanitize=undefined NATIVE_LDFLAGS+=-fno-sanitize=vptr NATIVE_LDFLAGS+=-fno-sanitize=alignment + NATIVE_LDFLAGS+=-fuse-ld=gold + NATIVE_LDFLAGS+=-Wl,--no-as-needed endif ################################################################################ diff --git a/include/error_codes.h b/include/error_codes.h index f9eb6daa..c6071023 100644 --- a/include/error_codes.h +++ b/include/error_codes.h @@ -134,6 +134,12 @@ typedef INT64 int64_t; #define BF_IOCTL_SUCCESS sign(SUCCESS) #define BF_IOCTL_FAILURE sign(-1) +/* -------------------------------------------------------------------------- */ +/* Bad Alloc */ +/* -------------------------------------------------------------------------- */ + +#define BF_BAD_ALLOC sign(0x8000000100000000) + /* -------------------------------------------------------------------------- */ /* Stringify Error Codes */ /* -------------------------------------------------------------------------- */ @@ -187,6 +193,8 @@ ec_to_str(int64_t value) EC_CASE(BF_ERROR_VMM_CORRUPTED); EC_CASE(BF_ERROR_UNKNOWN); + EC_CASE(BF_BAD_ALLOC); + EC_CASE(BF_IOCTL_FAILURE); default: diff --git a/include/guard_exceptions.h b/include/guard_exceptions.h index 3a45fecc..e1ffa9cf 100644 --- a/include/guard_exceptions.h +++ b/include/guard_exceptions.h @@ -43,6 +43,10 @@ guard_exceptions(int64_t error_code, T func) bferror << "----------------------------------------" << bfendl; bferror << ge << bfendl; } + catch (std::bad_alloc &e) + { + return BF_BAD_ALLOC; + } catch (std::exception &e) { bfinfo << bfendl; diff --git a/tools/scripts/setup_ubuntu.sh b/tools/scripts/setup_ubuntu.sh index cb346066..26211f88 100755 --- a/tools/scripts/setup_ubuntu.sh +++ b/tools/scripts/setup_ubuntu.sh @@ -66,11 +66,11 @@ install_apt_tools() { } add_cmake_repositories() { - sudo add-apt-repository ppa:george-edison55/cmake-3.x + sudo add-apt-repository ppa:george-edison55/cmake-3.x -y } add_gcc_repositories() { - sudo add-apt-repository ppa:ubuntu-toolchain-r/test + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y } add_docker_repositories() { @@ -93,12 +93,15 @@ install_common_packages() { sudo DEBIAN_FRONTEND=noninteractive apt-get install --yes -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" docker-engine } -install_g++-5() { - sudo apt-get install --yes g++-5 +install_g++-6() { + sudo apt-get update + sudo apt-get install --yes gcc-snapshot + sudo apt-get install --yes gcc-6 + sudo apt-get install --yes g++-6 sudo rm /usr/bin/gcc sudo rm /usr/bin/g++ - sudo ln -s /usr/bin/gcc-5 /usr/bin/gcc - sudo ln -s /usr/bin/g++-5 /usr/bin/g++ + sudo ln -s /usr/bin/gcc-6 /usr/bin/gcc + sudo ln -s /usr/bin/g++-6 /usr/bin/g++ } prepare_docker() { @@ -159,7 +162,7 @@ case $(lsb_release -sr) in add_gcc_repositories add_docker_repositories install_common_packages - install_g++-5 + install_g++-6 prepare_docker ;;