singrdk/base/Windows/singx86/procs.cpp

169 lines
6.0 KiB
C++
Raw Permalink Normal View History

2008-03-05 09:52:00 -05:00
/////////////////////////////////////////////////////////////////////////////
//
// procs.cpp - Extension to find Singularity Processes.
//
2008-11-17 18:29:00 -05:00
// Copyright Microsoft Corporation. All rights reserved.
2008-03-05 09:52:00 -05:00
//
#include "singx86.h"
HRESULT DumpProcess(ULONG64 address, bool stack, bool detail)
{
if (address == 0) {
return S_FALSE;
}
2008-11-17 18:29:00 -05:00
HRESULT status = S_FALSE;
#if 0 // TODO: This needs to be implemented!
2008-03-05 09:52:00 -05:00
HRESULT status = S_OK;
Thread thread;
2008-11-17 18:29:00 -05:00
EXT_CHECK(ThreadStruct->Read(address, &thread));
2008-03-05 09:52:00 -05:00
if (stack) {
ExtOut(" thread=%p { tid=%03x pid=%03x ebp=%p, esp=%p, eip=%p }\n",
address,
(ULONG)(thread.context.threadIndex == 0xffff ? 0xfff : thread.context.threadIndex),
(ULONG)(thread.context.processId == 0xffff ? 0xfff : thread.context.processId),
2008-11-17 18:29:00 -05:00
thread.context.threadRecord.spill.ip,
thread.context.threadRecord.spill.bp,
thread.context.threadRecord.spill.sp);
2008-03-05 09:52:00 -05:00
DEBUG_STACK_FRAME frames[10];
ULONG filled = 0;
2008-11-17 18:29:00 -05:00
status = g_ExtControl->GetStackTrace(thread.context.threadRecord.spill.bp,
thread.context.threadRecord.spill.sp,
thread.context.threadRecord.spill.ip,
2008-03-05 09:52:00 -05:00
frames,
arrayof(frames),
&filled);
if (status == S_OK) {
g_ExtClient->SetOutputLinePrefix(" ");
g_ExtControl->OutputStackTrace(DEBUG_OUTPUT_NORMAL,
frames,
filled,
detail ? (DEBUG_STACK_FRAME_ADDRESSES |
DEBUG_STACK_COLUMN_NAMES |
DEBUG_STACK_SOURCE_LINE) : 0);
}
}
else {
CHAR name[512];
ULONG64 displacement = 0;
2008-11-17 18:29:00 -05:00
status = g_ExtSymbols->GetNameByOffset((ULONG64)thread.context.threadRecord.spill.ip,
2008-03-05 09:52:00 -05:00
name,
arrayof(name),
NULL,
&displacement);
if (status == S_OK) {
ExtOut(" thread=%p { tid=%03x pid=%03x ebp=%p, esp=%p, eip=%p } %s+%I64d\n",
address,
(ULONG)(thread.context.threadIndex == 0xffff ? 0xfff : thread.context.threadIndex),
(ULONG)(thread.context.processId == 0xffff ? 0xfff : thread.context.processId),
2008-11-17 18:29:00 -05:00
thread.context.threadRecord.spill.ip,
thread.context.threadRecord.spill.bp,
thread.context.threadRecord.spill.sp,
2008-03-05 09:52:00 -05:00
name,
(LONG64)displacement);
}
else {
ExtOut(" thread=%p { tid=%03x pid=%03x ebp=%p, esp=%p, eip=%p }\n",
address,
(ULONG)(thread.context.threadIndex == 0xffff ? 0xfff : thread.context.threadIndex),
(ULONG)(thread.context.processId == 0xffff ? 0xfff : thread.context.processId),
2008-11-17 18:29:00 -05:00
thread.context.threadRecord.spill.ip,
thread.context.threadRecord.spill.bp,
thread.context.threadRecord.spill.sp);
2008-03-05 09:52:00 -05:00
}
}
Exit:
2008-11-17 18:29:00 -05:00
#endif
2008-03-05 09:52:00 -05:00
return status;
}
EXT_DECL(procs) // Defines: PDEBUG_CLIENT Client, PCSTR args
{
EXT_ENTER(); // Defines: HRESULT status = S_OK;
bool stack = false;
bool detail = false;
while (*args != '\0') {
if (*args == '-' || *args == '/') {
args++;
switch (*args++) {
case 'd': // detail
case 'D':
detail = !detail;
break;
case 's': // stack
case 'S':
stack = !stack;
break;
}
while (*args != ' ') {
args++;
}
}
else {
break;
}
}
ULONG pointerSize = (g_ExtControl->IsPointer64Bit() == S_OK) ? 8 : 4;
ULONG64 address = 0;
ULONG64 procs = 0;
ULONG type = 0;
ULONG subtype = 0;
ULONG64 module = 0;
2008-11-17 18:29:00 -05:00
EXT_CHECK(g_ExtSymbols->GetOffsetByName(kernel_processTable, &address));
2008-03-05 09:52:00 -05:00
EXT_CHECK(g_ExtSymbols->GetOffsetTypeId(address, &type, &module));
2008-11-17 18:29:00 -05:00
EXT_CHECK(TraceReadPointer(1, address, &procs));
2008-03-05 09:52:00 -05:00
ExtVerb("processTable: %p\n", procs);
CHAR name[512];
EXT_CHECK(g_ExtSymbols->GetTypeName(module, type, name, arrayof(name), NULL));
ExtVerb(" processTable type: %s\n", name);
2008-11-17 18:29:00 -05:00
int len = (int)strlen(name);
2008-03-05 09:52:00 -05:00
if (len > 3 &&
name[len-3] == '[' &&
name[len-2] == ']' &&
name[len-1] == '*') {
name[len-3] = '\0';
EXT_CHECK(g_ExtSymbols->GetTypeId(module, name, &subtype));
EXT_CHECK(g_ExtSymbols->GetTypeName(module, subtype, name, arrayof(name), NULL));
ExtVerb(" processTable[] type: %s\n", name);
}
ULONG lengthOffset = 0;
EXT_CHECK(g_ExtSymbols->GetFieldOffset(module, type, "overall_length", &lengthOffset));
ULONG valuesOffset = 0;
EXT_CHECK(g_ExtSymbols->GetFieldOffset(module, type, "values", &valuesOffset));
ULONG length = 0;
2008-11-17 18:29:00 -05:00
EXT_CHECK(TraceRead(procs + lengthOffset, &length, sizeof(length)));
2008-03-05 09:52:00 -05:00
ExtOut("processTable: %p [maximum %d entries]\n", procs, length);
for (ULONG id = 0; id < length; id++) {
ULONG64 process = 0;
2008-11-17 18:29:00 -05:00
EXT_CHECK(TraceReadPointer(1, procs + valuesOffset + id * pointerSize, &process));
2008-03-05 09:52:00 -05:00
if (process != 0) {
if (detail) {
ExtOut(" %p\n", process);
}
else {
ExtOut(" %p\n", process);
}
}
}
EXT_LEAVE(); // Macro includes: return status;
}