Skip to content

Commit

Permalink
UnitTestFrameworkPkg/UnitTestLib: Reduce sanitizer false positive
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
mdkinney committed Jan 20, 2025
1 parent ce4f9e4 commit 5eaae04
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,27 @@ extern "C" {
///
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.
Expand All @@ -47,7 +68,8 @@ extern "C" {

if (gUnitTestExpectAssertFailureJumpBuffer != NULL) {
UT_LOG_INFO ("Detected expected ASSERT: %a(%d): %a\n", FileName, LineNumber, Description);
LongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
HostLongJump (gUnitTestExpectAssertFailureJumpBuffer, 1);
UNREACHABLE ();
} else {
if (GetActiveFrameworkHandle () != NULL) {
AsciiStrCpyS (Message, sizeof (Message), "Detected unexpected ASSERT(");
Expand Down
18 changes: 12 additions & 6 deletions UnitTestFrameworkPkg/Library/UnitTestLib/AssertCmocka.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,21 +381,27 @@ UnitTestExpectAssertFailure (
}

if (UnitTestStatus == UNIT_TEST_PASSED) {
UT_LOG_INFO (
"[ASSERT PASS] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) detected expected assert\n",
snprintf (
TempStr,
sizeof (TempStr),
"[ASSERT PASS] %s:%d: UT_EXPECT_ASSERT_FAILURE(%s) detected expected assert\n",
FileName,
LineNumber,
(int)LineNumber,
FunctionCall
);
UT_LOG_INFO (TempStr);
}

if (UnitTestStatus == UNIT_TEST_SKIPPED) {
UT_LOG_WARNING (
"[ASSERT WARN] %a:%d: UT_EXPECT_ASSERT_FAILURE(%a) disabled\n",
snprintf (
TempStr,
sizeof (TempStr),
"[ASSERT WARN] %s:%d: UT_EXPECT_ASSERT_FAILURE(%s) disabled\n",
FileName,
LineNumber,
(int)LineNumber,
FunctionCall
);
UT_LOG_WARNING (TempStr);
}

if (UnitTestStatus == UNIT_TEST_ERROR_TEST_FAILED) {
Expand Down
12 changes: 8 additions & 4 deletions UnitTestFrameworkPkg/Library/UnitTestLib/RunTestsCmocka.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,14 @@ CmockaUnitTestTeardownFunctionRunner (
// stdout and stderr in their xml format
//
if (UnitTest->Log != NULL) {
print_message ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description);
print_message ("Log Output Start\n");
print_message ("%s", UnitTest->Log);
print_message ("Log Output End\n");
//
// UnitTest->Log can be a large buffer that is larger than what DEBUG()
// can support. Use printf() directly.
//
printf ("UnitTest: %s - %s\n", UnitTest->Name, UnitTest->Description);
printf ("Log Output Start\n");
printf (UnitTest->Log);
printf ("Log Output End\n");
}

//
Expand Down

0 comments on commit 5eaae04

Please sign in to comment.