Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

338 lines
7.2 KiB

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
Sprof.c
Abstract:
This is the debugger engine for the segmented profiler. It attaches
to the appropriate process, and fields the debug events. The interesting
events are passed to other modules to deal with.
Author:
Dave Hastings (daveh) 22-Oct-1992
Revision History:
--*/
#include "sprofp.h"
int WINAPI WinMain(
HANDLE hInst,
HANDLE hPrevInst,
LPSTR lpCmdLine,
int nCmdShow
)
/*++
Routine Description:
This routine contains the initialization for the profiler
Arguments:
hInst -- Supplies the handle of the current instance
hPrevInst -- Supplies the handle of the previous instance
lpCmdLine -- Supplies a pointer to the NULL terminated command line
nCmdShow -- Supplies flags to indicate how the window should be shown
Return Value:
None.
--*/
{
PUCHAR CommandLine = NULL;
DWORD ProcessId = 0;
DWORD CreateFlags = 0;
HWND MainWindow;
MSG Message;
UCHAR StringBuffer[256];
//
// Initialize Window package
//
if (!InitSprof(hInst)) {
return FALSE;
}
//
// Parse arguments, and determine process to debug
//
if (!ParseArguments(
lpCmdLine,
&CommandLine,
&ProcessId,
&CreateFlags)
) {
exit(-1);
}
//
// Create the main Window
//
MainWindow = CreateSprofWindow(
"Segmented Profiler",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInst
);
if (!MainWindow) {
return FALSE;
}
//
// Show the window
//
ShowWindow(MainWindow, SW_SHOWDEFAULT);
//
// Print a signon message
//
sprintf(StringBuffer, "Segmented Profiler profiling %s", CommandLine);
PrintToSprofWindow(
MainWindow,
StringBuffer
);
//
// Start DebugEvent processing
//
StartDebugProcessing(
MainWindow,
CommandLine,
ProcessId,
CreateFlags
);
//
// Process Messages till WM_QUIT
//
while (GetMessage(&Message, NULL, 0, 0)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
return Message.wParam;
}
BOOL
ParseArguments(
IN PUCHAR SprofCommandLine,
OUT PUCHAR *CommandLine,
OUT PDWORD ProcessId,
OUT PDWORD CreateFlags
)
/*++
Routine Description:
This routine parses the command line arguments for Sprof.
-p # -- profile the process specified by #
-o -- profile the process tree.
Arguments:
SprofCommandLine -- Supplies the command line string
CommandLine -- Returns the composite command line
ProcessId -- Returns the process id, if -p specified
CreateFlags -- Returns the flags for the process creation
Return Value:
TRUE if no errors
FALSE otherwise
--*/
{
BOOL MoreSwitches = TRUE;
ULONG Flags = DEFAULT_CREATE_FLAGS | DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS;
ULONG CommandLength = 0;
ULONG Pid = 0;
PUCHAR CurrentPosn;
int RetVal;
CurrentPosn = SprofCommandLine;
//
// Check for switches
//
// Note: Switches for Sprof MUST be the first argument(s), because any
// switches later on must be passed the the application being
// profiled
//
while (MoreSwitches && *CurrentPosn) {
//
// If this is a switch
//
if (*CurrentPosn == '-') {
//
// If it is the process ID switch
//
if (tolower(CurrentPosn[1]) == 'p') {
//
// Scan the next string for the process ID
//
CurrentPosn += 2;
RetVal = 0;
if (*CurrentPosn) {
while (*CurrentPosn++ == ' ') {
}
RetVal = sscanf(CurrentPosn,"%lx",&Pid);
}
if (RetVal != 1) {
Usage();
return FALSE;
}
//
// Else If it is the profile process tree switch
//
} else if (tolower(CurrentPosn[1]) == 'o') {
CurrentPosn += 2;
//
// Turn off ONLY_THIS_PROCESS bit
//
Flags &= ~DEBUG_ONLY_THIS_PROCESS;
//
// Else Incorrect Command Line
//
} else {
Usage();
return FALSE;
}
//
// Else No more switches
//
} else {
MoreSwitches = FALSE;
}
while (*CurrentPosn && (*CurrentPosn == ' ')) {
CurrentPosn++;
}
}
//
// Return information
//
*CreateFlags = Flags;
*ProcessId = Pid;
*CommandLine = CurrentPosn;
return TRUE;
}
VOID
Usage(
VOID
)
/*++
Routine Description:
This routine prints out usage information for sprof
Arguments:
None.
Return Value:
None.
--*/
{
printf("Sprof useage: sprof [-o] [-p <pid>] <command line>\n");
printf(" -o -- profile process tree\n");
printf(" -p <pid> -- profile running process <pid>\n");
}
#if 0
// stuff for connecting to the process
if (ProcessId) {
//
// Connect to an existing process
//
if (!DebugActiveProcess(ProcessId)) {
printf(
"Sprof: could not attach to process %lx, error %lx\n",
ProcessId,
GetLastError()
);
exit(-1);
}
} else {
PROCESS_INFORMATION ProcessInfo;
STARTUPINFO StartupInfo;
//
// Create the process to profile
//
StartupInfo.cb = sizeof(STARTUPINFO);
StartupInfo.lpReserved = NULL;
StartupInfo.lpDesktop = NULL;
StartupInfo.lpTitle = NULL;
StartupInfo.dwFlags = 0L;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = NULL;
if (!
CreateProcess(
NULL, // no image file name
CommandLine, // command line from ParseArg..
NULL, // no process security
NULL, // no thread security
FALSE, // don't inherit handles
CreateFlags, // creation flags from Parse...
NULL, // use current env
NULL, // use current cd
&StartupInfo,
&ProcessInfo
)
) {
printf(
"Sprof: could not create process %s, error %lx\n",
CommandLine,
GetLastError
);
exit(-1);
}
//
// Close the handles from create process, because we will get
// another set in the first debug event
//
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
}
//
// Process Debug Events
//
ProcessDebugEvents();
#endif