Windows-Server-2003/sdktools/debuggers/ntsd64/stepgo.hpp

204 lines
4.8 KiB
C++

//----------------------------------------------------------------------------
//
// Handles stepping, tracing, watching and go.
//
// Copyright (C) Microsoft Corporation, 1997-2002.
//
//----------------------------------------------------------------------------
#ifndef _STEPGO_HPP_
#define _STEPGO_HPP_
struct WatchFunction
{
ULONG64 StartOffset;
// Hash bucket list.
WatchFunction* Next;
// Sorted list.
WatchFunction* Sort;
ULONG Calls;
ULONG MinInstr, MaxInstr, TotalInstr;
// This counter is incremented every time a system call
// instruction is hit inside the function.
ULONG SystemCalls;
// There's no strong need to make this symbol buffer
// MAX_SYMBOL_LEN as the output only displays half a
// line's worth of the name. The only real reason to
// keep more is to reduce false sharing due to prefix
// matches. The buffer is large enough that this should
// be extremely rare, plus we keep the true length
// as a further check.
ULONG SymbolLength;
CHAR Symbol[256];
};
struct WatchCallStack
{
ADDR CallSite;
WatchFunction* Func;
WatchCallStack* Prev, *Next;
LONG Level;
ULONG InstrCount, ChildInstrCount;
};
enum WATCH_CALL_TYPE
{
WCALL_OTHER,
WCALL_CALL,
WCALL_RETURN,
};
//----------------------------------------------------------------------------
//
// WatchFunctions.
//
// Collects function information encountered during watch tracing.
//
//----------------------------------------------------------------------------
#define WF_BUCKETS 71
class WatchFunctions
{
public:
WatchFunctions(void);
void Start(void);
void End(PADDR PcAddr);
BOOL IsStarted(void)
{
return m_Started;
}
void OutputFunctions(void);
void OutputSysCallFunctions(void);
WatchFunction* FindAlways(PSTR Sym, ULONG64 Start);
WatchCallStack* GetTopCall(void)
{
return m_CallTop;
}
WatchCallStack* PushCall(WatchFunction* Func);
void PopCall(void);
WatchCallStack* PopCallsToCallSite(PADDR Pc);
WatchCallStack* PopCallsToFunctionStart(ULONG64 Start);
void ReuseCall(WatchCallStack* Call,
WatchFunction* ReinitFunc);
void IndentForCall(WatchCallStack* Call);
void OutputCall(WatchCallStack* Call, WATCH_CALL_TYPE Type);
void SetDefaultParameters(void);
void ParseParameters(void);
LONG GetCallLevel(void)
{
return m_CallLevel;
}
LONG ChangeCallLevel(LONG Delta)
{
m_CallLevel += Delta;
if (m_CallLevel < 0)
{
m_CallLevel = 0;
}
return m_CallLevel;
}
ULONG RecordEvent(void)
{
return ++m_TotalWatchTraceEvents;
}
ULONG RecordThreadMismatch(void)
{
return ++m_TotalWatchThreadMismatches;
}
LONG m_MaxCallLevelAllowed;
ULONG m_OutputReturnValues:1;
ULONG m_OutputCallAddrs:1;
ULONG m_OutputCalls:1;
ULONG m_OutputSummary:1;
protected:
ULONG Hash(PSTR Sym, ULONG SymLen)
{
// Hash on the first and last letters of the symbol.
return ((ULONG)(UCHAR)Sym[0] +
(ULONG)(UCHAR)Sym[SymLen - 1]) % WF_BUCKETS;
}
WatchFunction* Add(PSTR Sym, ULONG64 Start);
WatchFunction* Find(PSTR Sym);
void Clear(void);
BOOL m_Started;
ULONG m_TotalInstr;
ULONG m_TotalWatchTraceEvents;
ULONG m_TotalWatchThreadMismatches;
WatchFunction* m_Funcs[WF_BUCKETS];
WatchFunction* m_Sorted;
WatchCallStack* m_CallTop, *m_CallBot;
LONG m_CallLevel;
};
extern WatchFunctions g_WatchFunctions;
extern ULONG g_StepTracePassCount;
extern ULONG64 g_StepTraceInRangeStart;
extern ULONG64 g_StepTraceInRangeEnd;
extern BOOL g_SrcLineValid;
extern BOOL g_WatchTrace;
extern BOOL g_WatchWhole;
extern ADDR g_WatchTarget;
extern ULONG64 g_WatchInitialSP;
extern ULONG64 g_WatchBeginCurFunc;
extern ULONG64 g_WatchEndCurFunc;
#define MAX_GO_BPS 16
extern Breakpoint* g_GoBreakpoints[MAX_GO_BPS];
extern ULONG g_NumGoBreakpoints;
void ResetStepTrace(void);
BOOL StepTracePass(PADDR PcAddr);
void
SetExecGo(ULONG ExecStatus,
PADDR StartAddr,
ThreadInfo* Thread,
BOOL ThreadFreeze,
ULONG BpCount,
PADDR BpArray,
PCSTR BpCmd);
void
SetExecStepTrace(PADDR StartAddr,
ULONG64 PassCount,
ThreadInfo* Thread,
BOOL ThreadFreeze,
BOOL ToCall,
char StepType);
void
ParseGoCmd(ThreadInfo* Thread,
BOOL ThreadFreeze);
void ParseStepTrace(ThreadInfo* Thread,
BOOL ThreadFreeze,
char StepType);
VOID SetupSpecialCalls(VOID);
#endif // #ifndef _STEPGO_HPP_