//----------------------------------------------------------------------------------------------------------------------
/// \file
/// Common classes and macros for debugging.
// Copyright (c) Microsoft Corporation. All Rights Reserved.
//----------------------------------------------------------------------------------------------------------------------
#if !defined(__WEXDEBUG_H__) && defined(_WIN32)
#define __WEXDEBUG_H__
#include "Wex.Common.h"
#include "WexTypes.h"
#pragma warning(push)
#pragma warning(disable:4481)
#pragma push_macro("Assert")
#undef Assert
#pragma push_macro("Debug")
#undef Debug
/// \internal
///
/// Define __WFILE__ and __WFUNCTION__ macros; do not use __FILEW__ and __FUNCTIONW__ names since STL
/// uses macros with the same names, but does not check if they exist before defining them
///
#if !defined(WIDEN2)
#define WIDEN2(x) L ## x
#endif
#if !defined(WIDEN)
#define WIDEN(x) WIDEN2(x)
#endif
#if !defined(__WFILE__)
#define __WFILE__ WIDEN(__FILE__)
#endif
#if !defined(__WFUNCTION__)
#if defined(_WIN32)
#define __WFUNCTION__ WIDEN(__FUNCTION__)
#else
#define __WFUNCTION__ L""
#endif
#endif
#if !defined(UNREFERENCED_PARAMETER)
#define UNREFERENCED_PARAMETER(P) (P)
#endif
namespace WEX { namespace Common
{
///
/// Flags for GetStack stackFormats parameter
///
///
/// The flags are combinable with the | operator
///
namespace CallStackFormat
{
/// Displays only functionModule!functionName for each frame.
const extern WEXCOMMON_API DWORD Default;
/// Show return, previous frame and other relevant address values for each frame.
const extern WEXCOMMON_API DWORD FrameAddress;
/// This option is currently ignored.
const extern WEXCOMMON_API DWORD FunctionInfo;
/// Displays source line information for each frame of the stack trace.
const extern WEXCOMMON_API DWORD SourceLine;
/// Shows frame numbers.
const extern WEXCOMMON_API DWORD FrameNumbers;
/// This option is currently ignored.
const extern WEXCOMMON_API DWORD Parameters;
/// Shows column names.
const extern WEXCOMMON_API DWORD ColumnNames;
/// Shows frame-to-frame memory usage.
const extern WEXCOMMON_API DWORD FrameMemoryUsage;
/// Shows all available information. This is equivalent to Default | FrameAddress | FunctionInfo | SourceLine
/// | FrameNumbers | Parameters | ColumnNames | FrameMemoryUsage.
const extern WEXCOMMON_API DWORD FullInfo;
}
///
/// Flags for SaveDump miniDumpFormats parameter
///
///
/// The flags are combinable with the | operator
///
namespace MiniDumpFormat
{
/// Include process memory, stacks, etc - enough for most scenarios
const extern WEXCOMMON_API DWORD Default;
/// Packages dump into a CAB file
const extern WEXCOMMON_API DWORD WriteCab;
/// When creating a CAB adds secondary files such as current symbols and mapped images; takes very long time to complete
const extern WEXCOMMON_API DWORD WriteCabSecondaryFiles;
/// Adds full memory data. All accessible committed pages owned by the target application will be included
const extern WEXCOMMON_API DWORD FullMemory;
/// Adds data about the handles that are associated with the target application
const extern WEXCOMMON_API DWORD HandleData;
/// Adds unloaded module information
const extern WEXCOMMON_API DWORD UnloadedModules;
/// Adds indirect memory, a small region of memory that surrounds any address that is referenced by a pointer on the stack or backing store is included
const extern WEXCOMMON_API DWORD IndirectMemory;
/// Adds all data segments within the executable images
const extern WEXCOMMON_API DWORD DataSegments;
/// Adds the process environment block (PEB) and thread environment block (TEB). This flag can be used to provide Windows system information for threads and processes.
const extern WEXCOMMON_API DWORD ProcessThreadData;
/// Adds all committed private read-write memory pages
const extern WEXCOMMON_API DWORD PrivateReadWriteMemory;
/// Adds all basic memory information. The information for all memory is included, not just valid memory, which allows the debugger to reconstruct the complete virtual memory layout from the Minidump
const extern WEXCOMMON_API DWORD FullMemoryInfo;
/// Adds additional thread information, which includes execution time, start time, exit time, start address, and exit status
const extern WEXCOMMON_API DWORD ThreadInfo;
/// Adds all code segments with the executable images
const extern WEXCOMMON_API DWORD CodeSegments;
/// Creates a mixed / managed process actionable dump (alias to FullMemory)
const extern WEXCOMMON_API DWORD ManagedDump;
/// FullMemory | HandleData | FullMemoryInfo | ThreadInfo | UnloadedModules | CodeSegments | IndirectMemory
const extern WEXCOMMON_API DWORD FullDump;
}
class NoThrowString;
///
/// Debugger related operations helper class
///
class WEXCOMMON_API Debug final
{
public:
///
/// Assert when a given condition is false
///
/// Assert condition
/// Assert condition string
/// Assert message
/// Assert source file name
/// Assert source function name
/// Assert souce line number
static void WEXCOMMON_STDCALL Assert(bool condition, const wchar_t* pszCondition, const wchar_t* pszMessage,
const wchar_t* pszFile, const wchar_t* pszFunction, int line);
///
/// Causes a breakpoint in the code
///
static void WEXCOMMON_STDCALL Break();
///
/// Checks whether a debugger is present on the system
///
/// true if a debugger found under AEDebug
static bool WEXCOMMON_STDCALL IsDebuggerPresent();
// SaveDump and GetStack require dbgeng.dll and dbghelp.dll of version 6.x or above
// to exist in the LoadLibrary search path
// If older version found, NTE_BAD_VER error is returned
///
/// Creates a minidump for the current process and saves it in the process local directory
///
/// The full path to the minidump file (set on success)
/// Success of saving a dump
static HRESULT WEXCOMMON_STDCALL SaveDump(NoThrowString& savedDumpFilePath);
///
/// Creates a minidump for the current process and saves it in the process local directory
///
/// See the values in namespace MiniDumpFormat above for miniDumpFormat parameter
/// The full path to the minidump file (set on success)
/// Success of saving a dump
static HRESULT WEXCOMMON_STDCALL SaveDump(DWORD miniDumpFormat, NoThrowString& savedDumpFilePath);
///
/// Obtains the call stack for the context in capturedStack
///
/// The captured stack value
/// Success of capturing stack
static HRESULT WEXCOMMON_STDCALL GetStack(NoThrowString& capturedStack);
///
/// Obtains the call stack for the context in capturedStack
///
/// See the values in namespace CallStackFormat above for stackFormat parameter
/// The captured stack value
/// Success of capturing stack
static HRESULT WEXCOMMON_STDCALL GetStack(DWORD stackFormat, NoThrowString& capturedStack);
///
/// Obtains the call stack for the specified context in capturedStack
///
/// A pointer to the CONTEXT to get the stack for. Note that we want to avoid including in this header, so this is typed to const void*.
/// The captured stack value
/// Success of capturing stack
static HRESULT WEXCOMMON_STDCALL GetStack(const void* context, NoThrowString& capturedStack);
///
/// Obtains the call stack for the specified context in capturedStack
///
/// See the values in namespace CallStackFormat above for stackFormat parameter
/// A pointer to the CONTEXT to get the stack for. Note that we want to avoid including in this header, so this is typed to const void*.
/// The captured stack value
/// Success of capturing stack
static HRESULT WEXCOMMON_STDCALL GetStack(DWORD stackFormat, const void* context, NoThrowString& capturedStack);
///
/// Returns the last 'Win32' error - acting as a compiler firewall so that the Verify classes don't have to depend on Windows.h
///
/// The calling thread's last error code.
static DWORD WEXCOMMON_STDCALL GetLastError();
///
/// Sets the last 'Win32' error - acting as a compiler firewall so that the Verify classes don't have to depend on Windows.h
///
/// The error code to set for the calling thread.
static void WEXCOMMON_STDCALL SetLastError(unsigned long lastError);
///
/// Sends text to debug output.
///
///
/// The text will only be written on a 'debug' build.
///
/// The message to be sent
static void WEXCOMMON_STDCALL Write(const wchar_t* pszString)
{
#if !defined(NDEBUG)
Debug::WriteImpl(pszString);
#else
UNREFERENCED_PARAMETER(pszString);
#endif
}
///
/// Sends text to debug output. Each text message ends with a new line
///
///
/// The text will only be written on a 'debug' build.
///
/// The message to be sent
static void WEXCOMMON_STDCALL WriteLine(const wchar_t* pszString)
{
#if !defined(NDEBUG)
Debug::WriteLineImpl(pszString);
#else
UNREFERENCED_PARAMETER(pszString);
#endif
}
// unsigned short exports
#if defined(WEXCOMMON_FULL_BUILD)
static void WEXCOMMON_STDCALL Assert(bool condition, const unsigned short* pszCondition, const unsigned short* pszMessage,
const unsigned short* pszFile, const unsigned short* pszFunction, int line);
static void WEXCOMMON_STDCALL Write(const unsigned short* pszString)
{
# if !defined(NDEBUG)
Debug::WriteImpl(reinterpret_cast(pszString));
# else
UNREFERENCED_PARAMETER(pszString);
# endif
}
static void WEXCOMMON_STDCALL WriteLine(const unsigned short* pszString)
{
# if !defined(NDEBUG)
Debug::WriteLineImpl(reinterpret_cast(pszString));
# else
UNREFERENCED_PARAMETER(pszString);
# endif
}
#endif // #if defined(WEXCOMMON_FULL_BUILD)
private:
Debug() = delete;
Debug(const Debug&) = delete;
Debug& operator=(const Debug&) = delete;
static void WEXCOMMON_STDCALL WriteImpl(const wchar_t* pszString);
static void WEXCOMMON_STDCALL WriteLineImpl(const wchar_t* pszString);
// unsigned short exports
#if defined(WEXCOMMON_FULL_BUILD)
static void WEXCOMMON_STDCALL WriteImpl(const unsigned short* pszString);
static void WEXCOMMON_STDCALL WriteLineImpl(const unsigned short* pszString);
#endif
static const bool c_fullDebug;
};
}/* namespace Common */}/* namespace WEX */
#pragma pop_macro("Debug")
#pragma pop_macro("Assert")
#pragma warning(pop)
#endif // #if !defined(__WEXDEBUG_H__) && defined(_WIN32)