tst: fscrash: WIP

This commit is contained in:
Bill Zissimopoulos 2016-11-04 00:03:30 -07:00
parent aae6a15e5a
commit 1a43619c5e

View File

@ -23,13 +23,16 @@
#include "fscrash.h" #include "fscrash.h"
#include "memfs.h" #include "memfs.h"
#define fail(format, ...) fprintf(stderr, format, __VA_ARGS__) #define fail(format, ...) fprintf(stderr, format "\n", __VA_ARGS__)
#define ASSERT(expr) \ #define ASSERT(expr) \
(!(expr) ? \ (!(expr) ? \
(fail("ASSERT(%s) failed at %s:%d:%s\n", #expr, __FILE__, __LINE__, __func__), abort()) :\ (fail("ASSERT(%s) failed at %s:%d:%s\n", #expr, __FILE__, __LINE__, __func__), exit(1)) :\
(void)0) (void)0)
/* do not use abort() in ASSERT to avoid Windows error dialogs */
VOID Test(PWSTR Prefix) #define FSCRASH_EVENT_NAME "fscrash-626ECD8572604254A690C31D563B244C"
static VOID Test(PWSTR Prefix)
{ {
static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)"; static PWSTR Sddl = L"D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;WD)";
static const GUID ReparseGuid = static const GUID ReparseGuid =
@ -157,9 +160,54 @@ VOID Test(PWSTR Prefix)
LocalFree(SecurityDescriptor); LocalFree(SecurityDescriptor);
} }
static NTSTATUS CreateTestProcess(PWSTR GlobalRoot, PWSTR Prefix, PHANDLE PProcess)
{
WCHAR Executable[MAX_PATH];
WCHAR CommandLine[1024];
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
HANDLE Event;
DWORD WaitResult, ExitCode = -1, MaxTries = 5;
*PProcess = 0;
GetModuleFileName(0, Executable, MAX_PATH);
wsprintfW(CommandLine, L"%s --run-test=%s%s",
GetCommandLineW(), GlobalRoot, Prefix);
Event = CreateEventW(0, TRUE, FALSE, L"" FSCRASH_EVENT_NAME);
if (0 == Event)
return FspNtStatusFromWin32(GetLastError());
memset(&StartupInfo, 0, sizeof StartupInfo);
memset(&ProcessInfo, 0, sizeof ProcessInfo);
StartupInfo.cb = sizeof StartupInfo;
if (!CreateProcessW(Executable, CommandLine, 0, 0, FALSE, 0, 0, 0, &StartupInfo, &ProcessInfo))
return FspNtStatusFromWin32(GetLastError());
CloseHandle(ProcessInfo.hThread);
do
{
WaitResult = WaitForSingleObject(Event, 1000);
GetExitCodeProcess(ProcessInfo.hProcess, &ExitCode);
} while (WAIT_TIMEOUT == WaitResult && 0 != --MaxTries && STILL_ACTIVE == ExitCode);
if (WAIT_OBJECT_0 != WaitResult)
{
CloseHandle(ProcessInfo.hProcess);
return STATUS_UNSUCCESSFUL;
}
*PProcess = ProcessInfo.hProcess;
return STATUS_SUCCESS;
}
ULONG OptCrashMask = -1, OptCrashFlags = FspCrashInterceptAccessViolation, OptCrashPercent = 10; ULONG OptCrashMask = -1, OptCrashFlags = FspCrashInterceptAccessViolation, OptCrashPercent = 10;
ULONG OptMemfsFlags = MemfsDisk; ULONG OptMemfsFlags = MemfsDisk;
ULONG OptIterations = -1; ULONG OptIterations = -1;
PWSTR OptPrefix = 0;
int wmain(int argc, wchar_t **argv) int wmain(int argc, wchar_t **argv)
{ {
@ -172,7 +220,7 @@ int wmain(int argc, wchar_t **argv)
for (int argi = 1; argc > argi; argi++) for (int argi = 1; argc > argi; argi++)
{ {
const wchar_t *a = argv[argi]; wchar_t *a = argv[argi];
if ('-' == a[0]) if ('-' == a[0])
{ {
if (0 == wcsncmp(L"--mask=", a, sizeof "--mask=" - 1)) if (0 == wcsncmp(L"--mask=", a, sizeof "--mask=" - 1))
@ -199,12 +247,17 @@ int wmain(int argc, wchar_t **argv)
OptMemfsFlags = MemfsNet; OptMemfsFlags = MemfsNet;
else if (0 == wcsncmp(L"--iterations=", a, sizeof "--iterations=" - 1)) else if (0 == wcsncmp(L"--iterations=", a, sizeof "--iterations=" - 1))
OptIterations = wcstoul(a + sizeof "--iterations=" - 1, 0, 10); OptIterations = wcstoul(a + sizeof "--iterations=" - 1, 0, 10);
else if (0 == wcsncmp(L"--run-test=", a, sizeof "--run-test=" - 1))
OptPrefix = a + sizeof "--run-test=" - 1;
} }
} }
if (0 == OptPrefix)
{
MEMFS *Memfs; MEMFS *Memfs;
HANDLE Process;
DWORD ExitCode = -1;
NTSTATUS Result; NTSTATUS Result;
WCHAR Prefix[1024];
Result = MemfsCreate( Result = MemfsCreate(
OptMemfsFlags, OptMemfsFlags,
@ -230,19 +283,47 @@ int wmain(int argc, wchar_t **argv)
exit(1); exit(1);
} }
if (0 == (MemfsNet & OptMemfsFlags)) Result = CreateTestProcess(
wsprintfW(Prefix, L"\\\\?\\GLOBALROOT%s", MemfsFileSystem(Memfs)->VolumeName); (MemfsNet & OptMemfsFlags) ? L"" : L"\\\\?\\GLOBALROOT",
else (MemfsNet & OptMemfsFlags) ? L"\\memfs\\share" : MemfsFileSystem(Memfs)->VolumeName,
wsprintfW(Prefix, L"\\memfs\\share"); &Process);
if (!NT_SUCCESS(Result))
for (ULONG Iterations = 0; -1 == OptIterations || OptIterations != Iterations; Iterations++)
{ {
Test(Prefix); fail("cannot create test process: (Status=%lx)", Result);
FspCrash(MemfsFileSystem(Memfs)); /* after one time through, go ahead and crash! */ exit(1);
} }
FspCrash(MemfsFileSystem(Memfs));
WaitForSingleObject(Process, INFINITE);
GetExitCodeProcess(Process, &ExitCode);
CloseHandle(Process);
MemfsStop(Memfs); MemfsStop(Memfs);
MemfsDelete(Memfs); MemfsDelete(Memfs);
if (0 != ExitCode)
{
fail("test process exitcode: %lx", ExitCode);
exit(1);
}
}
else
{
HANDLE Event;
Event = OpenEvent(EVENT_MODIFY_STATE, FALSE, L"" FSCRASH_EVENT_NAME);
if (0 == Event)
{
fail("cannot create test event: (Status=%lx)", FspNtStatusFromWin32(GetLastError()));
exit(1);
}
for (ULONG Iterations = 0; -1 == OptIterations || OptIterations != Iterations; Iterations++)
{
Test(OptPrefix);
SetEvent(Event);
}
}
return 0; return 0;
} }