* 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:
Corinna Vinschen 2011-05-20 18:07:52 +00:00
parent 6bdbccf7bf
commit 5a755a9471
2 changed files with 122 additions and 12 deletions

View 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

View 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]");