Files
open-gpu-kernel-modules/src/nvidia/inc/libraries/nvport/debug.h
Andy Ritger 90eb10774f 520.61.05
2022-10-10 14:59:24 -07:00

317 lines
9.9 KiB
C

/*
* SPDX-FileCopyrightText: Copyright (c) 2014-2020 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: MIT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* @file
* @brief Debug module public interface
*/
#ifndef _NVPORT_H_
#error "This file cannot be included directly. Include nvport.h instead."
#endif
#ifndef _NVPORT_DEBUG_H_
#define _NVPORT_DEBUG_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup NVPORT_DEBUG Debug Support Routines
* @brief This module provides debug support routines like breakpoints and prints.
* @{
*/
/** @brief See @ref PORT_UTIL_INLINE */
#ifndef PORT_DEBUG_INLINE
#define PORT_DEBUG_INLINE PORT_INLINE
#endif
/**
* @name Core Functions
* @{
*
* @note The breakpoint macro comes in several flavors:
* - @ref PORT_BREAKPOINT -
* Shouldn't be used directly
* - @ref PORT_BREAKPOINT_DEBUG -
* Causes a breakpoint in debug builds only, use for all debug purposes.
* - @ref PORT_BREAKPOINT_CHECKED -
* Causes a breakpoint in checked builds only, use when you want the
* @c int3 present in develop and release builds, such as QA builds.
* - @ref PORT_BREAKPOINT_ALWAYS -
* Always breaks, use only if you want to trigger @c int3 even on
* public release builds.
*/
/**
* @brief Prints a string to a platform dependent output stream
*
* This function will print the string where you would expect it for a given
* platform. In user space it will be standard out. In kernel space it will
* be the kernel debug log.
*
* Note NvPort does not provide advanced logging capabilities, only the ability
* to emit a string. For a more robust logging solution see the NvLog project.
*
*/
PORT_DEBUG_INLINE void portDbgPrintString(const char *str, NvLength length);
/**
* @brief Convenience macro when printing a string literal.
*/
#define PORT_DBG_PRINT_STRING_LITERAL(s) portDbgPrintString(s, sizeof(s)-1)
/**
* @def PORT_BREAKPOINT_DEBUG_ENABLED
* @brief Controls whether @ref PORT_BREAKPOINT_DEBUG is enabled or not
*/
#if !defined(PORT_BREAKPOINT_DEBUG_ENABLED)
#if defined(DEBUG)
#define PORT_BREAKPOINT_DEBUG_ENABLED 1
#else
#define PORT_BREAKPOINT_DEBUG_ENABLED 0
#endif
#endif
/**
* @def PORT_BREAKPOINT_DEBUG
* @brief Cause a breakpoint into the debugger only when
* @ref PORT_BREAKPOINT_DEBUG_ENABLED is defined.
*
* By default PORT_BREAKPOINT_DEBUG_ENABLED is set based on the value of DEBUG.
* However it is kept as a separate define so you can override separately if so
* desired.
*/
#if PORT_BREAKPOINT_DEBUG_ENABLED
#define PORT_BREAKPOINT_DEBUG PORT_BREAKPOINT
#else
#define PORT_BREAKPOINT_DEBUG()
#endif
#define PORT_FILE_STR __FILE__
/// @cond NVPORT_INTERNAL
#if !defined(PORT_ASSERT_FAILED_USES_STRINGS)
#define PORT_ASSERT_FAILED_USES_STRINGS PORT_IS_CHECKED_BUILD
#endif
#if PORT_ASSERT_FAILED_USES_STRINGS
#define _PORT_STRINGIFY2(x) #x
#define _PORT_STRINGIFY(x) _PORT_STRINGIFY2(x)
#define _PORT_ASSERT_MESSAGE(cond) "Assertion failed: \"" #cond "\" at " \
PORT_FILE_STR ":" _PORT_STRINGIFY(__LINE__) "\n"
#else
#define _PORT_ASSERT_MESSAGE(cond) "Assertion failed"
#endif
/// @endcond
/**
* @brief Causes a breakpoint if the condition evaluates to false.
*/
#define PORT_ASSERT(cond) \
do \
{ \
PORT_COVERAGE_PUSH_OFF(); \
if (!(cond)) \
{ \
PORT_DBG_PRINT_STRING_LITERAL(_PORT_ASSERT_MESSAGE(cond)); \
PORT_BREAKPOINT(); \
} \
PORT_COVERAGE_POP(); \
} while (0)
/*
* Checks osDbgBreakpointEnabled and PDB_PROP_SYS_DEBUGGER_DISABLED
* to see if breakpoints are allowed
*/
NvBool nvDbgBreakpointEnabled(void);
/**
* @def PORT_BREAKPOINT_CHECKED()
* @brief Causes a breakpoint in checked builds only
*/
/**
* @def PORT_ASSERT_CHECKED(x)
* @brief Causes an assert in checked builds only
*/
#if PORT_IS_CHECKED_BUILD
/*
* TODO: defined(NVRM) && PORT_IS_KERNEL_BUILD && defined(NVWATCH) are all true
* when NvWatch is included in the Debug Linux AMD64 Mfg Mods build.
* This seems wrong...
*/
#if defined(NVRM) && PORT_IS_KERNEL_BUILD == 1 && !defined(NVWATCH)
#define PORT_BREAKPOINT_CHECKED() \
do \
{ \
if (nvDbgBreakpointEnabled()) \
PORT_BREAKPOINT(); \
} while (0)
#else
#define PORT_BREAKPOINT_CHECKED() PORT_BREAKPOINT()
#endif
#define PORT_ASSERT_CHECKED(x) PORT_ASSERT(x)
#else // PORT_IS_CHECKED_BUILD
#define PORT_BREAKPOINT_CHECKED()
#define PORT_ASSERT_CHECKED(x)
#endif // PORT_IS_CHECKED_BUILD
/**
* @brief Causes a breakpoint into the debugger regardless of build configuration.
*
* Note this is equivalent to just calling @ref PORT_BREAKPOINT. It is only
* included to provide an alternative to @ref PORT_BREAKPOINT_DEBUG that is
* consistent in look and usage.
*/
#define PORT_BREAKPOINT_ALWAYS PORT_BREAKPOINT
/**
* @def PORT_COVERAGE_PUSH_OFF()
* @brief Saves the current coverage tracking state to a stack and disables it
*
* This is useful to do around some error checking code (e.g. "default:") so the
* bullseye tool doesn't take those branches into account when checking code
* coverage.
*
* - See @ref PORT_ASSERT for usage example.
* - See https://www.bullseye.com/help/build-exclude.html for more details.
*/
/**
* @def PORT_COVERAGE_PUSH_ON()
* @brief Saves the current coverage tracking state to a stack and enables it
*/
/**
* @def PORT_COVERAGE_POP()
* @brief Restores the last saved coverage tracking state
*
* See @ref PORT_ASSERT for usage example.
*/
#if defined(NV_BULLSEYE)
#define PORT_COVERAGE_PUSH_OFF() "BullseyeCoverage save off"
#define PORT_COVERAGE_PUSH_ON() "BullseyeCoverage save on"
#define PORT_COVERAGE_POP() "BullseyeCoverage restore"
#else
#define PORT_COVERAGE_PUSH_OFF()
#define PORT_COVERAGE_PUSH_ON()
#define PORT_COVERAGE_POP()
#endif
/// @} End core functions
/**
* @def NVPORT_CHECK_PRINTF_ARGUMENTS(a,b)
* @brief Compile time check that arguments conform to printf rules
*/
#if PORT_COMPILER_HAS_ATTRIBUTE_FORMAT
#define NVPORT_CHECK_PRINTF_ARGUMENTS(a,b) __attribute__((format(printf, a, b)))
#else
#define NVPORT_CHECK_PRINTF_ARGUMENTS(a,b)
#endif
/**
* @name Extended Functions
* @{
*/
#if !defined(portDbgPrintf_SUPPORTED)
#define portDbgPrintf_SUPPORTED 0
#endif
#if !defined(portDbgExPrintfLevel_SUPPORTED)
#define portDbgExPrintfLevel_SUPPORTED 0
#endif
#if PORT_IS_FUNC_SUPPORTED(portDbgPrintf)
/**
* @brief Prints a formatted string to using @ref portDbgPrintString
*
* The parameters are like those of printf().
*/
PORT_DEBUG_INLINE void portDbgPrintf(const char *format, ...) NVPORT_CHECK_PRINTF_ARGUMENTS(1, 2);
#endif
#if PORT_IS_FUNC_SUPPORTED(portDbgExPrintfLevel)
/**
* @brief Similar to @ref portDbgPrintf, except that it passes the level to the
* underlying implementation.
*
* Some platforms (e.g. MODS) have an API where prints are given a level, and
* some tools may depend on certain prints being at a certain level. This
* function simply passes the level to that API- NvPort does not understand
* or filter these levels.
*
* @param level - An int representing the level at which to print.
*/
PORT_DEBUG_INLINE void portDbgExPrintfLevel(NvU32 level, const char *format, ...) NVPORT_CHECK_PRINTF_ARGUMENTS(2, 3);
#endif
/// @} End extended functions
// Include platform specific inline definitions
#if NVOS_IS_QNX
#include "nvport/inline/debug_qnx.h"
#elif NVOS_IS_DCECORE
#include "nvport/inline/debug_dcecore.h"
#elif defined(GSP_PLUGIN_BUILD)
#include "nvport/inline/debug_vgpu_gsp.h"
#else
#if PORT_IS_KERNEL_BUILD
#if NVOS_IS_WINDOWS
#include "nvport/inline/debug_win_kernel.h"
#elif NVOS_IS_UNIX
#include "nvport/inline/debug_unix_kernel_os.h"
#elif NVOS_IS_LIBOS
#include "nvport/inline/debug_libos.h"
#else
#error "Unsupported target OS"
#endif
#else // Usermode build
#if NVOS_IS_WINDOWS
#include "nvport/inline/debug_win_user.h"
#elif NVOS_IS_UNIX
#include "nvport/inline/debug_unix_user.h"
#elif NVOS_IS_LIBOS
#include "nvport/inline/debug_libos.h"
#else
#error "Unsupported target OS"
#endif
#endif // PORT_IS_KERNEL_BUILD
#endif // NV_MODS
#ifdef __cplusplus
}
#endif //__cplusplus
#endif // _NVPORT_DEBUG_H_
/// @}