sys: add trace functionality

This commit is contained in:
Bill Zissimopoulos 2021-01-13 16:15:06 -08:00
parent 870c54253a
commit a5726c820b
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
6 changed files with 189 additions and 0 deletions

View File

@ -187,6 +187,7 @@
<ClCompile Include="..\..\src\sys\shutdown.c" />
<ClCompile Include="..\..\src\sys\silo.c" />
<ClCompile Include="..\..\src\sys\statistics.c" />
<ClCompile Include="..\..\src\sys\trace.c" />
<ClCompile Include="..\..\src\sys\util.c" />
<ClCompile Include="..\..\src\sys\volinfo.c" />
<ClCompile Include="..\..\src\sys\volume.c" />

View File

@ -125,6 +125,9 @@
<ClCompile Include="..\..\src\sys\silo.c">
<Filter>Source</Filter>
</ClCompile>
<ClCompile Include="..\..\src\sys\trace.c">
<Filter>Source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\src\sys\driver.h">

View File

@ -22,6 +22,10 @@
#include <sys/driver.h>
#if DBG
#undef STATUS_INSUFFICIENT_RESOURCES
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL)
#define SYM(x) case x: return #x;
#define SYMBRC(x) case x: return "[" #x "]";
@ -330,4 +334,5 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result)
NtStatusSym(Result),
(LONGLONG)Irp->IoStatus.Information);
}
#endif

View File

