home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 40 / IOPROG_40.ISO / SOFT / NETFrameworkSDK.exe / comsdk.cab / samples1.exe / Debugger / dshell.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-06-23  |  45.7 KB  |  1,500 lines

  1. /* ------------------------------------------------------------------------- *
  2.  * debug\comshell.h: com debugger shell class
  3.  * ------------------------------------------------------------------------- */
  4.  
  5. #ifndef __DSHELL_H__
  6. #define __DSHELL_H__
  7.  
  8. #include <stdio.h>
  9.  
  10. #define ADDRESS IMAGHLP_ADDRESS
  11. #include <imagehlp.h>
  12. #undef ADDRESS
  13.  
  14. #undef CreateProcess
  15.  
  16. #include "cor.h"
  17. #include "shell.h"
  18. #include "corpub.h"
  19. #include "corsym.h"
  20. #include "cordebug.h"
  21. #include "corerror.h"
  22.  
  23.  
  24. #ifdef _INTERNAL_DEBUG_SUPPORT_
  25. #include <msdis.h>
  26.  
  27. #ifdef _X86_
  28. #include <disx86.h>
  29. #endif
  30. #else
  31. #include <strstream>           // For std::ostream
  32. #endif
  33.  
  34. #include <imagehlp.h>
  35.  
  36. // Names of registry keys used to hold the source files path.
  37. #define REG_DEBUGGER_KEY "Software\\Microsoft\\COMPlus\\Samples\\CorDbg"
  38. #define REG_SOURCES_KEY  "CorDbgSourceFilePath"
  39. #define REG_MODE_KEY     "CorDbgModes"
  40.  
  41. #define REG_COMPLUS_KEY          "Software\\Microsoft\\COMPlus\\"
  42. #define REG_COMPLUS_DEBUGGER_KEY "DbgManagedDebugger"
  43.  
  44. #define MAX_MODULES                        64
  45. #define MAX_FILE_MATCHES_PER_MODULE        4
  46. #define MAX_EXT                            20
  47. #define MAX_PATH_ELEMS                    64
  48. #define MAX_CACHE_ELEMS                    256
  49.  
  50. #define MAX_SYMBOL_NAME_LENGTH            256
  51.  
  52. enum
  53. {
  54.     NULL_THREAD_ID = -1,
  55.     NULL_PROCESS_ID = -1
  56. };
  57.  
  58. enum ListType
  59. {
  60.     LIST_MODULES = 0,
  61.     LIST_CLASSES,
  62.     LIST_FUNCTIONS
  63. };
  64.  
  65. #define SETBITULONG64( x ) ( (ULONG64)1 << (x) )
  66.  
  67. // Define max source file buckets for source file cache present for each module
  68. #define MAX_SF_BUCKETS      9
  69.  
  70. // Modes used in the shell to control various global settings.
  71. enum DebuggerShellModes
  72. {
  73.     DSM_DISPLAY_REGISTERS_AS_HEX        = 0x00000001,
  74.     DSM_WIN32_DEBUGGER                  = 0x00000002,
  75.     DSM_SEPARATE_CONSOLE                = 0x00000004,
  76.     DSM_ENABLE_JIT_OPTIMIZATIONS        = 0x00000008,
  77.     DSM_ENABLE_EDIT_AND_CONTINUE        = 0x00000010,
  78.     DSM_SHOW_CLASS_LOADS                = 0x00000020,
  79.     DSM_SHOW_MODULE_LOADS               = 0x00000040,
  80.     DSM_SHOW_UNMANAGED_TRACE            = 0x00000080,
  81.     DSM_IL_NATIVE_PRINTING              = 0x00000100,
  82.     DSM_SHOW_ARGS_IN_STACK_TRACE        = 0x00000200,
  83.     DSM_UNMAPPED_STOP_PROLOG            = 0x00000400,
  84.     DSM_UNMAPPED_STOP_EPILOG            = 0x00000800,
  85.     DSM_UNMAPPED_STOP_UNMANAGED         = 0x00001000,
  86.     DSM_UNMAPPED_STOP_ALL               = 0x00002000,
  87.     DSM_INTERCEPT_STOP_CLASS_INIT       = 0x00004000,
  88.     DSM_INTERCEPT_STOP_EXCEPTION_FILTER = 0x00008000,
  89.     DSM_INTERCEPT_STOP_SECURITY         = 0x00010000,    
  90.     DSM_INTERCEPT_STOP_CONTEXT_POLICY   = 0x00020000,
  91.     DSM_INTERCEPT_STOP_INTERCEPTION     = 0x00040000,
  92.     DSM_INTERCEPT_STOP_ALL              = 0x00080000,  
  93.     DSM_SHOW_APP_DOMAIN_ASSEMBLY_LOADS  = 0x00100000,
  94.     DSM_ENHANCED_DIAGNOSTICS            = 0x00200000,
  95.     DSM_SHOW_MODULES_IN_STACK_TRACE     = 0x00400000,
  96.     DSM_SHOW_SELECTIVE_APPDOMAIN        = 0x00800000,
  97.     DSM_LOGGING_MESSAGES                = 0x01000000,
  98.     DSM_DUMP_MEMORY_IN_BYTES            = 0x02000000,
  99.     DSM_SHOW_SUPERCLASS_ON_PRINT        = 0x04000000,
  100.     DSM_SHOW_STATICS_ON_PRINT           = 0x08000000,
  101.  
  102.     DSM_MAXIMUM_MODE             = 28, // count of all modes, not a mask.
  103.     DSM_INVALID_MODE             = 0x00000000,
  104.     DSM_DEFAULT_MODES            = DSM_DISPLAY_REGISTERS_AS_HEX |
  105.                                    DSM_ENABLE_EDIT_AND_CONTINUE |
  106.                                    DSM_SHOW_ARGS_IN_STACK_TRACE |
  107.                                    DSM_SHOW_MODULES_IN_STACK_TRACE
  108. };
  109.  
  110. // A helper function which will return the generic interface for
  111. // either the appdomain or process, if DSM_SHOW_SELECTIVE_APPDOMAIN
  112. // is 1 or 0, respectively
  113. ICorDebugController *GetControllerInterface(ICorDebugAppDomain *pAppDomain);
  114.  
  115. // Structure used to define information about debugger shell modes.
  116. struct DSMInfo
  117. {
  118.     DebuggerShellModes  modeFlag;
  119.     WCHAR              *name;
  120.     WCHAR              *onDescription;
  121.     WCHAR              *offDescription;
  122.     WCHAR              *generalDescription;
  123.     WCHAR              *descriptionPad;
  124. };
  125.  
  126.  
  127. /* ------------------------------------------------------------------------- *
  128.  * Forward declarations
  129.  * ------------------------------------------------------------------------- */
  130.  
  131. class DebuggerBreakpoint;
  132. class DebuggerCodeBreakpoint;
  133. class DebuggerSourceCodeBreakpoint;
  134. class DebuggerModule;
  135. class DebuggerUnmanagedThread;
  136. class DebuggerManagedThread;
  137. class DebuggerSourceFile;
  138. class DebuggerFunction;
  139. class DebuggerFilePathCache;
  140. class ModuleSourceFile;
  141.  
  142.  
  143. /* ------------------------------------------------------------------------- *
  144.  * Debugger FilePathCache
  145.  * This class keeps track of the fully qualified filename for each module
  146.  * for files which were opened as a result of hitting a breakpoint, stack 
  147.  * trace, etc. This will be persisted for later runs of the debugger.
  148.  * ------------------------------------------------------------------------- */
  149. class DebuggerFilePathCache
  150. {
  151. private:
  152.     CHAR            *m_rstrPath [MAX_PATH_ELEMS];
  153.     int                m_iPathCount;
  154.     CHAR            *m_rpstrModName [MAX_CACHE_ELEMS];
  155.     ISymUnmanagedDocument    *m_rDocs [MAX_CACHE_ELEMS];
  156.     CHAR            *m_rpstrFullPath [MAX_CACHE_ELEMS];
  157.     int                m_iCacheCount;
  158.  
  159.     WCHAR            m_szExeName [MAX_PATH];
  160.  
  161. public:
  162.     // Constructor
  163.     DebuggerFilePathCache()
  164.     {
  165.         for (int i=0; i<MAX_PATH_ELEMS; i++)
  166.             m_rstrPath [i] = NULL;
  167.         m_iPathCount = 0;
  168.  
  169.         m_iCacheCount = 0;
  170.  
  171.         m_szExeName [0] = L'\0';
  172.     }
  173.  
  174.     // Destructor
  175.     ~DebuggerFilePathCache()
  176.     {
  177.         for (int i=0; i<m_iPathCount; i++)
  178.             delete [] m_rstrPath [i];
  179.  
  180.         for (i=0; i<m_iCacheCount; i++)
  181.         {
  182.             delete [] m_rpstrModName [i];
  183.             delete [] m_rpstrFullPath [i];
  184.         }
  185.     }
  186.  
  187.     HRESULT Init (void);
  188.     HRESULT    InitPathArray (WCHAR *pstrName);
  189.     int  GetPathElemCount (void) { return m_iPathCount;}
  190.     CHAR *GetPathElem (int iIndex) { return m_rstrPath [iIndex];}
  191.     int     GetFileFromCache (DebuggerModule *pModule, ISymUnmanagedDocument *doc,
  192.                            CHAR **ppstrFName);    
  193.     BOOL UpdateFileCache (DebuggerModule *pModule, ISymUnmanagedDocument *doc,
  194.                           CHAR *pFullPath);
  195. };
  196.  
  197. class ModuleSearchElement
  198. {
  199. private:
  200.     char *pszName;
  201.     ModuleSearchElement *pNext;
  202.  
  203. public:
  204.     ModuleSearchElement() 
  205.     {
  206.         pszName = NULL;
  207.         pNext = NULL;
  208.     }
  209.  
  210.     ~ModuleSearchElement()
  211.     {
  212.         delete [] pszName;
  213.     }
  214.  
  215.     void SetName (char *szModName)
  216.     {
  217.         pszName = new char [strlen(szModName) + 1];
  218.  
  219.         if (pszName)
  220.         {
  221.             strcpy (pszName, szModName);
  222.         }
  223.     }
  224.  
  225.     char *GetName (void) { return pszName;}
  226.  
  227.     void SetNext (ModuleSearchElement *pEle) { pNext = pEle;}
  228.     ModuleSearchElement *GetNext (void) { return pNext;}
  229. };
  230.  
  231. class ModuleSearchList
  232. {
  233. private:
  234.     ModuleSearchElement *pHead;
  235. public:
  236.     ModuleSearchList()
  237.     {
  238.         pHead = NULL;
  239.     }
  240.  
  241.     ~ModuleSearchList()
  242.     {
  243.         ModuleSearchElement *pTemp;
  244.         while (pHead)
  245.         {
  246.             pTemp = pHead;
  247.             pHead = pHead->GetNext();
  248.             delete pTemp;
  249.         }        
  250.     }
  251.  
  252.     BOOL ModuleAlreadySearched (char *szModName)
  253.     {
  254.         ModuleSearchElement *pTemp = pHead;
  255.         while (pTemp)
  256.         {
  257.             char *pszName = pTemp->GetName();
  258.             if (pszName)
  259.                 if (!strcmp (pszName, szModName))
  260.                     return TRUE;
  261.             pTemp = pTemp->GetNext();
  262.         }
  263.  
  264.         return FALSE;
  265.     }
  266.     void AddModuleToAlreadySearchedList (char *szModName)
  267.     {
  268.         ModuleSearchElement *pTemp = new ModuleSearchElement;
  269.         if (pTemp)
  270.         {
  271.             pTemp->SetName (szModName);
  272.             pTemp->SetNext (pHead);
  273.             pHead = pTemp;
  274.         }        
  275.     }    
  276. };
  277.  
  278. /* ------------------------------------------------------------------------- *
  279.  * Base class
  280.  * ------------------------------------------------------------------------- */
  281.  
  282. class DebuggerBase
  283. {
  284. public:
  285.     DebuggerBase(ULONG token) : m_token(token)
  286.     {
  287.         
  288.     }
  289.     virtual ~DebuggerBase()
  290.     {
  291.         
  292.     }
  293.  
  294.     ULONG GetToken()
  295.     {
  296.         return(m_token);
  297.     }
  298.  
  299. protected:
  300.     ULONG   m_token;
  301. };
  302.  
  303. /* ------------------------------------------------------------------------- *
  304.  * HashTable class
  305.  * ------------------------------------------------------------------------- */
  306.  
  307. struct DebuggerHashEntry
  308. {
  309.     FREEHASHENTRY entry;
  310.     DebuggerBase* pBase;
  311. };
  312.  
  313. class DebuggerHashTable : private CHashTableAndData<CNewData>
  314. {
  315. private:
  316.     bool    m_initialized;
  317.  
  318.     BOOL Cmp(const BYTE* pc1, const HASHENTRY* pc2)
  319.     {
  320.         return((ULONG)pc1) != ((DebuggerHashEntry*)pc2)->pBase->GetToken();
  321.     }
  322.  
  323.     USHORT HASH(ULONG token)
  324.     {
  325.         return(USHORT) (token ^ (token>>16));
  326.     }
  327.  
  328.     BYTE* KEY(ULONG token)
  329.     {
  330.         return(BYTE* ) token;
  331.     }
  332.  
  333. public:
  334.  
  335.     DebuggerHashTable(USHORT size) 
  336.     : CHashTableAndData<CNewData>(size), m_initialized(false)
  337.     {
  338.         
  339.     }
  340.     ~DebuggerHashTable();
  341.  
  342.     HRESULT AddBase(DebuggerBase* pBase);
  343.     DebuggerBase* GetBase(ULONG token);
  344.     BOOL RemoveBase(ULONG token);
  345.     void RemoveAll();
  346.  
  347.     DebuggerBase* FindFirst(HASHFIND* find);
  348.     DebuggerBase* FindNext(HASHFIND* find);
  349. };
  350.  
  351. /* ------------------------------------------------------------------------- *
  352.  * Debugger Stepper Table class
  353.  * ------------------------------------------------------------------------- *
  354.  
  355.     @class StepperHashTable | It's possible for there to be multiple,
  356.     outstanding,uncompleted steppers within the debuggee, and any of them 
  357.     can complete after a given 'continue'. Thus, instead of a 'last stepper'
  358.     field off of the thread object, we really need a table of active steppers
  359.     off the thread object, which is what a StepperHashTable is.  
  360.     @comm Currently unused, will fix a known bug in cordbg
  361. */
  362. struct StepperHashEntry
  363. {
  364.     FREEHASHENTRY         entry;
  365.     ICorDebugStepper*     pStepper;
  366. };
  367.  
  368. class StepperHashTable : private CHashTableAndData<CNewData>
  369. {
  370. private:
  371.     bool    m_initialized;
  372.  
  373.     BOOL Cmp(const BYTE* pc1, const HASHENTRY* pc2)
  374.     {
  375.         return((ICorDebugStepper*)pc1) != ((StepperHashEntry*)pc2)->pStepper;
  376.     }
  377.  
  378.     USHORT HASH(ICorDebugStepper *pStepper)
  379.     {
  380.         return(USHORT) ((UINT)pStepper ^ ((UINT)pStepper >>16));
  381.     }
  382.  
  383.     BYTE* KEY(ICorDebugStepper *pStepper)
  384.     {
  385.         return(BYTE* ) pStepper;
  386.     }
  387.  
  388. public:
  389.  
  390.     StepperHashTable(USHORT size) 
  391.     : CHashTableAndData<CNewData>(size), m_initialized(false)
  392.     {
  393.     }
  394.     ~StepperHashTable();
  395.  
  396.     HRESULT Initialize(void);
  397.  
  398.     HRESULT AddStepper(ICorDebugStepper *pStepper);
  399.         //Also does an AddRef, of course
  400.     
  401.     bool IsStepperPresent(ICorDebugStepper *pStepper);
  402.     
  403.     BOOL RemoveStepper(ICorDebugStepper *pStepper);
  404.     
  405.     void ReleaseAll(); //will go through & release all the steppers
  406.         //in the table, twice, then delete them.  This should deallocate
  407.         //them both from the table & from cordbg
  408.  
  409.     ICorDebugStepper *FindFirst(HASHFIND* find);
  410.     ICorDebugStepper *FindNext(HASHFIND* find);
  411. };
  412.  
  413.  
  414. class DebuggerManagedThread : public DebuggerBase
  415. {
  416. public:
  417.  
  418.     DebuggerManagedThread(DWORD dwThreadId,ICorDebugThread *icdThread) :
  419.         m_thread(icdThread), DebuggerBase(dwThreadId),
  420.         m_lastFuncEval(NULL)
  421.     {
  422.         fSuperfluousFirstStepCompleteMessageSuppressed = false;
  423.     
  424.         //@todo port: if DWORD or ULONG size changes, create a field
  425.         //for dwThreadId
  426.         _ASSERTE( sizeof(dwThreadId) == sizeof(m_token));
  427.  
  428.         if (m_thread != NULL )
  429.             m_thread->AddRef();
  430.  
  431.  
  432.         m_pendingSteppers = new StepperHashTable(7);
  433.     }
  434.  
  435.     virtual ~DebuggerManagedThread()
  436.     {
  437.         _ASSERTE( m_thread != NULL );
  438.         m_thread->Release();
  439.         m_thread = NULL;
  440.  
  441.         if (m_pendingSteppers != NULL )
  442.         {
  443.             m_pendingSteppers->ReleaseAll();
  444.         }
  445.  
  446.         if (m_lastFuncEval)
  447.         {
  448.             m_lastFuncEval->Release();
  449.             m_lastFuncEval = NULL;
  450.         }
  451.     }
  452.     
  453.     StepperHashTable*       m_pendingSteppers;
  454.     ICorDebugThread*       m_thread;
  455.     bool                   fSuperfluousFirstStepCompleteMessageSuppressed;
  456.     ICorDebugEval*         m_lastFuncEval;
  457. };
  458.  
  459. /* ------------------------------------------------------------------------- *
  460.  * DebuggerShell class
  461.  * ------------------------------------------------------------------------- */
  462.  
  463. class DebuggerShell : public Shell
  464. {
  465. public:
  466.     DebuggerShell(FILE* in, FILE* out);
  467.     virtual ~DebuggerShell();
  468.  
  469.     HRESULT Init();
  470.  
  471.     CorDebugUnmappedStop ComputeStopMask( void );
  472.     CorDebugIntercept    ComputeInterceptMask( void );
  473.     
  474.     
  475.     bool ReadLine(WCHAR* buffer, int maxCount);
  476.     virtual void Write(const WCHAR* buffer, ...);
  477.     virtual void Error(const WCHAR* buffer, ...);
  478.  
  479.     void AddCommands();
  480.  
  481.     void Kill();
  482.     virtual void Run(bool fNoInitialContinue = false);
  483.     void Stop(ICorDebugController *controller, 
  484.               ICorDebugThread* thread,
  485.               DebuggerUnmanagedThread *unmanagedThread = NULL);
  486.     HRESULT AsyncStop(ICorDebugController *controller, 
  487.                       DWORD dwTimeout = 500);
  488.     void Continue(ICorDebugController* process, 
  489.                   ICorDebugThread* thread,
  490.                   DebuggerUnmanagedThread *unmanagedThread = NULL,
  491.                   BOOL fIsOutOfBand = FALSE);
  492.     void Interrupt();
  493.     void SetTargetProcess(ICorDebugProcess* process);
  494.     void SetCurrentThread(ICorDebugProcess* process, ICorDebugThread* thread,
  495.                           DebuggerUnmanagedThread *unmanagedThread = NULL);
  496.     void SetCurrentChain(ICorDebugChain* chain);
  497.     void SetCurrentFrame(ICorDebugFrame* frame);
  498.     void SetDefaultFrame();
  499.  
  500.     HRESULT PrintThreadState(ICorDebugThread* thread);
  501.     HRESULT PrintChain(ICorDebugChain *chain, int *frameIndex = NULL,
  502.                                             int *iNumFramesToShow = NULL);
  503.     HRESULT PrintFrame(ICorDebugFrame *frame);
  504.  
  505.     ICorDebugValue* EvaluateExpression(const WCHAR* exp, ICorDebugILFrame* context, bool silently = false);
  506.     ICorDebugValue* EvaluateName(const WCHAR* name, ICorDebugILFrame* context,
  507.                                  bool* unavailable);
  508.     void PrintVariable(const WCHAR* name, ICorDebugValue* value,
  509.                        unsigned int indent, BOOL expandObjects);
  510.     void PrintArrayVar(ICorDebugArrayValue *iarray,
  511.                        const WCHAR* name,
  512.                        unsigned int indent, BOOL expandObjects);
  513.     void PrintStringVar(ICorDebugStringValue *istring,
  514.                         const WCHAR* name,
  515.                         unsigned int indent, BOOL expandObjects);
  516.     void PrintObjectVar(ICorDebugObjectValue *iobject,
  517.                         const WCHAR* name,
  518.                         unsigned int indent, BOOL expandObjects);
  519.     bool EvaluateAndPrintGlobals(const WCHAR *exp);
  520.     void PrintGlobalVariable (mdFieldDef md, 
  521.                               WCHAR  *wszName,
  522.                               DebuggerModule *dm);
  523.     
  524.     HRESULT ResolveClassName(WCHAR *className,
  525.                              DebuggerModule **pDM, mdTypeDef *pTD);
  526.     HRESULT FindTypeDefByName(DebuggerModule *m,
  527.                               WCHAR *className,
  528.                               mdTypeDef *pTD);
  529.     HRESULT ResolveTypeRef(DebuggerModule *currentDM, mdTypeRef tr,
  530.                            DebuggerModule **pDM, mdTypeDef *pTD);
  531.     HRESULT ResolveQualifiedFieldName(DebuggerModule *currentDM,
  532.                                       mdTypeDef currentTD,
  533.                                       WCHAR *fieldName,
  534.                                       DebuggerModule **pDM,
  535.                                       mdTypeDef *pTD,
  536.                                       ICorDebugClass **pIClass,
  537.                                       mdFieldDef *pFD,
  538.                                       bool *pbIsStatic);
  539.     HRESULT ResolveFullyQualifiedMethodName(WCHAR *methodName,
  540.                                             ICorDebugFunction **ppFunc);
  541.     HRESULT GetArrayIndicies(WCHAR **pp, ICorDebugILFrame *context,
  542.                              ULONG32 rank, ULONG32 *indicies);
  543.     HRESULT StripReferences(ICorDebugValue **ppValue, bool printAsYouGo);
  544.     BOOL PrintCurrentSourceLine(unsigned int around);
  545.     virtual void ActivateSourceView(DebuggerSourceFile *psf, unsigned int lineNumber);
  546.     BOOL PrintCurrentInstruction(unsigned int around);
  547.     void PrintIndent(unsigned int level);
  548.     void PrintVarName(const WCHAR* name);
  549.     void PrintBreakpoint(DebuggerBreakpoint* breakpoint);
  550.  
  551.     void PrintThreadPrefix(ICorDebugThread* pThread, bool forcePrint = false); 
  552.     HRESULT  StepStart(ICorDebugThread *pThread,
  553.                    ICorDebugStepper* pStepper);
  554.     void StepNotify(ICorDebugThread* pThread, 
  555.                     ICorDebugStepper* pStepper);
  556.  
  557.     DebuggerBreakpoint* FindBreakpoint(SIZE_T id);
  558.     void RemoveAllBreakpoints();
  559.     virtual void OnActivateBreakpoint(DebuggerBreakpoint *pb);
  560.     virtual void OnDeactivateBreakpoint(DebuggerBreakpoint *pb);
  561.     virtual void OnUnBindBreakpoint(DebuggerBreakpoint *pb, DebuggerModule *pm);
  562.     virtual void OnBindBreakpoint(DebuggerBreakpoint *pb, DebuggerModule *pm);
  563.  
  564.     BOOL OpenDebuggerRegistry(HKEY* key);
  565.     void CloseDebuggerRegistry(HKEY key);
  566.     BOOL ReadSourcesPath(HKEY key, WCHAR** currentPath);
  567.     BOOL WriteSourcesPath(HKEY key, WCHAR* newPath);
  568.     BOOL AppendSourcesPath(const WCHAR *newpath);
  569.     BOOL ReadDebuggerModes(HKEY key);
  570.     BOOL WriteDebuggerModes(void);
  571.  
  572.     DebuggerModule* ResolveModule(ICorDebugModule *pIModule);
  573.     DebuggerSourceFile* LookupSourceFile(const WCHAR* name);
  574.     mdTypeDef LookupClass(const WCHAR* name);
  575.  
  576.     virtual HRESULT ResolveSourceFile(DebuggerSourceFile *pf, char *szPath, 
  577.                                       char*pszFullyQualName, 
  578.                                       int iMaxLen, bool bChangeOfFile);
  579.     virtual ICorDebugManagedCallback *GetDebuggerCallback();
  580.     virtual ICorDebugUnmanagedCallback *GetDebuggerUnmanagedCallback();
  581.  
  582. #ifdef _INTERNAL_DEBUG_SUPPORT_
  583.     BOOL InitDisassembler(void);
  584. #endif
  585.  
  586.     bool SkipCompilerStubs(ICorDebugAppDomain *pAppDomain,
  587.                            ICorDebugThread *pThread);
  588.  
  589.     BOOL SkipProlog( ICorDebugAppDomain *pAD,
  590.                      ICorDebugThread *thread);
  591.     
  592.  
  593.     virtual WCHAR *GetJITLaunchCommand(void)
  594.     {
  595.         return L"cordbg.exe !a 0x%x";
  596.     }
  597.  
  598.     void LoadUnmanagedSymbols(HANDLE hProcess, HANDLE hFile, DWORD imageBase);
  599.     void HandleUnmanagedThreadCreate(DWORD dwThreadId, HANDLE hThread);
  600.     void TraceUnmanagedThreadStack(HANDLE hProcess,
  601.                                    DebuggerUnmanagedThread *ut,
  602.                                    bool lie);
  603.     void TraceAllUnmanagedThreadStacks(void);
  604.     void PrintUnmanagedStackFrame(HANDLE hProcess, CORDB_ADDRESS ip);
  605.     
  606.     void TraceUnmanagedStack(HANDLE hProcess, HANDLE hThread,
  607.                              CORDB_ADDRESS ip, CORDB_ADDRESS bp, 
  608.                              CORDB_ADDRESS sp, CORDB_ADDRESS bpEnd);
  609.  
  610.     bool HandleUnmanagedEvent(void);
  611.  
  612.     // !!! Move to process object
  613.     HRESULT AddManagedThread( ICorDebugThread *icdThread,
  614.                               DWORD dwThreadId )
  615.     {
  616.         DebuggerManagedThread *pdt = new DebuggerManagedThread( dwThreadId,
  617.                                                                 icdThread);
  618.         if (pdt == NULL)
  619.             return E_OUTOFMEMORY;
  620.  
  621.         if (FAILED(pdt->m_pendingSteppers->Initialize()))
  622.             return E_OUTOFMEMORY;
  623.         
  624.         return m_managedThreads.AddBase( (DebuggerBase *)pdt );
  625.     } 
  626.  
  627.     DebuggerManagedThread *GetManagedDebuggerThread(
  628.                                      ICorDebugThread *icdThread )
  629.     {
  630.         DWORD dwThreadId = 0;
  631.         HRESULT hr = icdThread->GetID(&dwThreadId);
  632.         _ASSERTE( !FAILED(hr));
  633.  
  634.         return (DebuggerManagedThread *)m_managedThreads.GetBase( dwThreadId );
  635.     }
  636.     
  637.     BOOL RemoveManagedThread( DWORD dwThreadId )
  638.     {
  639.         return m_managedThreads.RemoveBase( dwThreadId );
  640.     }
  641.  
  642.  
  643.     int GetUserSelection(DebuggerModule *rgpDebugModule[],
  644.                             WCHAR *rgpstrFileName[][MAX_FILE_MATCHES_PER_MODULE],    
  645.                             int rgiCount[],
  646.                             int iModuleCount,
  647.                             int iCumulCount
  648.                               );
  649.  
  650.     BOOL ChangeCurrStackFile (WCHAR *fileName);
  651.     BOOL DebuggerShell::UpdateCurrentPath (WCHAR *args);
  652.     void ListAllModules (ListType lt);
  653.     void ListAllGlobals (DebuggerModule *m);
  654.  
  655.     const WCHAR *UserThreadStateToString(CorDebugUserState us);
  656.  
  657.     bool MatchAndPrintSymbols (WCHAR *pszArg, BOOL fSymbol, bool fSilently = false);
  658.  
  659.     FILE *GetM_in(void) { return m_in; };
  660.     void  PutM_in(FILE *f) { m_in = f; };
  661.     HRESULT NotifyModulesOfEnc(ICorDebugModule *pModule, IStream *pSymStream);
  662.     
  663.     void ClearDebuggeeState(void); //when we Restart, for example, we'll want to
  664.         //reset some flags.
  665. private:
  666.     FILE*                  m_in;
  667.     FILE*                  m_out;
  668.  
  669. public:
  670.     ICorDebug*             m_cor;
  671.  
  672.     ICorDebugProcess*      m_targetProcess;
  673.     bool                   m_targetProcessHandledFirstException;
  674.     
  675.     ICorDebugProcess*      m_currentProcess;
  676.     ICorDebugThread*       m_currentThread;
  677.     ICorDebugChain*        m_currentChain;
  678.     ICorDebugILFrame*      m_currentFrame;
  679.     ICorDebugFrame*        m_rawCurrentFrame;
  680.  
  681.     DebuggerUnmanagedThread* m_currentUnmanagedThread;
  682.  
  683.     DWORD                  m_lastThread;
  684.     ICorDebugStepper*      m_lastStepper;
  685.     
  686.     bool                   m_showSource;
  687.     bool                   m_silentTracing;
  688.  
  689.     WCHAR*                 m_currentSourcesPath;
  690.  
  691.     HANDLE                 m_stopEvent;
  692.     HANDLE                 m_hProcessCreated;
  693.     bool                   m_stop;
  694.     bool                   m_quit;
  695.  
  696.     bool                   m_gotFirstThread;
  697.  
  698.     DebuggerBreakpoint*    m_breakpoints;
  699.     SIZE_T                 m_lastBreakpointID;
  700.  
  701.     DebuggerHashTable      m_modules;
  702.  
  703.     // !!! Move to process object
  704.     DebuggerHashTable      m_unmanagedThreads;
  705.     DebuggerHashTable      m_managedThreads;
  706.     
  707. #ifdef _INTERNAL_DEBUG_SUPPORT_
  708.     DIS*                   m_pDIS;
  709. #endif
  710.  
  711.     WCHAR*                 m_lastRunArgs;
  712.  
  713.     bool                   m_catchException;
  714.     bool                   m_catchUnhandled;
  715.     bool                   m_catchClass;
  716.     bool                   m_catchModule;
  717.     bool                   m_catchThread;
  718.  
  719.     bool                   m_needToSkipCompilerStubs;
  720.     DWORD                   m_rgfActiveModes;
  721.     bool                   m_invalidCache; //if true, we've affected the left 
  722.                             //  side & anything that has cached information
  723.                             //  should refresh
  724.  
  725.     DebuggerFilePathCache  m_FPCache;
  726.  
  727.     DEBUG_EVENT            m_lastUnmanagedEvent;
  728.     bool                   m_handleUnmanagedEvent;
  729.  
  730.     bool                   m_unmanagedDebuggingEnabled;
  731.  
  732.     ULONG                  m_cEditAndContinues;
  733.  
  734.     ICorDebugEval          *m_pCurrentEval;
  735. };
  736.  
  737. /* ------------------------------------------------------------------------- *
  738.  * Breakpoint class
  739.  * ------------------------------------------------------------------------- */
  740.  
  741. class DebuggerBreakpoint
  742. {
  743. public:
  744.     DebuggerBreakpoint(const WCHAR* name, SIZE_T nameLength, SIZE_T index, DWORD threadID);
  745.     DebuggerBreakpoint(DebuggerFunction* f, SIZE_T offset, DWORD threadID);
  746.     DebuggerBreakpoint(DebuggerSourceFile* file, SIZE_T lineNumber, DWORD threadID);
  747.  
  748.     ~DebuggerBreakpoint();
  749.  
  750.     // Create/remove a breakpoint.
  751.     bool Bind(DebuggerModule* m_module, ISymUnmanagedDocument *doc);
  752.     bool BindUnmanaged(ICorDebugProcess *m_process,
  753.                        DWORD moduleBase = 0);
  754.     void Unbind();
  755.  
  756.     // Enable/disable an active breakpoint.
  757.     void Activate();
  758.     void Deactivate();
  759.  
  760.     // Leave bp active; tear down or reset NGWS bp object.
  761.     void Detach();
  762.     void Attach();
  763.  
  764.     bool Match(ICorDebugBreakpoint* ibreakpoint);
  765.     bool MatchUnmanaged(CORDB_ADDRESS address);
  766.  
  767.     SIZE_T GetId (void) {return m_id;}
  768.     SIZE_T GetIndex (void) { return m_index;}
  769.     WCHAR *GetName (void) { return m_name;}
  770.     void UpdateName (WCHAR *pstrName);
  771.  
  772.     void ChangeSourceFile (WCHAR *filename);
  773.  
  774.     DebuggerBreakpoint*          m_next;
  775.     SIZE_T                       m_id;
  776.  
  777.     WCHAR*                       m_name;
  778.     SIZE_T                       m_index;
  779.     DWORD                        m_threadID;
  780.  
  781.     bool                         m_active;
  782.  
  783.     bool                         m_managed;
  784.  
  785.     ISymUnmanagedDocument                *m_doc;
  786.  
  787.     ICorDebugProcess    *m_process;
  788.     CORDB_ADDRESS         m_address;
  789.     BYTE                 m_patchedValue;
  790.     DWORD                 m_skipThread;
  791.     CORDB_ADDRESS        m_unmanagedModuleBase;
  792.  
  793. public:
  794.     struct BreakpointModuleNode
  795.     {
  796.         DebuggerModule *m_pModule;
  797.         BreakpointModuleNode *m_pNext;
  798.     };
  799.  
  800.     // Will be a list of modules for which this breakpoint is
  801.     // associated.  This is necessary because the same module
  802.     // may be loaded into separate AppDomains, but the breakpoint
  803.     // should still be valid for all instances of the module.
  804.     BreakpointModuleNode *m_pModuleList;
  805.  
  806.     // This will return true if this breakpoint is associated
  807.     // with the pModule argument
  808.     bool IsBoundToModule(DebuggerModule *pModule);
  809.  
  810.     // This will add the provided module to the list of bound
  811.     // modules
  812.     bool AddBoundModule(DebuggerModule *pModule);
  813.  
  814.     // This will remove the specified module from the list of
  815.     // bound modules
  816.     bool RemoveBoundModule(DebuggerModule *pModule);
  817.  
  818. private:
  819.     void CommonCtor(void);
  820.     void Init(DebuggerModule* module, bool bProceed);
  821.  
  822.     void ApplyUnmanagedPatch();
  823.     void UnapplyUnmanagedPatch();
  824. };
  825.  
  826.  
  827. //
  828. // DebuggerVarInfo
  829. //
  830. // Holds basic information about local variables, method arguments,
  831. // and class static and instance variables.
  832. //
  833. struct DebuggerVarInfo
  834. {
  835.     LPCSTR                 name;
  836.     PCCOR_SIGNATURE        sig;
  837.     unsigned long          varNumber;  // placement info for IL code
  838.  
  839.     DebuggerVarInfo() : name(NULL), sig(NULL), varNumber(0)
  840.                          {}
  841. };
  842.  
  843.  
  844. /* ------------------------------------------------------------------------- *
  845.  * Class class
  846.  * ------------------------------------------------------------------------- */
  847.  
  848. class DebuggerClass : public DebuggerBase
  849. {
  850. public:
  851.     DebuggerClass (ICorDebugClass *pClass);
  852.     ~DebuggerClass ();
  853.  
  854.     void SetName (WCHAR *pszName, WCHAR *pszNamespace);
  855.     WCHAR *GetName (void);
  856.     WCHAR *GetNamespace (void);
  857.     
  858. private:
  859.     WCHAR    *m_szName;
  860.     WCHAR    *m_szNamespace;
  861. };
  862.  
  863.  
  864. /* ------------------------------------------------------------------------- *
  865.  * Module class
  866.  * ------------------------------------------------------------------------- */
  867.  
  868. class DebuggerModule : public DebuggerBase
  869. {
  870. public:
  871.     DebuggerModule(ICorDebugModule* module);
  872.     ~DebuggerModule();
  873.  
  874.     HRESULT Init();
  875.     
  876.     DebuggerSourceFile* LookupSourceFile(const WCHAR* name);
  877.     DebuggerSourceFile* ResolveSourceFile(ISymUnmanagedDocument *doc);
  878.  
  879.     DebuggerFunction* ResolveFunction(mdMethodDef mb,
  880.                                       ICorDebugFunction* iFunction);
  881.     DebuggerFunction* ResolveFunction(ISymUnmanagedMethod *method,
  882.                                       ICorDebugFunction* iFunction);
  883.  
  884.     static DebuggerModule* FromCorDebug(ICorDebugModule* module);
  885.  
  886.     IMetaDataImport *GetMetaData(void)
  887.     {
  888.         return m_pIMetaDataImport;
  889.     }
  890.  
  891.     ISymUnmanagedReader *GetSymbolReader(void)
  892.     {
  893.         return m_pISymUnmanagedReader;
  894.     }
  895.  
  896.     ICorDebugModule *GetICorDebugModule(void)
  897.     {
  898.         return (ICorDebugModule*)m_token;
  899.     }
  900.  
  901.     HRESULT    LoadSourceFileNames (void);
  902.     HRESULT    MatchStrippedFNameInModule    (
  903.                     WCHAR *pstrFileName,                                    
  904.                     WCHAR **ppstrMatchedNames, 
  905.                     ISymUnmanagedDocument **ppDocs, 
  906.                     int *piCount);
  907.     HRESULT    MatchFullFileNameInModule (WCHAR *pstrFileName, 
  908.                                            ISymUnmanagedDocument **ppDocs);
  909.  
  910.     BOOL PrintMatchingSymbols (WCHAR *szSearchString, char *szModName);
  911.     BOOL PrintGlobalVariables (WCHAR *szSearchString, 
  912.                                char *szModName,
  913.                                DebuggerModule *dm);
  914.  
  915.     void    SetName (WCHAR *pszName);
  916.     WCHAR*    GetName (void) { return m_szName;}
  917.  
  918.     HRESULT UpdateSymbols(IStream *pSymbolStream);
  919.     
  920. public:
  921.     IMetaDataImport        *m_pIMetaDataImport;
  922.  
  923.     ISymUnmanagedReader    *m_pISymUnmanagedReader;
  924.  
  925.     DebuggerHashTable       m_sourceFiles;
  926.     DebuggerHashTable       m_functions;
  927.     DebuggerHashTable       m_functionsByIF;
  928.     DebuggerHashTable        m_loadedClasses;
  929.  
  930.     DebuggerCodeBreakpoint* m_breakpoints;
  931.  
  932. private:
  933.     ModuleSourceFile        *m_pModSourceFile [MAX_SF_BUCKETS];
  934.     bool                    m_fSFNamesLoaded;
  935.     WCHAR                    *m_szName;
  936.  
  937. };
  938.  
  939. class DebuggerCodeBreakpoint
  940. {
  941. public:
  942.     DebuggerCodeBreakpoint(int breakpointID, 
  943.                            DebuggerModule* module,
  944.                            DebuggerFunction* function, SIZE_T offset, BOOL il,
  945.                            DWORD threadID);
  946.     DebuggerCodeBreakpoint(int breakpointID, 
  947.                            DebuggerModule* module,
  948.                            DebuggerSourceCodeBreakpoint* parent,
  949.                            DebuggerFunction* function, SIZE_T offset, BOOL il,
  950.                            DWORD threadID);
  951.  
  952.     virtual ~DebuggerCodeBreakpoint();
  953.  
  954.     virtual bool Activate();
  955.     virtual void Deactivate();
  956.  
  957.     virtual bool Match(ICorDebugBreakpoint* ibreakpoint);
  958.  
  959.     virtual void Print();
  960.  
  961. public:
  962.     DebuggerCodeBreakpoint      *m_next;
  963.     int                         m_id;
  964.     DebuggerModule              *m_module;
  965.     DebuggerFunction            *m_function;
  966.     SIZE_T                      m_offset;
  967.     BOOL                        m_il;
  968.     DWORD                       m_threadID;
  969.  
  970.     ICorDebugFunctionBreakpoint* m_ibreakpoint;
  971.  
  972.     DebuggerSourceCodeBreakpoint* m_parent;
  973. };
  974.  
  975. class DebuggerSourceCodeBreakpoint : public DebuggerCodeBreakpoint
  976. {
  977. public:
  978.     DebuggerSourceCodeBreakpoint(int breakpointID, 
  979.                                  DebuggerSourceFile* file, SIZE_T lineNumber,
  980.                                  DWORD threadID);
  981.     ~DebuggerSourceCodeBreakpoint();
  982.  
  983.     bool Activate();
  984.     void Deactivate();
  985.     bool Match(ICorDebugBreakpoint *ibreakpoint);
  986.     void Print();
  987.  
  988. public:
  989.     DebuggerSourceFile*     m_file;
  990.     SIZE_T                  m_lineNumber;
  991.  
  992.     DebuggerCodeBreakpoint* m_breakpoints;
  993. };
  994.  
  995. /* ------------------------------------------------------------------------- *
  996.  * SourceFile class
  997.  * ------------------------------------------------------------------------- */
  998.  
  999. class DebuggerSourceFile : public DebuggerBase
  1000. {
  1001. public:
  1002.     //-----------------------------------------------------------
  1003.     // Create a DebuggerSourceFile from a scope and a SourceFile
  1004.     // token.
  1005.     //-----------------------------------------------------------
  1006.     DebuggerSourceFile(DebuggerModule* m, ISymUnmanagedDocument *doc);
  1007.     ~DebuggerSourceFile();
  1008.  
  1009.     //-----------------------------------------------------------
  1010.     // Given a line find the closest line which has code
  1011.     //-----------------------------------------------------------
  1012.     unsigned int FindClosestLine(unsigned int line, bool silently);
  1013.  
  1014.     const WCHAR* GetName(void)
  1015.     {
  1016.         return(m_name);
  1017.     }
  1018.     const WCHAR* GetPath(void)
  1019.     {
  1020.         return(m_path);
  1021.     }
  1022.     DebuggerModule* GetModule()
  1023.     {
  1024.         return(m_module);
  1025.     }
  1026.  
  1027.     //-----------------------------------------------------------
  1028.     // Methods to load the text of a source file and provide
  1029.     // access to it a line at a time.
  1030.     //-----------------------------------------------------------
  1031.     BOOL LoadText(const WCHAR* path, bool bChangeOfName);
  1032.     BOOL ReloadText(const WCHAR* path, bool bChangeOfName);
  1033.     unsigned int TotalLines(void)
  1034.     {
  1035.         return(m_totalLines);
  1036.     }
  1037.     const WCHAR* GetLineText(unsigned int lineNumber)
  1038.     {
  1039.         _ASSERTE((lineNumber > 0) && (lineNumber <= m_totalLines));
  1040.         return(m_lineStarts[lineNumber - 1]);
  1041.     }
  1042.  
  1043.     ISymUnmanagedDocument    *GetDocument (void) {return (ISymUnmanagedDocument*)m_token;}
  1044.  
  1045. public:
  1046.     DebuggerModule*    m_module;
  1047.     WCHAR*             m_name;
  1048.     WCHAR*             m_path;
  1049.  
  1050.     unsigned int       m_totalLines;
  1051.     WCHAR**            m_lineStarts;
  1052.     WCHAR*             m_source;
  1053.     BOOL               m_sourceTextLoaded;
  1054.     BOOL               m_allBlocksLoaded;
  1055.     BOOL               m_sourceNotFound;
  1056. };
  1057.  
  1058. /* ------------------------------------------------------------------------- *
  1059.  * DebuggerVariable struct
  1060.  * ------------------------------------------------------------------------- */
  1061.  
  1062. // Holds basic info about local variables and method arguments within
  1063. // the debugger. This is really only the name and variable number. No
  1064. // signature is required.
  1065. struct DebuggerVariable
  1066. {
  1067.     WCHAR        *m_name;
  1068.     ULONG32       m_varNumber;
  1069.  
  1070.     DebuggerVariable() : m_name(NULL), m_varNumber(0) {}
  1071.  
  1072.     ~DebuggerVariable()
  1073.     {
  1074.         if (m_name)
  1075.             delete [] m_name;
  1076.     }
  1077. };
  1078.  
  1079. /* ------------------------------------------------------------------------- *
  1080.  * Function class
  1081.  * ------------------------------------------------------------------------- */
  1082.  
  1083. class DebuggerFunction : public DebuggerBase
  1084. {
  1085. public:
  1086.     //-----------------------------------------------------------
  1087.     // Create from scope and member tokens.
  1088.     //-----------------------------------------------------------
  1089.     DebuggerFunction(DebuggerModule* m, mdMethodDef md,
  1090.                      ICorDebugFunction* iFunction);
  1091.     ~DebuggerFunction();
  1092.  
  1093.     HRESULT Init(void);
  1094.  
  1095.     HRESULT FindLineFromIP(UINT_PTR ip,
  1096.                            DebuggerSourceFile** sourceFile,
  1097.                            unsigned int* line);
  1098.  
  1099.     void GetStepRangesFromIP(UINT_PTR ip, 
  1100.                              COR_DEBUG_STEP_RANGE** range,
  1101.                              SIZE_T* rangeCount);
  1102.  
  1103.     //-----------------------------------------------------------
  1104.     // These allow you to get the count of method argument and
  1105.     // get access to the info for each individual argument.
  1106.     // Ownership of the DebugVarInfo returned from GetArgumentAt
  1107.     // is retained by the DebugFunction.
  1108.     //-----------------------------------------------------------
  1109.     unsigned int GetArgumentCount(void)
  1110.     {
  1111.         return(m_argCount);
  1112.     }
  1113.     DebuggerVarInfo* GetArgumentAt(unsigned int index)
  1114.     {
  1115.         if (m_arguments)
  1116.             if (index < m_argCount)
  1117.                 return(&m_arguments[index]);
  1118.  
  1119.         return NULL;
  1120.     }
  1121.  
  1122.     PCCOR_SIGNATURE GetReturnType()
  1123.     {
  1124.         return(m_returnType);
  1125.     }
  1126.  
  1127.     //-----------------------------------------------------------
  1128.     // This returns an array of pointers to DebugVarInfo blocks,
  1129.     // each representing a local variable that in in scope given
  1130.     // a certian IP. The variables are ordered in the list are in
  1131.     // increasingly larger lexical scopes, i.e., variables in the
  1132.     // smallest scope are first, then variables in the enclosing
  1133.     // scope, and so on. So, to find a certian variable "i",
  1134.     // search the list of "i" and take the first one you find.
  1135.     // If there are other "i"s, then they are shadowed by the
  1136.     // first one.
  1137.     // You must free the array returned in vars with delete [].
  1138.     // RETURNS: true if we succeeded, or at least found some debugging info
  1139.     //          false if we couldn't find any debugging info
  1140.     //-----------------------------------------------------------
  1141.     bool GetActiveLocalVars(UINT_PTR IP,
  1142.                             DebuggerVariable** vars, unsigned int* count);
  1143.  
  1144.     //-----------------------------------------------------------
  1145.     // Misc methods to get basic method information.
  1146.     //-----------------------------------------------------------
  1147.     WCHAR* GetName(void)
  1148.     {
  1149.         return(m_name);
  1150.     }
  1151.     PCCOR_SIGNATURE GetSignature(void)
  1152.     {
  1153.         return(m_signature);
  1154.     }
  1155.     WCHAR* GetNamespaceName(void)
  1156.     {
  1157.         return(m_namespaceName);
  1158.     }
  1159.     WCHAR* GetClassName(void)
  1160.     {
  1161.         return(m_className);
  1162.     }
  1163.     DebuggerModule* GetModule(void)
  1164.     {
  1165.         return(m_module);
  1166.     }
  1167.     BOOL IsStatic(void)
  1168.     {
  1169.         return(m_isStatic);
  1170.     }
  1171.  
  1172.  
  1173.     static DebuggerFunction* FromCorDebug(ICorDebugFunction* function);
  1174.  
  1175.     //-----------------------------------------------------------
  1176.     // EE interaction methods
  1177.     //-----------------------------------------------------------
  1178.     HRESULT LoadCode(BOOL native);
  1179.  
  1180. #ifdef _INTERNAL_DEBUG_SUPPORT_
  1181.     SIZE_T WalkInstruction(BOOL native, SIZE_T offset);
  1182.     SIZE_T Disassemble(BOOL native, SIZE_T offset, WCHAR* buffer);
  1183. #endif
  1184.     BOOL ValidateInstruction(BOOL native, SIZE_T offset);
  1185.     HRESULT CacheSequencePoints(void);
  1186.  
  1187. public:
  1188.     DebuggerModule*           m_module;
  1189.     mdTypeDef                 m_class;
  1190.     ICorDebugFunction*        m_ifunction;
  1191.     BOOL                      m_isStatic;
  1192.     BOOL                      m_allBlocksLoaded;
  1193.     BOOL                      m_allScopesLoaded;
  1194.     WCHAR*                    m_name;
  1195.     PCCOR_SIGNATURE           m_signature;
  1196.     WCHAR*                      m_namespaceName;
  1197.     WCHAR*                    m_className;
  1198.     BOOL                      m_VCHack;
  1199.                               
  1200.     DebuggerVarInfo*          m_arguments;
  1201.     unsigned int              m_argCount;
  1202.     PCCOR_SIGNATURE           m_returnType;    
  1203.  
  1204.     void CountActiveLocalVars(ISymUnmanagedScope* head,
  1205.                               unsigned int line,
  1206.                               unsigned int* varCount);
  1207.     void FillActiveLocalVars(ISymUnmanagedScope* head,
  1208.                              unsigned int line,
  1209.                              unsigned int varCount,
  1210.                              unsigned int* currentVar,
  1211.                              DebuggerVariable* varPtrs);
  1212.  
  1213.     ISymUnmanagedMethod    *m_symMethod;
  1214.     ULONG32                *m_SPOffsets;
  1215.     ISymUnmanagedDocument **m_SPDocuments;
  1216.     ULONG32                *m_SPLines;
  1217.     ULONG32                 m_SPCount;
  1218.  
  1219.     BYTE*                   m_ilCode;
  1220.     ULONG32                 m_ilCodeSize;
  1221.     BYTE*                   m_nativeCode;
  1222.     ULONG32                 m_nativeCodeSize;
  1223.     ULONG                   m_nEditAndContinueLastSynched;
  1224. };
  1225.  
  1226. /* ------------------------------------------------------------------------- *
  1227.  * DebuggerCallback
  1228.  * ------------------------------------------------------------------------- */
  1229.  
  1230. #define COM_METHOD HRESULT STDMETHODCALLTYPE
  1231.  
  1232. class DebuggerCallback : public ICorDebugManagedCallback
  1233. {
  1234. public:    
  1235.     DebuggerCallback() : m_refCount(0)
  1236.     {
  1237.     }
  1238.  
  1239.     // 
  1240.     // IUnknown
  1241.     //
  1242.  
  1243.     ULONG STDMETHODCALLTYPE AddRef() 
  1244.     {
  1245.         return (InterlockedIncrement((long *) &m_refCount));
  1246.     }
  1247.  
  1248.     ULONG STDMETHODCALLTYPE Release() 
  1249.     {
  1250.         long refCount = InterlockedDecrement(&m_refCount);
  1251.         if (refCount == 0)
  1252.             delete this;
  1253.  
  1254.         return (refCount);
  1255.     }
  1256.  
  1257.     COM_METHOD QueryInterface(REFIID riid, void **ppInterface)
  1258.     {
  1259.         if (riid == IID_IUnknown)
  1260.             *ppInterface = (IUnknown *) this;
  1261.         else if (riid == IID_ICorDebugManagedCallback)
  1262.             *ppInterface = (ICorDebugManagedCallback *) this;
  1263.         else
  1264.             return (E_NOINTERFACE);
  1265.  
  1266.         this->AddRef();
  1267.         return (S_OK);
  1268.     }
  1269.  
  1270.     // 
  1271.     // ICorDebugManagedCallback
  1272.     //
  1273.  
  1274.     COM_METHOD CreateProcess(ICorDebugProcess *pProcess);
  1275.     COM_METHOD ExitProcess(ICorDebugProcess *pProcess);
  1276.     COM_METHOD DebuggerError(ICorDebugProcess *pProcess,
  1277.                              HRESULT errorHR,
  1278.                              DWORD errorCode);
  1279.  
  1280.     COM_METHOD CreateAppDomain(ICorDebugProcess *pProcess,
  1281.                             ICorDebugAppDomain *pAppDomain); 
  1282.  
  1283.     COM_METHOD ExitAppDomain(ICorDebugProcess *pProcess,
  1284.                           ICorDebugAppDomain *pAppDomain); 
  1285.  
  1286.     COM_METHOD LoadAssembly(ICorDebugAppDomain *pAppDomain,
  1287.                          ICorDebugAssembly *pAssembly);
  1288.  
  1289.     COM_METHOD UnloadAssembly(ICorDebugAppDomain *pAppDomain,
  1290.                            ICorDebugAssembly *pAssembly);
  1291.  
  1292.     COM_METHOD Breakpoint( ICorDebugAppDomain *pAppDomain,
  1293.                         ICorDebugThread *pThread, 
  1294.                         ICorDebugBreakpoint *pBreakpoint);
  1295.  
  1296.     COM_METHOD StepComplete( ICorDebugAppDomain *pAppDomain,
  1297.                           ICorDebugThread *pThread,
  1298.                           ICorDebugStepper *pStepper,
  1299.                           CorDebugStepReason reason);
  1300.  
  1301.     COM_METHOD Break( ICorDebugAppDomain *pAppDomain,
  1302.                    ICorDebugThread *thread);
  1303.  
  1304.     COM_METHOD Exception( ICorDebugAppDomain *pAppDomain,
  1305.                        ICorDebugThread *pThread,
  1306.                        BOOL unhandled);
  1307.  
  1308.     COM_METHOD EvalComplete( ICorDebugAppDomain *pAppDomain,
  1309.                                ICorDebugThread *pThread,
  1310.                                ICorDebugEval *pEval);
  1311.  
  1312.     COM_METHOD EvalException( ICorDebugAppDomain *pAppDomain,
  1313.                                 ICorDebugThread *pThread,
  1314.                                 ICorDebugEval *pEval);
  1315.  
  1316.     COM_METHOD CreateThread( ICorDebugAppDomain *pAppDomain,
  1317.                           ICorDebugThread *thread);
  1318.  
  1319.     COM_METHOD ExitThread( ICorDebugAppDomain *pAppDomain,
  1320.                         ICorDebugThread *thread);
  1321.  
  1322.     COM_METHOD LoadModule( ICorDebugAppDomain *pAppDomain,
  1323.                         ICorDebugModule *pModule);
  1324.  
  1325.     COM_METHOD UnloadModule( ICorDebugAppDomain *pAppDomain,
  1326.                           ICorDebugModule *pModule);
  1327.  
  1328.     COM_METHOD LoadClass( ICorDebugAppDomain *pAppDomain,
  1329.                        ICorDebugClass *c);
  1330.  
  1331.     COM_METHOD UnloadClass( ICorDebugAppDomain *pAppDomain,
  1332.                          ICorDebugClass *c);
  1333.  
  1334.     COM_METHOD LogMessage(ICorDebugAppDomain *pAppDomain,
  1335.                       ICorDebugThread *pThread,
  1336.                       LONG lLevel,
  1337.                       WCHAR *pLogSwitchName,
  1338.                       WCHAR *pMessage);
  1339.  
  1340.     COM_METHOD LogSwitch(ICorDebugAppDomain *pAppDomain,
  1341.                       ICorDebugThread *pThread,
  1342.                       LONG lLevel,
  1343.                       ULONG ulReason,
  1344.                       WCHAR *pLogSwitchName,
  1345.                       WCHAR *pParentName);
  1346.  
  1347.     COM_METHOD ControlCTrap(ICorDebugProcess *pProcess);
  1348.     COM_METHOD NameChange(ICorDebugAppDomain *pAppDomain, 
  1349.                           ICorDebugThread *pThread);
  1350.     COM_METHOD UpdateModuleSymbols(ICorDebugAppDomain *pAppDomain,
  1351.                                    ICorDebugModule *pModule,
  1352.                                    IStream *pSymbolStream);
  1353.     
  1354.     long        m_refCount;
  1355. };
  1356.  
  1357.  
  1358. /* ------------------------------------------------------------------------- *
  1359.  * DebuggerUnmanagedCallback
  1360.  * ------------------------------------------------------------------------- */
  1361.  
  1362. class DebuggerUnmanagedCallback : public ICorDebugUnmanagedCallback
  1363. {
  1364. public:    
  1365.     DebuggerUnmanagedCallback() : m_refCount(0)
  1366.     {
  1367.     }
  1368.  
  1369.     // IUnknown
  1370.     ULONG STDMETHODCALLTYPE AddRef() 
  1371.     {
  1372.         return (InterlockedIncrement((long *) &m_refCount));
  1373.     }
  1374.  
  1375.     ULONG STDMETHODCALLTYPE Release() 
  1376.     {
  1377.         long refCount = InterlockedDecrement(&m_refCount);
  1378.         if (refCount == 0)
  1379.             delete this;
  1380.  
  1381.         return (refCount);
  1382.     }
  1383.  
  1384.     COM_METHOD QueryInterface(REFIID riid, void **ppInterface)
  1385.     {
  1386.         if (riid == IID_IUnknown)
  1387.             *ppInterface = (IUnknown*)(ICorDebugUnmanagedCallback*)this;
  1388.         else if (riid == IID_ICorDebugUnmanagedCallback)
  1389.             *ppInterface = (ICorDebugUnmanagedCallback*) this;
  1390.         else
  1391.             return (E_NOINTERFACE);
  1392.  
  1393.         this->AddRef();
  1394.         return (S_OK);
  1395.     }
  1396.  
  1397.     COM_METHOD DebugEvent(LPDEBUG_EVENT pDebugEvent,
  1398.                           BOOL fIsOutOfband);
  1399.  
  1400.     long        m_refCount;
  1401. };
  1402.  
  1403. /* ------------------------------------------------------------------------- *
  1404.  * Unmanaged Thread class
  1405.  * ------------------------------------------------------------------------- */
  1406.  
  1407. class DebuggerUnmanagedThread : public DebuggerBase
  1408. {
  1409. public:
  1410.     DebuggerUnmanagedThread(DWORD dwThreadId, HANDLE hThread)
  1411.       : DebuggerBase(dwThreadId), m_hThread(hThread), 
  1412.         m_stepping(FALSE), m_unmanagedStackEnd(NULL) {}
  1413.  
  1414.     HANDLE GetHandle(void) { return m_hThread; }
  1415.     DWORD GetId(void) { return m_token; }
  1416.  
  1417.     BOOL            m_stepping;
  1418.     CORDB_ADDRESS    m_unmanagedStackEnd;
  1419.  
  1420. private:
  1421.     HANDLE            m_hThread;
  1422. };
  1423.  
  1424. /* ------------------------------------------------------------------------- *
  1425.  * Debugger ShellCommand classes
  1426.  * ------------------------------------------------------------------------- */
  1427.  
  1428. class DebuggerCommand : public ShellCommand
  1429. {
  1430. public:
  1431.     DebuggerCommand(const WCHAR *name, int minMatchLength = 0)
  1432.         : ShellCommand(name, minMatchLength)
  1433.     {
  1434.     }
  1435.  
  1436.     void Do(Shell *shell, const WCHAR *args) 
  1437.     {
  1438.         DebuggerShell *dsh = static_cast<DebuggerShell *>(shell);
  1439.  
  1440.         Do(dsh, dsh->m_cor, args);
  1441.     }
  1442.  
  1443.     virtual void Do(DebuggerShell *shell, ICorDebug *cor, const WCHAR *args) = 0;
  1444. };
  1445.  
  1446.  
  1447. /* ------------------------------------------------------------------------- *
  1448.  * class ModuleSourceFile
  1449.  * ------------------------------------------------------------------------- */
  1450.  
  1451. class ModuleSourceFile
  1452. {
  1453. private:
  1454.     ISymUnmanagedDocument    *m_SFDoc;                // Symbol reader document
  1455.     WCHAR             *m_pstrFullFileName;    // File name along with path (as returned by the metadata API)
  1456.     WCHAR            *m_pstrStrippedFileName;// The barebone file name (eg. foo.cpp)
  1457.     ModuleSourceFile *m_pNext;
  1458.  
  1459. public:
  1460.     ModuleSourceFile()
  1461.     {
  1462.         m_SFDoc = NULL;
  1463.         m_pstrFullFileName = NULL;
  1464.         m_pstrStrippedFileName = NULL;
  1465.         m_pNext = NULL;
  1466.     }
  1467.  
  1468.     ~ModuleSourceFile()
  1469.     {
  1470.         delete [] m_pstrFullFileName;
  1471.         delete [] m_pstrStrippedFileName;
  1472.  
  1473.         if (m_SFDoc)
  1474.         {
  1475.             m_SFDoc->Release();
  1476.             m_SFDoc = NULL;
  1477.         }
  1478.     }
  1479.  
  1480.     ISymUnmanagedDocument    *GetDocument (void) {return m_SFDoc;}
  1481.  
  1482.     // This sets the full file name as well as the stripped file name
  1483.     BOOL    SetFullFileName (ISymUnmanagedDocument *doc, LPCSTR pstrFullFileName);
  1484.     WCHAR    *GetFullFileName (void) { return m_pstrFullFileName;}
  1485.     WCHAR    *GetStrippedFileName (void) { return m_pstrStrippedFileName;}
  1486.  
  1487.     void    SetNext (ModuleSourceFile *pNext) { m_pNext = pNext;}
  1488.     ModuleSourceFile *GetNext (void) { return m_pNext;}
  1489.  
  1490. };
  1491.  
  1492. /* ------------------------------------------------------------------------- *
  1493.  * Global variables
  1494.  * ------------------------------------------------------------------------- */
  1495.  
  1496. extern DebuggerShell        *g_pShell;
  1497.  
  1498. #endif __DSHELL_H__
  1499.  
  1500.