Bad Alloc Testing

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”>
This commit is contained in:
“Rian 2016-09-05 07:07:26 -06:00
parent acd0aaceb9
commit 5b01e8ce80
9 changed files with 68 additions and 13 deletions

View file

@ -25,13 +25,13 @@
#include <abort.h>
#include <stdint.h>
inline uint64_t abs(int64_t value)
inline uint64_t bfabs(int64_t value)
{ return value >= 0 ? static_cast<uint64_t>(value) : static_cast<uint64_t>(-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;

View file

@ -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;

View file

@ -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();
};

View file

@ -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<vcpu_manager>();
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<vcpu_manager>();
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()
{

View file

@ -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));
}

View file

@ -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
################################################################################

View file

@ -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:

View file

@ -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;

View file

@ -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
;;