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:
parent
4fda571831
commit
b4966f9139
@ -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>
|
||||
|
||||
Based on newlib patch to strptime by Peter Rosin <peda@lysator.liu.se>:
|
||||
|
@ -614,34 +614,68 @@ struct heap_info
|
||||
struct heap
|
||||
{
|
||||
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)
|
||||
: heaps (0)
|
||||
: heap_vm_chunks (0)
|
||||
{
|
||||
HANDLE hHeapSnap = CreateToolhelp32Snapshot (TH32CS_SNAPHEAPLIST, pid);
|
||||
HEAPLIST32 hl;
|
||||
hl.dwSize = sizeof(hl);
|
||||
PDEBUG_BUFFER buf;
|
||||
NTSTATUS status;
|
||||
PDEBUG_HEAP_ARRAY harray;
|
||||
|
||||
if (hHeapSnap != INVALID_HANDLE_VALUE && Heap32ListFirst (hHeapSnap, &hl))
|
||||
do
|
||||
{
|
||||
heap *h = (heap *) cmalloc (HEAP_FHANDLER, sizeof (heap));
|
||||
*h = (heap) {heaps, (void*) hl.th32HeapID};
|
||||
heaps = h;
|
||||
} while (Heap32ListNext (hHeapSnap, &hl));
|
||||
CloseHandle (hHeapSnap);
|
||||
buf = RtlCreateQueryDebugBuffer (0, FALSE);
|
||||
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));
|
||||
*h = (heap) { heap_vm_chunks,
|
||||
hcnt, barray[bcnt].Address,
|
||||
barray[bcnt].Address + barray[bcnt].Size,
|
||||
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 = heaps; h && ++count; h = h->next)
|
||||
if (base == h->base)
|
||||
for (heap *h = heap_vm_chunks; h; h = h->next)
|
||||
if ((uintptr_t) base >= h->base && (uintptr_t) base < h->end)
|
||||
{
|
||||
__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 0;
|
||||
@ -650,7 +684,7 @@ struct heap_info
|
||||
~heap_info ()
|
||||
{
|
||||
heap *n = 0;
|
||||
for (heap *m = heaps; m; m = n)
|
||||
for (heap *m = heap_vm_chunks; m; m = n)
|
||||
{
|
||||
n = m->next;
|
||||
cfree (m);
|
||||
@ -777,11 +811,13 @@ format_process_maps (void *data, char *&destbuf)
|
||||
sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
|
||||
stat64 (posix_modname, &st);
|
||||
}
|
||||
else if (mb.Type & MEM_MAPPED)
|
||||
strcpy (posix_modname, "[shareable]");
|
||||
else if (!(mb.Type & MEM_PRIVATE
|
||||
&& heaps.fill_if_match (cur.abase, posix_modname)))
|
||||
posix_modname[0] = 0;
|
||||
else if (!heaps.fill_if_match (cur.abase, mb.Type, posix_modname))
|
||||
{
|
||||
if (mb.Type & MEM_MAPPED)
|
||||
strcpy (posix_modname, "[shareable]");
|
||||
else
|
||||
posix_modname[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,6 +63,7 @@
|
||||
|
||||
#define PDI_MODULES 0x01
|
||||
#define PDI_HEAPS 0x04
|
||||
#define PDI_HEAP_BLOCKS 0x10
|
||||
#define LDRP_IMAGE_DLL 0x00000004
|
||||
#define WSLE_PAGE_READONLY 0x001
|
||||
#define WSLE_PAGE_EXECUTE 0x002
|
||||
@ -510,6 +511,15 @@ typedef struct _DEBUG_BUFFER
|
||||
PVOID Reserved[9];
|
||||
} 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
|
||||
{
|
||||
ULONG Base;
|
||||
@ -525,6 +535,20 @@ typedef struct _DEBUG_HEAP_INFORMATION
|
||||
PVOID Blocks;
|
||||
} 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
|
||||
{
|
||||
ULONG Reserved[2];
|
||||
|
Loading…
x
Reference in New Issue
Block a user