]> sourceware.org Git - newlib-cygwin.git/commitdiff
* fhandler_process.cc (struct heap_info): Change type of base and end
authorCorinna Vinschen <corinna@vinschen.de>
Fri, 20 May 2011 18:07:52 +0000 (18:07 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Fri, 20 May 2011 18:07:52 +0000 (18:07 +0000)
members to char *.  Print "shared" rather than "share".
(struct stack_info): New class to fetch process stack information.
(format_process_maps): Initialize and check for stack information.

winsup/cygwin/ChangeLog
winsup/cygwin/fhandler_process.cc

index d7d7e593c4e806bedbadc559e16830c6611e5c19..679d9295a0abb881efe1e63ef29aba7f2105f770 100644 (file)
@@ -1,3 +1,10 @@
+2011-05-20  Corinna Vinschen  <corinna@vinschen.de>
+
+       * fhandler_process.cc (struct heap_info): Change type of base and end
+       members to char *.  Print "shared" rather than "share".
+       (struct stack_info): New class to fetch process stack information.
+       (format_process_maps): Initialize and check for stack information.
+
 2011-05-20  Corinna Vinschen  <corinna@vinschen.de>
 
        * miscfuncs.cc (thread_wrapper): Remove statements added for debugging
index 1038537cec6710c6e2319d440418228daa82a181..29044b2ea9d61c20d7947575561e1c7726d8900c 100644 (file)
@@ -615,14 +615,14 @@ struct heap_info
   {
     heap *next;
     unsigned heap_id;
-    uintptr_t base;
-    uintptr_t end;
+    char *base;
+    char *end;
     unsigned long flags;
   };
   heap *heap_vm_chunks;
 
   heap_info (DWORD pid)
-    : heap_vm_chunks (0)
+    : heap_vm_chunks (NULL)
   {
     PDEBUG_BUFFER buf;
     NTSTATUS status;
@@ -646,8 +646,8 @@ struct heap_info
              {
                heap *h = (heap *) cmalloc (HEAP_FHANDLER, sizeof (heap));
                *h = (heap) { heap_vm_chunks,
-                             hcnt, barray[bcnt].Address,
-                             barray[bcnt].Address + barray[bcnt].Size,
+                             hcnt, (char *) barray[bcnt].Address,
+                             (char *) barray[bcnt].Address + barray[bcnt].Size,
                              harray->Heaps[hcnt].Flags };
                heap_vm_chunks = h;
              }
@@ -655,18 +655,16 @@ struct heap_info
     RtlDestroyQueryDebugBuffer (buf);
   }
   
-  char *fill_if_match (void *base, ULONG type, char *dest )
+  char *fill_if_match (char *base, ULONG type, char *dest)
   {
     for (heap *h = heap_vm_chunks; h; h = h->next)
-      if ((uintptr_t) base >= h->base && (uintptr_t) base < h->end)
+      if (base >= h->base && base < h->end)
        {
-         char *p;
-         __small_sprintf (dest, "[heap %ld", h->heap_id);
-         p = strchr (dest, '\0');
+         char *p = dest + __small_sprintf (dest, "[heap %ld", h->heap_id);
          if (!(h->flags & HEAP_FLAG_NONDEFAULT))
            p = stpcpy (p, " default");
          if ((h->flags & HEAP_FLAG_SHAREABLE) && (type & MEM_MAPPED))
-           p = stpcpy (p, " share");
+           p = stpcpy (p, " shared");
          if (h->flags & HEAP_FLAG_EXECUTABLE)
            p = stpcpy (p, " exec");
          if (h->flags & HEAP_FLAG_GROWABLE)
@@ -692,6 +690,107 @@ struct heap_info
   }
 };
 
+struct stack_info
+{
+  struct stack
+  {
+    stack *next;
+    ULONG thread_id;
+    char *start;
+    char *end;
+  };
+  stack *stacks;
+
+  stack_info (DWORD pid, HANDLE process)
+    : stacks (NULL)
+  {
+    NTSTATUS status;
+    PVOID buf = NULL;
+    size_t size = 50 * (sizeof (SYSTEM_PROCESSES)
+                       + 16 * sizeof (SYSTEM_THREADS));
+    PSYSTEM_PROCESSES proc;
+    PSYSTEM_THREADS thread;
+
+    do
+      {
+       buf = realloc (buf, size);
+       status = NtQuerySystemInformation (SystemProcessesAndThreadsInformation,
+                                          buf, size, NULL);
+       size <<= 1;
+      }
+    while (status == STATUS_INFO_LENGTH_MISMATCH);
+    if (!NT_SUCCESS (status))
+      {
+       if (buf)
+         free (buf);
+       debug_printf ("NtQuerySystemInformation, %p", status);
+       return;
+      }
+    proc = (PSYSTEM_PROCESSES) buf;
+    while (true)
+      {
+       if (proc->ProcessId == pid)
+         break;
+       if (!proc->NextEntryDelta)
+         {
+           free (buf);
+           return;
+         }
+       proc = (PSYSTEM_PROCESSES) ((PBYTE) proc + proc->NextEntryDelta);
+      }
+    thread = proc->Threads;
+    for (ULONG i = 0; i < proc->ThreadCount; ++i)
+      {
+       THREAD_BASIC_INFORMATION tbi;
+       TEB teb;
+       HANDLE thread_h;
+       
+       if (!(thread_h = OpenThread (THREAD_QUERY_INFORMATION, FALSE,
+                                    (ULONG) thread[i].ClientId.UniqueThread)))
+         continue;
+       status = NtQueryInformationThread (thread_h, ThreadBasicInformation,
+                                          &tbi, sizeof tbi, NULL);
+       CloseHandle (thread_h);
+       if (!NT_SUCCESS (status))
+         continue;
+       if (!ReadProcessMemory (process, (PVOID) tbi.TebBaseAddress,
+                               &teb, sizeof teb, NULL))
+         continue;
+       stack *s = (stack *) cmalloc (HEAP_FHANDLER, sizeof (stack));
+       *s = (stack) { stacks, (ULONG) thread[i].ClientId.UniqueThread,
+                      (char *) (teb.DeallocationStack ?: teb.Tib.StackLimit),
+                      (char *) teb.Tib.StackBase };
+       stacks = s;
+      }
+    free (buf);
+  }
+  
+  char *fill_if_match (char *base, ULONG type, char *dest)
+  {
+    for (stack *s = stacks; s; s = s->next)
+      if (base >= s->start && base < s->end)
+       {
+         char *p = dest + __small_sprintf (dest, "[stack (tid %ld)",
+                                           s->thread_id);
+         if (type & MEM_MAPPED)
+           p = stpcpy (p, " shared");
+         stpcpy (p, "]");
+         return dest;
+       }
+    return 0;
+  }
+  
+  ~stack_info () 
+  {
+    stack *n = 0;
+    for (stack *m = stacks; m; m = n)
+      {
+       n = m->next;
+       cfree (m);
+      }
+  }
+};
+
 static _off64_t
 format_process_maps (void *data, char *&destbuf)
 {
@@ -720,6 +819,7 @@ format_process_maps (void *data, char *&destbuf)
   MEMORY_BASIC_INFORMATION mb;
   dos_drive_mappings drive_maps;
   heap_info heaps (p->dwProcessId);
+  stack_info stacks (p->dwProcessId, proc);
   struct __stat64 st;
   long last_pass = 0;
 
@@ -811,7 +911,10 @@ format_process_maps (void *data, char *&destbuf)
                    sys_wcstombs (posix_modname, NT_MAX_PATH, dosname);
                  stat64 (posix_modname, &st);
                }
-             else if (!heaps.fill_if_match (cur.abase, mb.Type, posix_modname))
+             else if (!stacks.fill_if_match (cur.abase, mb.Type,
+                                             posix_modname)
+                      && !heaps.fill_if_match (cur.abase, mb.Type,
+                                               posix_modname))
                {
                  if (mb.Type & MEM_MAPPED)
                    strcpy (posix_modname, "[shareable]");
This page took 0.099235 seconds and 5 git commands to generate.