mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-07 22:04:27 +02:00
PR #6408 introduced a host specific NORETURN function to resolve false positives from the address sanitizer when LongJump() is called and the stack is reset to a previous stack frame. This approach was discussed here: https://github.com/tianocore/edk2/pull/6408/files#r1918810499 False positives are still being observed with this initial solution. The address sanitizer provides __asan_handle_no_return() to clean up shadow memory before a NORETURN function is called and provides a simpler implementation for this issue without having to introduce a host specific NORETURN function. https://github.com/llvm/llvm-project/blob/main/compiler-rt/include/sanitizer/asan_interface.h Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
86 lines
2.7 KiB
C++
86 lines
2.7 KiB
C++
/** @file
|
|
Unit Test Debug Assert Library for host-based environments
|
|
|
|
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
|
|
**/
|
|
|
|
#include <stdexcept>
|
|
|
|
#ifdef NULL
|
|
#undef NULL
|
|
#endif
|
|
|
|
extern "C" {
|
|
#include <Uefi.h>
|
|
#include <UnitTestFrameworkTypes.h>
|
|
#include <Library/BaseLib.h>
|
|
#include <Library/UnitTestLib.h>
|
|
|
|
//
|
|
// If address sanitizer is enabled, then declare the function that is used to
|
|
// handle custom long jump implementation.
|
|
//
|
|
#ifdef __SANITIZE_ADDRESS__
|
|
void
|
|
__asan_handle_no_return (
|
|
);
|
|
|
|
#endif
|
|
|
|
///
|
|
/// Point to jump buffer used with SetJump()/LongJump() to test if a function
|
|
/// under test generates an expected ASSERT() condition.
|
|
///
|
|
BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL;
|
|
|
|
/**
|
|
Unit test library replacement for DebugAssert() in DebugLib.
|
|
|
|
If FileName is NULL, then a <FileName> string of "(NULL) Filename" is printed.
|
|
If Description is NULL, then a <Description> string of "(NULL) Description" is printed.
|
|
|
|
@param FileName The pointer to the name of the source file that generated the assert condition.
|
|
@param LineNumber The line number in the source file that generated the assert condition
|
|
@param Description The pointer to the description of the assert condition.
|
|
|
|
**/
|
|
VOID
|
|
EFIAPI
|
|
UnitTestDebugAssert (
|
|
IN CONST CHAR8 *FileName,
|
|
IN UINTN LineNumber,
|
|
IN CONST CHAR8 *Description
|
|
)
|
|
{
|
|
CHAR8 Message[256];
|
|
|
|
if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
|
|
UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
|
|
|
|
//
|
|
// If address sanitizer is enabled, then inform sanitizer that a no return
|
|
// function is being called that will reset to a previous stack frame.
|
|
// This is required to avoid false positives from the address sanitizer
|
|
// due to the use of a custom long jump implementation.
|
|
//
|
|
#ifdef __SANITIZE_ADDRESS__
|
|
__asan_handle_no_return ();
|
|
#endif
|
|
|
|
LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
|
|
} else {
|
|
if (GetActiveFrameworkHandle () != NULL) {
|
|
AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");
|
|
AsciiStrCatS (Message, sizeof (Message), Description);
|
|
AsciiStrCatS (Message, sizeof (Message), ")");
|
|
UnitTestAssertTrue (FALSE, "", LineNumber, FileName, Message);
|
|
} else {
|
|
snprintf (Message, sizeof (Message), "Detected unexpected ASSERT: %s(%d): %s\n", FileName, (INT32)(UINT32)LineNumber, Description);
|
|
throw std::runtime_error (Message);
|
|
}
|
|
}
|
|
}
|
|
}
|