* 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> 2010-09-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_base): Change inheritance of fstat_helper * 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 *vmtext, unsigned long *vmdata,
unsigned long *vmlib, unsigned long *vmshare) unsigned long *vmlib, unsigned long *vmshare)
{ {
bool res = true; bool res = false;
NTSTATUS ret; NTSTATUS ret;
HANDLE hProcess; HANDLE hProcess;
VM_COUNTERS vmc; VM_COUNTERS vmc;
MEMORY_WORKING_SET_LIST *mwsl; MEMORY_WORKING_SET_LIST *mwsl;
ULONG n = 0x1000, length; ULONG n = 0x4000, length;
PULONG p = (PULONG) malloc (sizeof (ULONG) * n); PMEMORY_WORKING_SET_LIST p = (PMEMORY_WORKING_SET_LIST) malloc (n);
unsigned page_size = getsystempagesize (); unsigned page_size = getsystempagesize ();
hProcess = OpenProcess (PROCESS_QUERY_INFORMATION, hProcess = OpenProcess (PROCESS_QUERY_INFORMATION,
FALSE, dwProcessId); FALSE, dwProcessId);
if (hProcess == NULL) if (hProcess == NULL)
{ {
DWORD error = GetLastError (); __seterrno ();
__seterrno_from_win_error (error); debug_printf ("OpenProcess, %E");
debug_printf ("OpenProcess: ret %d", error);
return false; return false;
} }
while ((ret = NtQueryVirtualMemory (hProcess, 0, do
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)
{ {
debug_printf ("NtQueryVirtualMemory: ret %d, Dos(ret) %d", ret = NtQueryVirtualMemory (hProcess, 0, MemoryWorkingSetList,
ret, RtlNtStatusToDosError (ret)); (PVOID) p, n, (length = ULONG_MAX, &length));
res = false; 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; goto out;
} }
mwsl = (MEMORY_WORKING_SET_LIST *) p; mwsl = (MEMORY_WORKING_SET_LIST *) p;
@ -1036,7 +1043,8 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
{ {
++*vmrss; ++*vmrss;
unsigned flags = mwsl->WorkingSetList[i] & 0x0FFF; 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; ++*vmlib;
else if (flags & WSLE_PAGE_SHAREABLE) else if (flags & WSLE_PAGE_SHAREABLE)
++*vmshare; ++*vmshare;
@ -1047,14 +1055,14 @@ get_mem_values (DWORD dwProcessId, unsigned long *vmsize, unsigned long *vmrss,
} }
ret = NtQueryInformationProcess (hProcess, ProcessVmCounters, (PVOID) &vmc, ret = NtQueryInformationProcess (hProcess, ProcessVmCounters, (PVOID) &vmc,
sizeof vmc, NULL); sizeof vmc, NULL);
if (ret != STATUS_SUCCESS) if (!NT_SUCCESS (ret))
{ {
debug_printf ("NtQueryInformationProcess: ret %d, Dos(ret) %d", debug_printf ("NtQueryInformationProcess: ret %p", ret);
ret, RtlNtStatusToDosError (ret)); __seterrno_from_nt_status (ret);
res = false;
goto out; goto out;
} }
*vmsize = vmc.PagefileUsage / page_size; *vmsize = vmc.PagefileUsage / page_size;
res = true;
out: out:
free (p); free (p);
CloseHandle (hProcess); CloseHandle (hProcess);