* 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:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user