* fhandler_process.cc (get_mem_values): Simplify code. Fix

NtQueryVirtualMemory loop so it handles memory allocation gracefully.
	Always set errno to a useful value.
This commit is contained in:
Corinna Vinschen 2010-09-13 13:02:19 +00:00
parent c80480bfa0
commit 27e79675f8
2 changed files with 37 additions and 23 deletions

View file

@ -1,3 +1,9 @@
2010-09-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_process.cc (get_mem_values): Simplify code. Fix
NtQueryVirtualMemory loop so it handles memory allocation gracefully.
Always set errno to a useful value.
2010-09-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_base): Change inheritance of fstat_helper

View file

@ -999,36 +999,43 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
unsigned long *vmtext, unsigned long *vmdata,
unsigned long *vmlib, unsigned long *vmshare)
{
bool res = true;
bool res = false;
NTSTATUS ret;
HANDLE hProcess;
VM_COUNTERS vmc;
MEMORY_WORKING_SET_LIST *mwsl;
ULONG n = 0x1000, length;
PULONG p = (PULONG) malloc (sizeof (ULONG) * n);
ULONG n = 0x4000, length;
PMEMORY_WORKING_SET_LIST p = (PMEMORY_WORKING_SET_LIST) malloc (n);
unsigned page_size = getsystempagesize ();
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION,
FALSE, dwProcessId);
if (hProcess == NULL)
{
DWORD error = GetLastError ();
__seterrno_from_win_error (error);
debug_printf ("OpenProcess: ret %d", error);
__seterrno ();
debug_printf ("OpenProcess, %E");
return false;
}
while ((ret = NtQueryVirtualMemory (hProcess, 0,
MemoryWorkingSetList,
(PVOID) p,
n * sizeof *p, &length)),
(ret == STATUS_SUCCESS || ret == STATUS_INFO_LENGTH_MISMATCH) &&
length >= (n * sizeof (*p)))
p = (PULONG) realloc (p, n *= (2 * sizeof (ULONG)));
if (ret != STATUS_SUCCESS)
do
{
debug_printf ("NtQueryVirtualMemory: ret %d, Dos(ret) %d",
ret, RtlNtStatusToDosError (ret));
res = false;
ret = NtQueryVirtualMemory (hProcess, 0, MemoryWorkingSetList,
(PVOID) p, n, (length = ULONG_MAX, &length));
if (ret == STATUS_INFO_LENGTH_MISMATCH
|| (!NT_SUCCESS (ret) && length > n))
{
ret = STATUS_INFO_LENGTH_MISMATCH;
n <<= 1;
PMEMORY_WORKING_SET_LIST new_p = (PMEMORY_WORKING_SET_LIST)
realloc (p, n);
if (!new_p)
goto out;
p = new_p;
}
}
while (!NT_SUCCESS (ret));
if (!NT_SUCCESS (ret))
{
debug_printf ("NtQueryVirtualMemory: ret %p", ret);
__seterrno_from_nt_status (ret);
goto out;
}
mwsl = (MEMORY_WORKING_SET_LIST *) p;
@ -1036,7 +1043,8 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
{
++*vmrss;
unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF;
if ((flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE)) == (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
if ((flags & (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
== (WSLE_PAGE_EXECUTE | WSLE_PAGE_SHAREABLE))
++*vmlib;
else if (flags & WSLE_PAGE_SHAREABLE)
++*vmshare;
@ -1047,14 +1055,14 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
}
ret = NtQueryInformationProcess (hProcess, ProcessVmCounters, (PVOID) &vmc,
sizeof vmc, NULL);
if (ret != STATUS_SUCCESS)
if (!NT_SUCCESS (ret))
{
debug_printf ("NtQueryInformationProcess: ret %d, Dos(ret) %d",
ret, RtlNtStatusToDosError (ret));
res = false;
debug_printf ("NtQueryInformationProcess: ret %p", ret);
__seterrno_from_nt_status (ret);
goto out;
}
*vmsize = vmc.PagefileUsage / page_size;
res = true;
out:
free (p);
CloseHandle (hProcess);