Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

360 lines
7.1 KiB

// test : test program for multithreaded stack walk
//
#include <stdio.h>
#include <windows.h>
#include <dbghelp.h>
#ifndef _WIN64
CRITICAL_SECTION g_cs;
BOOL CALLBACK cbEnumSym(
PSYMBOL_INFO si,
ULONG size,
PVOID context
)
{
// printf("%s ", si->Name);
return TRUE;
}
BOOL CALLBACK cbEnumMods(
PSTR name,
DWORD64 base,
PVOID context
)
{
HANDLE hp = (HANDLE)context;
SymEnumSymbols(hp, base, "*", cbEnumSym, NULL);
return TRUE;
}
BOOL
cbSymbol(
HANDLE hProcess,
ULONG ActionCode,
ULONG64 CallbackData,
ULONG64 UserContext
)
{
PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl;
PIMAGEHLP_CBA_READ_MEMORY prm;
IMAGEHLP_MODULE64 mi;
PUCHAR p;
ULONG i;
idsl = (PIMAGEHLP_DEFERRED_SYMBOL_LOAD64) CallbackData;
switch ( ActionCode ) {
case CBA_DEBUG_INFO:
printf("%s", (LPSTR)CallbackData);
break;
#if 0
case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
if (fControlC)
{
fControlC = 0;
return TRUE;
}
break;
#endif
case CBA_DEFERRED_SYMBOL_LOAD_START:
printf("loading symbols for %s\n", idsl->FileName);
break;
case CBA_DEFERRED_SYMBOL_LOAD_FAILURE:
if (idsl->FileName && *idsl->FileName)
printf( "*** Error: could not load symbols for %s\n", idsl->FileName );
else
printf( "*** Error: could not load symbols [MODNAME UNKNOWN]\n");
break;
case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
printf("loaded symbols for %s\n", idsl->FileName);
SymEnumSymbols(hProcess, idsl->BaseOfImage, "*", cbEnumSym, NULL);
break;
case CBA_SYMBOLS_UNLOADED:
printf("unloaded symbols for %s\n", idsl->FileName);
break;
#if 1
case CBA_READ_MEMORY:
prm = (PIMAGEHLP_CBA_READ_MEMORY)CallbackData;
return ReadProcessMemory(GetCurrentProcess(),
(LPCVOID)prm->addr,
prm->buf,
prm->bytes,
prm->bytesread);
#endif
default:
return FALSE;
}
return FALSE;
}
BOOL CALLBACK
MyReadProcessMemory(
HANDLE hProcess, // handle to the process
DWORD lpBaseAddress, // base of memory area
LPVOID lpBuffer, // data buffer
DWORD nSize, // number of bytes to read
LPDWORD lpNumberOfBytesRead) // number of bytes read
{
DWORD i = 0;
BOOL fRet = FALSE;
if (nSize == 0)
{
fRet = TRUE;
goto Exit;
}
//
// Try to read as much as possible
//
__try
{
for (i = 0; i < nSize; i++)
{
((PBYTE)lpBuffer)[i] = *((PBYTE)lpBaseAddress + i);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
//
// We have a partial read in this case
//
}
if (lpNumberOfBytesRead)
{
*lpNumberOfBytesRead = i;
}
fRet = (i > 0);
Exit:
return fRet;
}
VOID
GetStack()
{
BOOL fRet = FALSE;
HANDLE hProcess = GetCurrentProcess();
HANDLE hThread = GetCurrentThread();
DWORD dwStackDepth = 0;
DWORD i = 0;
DWORD dwStackAddr[16];
CONTEXT Context;
STACKFRAME StackFrame;
//
// First initialize data used by the
// stack walker
//
ZeroMemory(&Context, sizeof(CONTEXT));
Context.ContextFlags = CONTEXT_FULL;
ZeroMemory(&StackFrame, sizeof(STACKFRAME));
fRet = GetThreadContext(hThread, &Context);
if (!fRet)
{
printf("Could not get the thread context -0x%x\n", GetLastError());
goto Exit;
}
//
// Fill in our stack frame
//
StackFrame.AddrStack.Mode = AddrModeFlat;
StackFrame.AddrFrame.Mode = AddrModeFlat;
StackFrame.AddrPC.Mode = AddrModeFlat;
__asm
{
mov StackFrame.AddrStack.Offset, esp;
mov StackFrame.AddrFrame.Offset, ebp;
mov StackFrame.AddrPC.Offset, offset DummyLabel;
DummyLabel:
}
//
// Start walking the stack.
//
while (dwStackDepth < 16)
{
fRet = StackWalk(
IMAGE_FILE_MACHINE_I386, // MachineType
hProcess, // Current process
hThread, // Current thread
&StackFrame, // StackFrame
&Context, // ContextRecord - can be NULL for x86
&MyReadProcessMemory, // use our own read process memory
&SymFunctionTableAccess, // FunctionTableAccessRoutine
&SymGetModuleBase, // GetModuleBaseRoutine
NULL); // TranslateAddressProc
if (!fRet)
{
break;
}
dwStackAddr[dwStackDepth] = StackFrame.AddrPC.Offset;
dwStackDepth++;
}
EnterCriticalSection(&g_cs);
printf("\nThread: 0x%x\n", GetCurrentThreadId());
for (i = 0; i < dwStackDepth; i++)
{
printf("\t-0x%x\n", dwStackAddr[i]);
}
LeaveCriticalSection(&g_cs);
SymEnumerateModules64(hProcess, cbEnumMods, hProcess);
Exit:
fflush(stdout);
return;
}
VOID
Dummy2()
{
ULONG ul = (GetCurrentThreadId() % 2);
if (ul == 0)
{
GetStack();
}
else
return;
}
VOID
Dummy1()
{
ULONG ul = (GetCurrentThreadId() % 5);
if (ul == 0 || ul == 4)
{
Dummy2();
}
else
{
GetStack();
}
GetStack();
}
DWORD WINAPI
DwThreadFn(
LPVOID pvParam)
{
ULONG ul = (GetCurrentThreadId() % 7);
if (ul == 3 || ul == 1 || ul == 5 || ul == 6)
{
GetStack();
Dummy1();
}
else
{
Dummy2();
}
GetStack();
return 0;
}
#define THREAD_COUNT MAXIMUM_WAIT_OBJECTS
int __cdecl main(int argc, char* argv[])
{
int i = 0;
HANDLE rghThread[THREAD_COUNT] = {0};
InitializeCriticalSection(&g_cs);
#if 0
if (argc < 2 || argv[1] == NULL)
{
printf("usage: s.exe <sympath>\n");
goto Exit;
}
#endif
printf("Starting test!\n");
//
// Initialize the symbols handler
//
SymSetOptions(SymGetOptions() | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES |
SYMOPT_DEFERRED_LOADS | SYMOPT_DEBUG);
if (!SymInitialize(
GetCurrentProcess(), // hProcess
NULL, // UserSearchPath
TRUE))
{
printf("Cannot initialize the symbols - 0x%x!\n", GetLastError());
goto Exit;
}
SymRegisterCallback64(GetCurrentProcess(), cbSymbol, 0);
printf("Creating %u threads!\n", THREAD_COUNT);
for (i = 0; i < THREAD_COUNT; i++)
{
rghThread[i] = CreateThread(
NULL,
0,
&DwThreadFn,
NULL,
CREATE_SUSPENDED,
NULL);
if (!rghThread[i])
{
printf("Cannot create thread - 0x%x", GetLastError());
}
else printf("Created thread %x\n", rghThread[i]);
}
//
// Now resume all threads
//
for (i = 0; i < THREAD_COUNT; i++)
{
ResumeThread(rghThread[i]);
}
//
// Wait for the threads to finish
//
WaitForMultipleObjects(THREAD_COUNT, rghThread, TRUE, INFINITE);
for (i = 0; i < THREAD_COUNT; i++)
{
CloseHandle(rghThread[i]);
}
printf("Test finished!\n");
Exit:
DeleteCriticalSection(&g_cs);
return 0;
}
#else
int __cdecl main(int argc, char* argv[])
{
printf("storm.exe is not implemented for 64 bit platforms.\n");
return 0;
}
#endif // #ifndef _WIN64