A C background program developed in Visual Studio, called monitor
, watches another program, called target
, and restarts it each time it exits. A somewhat simplified version of the program is shown below.
#include <windows.h>
#include <tlhelp32.h>
#include <Process.h>
void BindToProcess();
const WCHAR PATH[] = L"C:\\Windows\\System32\\notepad.exe";
const WCHAR EXE[] = L"notepad.exe";
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nShowCmd)
{
do
{
BindToProcess();
_wspawnl(_P_WAIT, PATH, PATH, NULL);
} while (TRUE);
return 0;
}
void BindToProcess()
{
HANDLE hProcessSnap;
PROCESSENTRY32 pe32;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) return;
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap);
return;
}
// Now walk the snapshot of processes, and search for target
do
{
const int len = (int) wcsnlen_s(EXE, 10);
if (CompareStringW(0, 0, pe32.szExeFile, len, EXE, len) == CSTR_EQUAL)
{
HANDLE handle[1];
handle[0] = OpenProcess(SYNCHRONIZE, FALSE, pe32.th32ProcessID);
WaitForMultipleObjects(1, handle, TRUE, INFINITE);
CloseHandle(handle[0]);
CloseHandle(hProcessSnap);
return;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return;
}
Monitor
first checks to see if target
is running and, if so, binds itself to it. It stays inactive until target
exists. Then it restarts target
and again stays inactive until target
exists, just to restart it once more.
In the mockup program, I use notepad.exe as the target. In the real system, it is an application that searches the internet and displays the results in a graphical user interface. In practice, target
never exits unless deliberately killed, so monitor
does not loop; it stays hanging. Nevertheless, I observe that its memory grows.
Monitor
never uses new()
or malloc()
to allocate memory. The only allocations occur in the calls to CreateToolhelp32Snapshot()
and OpenProcess()
, but the corresponding memory is released through calls to CloseHandle()
. Therefore, no memory leaks should ever occur, even if the program was looping, but it doesn't, it hangs.
Why does a hanging program's memory grow? I observe both memory increases and memory decreases, but in the long run, memory grows.
CodePudding user response:
This happens because the information accessed by your program is variable.
CreateToolhelp32Snapshot()
does not always have the same memory usage because it is a snapshot of processes at any given time. Processes vary a lot, some can close and others can start.
And the snapshotted process information varies too. For example you are checking szExeFile
which does not have a fixed size.
Also, memory allocation is sometimes done in blocks. So one run can reserve a block that is bigger or smaller, depending on what is available.
As long as the memory does not grow indefinitely this behavior is normal.