mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 07:23:20 +00:00

Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016. The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021: Number of commits on the main branch: 2930 Number of contributors: 31 Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
347 lines
9.4 KiB
C
347 lines
9.4 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
lxtlog.h
|
|
|
|
Abstract:
|
|
|
|
This file contains lx test logging routines.
|
|
|
|
--*/
|
|
|
|
#ifndef _LXT_LOG
|
|
#define _LXT_LOG
|
|
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <stdbool.h>
|
|
|
|
typedef enum _LxtLogType
|
|
{
|
|
LxtLogTypeFile = 0x1,
|
|
LxtLogTypePrintf = 0x2,
|
|
LxtLogTypeStress = 0x4,
|
|
LxtLogTypeMax
|
|
} LxtLogType,
|
|
*PLxtLogType;
|
|
|
|
typedef enum _LxtLogLevel
|
|
{
|
|
LxtLogLevelInfo = 0,
|
|
LxtLogLevelError,
|
|
LxtLogLevelResourceError,
|
|
LxtLogLevelPass,
|
|
LxtLogLevelStart,
|
|
LxtLogLevelMax
|
|
} LxtLogLevel,
|
|
*PLxtLogLevel;
|
|
|
|
#define LXT_LOG_TYPE_DEFAULT_MASK (LxtLogTypeFile | LxtLogTypePrintf)
|
|
|
|
void LxtLog(LxtLogLevel LogLevel, const char* Message, ...);
|
|
|
|
int LxtLogInitialize(const char* TestName, LxtLogType LogTypeMask, bool LogAppend);
|
|
|
|
void LxtLogUninitialize(void);
|
|
|
|
#define LXT_RESULT_SUCCESS (0)
|
|
#define LXT_RESULT_FAILURE (-1)
|
|
#define LXT_SUCCESS(Result) ((Result) != LXT_RESULT_FAILURE)
|
|
|
|
#define LxtLogStart(str, ...) \
|
|
{ \
|
|
LxtLog(LxtLogLevelStart, "START: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
}
|
|
|
|
#define LxtLogInfo(str, ...) \
|
|
{ \
|
|
LxtLog(LxtLogLevelInfo, "INFO: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
}
|
|
|
|
#define LxtLogResourceError(str, ...) \
|
|
{ \
|
|
LxtLog(LxtLogLevelResourceError, "RESOURCE_ERROR: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
}
|
|
|
|
#define LxtLogError(str, ...) \
|
|
{ \
|
|
LxtLog(LxtLogLevelError, "ERROR: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
}
|
|
|
|
#define LxtLogPassed(str, ...) \
|
|
{ \
|
|
LxtLog(LxtLogLevelPass, "PASS: %s:%u: " str "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
|
}
|
|
|
|
#define LxtCheckErrno(fn) \
|
|
{ \
|
|
Result = (fn); \
|
|
if (LXT_SUCCESS(Result) == 0) \
|
|
{ \
|
|
LxtLogError("%s failed: %d (%s)", #fn, errno, strerror(errno)); \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckMapErrno(fn) \
|
|
{ \
|
|
MapResult = (fn); \
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
if (MapResult == MAP_FAILED) \
|
|
{ \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
LxtLogError("%s failed: %s", #fn, strerror(errno)); \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckMapErrnoFailure(_Fn, _ExpectedErrno) \
|
|
{ \
|
|
MapResult = (_Fn); \
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
if (MapResult != MAP_FAILED) \
|
|
{ \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
LxtLogError("%s succeeded, expected errno %d", #_Fn, (_ExpectedErrno)); \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
if (errno != (_ExpectedErrno)) \
|
|
{ \
|
|
LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, _ExpectedErrno, errno, strerror(errno)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckNullErrno(_Fn) \
|
|
{ \
|
|
PointerResult = (_Fn); \
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
if (PointerResult == NULL) \
|
|
{ \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
LxtLogError("%s failed: %s", #_Fn, strerror(errno)); \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckNullErrnoFailure(_Fn, _ExpectedErrno) \
|
|
{ \
|
|
PointerResult = (_Fn); \
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
if (PointerResult != NULL) \
|
|
{ \
|
|
LxtLogError("%s succeeded, expected errno %d", #_Fn, (_ExpectedErrno)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
if (errno != (_ExpectedErrno)) \
|
|
{ \
|
|
LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, _ExpectedErrno, errno, strerror(errno)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
//
|
|
// The following macro is for functions where 0 is the only valid success value
|
|
// (they don't return a pid or fd or anything), and where errno is set if an
|
|
// error occurs.
|
|
//
|
|
|
|
#define LxtCheckErrnoZeroSuccess(_Fn) \
|
|
{ \
|
|
Result = (_Fn); \
|
|
if (Result != LXT_RESULT_SUCCESS) \
|
|
{ \
|
|
if (LXT_SUCCESS(Result) != 0) \
|
|
{ \
|
|
LxtLogError("%s succeeded with %d, expected 0.", #_Fn, Result); \
|
|
} \
|
|
else \
|
|
{ \
|
|
LxtLogError("%s failed: %d, errno %d (%s)", #_Fn, Result, errno, strerror(errno)); \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckErrnoFailure(_Fn, _ExpectedErrno) \
|
|
{ \
|
|
Result = (_Fn); \
|
|
if ((LXT_SUCCESS(Result) != 0)) \
|
|
{ \
|
|
LxtLogError("%s succeeded with %d, expected errno %d", #_Fn, Result, _ExpectedErrno); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
if ((_ExpectedErrno) != errno) \
|
|
{ \
|
|
LxtLogError("%s unexpected failure status: %d, %d != %d (%s)", #_Fn, Result, _ExpectedErrno, errno, strerror(errno)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckEqual(_Val1, _Val2, _Format) \
|
|
{ \
|
|
if ((_Val1) != (_Val2)) \
|
|
{ \
|
|
LxtLogError("{:%s (" _Format ") != %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckGreaterOrEqual(_Val1, _Val2, _Format) \
|
|
{ \
|
|
if ((_Val1) < (_Val2)) \
|
|
{ \
|
|
LxtLogError("{:%s (" _Format ") < %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckNotEqual(_Val1, _Val2, _Format) \
|
|
{ \
|
|
if ((_Val1) == (_Val2)) \
|
|
{ \
|
|
LxtLogError("{:%s (" _Format ") == %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckStringEqual(_Val1, _Val2) \
|
|
{ \
|
|
if ((((_Val1) == NULL) && ((_Val2) != NULL)) || (((_Val1) != NULL) && ((_Val2) == NULL)) || \
|
|
(((_Val1) != (_Val2)) && (strcmp((_Val1), (_Val2)) != 0))) \
|
|
{ \
|
|
\
|
|
LxtLogError("%s (\"%s\") != %s (\"%s\")", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckStringNotEqual(_Val1, _Val2) \
|
|
{ \
|
|
if (strcmp((_Val1), (_Val2)) == 0) \
|
|
{ \
|
|
LxtLogError("%s (\"%s\") == %s (\"%s\")", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckGreater(_Val1, _Val2, _Format) \
|
|
{ \
|
|
if ((_Val1) <= (_Val2)) \
|
|
{ \
|
|
LxtLogError("{:%s (" _Format ") <= %s (" _Format "):}", #_Val1, (_Val1), #_Val2, (_Val2)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckMemoryEqual(_Ptr1, _Ptr2, _Size) \
|
|
{ \
|
|
Result = LxtCompareMemory((_Ptr1), (_Ptr2), (_Size), #_Ptr1, #_Ptr2); \
|
|
if (Result < 0) \
|
|
{ \
|
|
LxtLogError("Memory contents were not equal"); \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckTrue(_Val) \
|
|
{ \
|
|
if ((_Val) == FALSE) \
|
|
{ \
|
|
LxtLogError("The expression (" #_Val ") does not equal true"); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#define LxtCheckResult(fn) \
|
|
{ \
|
|
Result = (fn); \
|
|
if (LXT_SUCCESS(Result) == 0) \
|
|
{ \
|
|
LxtLogError("%s failed", #fn); \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
//
|
|
// Macro for functions that return a positive error value on failure, like
|
|
// pthread functions.
|
|
//
|
|
|
|
#define LxtCheckResultError(_Fn) \
|
|
{ \
|
|
Result = (_Fn); \
|
|
if (Result != 0) \
|
|
{ \
|
|
LxtLogError("%s failed: %d (%s)", #_Fn, Result, strerror(Result)); \
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
}
|
|
|
|
#define LxtCheckResultErrorFailure(_Fn, _ExpectedErrno) \
|
|
{ \
|
|
Result = (_Fn); \
|
|
if (Result == 0) \
|
|
{ \
|
|
LxtLogError("%s succeeded, expected errno %d", #_Fn, _ExpectedErrno); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
if ((_ExpectedErrno) != Result) \
|
|
{ \
|
|
LxtLogError("%s unexpected failure status: %d != %d (%s)", #_Fn, (_ExpectedErrno), Result, strerror(Result)); \
|
|
\
|
|
Result = LXT_RESULT_FAILURE; \
|
|
goto ErrorExit; \
|
|
} \
|
|
\
|
|
Result = LXT_RESULT_SUCCESS; \
|
|
}
|
|
|
|
#endif // _LXT_LOG
|