From 27e79675f8b36204c04433a6519bcdb5c4511bd9 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 13 Sep 2010 13:02:19 +0000 Subject: [PATCH] * fhandler_process.cc (get_mem_values): Simplify code. Fix NtQueryVirtualMemory loop so it handles memory allocation gracefully. Always set errno to a useful value. --- winsup/cygwin/ChangeLog | 6 ++++ winsup/cygwin/fhandler_process.cc | 54 ++++++++++++++++++------------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index dbea36cdc..80a705521 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,9 @@ +2010-09-13 Corinna Vinschen + + * 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 * fhandler.h (class fhandler_base): Change inheritance of fstat_helper diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc index b2fa5f771..526cd3322 100644 --- a/winsup/cygwin/fhandler_process.cc +++ b/winsup/cygwin/fhandler_process.cc @@ -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);