* 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.
This commit is contained in:
parent
6bdbccf7bf
commit
5a755a9471
|
@ -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
|
||||
|
|
|
@ -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]");
|
||||
|
|
Loading…
Reference in New Issue