Update abort() for AZURE_ASSERT (#2170)

* remove abort from Core
This commit is contained in:
Victor Vazquez 2021-05-06 15:30:46 -07:00 committed by GitHub
parent 7982417480
commit 08c8147f54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 151 additions and 29 deletions

View File

@ -63,6 +63,7 @@ set(
inc/azure/core/internal/json/json.hpp
inc/azure/core/internal/strings.hpp
inc/azure/core/io/body_stream.hpp
inc/azure/core/azure_assert.hpp
inc/azure/core/base64.hpp
inc/azure/core/case_insensitive_containers.hpp
inc/azure/core/context.hpp
@ -87,6 +88,7 @@ set(
AZURE_CORE_SOURCE
${CURL_TRANSPORT_ADAPTER_SRC}
${WIN_TRANSPORT_ADAPTER_SRC}
src/azure_assert.cpp
src/cryptography/md5.cpp
src/http/bearer_token_authentication_policy.cpp
src/http/http.cpp

View File

@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
/**
* @file
* @brief Provide assert macros to use with pre-conditions.
*
* @remark Asserts are turned ON when `NDEBUG` is NOT defined (for Debug build). For Release build,
* `std::abort()` is directly called if the condition is false, without calling assert().
*
*/
#pragma once
#include "platform.hpp"
#include <cstdlib>
#include <string>
#if defined(NDEBUG)
/*
* NDEBUG = defined = Build is on Release
* Define AZURE_ASSERT to call abort directly on exp == false
*/
#define AZURE_ASSERT(exp) \
do \
{ \
if (!(exp)) \
{ \
std::abort(); \
} \
} while (0)
#define AZURE_ASSERT_MSG(exp, msg) AZURE_ASSERT(exp)
#else
/*
* NDEBUG = NOT defined = Build is on Debug
* Define AZURE_ASSERT to call assert to provide better debug experience.
*/
#include <cassert>
#define AZURE_ASSERT(exp) assert((exp))
#define AZURE_ASSERT_MSG(exp, msg) assert(((void)msg, (exp)))
#endif
[[noreturn]] void AzureNoReturnPath(std::string const& msg);
#define AZURE_ASSERT_FALSE(exp) AZURE_ASSERT(!(exp))
#define AZURE_UNREACHABLE_CODE AzureNoReturnPath("unreachable code!")
#define AZURE_NOT_IMPLEMENTED AzureNoReturnPath("not implemented code!")

View File

@ -8,6 +8,7 @@
#pragma once
#include "azure/core/azure_assert.hpp"
#include "azure/core/datetime.hpp"
#include "azure/core/dll_import_export.hpp"
@ -175,11 +176,9 @@ namespace Azure { namespace Core {
{
if (ptr->Key == key)
{
if (typeid(T) != ptr->ValueType)
{
// type mismatch
std::abort();
}
AZURE_ASSERT_MSG(
typeid(T) == ptr->ValueType, "Type mismatch for Context::TryGetValue().");
outputValue = *reinterpret_cast<const T*>(ptr->Value.get());
return true;
}

View File

@ -8,6 +8,7 @@
#pragma once
#include "azure/core/azure_assert.hpp"
#include "azure/core/nullable.hpp"
#include <string>
@ -111,7 +112,7 @@ public:
break;
}
// Unknown comparison
abort();
AZURE_UNREACHABLE_CODE;
}
/**
@ -137,10 +138,8 @@ public:
*/
const std::string& ToString() const
{
if (!m_value.HasValue())
{
abort();
}
AZURE_ASSERT_MSG(m_value.HasValue(), "Empty ETag, check HasValue() before calling ToString().");
return m_value.Value();
}

View File

@ -8,7 +8,8 @@
#pragma once
#include <cstdlib> // for abort
#include <azure/core/azure_assert.hpp>
#include <new> // for placement new
#include <type_traits>
#include <utility> // for swap and move
@ -220,12 +221,7 @@ public:
*/
const T& Value() const& noexcept
{
if (!m_hasValue)
{
// throwing here prohibited by our guidelines
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
std::abort();
}
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
return m_value;
}
@ -235,12 +231,7 @@ public:
*/
T& Value() & noexcept
{
if (!m_hasValue)
{
// throwing here prohibited by our guidelines
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
std::abort();
}
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
return m_value;
}
@ -250,12 +241,7 @@ public:
*/
T&& Value() && noexcept
{
if (!m_hasValue)
{
// throwing here prohibited by our guidelines
// https://azure.github.io/azure-sdk/cpp_design.html#pre-conditions
std::abort();
}
AZURE_ASSERT_MSG(m_hasValue, "Empty Nullable, check HasValue() first.");
return std::move(m_value);
}

View File

@ -0,0 +1,12 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// SPDX-License-Identifier: MIT
#include "azure/core/azure_assert.hpp"
[[noreturn]] void AzureNoReturnPath(std::string const& msg)
{
// void msg for Release build where Assert is ignored
(void)msg;
AZURE_ASSERT_MSG(false, msg);
std::abort();
}

View File

@ -436,3 +436,23 @@ TEST(Context, Deadline)
EXPECT_EQ(childCtx.GetDeadline(), Azure::DateTime::min());
}
}
TEST(Context, PreCondition)
{
// Get a mismatch type from the context
std::string s("Test String");
Context context;
Context::Key const key;
// New context from previous
auto c2 = context.WithValue(key, s);
int value;
#if defined(NDEBUG)
// Release build won't provide assert msg
ASSERT_DEATH(c2.TryGetValue<int>(key, value), "");
#else
ASSERT_DEATH(c2.TryGetValue<int>(key, value), "Type mismatch for Context::TryGetValue");
#endif
}

View File

@ -232,3 +232,15 @@ TEST(ETag, EqualsWeak)
EXPECT_FALSE(ETag::Equals(weakTagTwo, weakTagtwo, ETag::ETagComparison::Weak));
EXPECT_FALSE(ETag::Equals(weakTagtwo, weakTagTwo, ETag::ETagComparison::Weak));
}
TEST(ETag, PreCondition)
{
ETag emptyTag;
#if defined(NDEBUG)
// Release build won't provide assert msg
ASSERT_DEATH(emptyTag.ToString(), "");
#else
ASSERT_DEATH(emptyTag.ToString(), "Empty ETag");
#endif
}

View File

@ -171,3 +171,39 @@ TEST(Nullable, ValueOr)
// Ensure val2 is still disengaged after call to ValueOr
EXPECT_FALSE(val2);
}
void Foo(int&& rValue) { (void)rValue; }
TEST(Nullable, PreCondition)
{
Nullable<int> emptyNullable;
#if defined(NDEBUG)
// Release build won't provide assert msg
ASSERT_DEATH(auto a = emptyNullable.Value(); (void)a;, "");
#else
ASSERT_DEATH(auto a = emptyNullable.Value(); (void)a;, "Empty Nullable");
#endif
}
TEST(Nullable, PreCondition2)
{
Nullable<int> emptyNullable;
#if defined(NDEBUG)
// Release build won't provide assert msg
ASSERT_DEATH(auto& a = emptyNullable.Value(); (void)a;, "");
#else
ASSERT_DEATH(auto& a = emptyNullable.Value(); (void)a;, "Empty Nullable");
#endif
}
TEST(Nullable, PreCondition3)
{
#if defined(NDEBUG)
// Release build won't provide assert msg
ASSERT_DEATH(Foo(Nullable<int>().Value());, "");
#else
ASSERT_DEATH(Foo(Nullable<int>().Value());, "Empty Nullable");
#endif
}