Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-05-13 10:50:20 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-05-13 10:50:20 +0400
commitb4966f91396b337dc0ce1c1b9f7a95a62a64c84e (patch)
tree365a6474147588268479073cb199bb892f2a8fff /winsup/cygwin
parent4fda5718319e0c66e6f4b017e722293a4516413d (diff)
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog24
-rw-r--r--winsup/cygwin/fhandler_process.cc88
-rw-r--r--winsup/cygwin/ntdll.h24
3 files changed, 110 insertions, 26 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index b3122ab28..0733a86a7 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>:
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 3d353096c..1038537ce 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -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);
-
- 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);
+ PDEBUG_BUFFER buf;
+ NTSTATUS status;
+ PDEBUG_HEAP_ARRAY harray;
+
+ 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;
+ }
}
}
}
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index df0ae29a3..cb4e6d962 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -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];