UnitTestFrameworkPkg/UnitTestLib: Reduce sanitizer false positive

Use snprintf() in host based unit tests to format log messages
and add host specific wrapper for LongJump() that is decorated
with NORETURN to provide hint to address sanitizer that LongJump()
never returns.

Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
This commit is contained in:
Michael D Kinney 2024-10-23 18:43:07 -07:00 committed by mergify[bot]
parent 1c73f0e71d
commit 5f97d5391e
3 changed files with 43 additions and 11 deletions

View File

@ -24,6 +24,27 @@ extern "C" {
/// ///
BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL; BASE_LIBRARY_JUMP_BUFFER *gUnitTestExpectAssertFailureJumpBuffer = NULL;
/**
LongJump wrapper for host-based unit test environments that is declared
NORETURN to avoid false positives from address sanitizer.
@param JumpBuffer A pointer to CPU context buffer.
@param Value The value to return when the SetJump() context is
restored and must be non-zero.
**/
static
VOID
NORETURN
EFIAPI
HostLongJump (
IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer,
IN UINTN Value
)
{
LongJump (JumpBuffer, Value);
UNREACHABLE ();
}
/** /**
Unit test library replacement for DebugAssert() in DebugLib. Unit test library replacement for DebugAssert() in DebugLib.
@ -47,7 +68,8 @@ extern "C" {
if (gUnitTestExpectAssertFailureJumpBuffer != NULL) { if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description); UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1); HostLongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
UNREACHABLE ();
} else { } else {
if (GetActiveFrameworkHandle () != NULL) { if (GetActiveFrameworkHandle () != NULL) {
AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT("); AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");

View File

@ -381,21 +381,27 @@ UnitTestExpectAssertFailure (
} }
if (UnitTestStatus == UNIT_TEST_PASSED) { if (UnitTestStatus == UNIT_TEST_PASSED) {
UT_LOG_INFO ( snprintf (
"[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n", TempStr,
sizeof (TempStr),
"[ASSERT PASS] %s:%d: UT_EXPECT_ASSERT_FAILURE(%s) detected expected assert\n",
FileName, FileName,
LineNumber, (int)LineNumber,
FunctionCall FunctionCall
); );
UT_LOG_INFO (TempStr);
} }
if (UnitTestStatus == UNIT_TEST_SKIPPED) { if (UnitTestStatus == UNIT_TEST_SKIPPED) {
UT_LOG_WARNING ( snprintf (
"[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n", TempStr,
sizeof (TempStr),
"[ASSERT WARN] %s:%d: UT_EXPECT_ASSERT_FAILURE(%s) disabled\n",
FileName, FileName,
LineNumber, (int)LineNumber,
FunctionCall FunctionCall
); );
UT_LOG_WARNING (TempStr);
} }
if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) { if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {

View File

@ -111,10 +111,14 @@ CmockaUnitTestTeardownFunctionRunner (
// stdout and stderr in their xml format // stdout and stderr in their xml format
// //
if (UnitTest->Log != NULL) { if (UnitTest->Log != NULL) {
print_message ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description); //
print_message ("Log Output Start\n"); // UnitTest->Log can be a large buffer that is larger than what DEBUG()
print_message ("%s", UnitTest->Log); // can support. Use printf() directly.
print_message ("Log Output End\n"); //
printf ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description);
printf ("Log Output Start\n");
printf (UnitTest->Log);
printf ("Log Output End\n");
} }
// //