4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-19 04:49:25 +08:00

* fhandler_process.cc (struct heap_info::heap): Convert base to

uintptr_t.  Add heap_id, end, flags members.
	(heap_info::heap_vm_chunks): Rename from heaps.
	(heap_info::heap_info): Rearrange using RtlQueryProcessDebugInformation
	to get information of heap virtual memory blocks.  Store heap id and
	flags, as well as end address of each block.
	(heap_info::fill_if_match): Check incoming base address against full
	address range of heap chunks.  Convert flag values in extra heap
	information.
	(format_process_maps): Change order so that heap check is done before
	MEM_MAPPED check since there are shareable heaps.
	* ntdll.h (PDI_HEAP_BLOCKS): Define.
	(HEAP_FLAG_NOSERIALIZE): Define.
	(HEAP_FLAG_GROWABLE): Define.
	(HEAP_FLAG_EXCEPTIONS): Define.
	(HEAP_FLAG_NONDEFAULT): Define.
	(HEAP_FLAG_SHAREABLE): Define.
	(HEAP_FLAG_EXECUTABLE): Define.
	(HEAP_FLAG_DEBUGGED): Define.
	(struct _DEBUG_HEAP_ARRAY): Define.
	(struct _DEBUG_HEAP_BLOCK): Define.
This commit is contained in:
Corinna Vinschen 2011-05-13 06:50:20 +00:00
parent 4fda571831
commit b4966f9139
3 changed files with 109 additions and 25 deletions

View File

@ -1,3 +1,27 @@
2011-05-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_process.cc (struct heap_info::heap): Convert base to
uintptr_t. Add heap_id, end, flags members.
(heap_info::heap_vm_chunks): Rename from heaps.
(heap_info::heap_info): Rearrange using RtlQueryProcessDebugInformation
to get information of heap virtual memory blocks. Store heap id and
flags, as well as end address of each block.
(heap_info::fill_if_match): Check incoming base address against full
address range of heap chunks. Convert flag values in extra heap
information.
(format_process_maps): Change order so that heap check is done before
MEM_MAPPED check since there are shareable heaps.
* ntdll.h (PDI_HEAP_BLOCKS): Define.
(HEAP_FLAG_NOSERIALIZE): Define.
(HEAP_FLAG_GROWABLE): Define.
(HEAP_FLAG_EXCEPTIONS): Define.
(HEAP_FLAG_NONDEFAULT): Define.
(HEAP_FLAG_SHAREABLE): Define.
(HEAP_FLAG_EXECUTABLE): Define.
(HEAP_FLAG_DEBUGGED): Define.
(struct _DEBUG_HEAP_ARRAY): Define.
(struct _DEBUG_HEAP_BLOCK): Define.
2011-05-12 Corinna Vinschen <corinna@vinschen.de> 2011-05-12 Corinna Vinschen <corinna@vinschen.de>
Based on newlib patch to strptime by Peter Rosin <peda@lysator.liu.se>: Based on newlib patch to strptime by Peter Rosin <peda@lysator.liu.se>:

View File