@ -38,6 +38,8 @@ NTSTATUS DriverEntry(
{
FSP_ENTER_DRV();
FSP_TRACE_INIT();
/* setup the driver object */
DriverObject->MajorFunction[IRP_MJ_CREATE] = FspCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FspClose;
@ -157,6 +159,8 @@ exit:
FspSiloFinalize();
if (InitDoneGRes)
ExDeleteResourceLite(&FspDeviceGlobalResource);
FSP_TRACE_FINI();
}
#pragma prefast(suppress:28175, "We are in DriverEntry: ok to access DriverName")

View File

@ -147,6 +147,40 @@ VOID FspDebugLogIrp(const char *func, PIRP Irp, NTSTATUS Result);
#define DEBUGTEST_EX(C, Percent, Deflt) (Deflt)
#endif
/* trace */
#if FSP_TRACE_ENABLED
VOID FspTraceInitialize(VOID);
VOID FspTraceFinalize(VOID);
VOID FspTrace(const char *file, int line, const char *func);
VOID FspTraceNtStatus(const char *file, int line, const char *func, NTSTATUS Status);
#define FSP_TRACE_INIT() \
(FspTraceInitialize(), FSP_TRACE())
#define FSP_TRACE_FINI() \
(FSP_TRACE(), FspTraceFinalize())
#define FSP_TRACE() \
FspTrace( \
__FILE__, \
__LINE__, \
__FUNCTION__)
#define FSP_TRACE_NTSTATUS(Status) \
FspTraceNtStatus( \
__FILE__, \
__LINE__, \
__FUNCTION__, \
Status)
#else
#define FSP_TRACE_INIT() \
((VOID)0)
#define FSP_TRACE_FINI() \
((VOID)0)
#define FSP_TRACE() \
((VOID)0)
#define FSP_TRACE_NTSTATUS(Result) \
((VOID)0)
#endif
#undef STATUS_INSUFFICIENT_RESOURCES
#define STATUS_INSUFFICIENT_RESOURCES (FSP_TRACE_NTSTATUS(0xC000009AL), (NTSTATUS)0xC000009AL)
/* FSP_ENTER/FSP_LEAVE */
#if DBG
#define FSP_DEBUGLOG_(fmt, rfmt, ...) \

142
src/sys/trace.c Normal file
View File

@ -0,0 +1,142 @@
/**
* @file sys/trace.c
*
* @copyright 2015-2020 Bill Zissimopoulos
*/
/*
* This file is part of WinFsp.
*
* You can redistribute it and/or modify it under the terms of the GNU
* General Public License version 3 as published by the Free Software
* Foundation.
*
* Licensees holding a valid commercial license may use this software
* in accordance with the commercial license agreement provided in
* conjunction with the software. The terms and conditions of any such
* commercial license agreement shall govern, supersede, and render
* ineffective any application of the GPLv3 license to this software,
* notwithstanding of any reference thereto in the software or
* associated repository.
*/
#include <sys/driver.h>
#if FSP_TRACE_ENABLED
#undef STATUS_INSUFFICIENT_RESOURCES
#define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS)0xC000009AL)
static struct
{
HANDLE Handle;
PKEVENT Event;
} FspLowMemoryCondition, FspLowNonPagedPoolCondition, FspLowPagedPoolCondition;
VOID FspTrace(const char *file, int line, const char *func)
{
for (const char *p = file; '\0' != *p; p++)
if ('\\' == *p)
file = p + 1;
ASSERT(DISPATCH_LEVEL >= KeGetCurrentIrql());
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL,
DRIVER_NAME ": %s[%s:%d]\n", func, file, line);
}
VOID FspTraceNtStatus(const char *file, int line, const char *func, NTSTATUS Status)
{
for (const char *p = file; '\0' != *p; p++)
if ('\\' == *p)
file = p + 1;
ASSERT(DISPATCH_LEVEL >= KeGetCurrentIrql());
BOOLEAN LowMemoryCondition, LowNonPagedPoolCondition, LowPagedPoolCondition;
switch (Status)
{
case STATUS_INSUFFICIENT_RESOURCES:
LowMemoryCondition = 0 != FspLowMemoryCondition.Event &&
!!KeReadStateEvent(FspLowMemoryCondition.Event);
LowNonPagedPoolCondition = 0 != FspLowNonPagedPoolCondition.Event &&
!!KeReadStateEvent(FspLowNonPagedPoolCondition.Event);
LowPagedPoolCondition = 0 != FspLowPagedPoolCondition.Event &&
!!KeReadStateEvent(FspLowPagedPoolCondition.Event);
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL,
DRIVER_NAME ": %s[%s:%d]: STATUS_INSUFFICIENT_RESOURCE (Memory=%c%c%c)\n",
func, file, line,
LowMemoryCondition ? 'M' : '-',
LowNonPagedPoolCondition ? 'N' : '-',
LowPagedPoolCondition ? 'P' : '-');
break;
default:
DbgPrintEx(DPFLTR_DEFAULT_ID, DPFLTR_TRACE_LEVEL,
DRIVER_NAME ": %s[%s:%d]: Status=%lx\n",
func, file, line,
Status);
break;
}
}
static PKEVENT FspOpenEvent(PWSTR Name, PHANDLE PHandle)
{
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES ObjectAttributes;
HANDLE Handle;
PKEVENT Event;
NTSTATUS Result;
*PHandle = 0;
RtlInitUnicodeString(&ObjectName, Name);
InitializeObjectAttributes(&ObjectAttributes,
&ObjectName, OBJ_KERNEL_HANDLE, 0, 0);
Result = ZwOpenEvent(&Handle,
EVENT_ALL_ACCESS, &ObjectAttributes);
if (!NT_SUCCESS(Result))
return 0;
Result = ObReferenceObjectByHandle(Handle,
0, *ExEventObjectType, KernelMode, &Event, 0);
if (!NT_SUCCESS(Result))
{
ZwClose(Handle);
return 0;
}
*PHandle = Handle;
return Event;
}
static VOID FspCloseEvent(PKEVENT Event, HANDLE Handle)
{
if (0 != Event)
ObDereferenceObject(Event);
if (0 != Handle)
ZwClose(Handle);
}
VOID FspTraceInitialize(VOID)
{
#define OPEN_EVENT(NAME) \
(Fsp ## NAME.Event = FspOpenEvent(L"\\KernelObjects\\" #NAME, &Fsp ## NAME.Handle))
OPEN_EVENT(LowMemoryCondition);
OPEN_EVENT(LowNonPagedPoolCondition);
OPEN_EVENT(LowPagedPoolCondition);
#undef OPEN_EVENT
}
VOID FspTraceFinalize(VOID)
{
#define CLOSE_EVENT(NAME) \
(FspCloseEvent(Fsp ## NAME.Event, Fsp ## NAME.Handle), Fsp ## NAME.Event = 0, Fsp ## NAME.Handle = 0)
CLOSE_EVENT(LowMemoryCondition);
CLOSE_EVENT(LowNonPagedPoolCondition);
CLOSE_EVENT(LowPagedPoolCondition);
#undef CLOSE_EVENT
}
#endif