windows-nt/Source/XPSP1/NT/sdktools/debuggers/windbg/statebuf.h
2020-09-26 16:20:57 +08:00

325 lines
7.6 KiB
C++

//----------------------------------------------------------------------------
//
// Debuggee state buffers.
//
// Copyright (C) Microsoft Corporation, 1999-2000.
//
//----------------------------------------------------------------------------
#ifndef __STATEBUF_H__
#define __STATEBUF_H__
// Different WU_UPDATE qualifiers, sent in WPARAM.
enum UpdateType
{
UPDATE_BUFFER,
UPDATE_BP,
UPDATE_EXEC,
UPDATE_INPUT_REQUIRED,
UPDATE_START_SESSION,
UPDATE_END_SESSION,
UPDATE_PROMPT_TEXT,
UPDATE_EXIT
};
typedef enum
{
MINVAL_WINDOW = 0,
DOC_WINDOW,
WATCH_WINDOW,
LOCALS_WINDOW,
CPU_WINDOW,
DISASM_WINDOW,
CMD_WINDOW,
SCRATCH_PAD_WINDOW,
MEM_WINDOW,
QUICKW_WINDOW,
CALLS_WINDOW,
PROCESS_THREAD_WINDOW,
MAXVAL_WINDOW,
// Artificial values so there are well-defined bit
// positions for state which is not tied to a specific window.
EVENT_BIT,
BP_BIT,
BP_CMDS_BIT,
FILTER_BIT,
MODULE_BIT
} WIN_TYPES, * PWIN_TYPES;
#define FIRST_WINDOW ((WIN_TYPES)(MINVAL_WINDOW + 1))
#define LAST_WINDOW ((WIN_TYPES)(MAXVAL_WINDOW - 1))
//----------------------------------------------------------------------------
//
// StateBuffer.
//
// A state buffer is a dynamic container for data passed from
// the engine thread to the UI thread. It may be used for
// holding window content, in which case it will have an HWND
// associated with it, or it can be an internal buffer for non-UI
// purposes.
//
// A list of current window-associated state buffers is kept for
// the engine to traverse when it is updating state for the UI.
// The UI thread is the only thread that can add to this list.
// The engine thread is the only thread that can remove a buffer
// from the list. This is necessary for proper lifetime management
// of dynamically-created buffers.
//
//----------------------------------------------------------------------------
class StateBuffer : public LIST_ENTRY
{
public:
DBG_CRITICAL_SECTION m_Lock;
WIN_TYPES m_enumType;
HWND m_Win;
ULONG m_UpdateTypes;
UpdateType m_UpdateType;
StateBuffer(ULONG ChangeBy);
virtual ~StateBuffer(void);
PVOID AddData(ULONG Len);
BOOL AddString(PCSTR Str, BOOL SoftTerminate);
void RemoveHead(ULONG Len);
void RemoveMiddle(ULONG Start, ULONG Len);
void RemoveTail(ULONG Len);
HRESULT Resize(ULONG Len);
void Free(void);
void Empty(void)
{
m_DataUsed = 0;
}
HRESULT GetStatus(void)
{
return m_Status;
}
void SetStatus(HRESULT Status)
{
m_Status = Status;
}
ULONG GetReadRequest(void)
{
return m_ReadRequest;
}
ULONG GetReadDone(void)
{
return m_ReadDone;
}
void RequestRead(void)
{
InterlockedIncrement((LONG *)&m_ReadRequest);
}
void SetReadDone(ULONG Done)
{
m_ReadDone = Done;
}
PVOID GetDataBuffer(void)
{
return m_Data;
}
ULONG GetDataLen(void)
{
return m_DataUsed;
}
HRESULT Update(void);
void UiRequestRead(void);
HRESULT UiLockForRead(void);
// Base implementation just returns S_OK for
// buffers maintained in other ways.
// ReadState should only be called in the engine thread.
virtual HRESULT ReadState(void);
protected:
void SetNoData(void)
{
m_Data = NULL;
m_DataLen = 0;
Empty();
}
ULONG m_ChangeBy;
UINT m_UpdateMessage;
HRESULT m_Status;
ULONG m_ReadRequest;
ULONG m_ReadDone;
PBYTE m_Data;
ULONG m_DataLen;
ULONG m_DataUsed;
};
//----------------------------------------------------------------------------
//
// OutputToStateBuffer.
//
//----------------------------------------------------------------------------
class OutputToStateBuffer : public DefOutputCallbacks
{
public:
OutputToStateBuffer(void)
{
m_Buffer = NULL;
}
void SetBuffer(StateBuffer* Buffer)
{
m_Buffer = Buffer;
}
HRESULT Start(BOOL Empty);
HRESULT End(BOOL RemoveLastNewLine);
ULONG GetLineCount(void)
{
return m_NewLineCount + m_PartialLine;
}
ULONG RecountLines(void)
{
m_NewLineCount = 0;
AddLines((PSTR)m_Buffer->GetDataBuffer() + m_DataStart);
return GetLineCount();
}
void ReplaceChar(char From, char To);
// IDebugOutputCallbacks.
STDMETHOD(Output)(
THIS_
IN ULONG Mask,
IN PCSTR Text
);
private:
void AddLines(PCSTR Start);
StateBuffer* m_Buffer;
ULONG m_DataStart;
HRESULT m_Status;
ULONG m_NewLineCount;
ULONG m_PartialLine;
};
extern OutputToStateBuffer g_OutStateBuf;
extern OutputToStateBuffer g_UiOutStateBuf;
//----------------------------------------------------------------------------
//
// Dynamic state buffers.
//
//----------------------------------------------------------------------------
extern LIST_ENTRY g_StateList;
// Global lock for short operations where it doesn't matter
// if the threads block on each other briefly. This lock should
// not be held longer than a fraction of a second.
// Used for protecting:
// State buffer list.
// g_Event values.
extern DBG_CRITICAL_SECTION g_QuickLock;
#define LockStateBuffer(Buffer) Dbg_EnterCriticalSection(&(Buffer)->m_Lock)
#define UnlockStateBuffer(Buffer) Dbg_LeaveCriticalSection(&(Buffer)->m_Lock)
#define AssertStateBufferLocked(Buffer) \
Assert(Dbg_CriticalSectionOwned(&(Buffer)->m_Lock))
extern ULONG64 g_CodeIp;
// If g_CodeFileFound[0] == 0 no source file was found.
extern char g_CodeFileFound[];
// If g_CodeSymFile[0] == 0 no source symbol information was found.
extern char g_CodeSymFile[];
extern ULONG g_CodeLine;
extern BOOL g_CodeUserActivated;
extern ULONG g_CodeBufferSequence;
extern ULONG64 g_EventIp;
extern ULONG64 g_EventReturnAddr;
extern ULONG g_CurProcessId, g_CurProcessSysId;
extern ULONG g_CurThreadId, g_CurThreadSysId;
enum BpStateType
{
BP_ENABLED,
BP_DISABLED,
BP_NONE,
BP_UNKNOWN
};
struct BpBufferData
{
ULONG64 Offset;
ULONG Id;
ULONG Flags;
ULONG Thread;
ULONG Sequence;
ULONG FileOffset;
};
extern ULONG g_BpCount;
extern StateBuffer* g_BpBuffer;
extern ULONG g_BpTextOffset;
extern StateBuffer* g_BpCmdsBuffer;
extern StateBuffer* g_FilterTextBuffer;
extern StateBuffer* g_FilterBuffer;
extern ULONG g_FilterArgsOffset;
extern ULONG g_FilterCmdsOffset;
extern ULONG g_FilterWspCmdsOffset;
extern ULONG g_NumSpecEvents, g_NumSpecEx, g_NumArbEx;
extern StateBuffer* g_ModuleBuffer;
extern ULONG g_NumModules;
void FillCodeBuffer(ULONG64 Ip, BOOL UserActivated);
void FillEventBuffer(void);
void ReadStateBuffers(void);
#define BUFFERS_ALL 0xffffffff
void InvalidateStateBuffers(ULONG Types);
void UpdateBufferWindows(ULONG Types, UpdateType Type);
//----------------------------------------------------------------------------
//
// Static state buffers.
//
//----------------------------------------------------------------------------
extern StateBuffer* g_RegisterNamesBuffer;
extern StateBuffer* g_WatchWinBuffer;
extern PUSHORT g_RegisterMap;
extern ULONG g_RegisterMapEntries;
#define MAP_REGISTER(i) \
(g_RegisterMap != NULL && (i) < g_RegisterMapEntries ? \
g_RegisterMap[(i)] : (i))
void GetRegisterMapText(HWND Edit);
void ScanRegisterMapText(HWND Edit);
//----------------------------------------------------------------------------
//
// UI thread state buffer.
//
// The UI thread has simple needs and so one state buffer for
// output capture is sufficient.
//
//----------------------------------------------------------------------------
extern StateBuffer g_UiOutputCapture;
#endif // #ifndef __STATEBUF_H__