@ -614,34 +614,68 @@ struct heap_info
struct heap struct heap
{ {
heap *next; heap *next;
void *base; unsigned heap_id;
uintptr_t base;
uintptr_t end;
unsigned long flags;
}; };
heap *heaps; heap *heap_vm_chunks;
heap_info (DWORD pid) heap_info (DWORD pid)
: heaps (0) : heap_vm_chunks (0)
{ {
HANDLE hHeapSnap = CreateToolhelp32Snapshot (TH32CS_SNAPHEAPLIST, pid); PDEBUG_BUFFER buf;
HEAPLIST32 hl; NTSTATUS status;
hl.dwSize = sizeof(hl); PDEBUG_HEAP_ARRAY harray;
if (hHeapSnap != INVALID_HANDLE_VALUE && Heap32ListFirst (hHeapSnap, &hl)) buf = RtlCreateQueryDebugBuffer (0, FALSE);
do if (!buf)
return;
status = RtlQueryProcessDebugInformation (pid, PDI_HEAPS | PDI_HEAP_BLOCKS,
buf);
if (NT_SUCCESS (status)
&& (harray = (PDEBUG_HEAP_ARRAY) buf->HeapInformation) != NULL)
for (ULONG hcnt = 0; hcnt < harray->Count; ++hcnt)
{
PDEBUG_HEAP_BLOCK barray = (PDEBUG_HEAP_BLOCK)
harray->Heaps[hcnt].Blocks;
if (!barray)
continue;
for (ULONG bcnt = 0; bcnt < harray->Heaps[hcnt].BlockCount; ++bcnt)
if (barray[bcnt].Flags & 2)
{ {
heap *h = (heap *) cmalloc (HEAP_FHANDLER, sizeof (heap)); heap *h = (heap *) cmalloc (HEAP_FHANDLER, sizeof (heap));
*h = (heap) {heaps, (void*) hl.th32HeapID}; *h = (heap) { heap_vm_chunks,
heaps = h; hcnt, barray[bcnt].Address,
} while (Heap32ListNext (hHeapSnap, &hl)); barray[bcnt].Address + barray[bcnt].Size,
CloseHandle (hHeapSnap); harray->Heaps[hcnt].Flags };
heap_vm_chunks = h;
}
}
RtlDestroyQueryDebugBuffer (buf);
} }
char *fill_if_match (void *base, char *dest ) char *fill_if_match (void *base, ULONG type, char *dest )
{ {
long count = 0; for (heap *h = heap_vm_chunks; h; h = h->next)
for (heap *h = heaps; h && ++count; h = h->next) if ((uintptr_t) base >= h->base && (uintptr_t) base < h->end)
if (base == h->base)
{ {
__small_sprintf (dest, "[heap %ld]", count); char *p;
__small_sprintf (dest, "[heap %ld", h->heap_id);
p = strchr (dest, '\0');
if (!(h->flags & HEAP_FLAG_NONDEFAULT))
p = stpcpy (p, " default");
if ((h->flags & HEAP_FLAG_SHAREABLE) && (type & MEM_MAPPED))
p = stpcpy (p, " share");
if (h->flags & HEAP_FLAG_EXECUTABLE)
p = stpcpy (p, " exec");
if (h->flags & HEAP_FLAG_GROWABLE)
p = stpcpy (p, " grow");
if (h->flags & HEAP_FLAG_NOSERIALIZE)
p = stpcpy (p, " noserial");
if (h->flags == HEAP_FLAG_DEBUGGED)
p = stpcpy (p, " debug");
stpcpy (p, "]");
return dest; return dest;
} }
return 0; return 0;
@ -650,7 +684,7 @@ struct heap_info
~heap_info () ~heap_info ()
{ {
heap *n = 0; heap *n = 0;
for (heap *m = heaps; m; m = n) for (heap *m = heap_vm_chunks; m; m = n)
{ {
n = m->next; n = m->next;
cfree (m); cfree (m);
@ -777,14 +811,16 @@ format_process_maps (void *data, char *&destbuf)
sys_wcstombs (posix_modname, NT_MAX_PATH, dosname); sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
stat64 (posix_modname, &st); stat64 (posix_modname, &st);
} }
else if (mb.Type & MEM_MAPPED) else if (!heaps.fill_if_match (cur.abase, mb.Type, posix_modname))
{
if (mb.Type & MEM_MAPPED)
strcpy (posix_modname, "[shareable]"); strcpy (posix_modname, "[shareable]");
else if (!(mb.Type & MEM_PRIVATE else
&& heaps.fill_if_match (cur.abase, posix_modname)))
posix_modname[0] = 0; posix_modname[0] = 0;
} }
} }
} }
}
CloseHandle (proc); CloseHandle (proc);
return len; return len;
} }

View File

@ -63,6 +63,7 @@
#define PDI_MODULES 0x01 #define PDI_MODULES 0x01
#define PDI_HEAPS 0x04 #define PDI_HEAPS 0x04
#define PDI_HEAP_BLOCKS 0x10
#define LDRP_IMAGE_DLL 0x00000004 #define LDRP_IMAGE_DLL 0x00000004
#define WSLE_PAGE_READONLY 0x001 #define WSLE_PAGE_READONLY 0x001
#define WSLE_PAGE_EXECUTE 0x002 #define WSLE_PAGE_EXECUTE 0x002
@ -510,6 +511,15 @@ typedef struct _DEBUG_BUFFER
PVOID Reserved[9]; PVOID Reserved[9];
} DEBUG_BUFFER, *PDEBUG_BUFFER; } DEBUG_BUFFER, *PDEBUG_BUFFER;
/* Known debug heap flags */
#define HEAP_FLAG_NOSERIALIZE 0x1
#define HEAP_FLAG_GROWABLE 0x2
#define HEAP_FLAG_EXCEPTIONS 0x4
#define HEAP_FLAG_NONDEFAULT 0x1000
#define HEAP_FLAG_SHAREABLE 0x8000
#define HEAP_FLAG_EXECUTABLE 0x40000
#define HEAP_FLAG_DEBUGGED 0x40000000
typedef struct _DEBUG_HEAP_INFORMATION typedef struct _DEBUG_HEAP_INFORMATION
{ {
ULONG Base; ULONG Base;
@ -525,6 +535,20 @@ typedef struct _DEBUG_HEAP_INFORMATION
PVOID Blocks; PVOID Blocks;
} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION; } DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;
typedef struct _DEBUG_HEAP_ARRAY
{
ULONG Count;
DEBUG_HEAP_INFORMATION Heaps[1];
} DEBUG_HEAP_ARRAY, *PDEBUG_HEAP_ARRAY;
typedef struct _DEBUG_HEAP_BLOCK
{
ULONG Size;
ULONG Flags;
ULONG Committed;
ULONG Address;
} DEBUG_HEAP_BLOCK, *PDEBUG_HEAP_BLOCK;
typedef struct _DEBUG_MODULE_INFORMATION typedef struct _DEBUG_MODULE_INFORMATION
{ {
ULONG Reserved[2]; ULONG Reserved[2];