Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

482 lines
12 KiB

//----------------------------------------------------------------------------
//
// AutoDump Plus support extension DLL.
//
// Copyright (C) Microsoft Corporation, 2000-2001.
//
//----------------------------------------------------------------------------
#include "dbgexts.h"
#define STATUS_CPP_EH_EXCEPTION 0xe06d7363
#define MAX_NAME 64
#define MAX_MACHINE 64
#define MAX_COMMENT 256
char g_BaseDir[MAX_PATH - 1];
char g_Machine[MAX_MACHINE];
struct PARAM
{
ULONG Len;
PSTR Buf;
};
PARAM g_DirMachParams[2] =
{
sizeof(g_BaseDir), g_BaseDir,
sizeof(g_Machine), g_Machine,
};
union LAST_EVENT_INFO_ALL
{
DEBUG_LAST_EVENT_INFO_BREAKPOINT Breakpoint;
DEBUG_LAST_EVENT_INFO_EXCEPTION Exception;
DEBUG_LAST_EVENT_INFO_EXIT_THREAD ExitThread;
DEBUG_LAST_EVENT_INFO_EXIT_PROCESS ExitProcess;
DEBUG_LAST_EVENT_INFO_LOAD_MODULE LoadModule;
DEBUG_LAST_EVENT_INFO_UNLOAD_MODULE UnloadModule;
DEBUG_LAST_EVENT_INFO_SYSTEM_ERROR SystemError;
};
ULONG g_LastEventType;
LAST_EVENT_INFO_ALL g_LastEventInfo;
PSTR g_LastExName;
char g_UnknownExceptionName[64];
PSTR g_LastExChanceStr;
ULONG g_ProcessId;
char g_ProcessName[MAX_NAME];
struct EXCEPTION_NAME
{
PSTR Name;
ULONG Code;
};
EXCEPTION_NAME g_ExceptionNames[] =
{
"Access Violation", STATUS_ACCESS_VIOLATION,
"C++ EH Exception", STATUS_CPP_EH_EXCEPTION,
"Invalid Handle Exception", STATUS_INVALID_HANDLE,
"Stack Overflow", STATUS_STACK_OVERFLOW,
NULL, 0,
};
PCSTR
GetParams(PCSTR Args, ULONG Count, PARAM* Params)
{
PCSTR Start;
ULONG Len;
ULONG Index = 0;
while (Count-- > 0)
{
while (*Args == ' ' || *Args == '\t')
{
Args++;
}
Start = Args;
while (*Args && *Args != ' ' && *Args != '\t')
{
Args++;
}
Len = (ULONG)(Args - Start);
if ((Count > 0 && !*Args) || Len >= Params[Index].Len)
{
ExtErr("Invalid extension command arguments\n");
return NULL;
}
memcpy(Params[Index].Buf, Start, Len);
Params[Index].Buf[Len] = 0;
Index++;
}
return Args;
}
HRESULT
GetProcessInfo(void)
{
HRESULT Status;
if ((Status = g_ExtSystem->
GetCurrentProcessSystemId(&g_ProcessId)) != S_OK)
{
ExtErr("Unable to get current process ID\n");
return Status;
}
if (FAILED(g_ExtClient->
GetRunningProcessDescription(0, g_ProcessId,
DEBUG_PROC_DESC_NO_PATHS,
NULL, 0, NULL,
g_ProcessName, MAX_NAME,
NULL)))
{
g_ProcessName[0] = 0;
}
else
{
PSTR Scan;
// Use the MTS package name as the name if it exists.
Scan = strstr(g_ProcessName, "MTS Packages: ");
if (Scan)
{
PSTR Start;
ULONG Len;
Scan += 14;
Start = Scan;
Scan = strchr(Start, ',');
if (!Scan)
{
Scan = strchr(Start, ' ');
}
if (Scan)
{
*Scan = 0;
}
Len = strlen(Start) + 1;
if (Len > 2)
{
memmove(g_ProcessName, Start, Len);
}
else
{
g_ProcessName[0] = 0;
}
}
else
{
g_ProcessName[0] = 0;
}
}
if (!g_ProcessName[0])
{
if (FAILED(g_ExtSystem->
GetCurrentProcessExecutableName(g_ProcessName, MAX_NAME,
NULL)))
{
// This can happen in some situations so handle it
// rather than exiting.
ExtErr("Unable to get current process name\n");
strcpy(g_ProcessName, "UnknownProcess");
}
}
return S_OK;
}
HRESULT
GetEventInfo(void)
{
HRESULT Status;
ULONG ProcessId, ThreadId;
if ((Status = g_ExtControl->
GetLastEventInformation(&g_LastEventType, &ProcessId, &ThreadId,
&g_LastEventInfo, sizeof(g_LastEventInfo),
NULL, NULL, 0, NULL)) != S_OK)
{
ExtErr("Unable to get event information\n");
return Status;
}
if ((Status = GetProcessInfo()) != S_OK)
{
return Status;
}
switch(g_LastEventType)
{
case DEBUG_EVENT_EXCEPTION:
{
EXCEPTION_NAME* ExName = g_ExceptionNames;
while (ExName->Name != NULL)
{
if (ExName->Code == g_LastEventInfo.Exception.
ExceptionRecord.ExceptionCode)
{
break;
}
ExName++;
}
if (ExName->Name != NULL)
{
g_LastExName = ExName->Name;
}
else
{
sprintf(g_UnknownExceptionName, "Unknown Exception (%08X)",
g_LastEventInfo.Exception.
ExceptionRecord.ExceptionCode);
g_LastExName = g_UnknownExceptionName;
}
if (g_LastEventInfo.Exception.FirstChance)
{
g_LastExChanceStr = "First";
}
else
{
g_LastExChanceStr = "Second";
}
}
break;
}
return S_OK;
}
void
SanitizeFileName(PSTR FileName)
{
while (*FileName)
{
switch(*FileName)
{
case ' ':
case '\t':
case '\n':
case '\r':
*FileName = '_';
break;
case '\\':
case '/':
case ':':
*FileName = '-';
break;
}
FileName++;
}
}
void
GetDumpPath(PSTR NameQual, PSTR TypeStr, PSTR Path)
{
SYSTEMTIME Time;
PSTR FilePart;
GetLocalTime(&Time);
strcpy(Path, g_BaseDir);
FilePart = Path + strlen(Path) - 1;
if (*FilePart != '/' && *FilePart != '\\')
{
*++FilePart = '\\';
}
FilePart++;
_snprintf(FilePart,
MAX_PATH - (FilePart - Path),
"PID-%d__%s__Date_%02d-%02d-%04d__Time_%02d-%02d-%02d__%s__%s.dmp",
g_ProcessId,
g_ProcessName,
Time.wMonth,
Time.wDay,
Time.wYear,
Time.wHour,
Time.wMinute,
Time.wSecond,
NameQual,
TypeStr);
Path[MAX_PATH - 1] = 0;
SanitizeFileName(FilePart);
}
void
WriteDump(PSTR NameQual, PSTR Comment,
ULONG DumpQual, ULONG DumpFormat, PSTR TypeStr)
{
char Path[MAX_PATH];
ULONG Len;
Len = strlen(Comment);
_snprintf(Comment + Len, MAX_COMMENT - Len,
" - %s dump from %s",
TypeStr, g_Machine);
Comment[MAX_COMMENT - 1] = 0;
GetDumpPath(NameQual, TypeStr, Path);
g_ExtClient->WriteDumpFile2(Path, DumpQual, DumpFormat, Comment);
}
extern "C" HRESULT
AdpEventControlC(PDEBUG_CLIENT Client, PCSTR Args)
{
char Comment[MAX_COMMENT];
INIT_API();
//
// Parameters: directory, machine name.
//
Args = GetParams(Args, 2, g_DirMachParams);
if (Args == NULL)
{
goto Exit;
}
//
// Retrieve standard information.
//
if ((Status = GetEventInfo()) != S_OK)
{
goto Exit;
}
//
// Log information.
//
ExtOut("\n\n----------------------------------------------------------------------\n");
ExtOut("CTRL-C was pressed to stop debugging this process!\n");
ExtOut("----------------------------------------------------------------------\n");
ExtOut("Exiting the debugger at:\n");
ExtExec(".time");
ExtOut("\n\n--- Listing all thread stacks: ---\n");
ExtExec("~*kb250");
ExtOut("\n--- Listing loaded modules: ---\n");
ExtExec("lmv");
ExtOut("\n--- Modules with matching symbols:\n");
ExtExec("lml");
ExtOut("\n--- Listing all locks: ---\n");
ExtExec("!locks");
//
// Create a dump file.
//
strcpy(Comment, "CTRL-C was pressed to stop the debugger while running in crash mode");
WriteDump("CTRL-C", Comment,
DEBUG_DUMP_SMALL, DEBUG_FORMAT_DEFAULT, "mini");
Exit:
EXIT_API();
return Status;
}
extern "C" HRESULT
AdpEventException(PDEBUG_CLIENT Client, PCSTR Args)
{
char Comment[MAX_COMMENT];
char Qual[MAX_COMMENT];
ULONG Format;
PSTR TypeStr;
INIT_API();
//
// Parameters: directory, machine name.
//
Args = GetParams(Args, 2, g_DirMachParams);
if (Args == NULL)
{
goto Exit;
}
//
// Retrieve standard information.
//
if ((Status = GetEventInfo()) != S_OK)
{
goto Exit;
}
if (g_LastEventType != DEBUG_EVENT_EXCEPTION)
{
ExtErr("Last event was not an exception\n");
goto Exit;
}
if (g_LastEventInfo.Exception.FirstChance)
{
Format = DEBUG_FORMAT_DEFAULT;
TypeStr = "mini";
}
else
{
Format = DEBUG_FORMAT_USER_SMALL_FULL_MEMORY |
DEBUG_FORMAT_USER_SMALL_HANDLE_DATA;
TypeStr = "mini full handle";
}
//
// Log information.
//
ExtOut("\n---- %s-chance %s - Exception stack below ----\n",
g_LastExChanceStr, g_LastExName);
ExtExec(".time");
ExtOut("\n");
ExtExec("kvn250");
ExtOut("-----------------------------------\n");
//
// Create a dump file.
//
_snprintf(Comment, sizeof(Comment), "%s-chance %s in %s",
g_LastExChanceStr, g_LastExName, g_ProcessName);
Comment[sizeof(Comment) - 1] = 0;
_snprintf(Qual, sizeof(Qual), "%s-chance %s",
g_LastExChanceStr, g_LastExName);
Qual[sizeof(Qual) - 1] = 0;
WriteDump(Qual, Comment, DEBUG_DUMP_SMALL, Format, TypeStr);
ExtOut("\n\n");
Exit:
EXIT_API();
return Status;
}
extern "C" HRESULT
AdpEventExitProcess(PDEBUG_CLIENT Client, PCSTR Args)
{
INIT_API();
UNREFERENCED_PARAMETER(Args);
//
// Log information.
//
ExtOut("\n\n----------------------------------------------------------------------\n");
ExtOut("This process is shutting down!\n");
ExtOut("\nThis can happen for the following reasons:\n");
ExtOut("1.) Someone killed the process with Task Manager or the kill command.\n");
ExtOut("\n2.) If this process is an MTS or COM+ server package, it could be\n");
ExtOut("* exiting because an MTS/COM+ server package idle limit was reached.\n");
ExtOut("\n3.) If this process is an MTS or COM+ server package,\n");
ExtOut("* someone may have shutdown the package via the MTS Explorer or\n");
ExtOut("* Component Services MMC snap-in.\n");
ExtOut("\n4.) If this process is an MTS or COM+ server package,\n");
ExtOut("* MTS or COM+ could be shutting down the process because an internal\n");
ExtOut("* error was detected in the process (MTS/COM+ fail fast condition).\n");
ExtOut("----------------------------------------------------------------------\n");
ExtOut("\nThe process was shut down at:\n");
ExtExec(".time");
ExtOut("\n\n");
EXIT_API();
return Status;
}