Почему мой код профилирования всегда говорит мне, что компьютер находится в KeFastSystemCallRet()?
Я пытаюсь профилировать отставание в моих рамках; так как я использую MinGW, gprof не работает с DLL (для меня он даже дал мне информацию о мусоре, такую как функция инициализации, выполняемая тысячи раз вместо одного раза), а профилировщик gperftools не поддерживается в Windows (пока), я попробовал развернуть мой собственный код профилирования, вдохновленный Cygwin's:
// 10 may 2015
#include "uipriv_windows.h"
static FILE *fprof = NULL;
static DWORD WINAPI profilerThread(LPVOID th)
{
HANDLE thread = (HANDLE) th;
LARGE_INTEGER counter;
CONTEXT ctxt;
// TODO check for errors
if (SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) == 0)
complain("error setting thread priority in profilerThread()");
for (;;) {
if (SuspendThread(thread) == (DWORD) (-1))
complain("error suspending thread in profilerThread()");
QueryPerformanceCounter(&counter);
ZeroMemory(&ctxt, sizeof (CONTEXT));
ctxt.ContextFlags = CONTEXT_CONTROL;
if (GetThreadContext(thread, &ctxt) == 0)
complain("error getting thread context in profilerThread()");
fprintf(fprof, "%I64X %I64d\n",
(DWORD64) (ctxt.Eip),
counter.QuadPart);
fflush(fprof);
if (ResumeThread(thread) == (DWORD) (-1))
complain("error resuming thread in profilerThread()");
Sleep(100);
}
return 0;
}
void initprofiler(HANDLE thread)
{
fprof = fopen("profiler.out", "w");
if (fprof == NULL) {
fprintf(stderr, "error opening profiler output file\n");
abort();
}
if (CreateThread(NULL, 0, profilerThread, thread, 0, NULL) == NULL)
complain("error creating profiler thread");
}
Однако эти профили бесполезны:
F77B0C03 3571425665428
F77B0C03 3571426671982
F77B0C03 3571427677119
F77B0C03 3571428683227
F77B0C03 3571429689442
F77B0C03 3571430696476
F77B0C03 3571431702590
F77B0C03 3571432708622
Это особое значение для вина, которое перенаправляет на __kernel_vsyscall+0x3
, Реальная Windows имеет что-то вроде 7C90E514
вместо этого, который перенаправляет на ntdll!KeFastSystemCallRet
,
Я предполагаю (учитывая след винного стека) это потому, что он застрял в GetMessage()
,
Если я изменю продолжительность сна со 100 на 1, я иногда получаю более значимые значения.
Я что-то упускаю? Есть ли лучший вариант профилирования, или я в какой-то мере ошибаюсь?
Благодарю.