├── .gitattributes ├── .gitignore ├── MinimalDebuggerForEnC.sln ├── MinimalDebuggerForEnC ├── App.config ├── MinimalDebuggerForEnC.csproj ├── MinimalDebuggerForEnC.csproj.user ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── MinimalDebuggerForEnCWithRoslyn ├── App.config ├── ArrayBuilder.cs ├── ComStreamWrapper.cs ├── CustomDebugInfoReader.cs ├── DummyMetadataImport.cs ├── Microsoft.DiaSymReader.Native.x86.dll ├── MinimalDebuggerForEnCWithRoslyn.csproj ├── MinimalDebuggerForEnCWithRoslyn.csproj.user ├── ObjectPool.cs ├── PdbTestUtilities.cs ├── PooledDictionary.cs ├── PooledHashSet.cs ├── PooledStringBuilder.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── StreamExtensions.cs ├── SymReaderFactory.cs ├── SymUnmanagedReaderExtensions.cs ├── Token2SourceLineExporter.cs └── packages.config ├── NativeDebugWrappers ├── DumpReader.cs ├── NativeDebugWrappers.csproj ├── NativeDebugWrappersAssemblyAttributes.cs ├── NativeImports.cs ├── PEReader.cs ├── ReadMe.txt ├── VersionInfo.cs ├── amd64Context.cs ├── context.cs ├── ia64Context.cs ├── mdbg.snk └── x86Context.cs ├── README.md ├── SampleExeWithILAndMetadata ├── SampleProcess.exe ├── SampleProcess.exe.1.dil ├── SampleProcess.exe.1.dmeta ├── SampleProcess.exe.1.pdb ├── SampleProcess.exe.config ├── SampleProcess.il ├── SampleProcess.pdb ├── SampleProcess.res └── SampleProcess_v1.il ├── SampleProcess ├── App.config ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── SampleProcess.csproj ├── corapi ├── AppDomain.cs ├── AppDomainEnumerator.cs ├── Assembly.cs ├── AssemblyEnumerator.cs ├── Breakpoint.cs ├── BreakpointEnumerator.cs ├── ChainEnumerator.cs ├── Class.cs ├── Constants.cs ├── Controller.cs ├── CorAPIAssemblyAttributes.cs ├── CorMetadata.cs ├── CorPublish.cs ├── Debugger.cs ├── ErrorInfoEnumerator.cs ├── Eval.cs ├── FunctionBreakpoint.cs ├── HResults.cs ├── IDiaReadExeAtRVACallback.cs ├── ISymBinder2.cs ├── ISymConstant.cs ├── ISymENCUpdate.cs ├── ISymEncMethod.cs ├── ISymReader2.cs ├── ISymScope2.cs ├── ISymSearchInfo.cs ├── ISymWriter2.cs ├── IldbSymbols.cs ├── MetadataFieldInfo.cs ├── MetadataLocator.cs ├── MetadataParameterInfo.cs ├── MetadataType.cs ├── Module.cs ├── ModuleBreakpoint.cs ├── ModuleEnumerator.cs ├── ModuleRVAReader.cs ├── ObjectEnumerator.cs ├── Process.cs ├── ProcessEnumerator.cs ├── ReadMe.txt ├── RegisterSet.cs ├── RemoteTarget.cs ├── StackWalk.cs ├── Stepper.cs ├── StepperEnumerator.cs ├── SymAccess.cs ├── SymConstant.cs ├── SymDocument.cs ├── SymDocumentWriter.cs ├── SymNamespace.cs ├── SymReader.cs ├── SymScope.cs ├── SymSearchInfo.cs ├── SymSearchPolicyAttributes.cs ├── SymWriter.cs ├── Thread.cs ├── ThreadEnumerator.cs ├── Type.cs ├── TypeEnumerator.cs ├── Value.cs ├── ValueBreakpoint.cs ├── VersionInfo.cs ├── WrapperBase.cs ├── corapi.csproj ├── mdbg.snk ├── symbinder.cs ├── symmethod.cs ├── symvariable.cs └── utility.cs ├── mdbg.snk └── raw ├── ICorDebugWrappers.cs ├── ICorPublishWrappers.cs ├── IMetadataImport.cs ├── RawAssemblyAttributes.cs ├── ReadMe.txt ├── VersionInfo.cs ├── WindowsImports.cs ├── mdbg.snk └── raw.csproj /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | #Performance files 18 | *.psess 19 | *.vspx 20 | 21 | #Visual Studio 22 | .vs/ 23 | obj/ 24 | bin/ 25 | packages/ 26 | 27 | # Windows shortcuts 28 | *.lnk 29 | 30 | # ========================= 31 | # Operating System Files 32 | # ========================= 33 | 34 | # OSX 35 | # ========================= 36 | 37 | .DS_Store 38 | .AppleDouble 39 | .LSOverride 40 | 41 | # Thumbnails 42 | ._* 43 | 44 | # Files that might appear on external disk 45 | .Spotlight-V100 46 | .Trashes 47 | 48 | # Directories potentially created on remote AFP share 49 | .AppleDB 50 | .AppleDesktop 51 | Network Trash Folder 52 | Temporary Items 53 | .apdisk 54 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnC.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.24720.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalDebuggerForEnC", "MinimalDebuggerForEnC\MinimalDebuggerForEnC.csproj", "{C0AE2F8F-BC26-441B-B7FB-3EEBD544A0FB}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeDebugWrappers", "NativeDebugWrappers\NativeDebugWrappers.csproj", "{3991AB6C-468B-4C28-95FC-3188CFB34180}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "raw", "raw\raw.csproj", "{C18D303B-2C55-43EB-A3DF-39CF3FB1D447}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "corapi", "corapi\corapi.csproj", "{04EF9865-E1B1-403D-802B-E4FAEA50A634}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleProcess", "SampleProcess\SampleProcess.csproj", "{B78B361C-70FF-4FBA-A397-BDA1FDCC91D9}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalDebuggerForEnCWithRoslyn", "MinimalDebuggerForEnCWithRoslyn\MinimalDebuggerForEnCWithRoslyn.csproj", "{F7D5FA28-5409-40AC-A2BE-F0164910DE50}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {C0AE2F8F-BC26-441B-B7FB-3EEBD544A0FB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {C0AE2F8F-BC26-441B-B7FB-3EEBD544A0FB}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {C0AE2F8F-BC26-441B-B7FB-3EEBD544A0FB}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {C0AE2F8F-BC26-441B-B7FB-3EEBD544A0FB}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {3991AB6C-468B-4C28-95FC-3188CFB34180}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {3991AB6C-468B-4C28-95FC-3188CFB34180}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {3991AB6C-468B-4C28-95FC-3188CFB34180}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {3991AB6C-468B-4C28-95FC-3188CFB34180}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {04EF9865-E1B1-403D-802B-E4FAEA50A634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {04EF9865-E1B1-403D-802B-E4FAEA50A634}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {04EF9865-E1B1-403D-802B-E4FAEA50A634}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {04EF9865-E1B1-403D-802B-E4FAEA50A634}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {B78B361C-70FF-4FBA-A397-BDA1FDCC91D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {B78B361C-70FF-4FBA-A397-BDA1FDCC91D9}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {B78B361C-70FF-4FBA-A397-BDA1FDCC91D9}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {B78B361C-70FF-4FBA-A397-BDA1FDCC91D9}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {F7D5FA28-5409-40AC-A2BE-F0164910DE50}.Debug|Any CPU.ActiveCfg = Debug|x86 45 | {F7D5FA28-5409-40AC-A2BE-F0164910DE50}.Debug|Any CPU.Build.0 = Debug|x86 46 | {F7D5FA28-5409-40AC-A2BE-F0164910DE50}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {F7D5FA28-5409-40AC-A2BE-F0164910DE50}.Release|Any CPU.Build.0 = Release|Any CPU 48 | EndGlobalSection 49 | GlobalSection(SolutionProperties) = preSolution 50 | HideSolutionNode = FALSE 51 | EndGlobalSection 52 | EndGlobal 53 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnC/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnC/MinimalDebuggerForEnC.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | ProjectFiles 5 | 6 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MinimalDebuggerForEnC")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MinimalDebuggerForEnC")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("c0ae2f8f-bc26-441b-b7fb-3eebd544a0fb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnC/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/ComStreamWrapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices.ComTypes; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace MinimalDebuggerForEnCWithRoslyn 11 | { 12 | internal sealed class ComStreamWrapper : IStream 13 | { 14 | private readonly Stream _stream; 15 | 16 | public ComStreamWrapper(Stream stream) 17 | { 18 | Debug.Assert(stream != null); 19 | Debug.Assert(stream.CanSeek); 20 | 21 | _stream = stream; 22 | } 23 | 24 | public void Commit(int grfCommitFlags) 25 | { 26 | _stream.Flush(); 27 | } 28 | 29 | /// 30 | /// The actual number of bytes read can be fewer than the number of bytes requested 31 | /// if an error occurs or if the end of the stream is reached during the read operation. 32 | /// 33 | public unsafe void Read(byte[] pv, int cb, IntPtr pcbRead) 34 | { 35 | int bytesRead = _stream.TryReadAll(pv, 0, cb); 36 | 37 | if (pcbRead != IntPtr.Zero) 38 | { 39 | *(int*)pcbRead = bytesRead; 40 | } 41 | } 42 | 43 | public unsafe void Seek(long dlibMove, int origin, IntPtr plibNewPosition) 44 | { 45 | long newPosition = _stream.Seek(dlibMove, (SeekOrigin)origin); 46 | if (plibNewPosition != IntPtr.Zero) 47 | { 48 | *(long*)plibNewPosition = newPosition; 49 | } 50 | } 51 | 52 | public void SetSize(long libNewSize) 53 | { 54 | _stream.SetLength(libNewSize); 55 | } 56 | 57 | public void Stat(out STATSTG pstatstg, int grfStatFlag) 58 | { 59 | pstatstg = new STATSTG() 60 | { 61 | cbSize = _stream.Length 62 | }; 63 | } 64 | 65 | public unsafe void Write(byte[] pv, int cb, IntPtr pcbWritten) 66 | { 67 | _stream.Write(pv, 0, cb); 68 | if (pcbWritten != IntPtr.Zero) 69 | { 70 | *(int*)pcbWritten = cb; 71 | } 72 | } 73 | 74 | public void Clone(out IStream ppstm) 75 | { 76 | throw new NotSupportedException(); 77 | } 78 | 79 | public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) 80 | { 81 | throw new NotSupportedException(); 82 | } 83 | 84 | public void LockRegion(long libOffset, long cb, int lockType) 85 | { 86 | throw new NotSupportedException(); 87 | } 88 | 89 | public void Revert() 90 | { 91 | throw new NotSupportedException(); 92 | } 93 | 94 | public void UnlockRegion(long libOffset, long cb, int lockType) 95 | { 96 | throw new NotSupportedException(); 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/Microsoft.DiaSymReader.Native.x86.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/MinimalDebuggerForEnCWithRoslyn/Microsoft.DiaSymReader.Native.x86.dll -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/MinimalDebuggerForEnCWithRoslyn.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/PdbTestUtilities.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.Emit; 3 | using Microsoft.DiaSymReader; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Collections.Immutable; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Reflection.Metadata; 10 | using System.Reflection.Metadata.Ecma335; 11 | using System.Text; 12 | using System.Threading.Tasks; 13 | 14 | namespace MinimalDebuggerForEnCWithRoslyn 15 | { 16 | internal static class PdbTestUtilities 17 | { 18 | public static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(this ISymUnmanagedReader symReader, MethodDefinitionHandle handle) 19 | { 20 | var cdi = CustomDebugInfoUtilities.GetCustomDebugInfoBytes(symReader, handle, methodVersion: 1); 21 | if (cdi == null) 22 | { 23 | return default(EditAndContinueMethodDebugInformation); 24 | } 25 | 26 | return GetEncMethodDebugInfo(cdi); 27 | } 28 | 29 | public static EditAndContinueMethodDebugInformation GetEncMethodDebugInfo(byte[] customDebugInfoBlob) 30 | { 31 | return EditAndContinueMethodDebugInformation.Create( 32 | CustomDebugInfoUtilities.GetEditAndContinueLocalSlotMapRecord(customDebugInfoBlob), 33 | CustomDebugInfoUtilities.GetEditAndContinueLambdaMapRecord(customDebugInfoBlob)); 34 | } 35 | 36 | public static string GetTokenToLocationMap(Compilation compilation, bool maskToken = false) 37 | { 38 | using (var exebits = new MemoryStream()) 39 | { 40 | using (var pdbbits = new MemoryStream()) 41 | { 42 | compilation.Emit(exebits, pdbbits); 43 | return Token2SourceLineExporter.TokenToSourceMap2Xml(pdbbits, maskToken); 44 | } 45 | } 46 | } 47 | } 48 | 49 | public static class CustomDebugInfoUtilities 50 | { 51 | public static byte[] GetCustomDebugInfoBytes(ISymUnmanagedReader reader, MethodDefinitionHandle handle, int methodVersion) 52 | { 53 | return reader.GetCustomDebugInfoBytes(MetadataTokens.GetToken(handle), methodVersion); 54 | } 55 | 56 | public static ImmutableArray GetEditAndContinueLocalSlotMapRecord(byte[] customDebugInfoBlob) 57 | { 58 | return CustomDebugInfoReader.TryGetCustomDebugInfoRecord(customDebugInfoBlob, CustomDebugInfoKind.EditAndContinueLocalSlotMap); 59 | } 60 | 61 | public static ImmutableArray GetEditAndContinueLambdaMapRecord(byte[] customDebugInfoBlob) 62 | { 63 | return CustomDebugInfoReader.TryGetCustomDebugInfoRecord(customDebugInfoBlob, CustomDebugInfoKind.EditAndContinueLambdaMap); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/PooledDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Immutable; 4 | using System.Diagnostics; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MinimalDebuggerForEnCWithRoslyn 10 | { 11 | internal class PooledDictionary : Dictionary 12 | { 13 | private readonly ObjectPool> _pool; 14 | 15 | private PooledDictionary(ObjectPool> pool) 16 | { 17 | _pool = pool; 18 | } 19 | 20 | public ImmutableDictionary ToImmutableDictionaryAndFree() 21 | { 22 | var result = this.ToImmutableDictionary(); 23 | this.Free(); 24 | return result; 25 | } 26 | 27 | public void Free() 28 | { 29 | this.Clear(); 30 | _pool?.Free(this); 31 | } 32 | 33 | // global pool 34 | private static readonly ObjectPool> s_poolInstance = CreatePool(); 35 | 36 | // if someone needs to create a pool; 37 | public static ObjectPool> CreatePool() 38 | { 39 | ObjectPool> pool = null; 40 | pool = new ObjectPool>(() => new PooledDictionary(pool), 128); 41 | return pool; 42 | } 43 | 44 | public static PooledDictionary GetInstance() 45 | { 46 | var instance = s_poolInstance.Allocate(); 47 | Debug.Assert(instance.Count == 0); 48 | return instance; 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/PooledHashSet.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MinimalDebuggerForEnCWithRoslyn 9 | { 10 | internal class PooledHashSet : HashSet 11 | { 12 | private readonly ObjectPool> _pool; 13 | 14 | private PooledHashSet(ObjectPool> pool) 15 | { 16 | _pool = pool; 17 | } 18 | 19 | public void Free() 20 | { 21 | this.Clear(); 22 | _pool?.Free(this); 23 | } 24 | 25 | // global pool 26 | private static readonly ObjectPool> s_poolInstance = CreatePool(); 27 | 28 | // if someone needs to create a pool; 29 | public static ObjectPool> CreatePool() 30 | { 31 | ObjectPool> pool = null; 32 | pool = new ObjectPool>(() => new PooledHashSet(pool), 128); 33 | return pool; 34 | } 35 | 36 | public static PooledHashSet GetInstance() 37 | { 38 | var instance = s_poolInstance.Allocate(); 39 | Debug.Assert(instance.Count == 0); 40 | return instance; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/PooledStringBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace MinimalDebuggerForEnCWithRoslyn 9 | { 10 | /// 11 | /// The usage is: 12 | /// var inst = PooledStringBuilder.GetInstance(); 13 | /// var sb = inst.builder; 14 | /// ... Do Stuff... 15 | /// ... sb.ToString() ... 16 | /// inst.Free(); 17 | /// 18 | internal class PooledStringBuilder 19 | { 20 | public readonly StringBuilder Builder = new StringBuilder(); 21 | private readonly ObjectPool _pool; 22 | 23 | private PooledStringBuilder(ObjectPool pool) 24 | { 25 | Debug.Assert(pool != null); 26 | _pool = pool; 27 | } 28 | 29 | public int Length 30 | { 31 | get { return this.Builder.Length; } 32 | } 33 | 34 | public void Free() 35 | { 36 | var builder = this.Builder; 37 | 38 | // do not store builders that are too large. 39 | if (builder.Capacity <= 1024) 40 | { 41 | builder.Clear(); 42 | _pool.Free(this); 43 | } 44 | else 45 | { 46 | _pool.ForgetTrackedObject(this); 47 | } 48 | } 49 | 50 | [System.Obsolete("Consider calling ToStringAndFree instead.")] 51 | public new string ToString() 52 | { 53 | return this.Builder.ToString(); 54 | } 55 | 56 | public string ToStringAndFree() 57 | { 58 | string result = this.Builder.ToString(); 59 | this.Free(); 60 | 61 | return result; 62 | } 63 | 64 | public string ToStringAndFree(int startIndex, int length) 65 | { 66 | string result = this.Builder.ToString(startIndex, length); 67 | this.Free(); 68 | 69 | return result; 70 | } 71 | 72 | // global pool 73 | private static readonly ObjectPool s_poolInstance = CreatePool(); 74 | 75 | // if someone needs to create a private pool; 76 | public static ObjectPool CreatePool() 77 | { 78 | ObjectPool pool = null; 79 | pool = new ObjectPool(() => new PooledStringBuilder(pool), 32); 80 | return pool; 81 | } 82 | 83 | public static PooledStringBuilder GetInstance() 84 | { 85 | var builder = s_poolInstance.Allocate(); 86 | Debug.Assert(builder.Builder.Length == 0); 87 | return builder; 88 | } 89 | 90 | public static implicit operator StringBuilder(PooledStringBuilder obj) 91 | { 92 | return obj.Builder; 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("MinimalDebuggerForEnCWithRoslyn")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MinimalDebuggerForEnCWithRoslyn")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f7d5fa28-5409-40ac-a2be-f0164910de50")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/StreamExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace MinimalDebuggerForEnCWithRoslyn 10 | { 11 | internal static class StreamExtensions 12 | { 13 | /// 14 | /// Attempts to read all of the requested bytes from the stream into the buffer 15 | /// 16 | /// 17 | /// The number of bytes read. Less than will 18 | /// only be returned if the end of stream is reached before all bytes can be read. 19 | /// 20 | /// 21 | /// Unlike it is not guaranteed that 22 | /// the stream position or the output buffer will be unchanged if an exception is 23 | /// returned. 24 | /// 25 | public static int TryReadAll( 26 | this Stream stream, 27 | byte[] buffer, 28 | int offset, 29 | int count) 30 | { 31 | // The implementations for many streams, e.g. FileStream, allows 0 bytes to be 32 | // read and returns 0, but the documentation for Stream.Read states that 0 is 33 | // only returned when the end of the stream has been reached. Rather than deal 34 | // with this contradiction, let's just never pass a count of 0 bytes 35 | Debug.Assert(count > 0); 36 | 37 | int totalBytesRead; 38 | int bytesRead = 0; 39 | for (totalBytesRead = 0; totalBytesRead < count; totalBytesRead += bytesRead) 40 | { 41 | // Note: Don't attempt to save state in-between calls to .Read as it would 42 | // require a possibly massive intermediate buffer array 43 | bytesRead = stream.Read(buffer, 44 | offset + totalBytesRead, 45 | count - totalBytesRead); 46 | if (bytesRead == 0) 47 | { 48 | break; 49 | } 50 | } 51 | return totalBytesRead; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/SymReaderFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Reflection.Metadata; 7 | using System.Reflection.PortableExecutable; 8 | using System.Runtime.InteropServices; 9 | using Microsoft.DiaSymReader; 10 | using System.IO; 11 | using System.Collections.Immutable; 12 | 13 | namespace MinimalDebuggerForEnCWithRoslyn 14 | { 15 | public static class SymReaderFactory 16 | { 17 | [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)] 18 | [DllImport("Microsoft.DiaSymReader.Native.x86.dll", EntryPoint = "CreateSymReader")] 19 | private extern static void CreateSymReader32(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)]out object symReader); 20 | 21 | [DefaultDllImportSearchPaths(DllImportSearchPath.AssemblyDirectory)] 22 | [DllImport("Microsoft.DiaSymReader.Native.amd64.dll", EntryPoint = "CreateSymReader")] 23 | private extern static void CreateSymReader64(ref Guid id, [MarshalAs(UnmanagedType.IUnknown)]out object symReader); 24 | 25 | private static ISymUnmanagedReader3 CreateNativeSymReader(Stream pdbStream, object metadataImporter) 26 | { 27 | object symReader = null; 28 | 29 | var guid = default(Guid); 30 | if (IntPtr.Size == 4) 31 | { 32 | CreateSymReader32(ref guid, out symReader); 33 | } 34 | else 35 | { 36 | CreateSymReader64(ref guid, out symReader); 37 | } 38 | 39 | var reader = (ISymUnmanagedReader3)symReader; 40 | int hr = reader.Initialize(metadataImporter, null, null, new ComStreamWrapper(pdbStream)); 41 | SymUnmanagedReaderExtensions.ThrowExceptionForHR(hr); 42 | return reader; 43 | } 44 | 45 | private static ISymUnmanagedReader CreatePortableSymReader(Stream pdbStream, object metadataImporter) 46 | { 47 | throw new NotImplementedException("I can't implement SymBinder yet"); 48 | 49 | //TODO: Implement SymbBinder 50 | //var binder = new PortablePdb.SymBinder(); 51 | 52 | //ISymUnmanagedReader reader; 53 | //int hr = binder.GetReaderFromStream(metadataImporter, new ComStreamWrapper(pdbStream), out reader); 54 | //SymUnmanagedReaderExtensions.ThrowExceptionForHR(hr); 55 | 56 | //return reader; 57 | } 58 | 59 | public static ISymUnmanagedReader CreateReader(byte[] pdbImage, byte[] peImageOpt = null) 60 | { 61 | return CreateReader(new MemoryStream(pdbImage), (peImageOpt != null) ? new PEReader(new MemoryStream(peImageOpt)) : null); 62 | } 63 | 64 | public static ISymUnmanagedReader CreateReader(ImmutableArray pdbImage, ImmutableArray peImageOpt = default(ImmutableArray)) 65 | { 66 | return CreateReader(new MemoryStream(pdbImage.ToArray()), (peImageOpt.IsDefault) ? null : new PEReader(peImageOpt)); 67 | } 68 | 69 | public static ISymUnmanagedReader CreateReader(Stream pdbStream, Stream peStreamOpt = null) 70 | { 71 | return CreateReader(pdbStream, (peStreamOpt != null) ? new PEReader(peStreamOpt) : null); 72 | } 73 | 74 | public static ISymUnmanagedReader CreateReader(Stream pdbStream, PEReader peReaderOpt) 75 | { 76 | return CreateReader(pdbStream, peReaderOpt?.GetMetadataReader(), peReaderOpt); 77 | } 78 | 79 | public static ISymUnmanagedReader CreateReader(Stream pdbStream, MetadataReader metadataReaderOpt, IDisposable metadataMemoryOwnerOpt) 80 | { 81 | return CreateReaderImpl(pdbStream, metadataImporter: new DummyMetadataImport(metadataReaderOpt, metadataMemoryOwnerOpt)); 82 | } 83 | 84 | public static ISymUnmanagedReader CreateReaderImpl(Stream pdbStream, object metadataImporter) 85 | { 86 | pdbStream.Position = 0; 87 | bool isPortable = pdbStream.ReadByte() == 'B' && pdbStream.ReadByte() == 'S' && pdbStream.ReadByte() == 'J' && pdbStream.ReadByte() == 'B'; 88 | pdbStream.Position = 0; 89 | 90 | if (isPortable) 91 | { 92 | return CreatePortableSymReader(pdbStream, metadataImporter); 93 | } 94 | else 95 | { 96 | return CreateNativeSymReader(pdbStream, metadataImporter); 97 | } 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /MinimalDebuggerForEnCWithRoslyn/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /NativeDebugWrappers/NativeDebugWrappers.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.50727 7 | 2.0 8 | {3991AB6C-468B-4C28-95FC-3188CFB34180} 9 | Library 10 | Properties 11 | NativeDebugWrappers 12 | NativeDebugWrappers 13 | v4.0 14 | 15 | 16 | 2.0 17 | 18 | publish\ 19 | true 20 | Disk 21 | false 22 | Foreground 23 | 7 24 | Days 25 | false 26 | false 27 | true 28 | 0 29 | 1.0.0.%2a 30 | false 31 | false 32 | true 33 | Client 34 | 35 | 36 | true 37 | full 38 | false 39 | ..\..\..\bin\Debug\ 40 | DEBUG;TRACE 41 | prompt 42 | 4 43 | true 44 | bin\Debug\NativeDebugWrappers.XML 45 | 1591 46 | MinimumRecommendedRules.ruleset 47 | true 48 | 49 | 50 | pdbonly 51 | true 52 | ..\..\..\bin\Release\ 53 | TRACE 54 | prompt 55 | 4 56 | true 57 | AllRules.ruleset 58 | 59 | 60 | true 61 | 62 | 63 | mdbg.snk 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | False 84 | .NET Framework 3.5 SP1 Client Profile 85 | false 86 | 87 | 88 | False 89 | .NET Framework 3.5 SP1 90 | true 91 | 92 | 93 | False 94 | Windows Installer 3.1 95 | true 96 | 97 | 98 | 99 | 100 | 101 | 102 | 109 | -------------------------------------------------------------------------------- /NativeDebugWrappers/NativeDebugWrappersAssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | 2 | // Attributes for the NativeDebugWrappers 3 | using System; 4 | using System.Runtime.InteropServices; 5 | using System.Runtime.InteropServices.ComTypes; 6 | using System.Security.Permissions; 7 | 8 | 9 | 10 | [assembly:CLSCompliant(false)] 11 | [assembly:System.Runtime.InteropServices.ComVisible(false)] 12 | [assembly:SecurityPermission(SecurityAction.RequestMinimum, Unrestricted=true)] -------------------------------------------------------------------------------- /NativeDebugWrappers/PEReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.IO; 5 | 6 | namespace Microsoft.Samples.Debugging.Native 7 | { 8 | 9 | /// 10 | /// A very basic PE reader that can extract a few useful pieces of information 11 | /// 12 | public class PEReader 13 | { 14 | // PE file 15 | FileStream m_peStream; 16 | 17 | // cached information from the PE file 18 | int peHeaderOffset = 0; 19 | 20 | public PEReader(FileStream peFileStream) 21 | { 22 | m_peStream = peFileStream; 23 | } 24 | 25 | public int TimeStamp 26 | { 27 | get 28 | { 29 | return ReadDwordAtFileOffset(PEHeaderOffset + 8); 30 | } 31 | } 32 | 33 | public int SizeOfImage 34 | { 35 | get 36 | { 37 | return ReadDwordAtFileOffset(PEHeaderOffset + 80); 38 | } 39 | } 40 | 41 | int PEHeaderOffset 42 | { 43 | get 44 | { 45 | if (peHeaderOffset == 0) 46 | { 47 | peHeaderOffset = ReadDwordAtFileOffset(0x3c); 48 | } 49 | return peHeaderOffset; 50 | } 51 | } 52 | 53 | int ReadDwordAtFileOffset(int fileOffset) 54 | { 55 | byte[] dword = new byte[4]; 56 | ReadBytesAtFileOffset(dword, fileOffset); 57 | return BitConverter.ToInt32(dword, 0); 58 | } 59 | 60 | void ReadBytesAtFileOffset(byte[] bytes, int fileOffset) 61 | { 62 | m_peStream.Seek(fileOffset, SeekOrigin.Begin); 63 | int bytesReadTotal = 0; 64 | do 65 | { 66 | int bytesRead = m_peStream.Read(bytes, bytesReadTotal, bytes.Length - bytesReadTotal); 67 | bytesReadTotal += bytesRead; 68 | } while (bytesReadTotal != bytes.Length); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /NativeDebugWrappers/ReadMe.txt: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | ReadMe.txt for NativeDebugWrappers project. 8 | 9 | The library NativeDebugWrappers can be used to write a native debugger 10 | in managed code. It complements the CorApi library that allows writing 11 | managed debuggers in managed code. -------------------------------------------------------------------------------- /NativeDebugWrappers/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.Reflection.AssemblyTitle("Managed Debugger Sample")] 2 | [assembly: System.Reflection.AssemblyCompany("Microsoft Corporation")] 3 | [assembly: System.Reflection.AssemblyCopyright("Copyright © Microsoft Corporation. All rights reserved.")] 4 | [assembly: System.Reflection.AssemblyTrademark("Microsoft® is a registered trademark of Microsoft Corporation.")] 5 | [assembly: System.Reflection.AssemblyVersion("2.1.0")] 6 | /* 7 | * ******************* 8 | * Maintenance History 9 | * ******************* 10 | * 11 | * - Version 2.1.0 12 | * - More advanced debug event control and logging is now available via "ca" and "log" commands. 13 | * - Breaking change in IMdbgIO.WriteOutput. This no longer includes a new line. 14 | * - IronPython extension added. 15 | * - Managed wrappers for native debug APIs added. 16 | * - Pdb to Xml conversion tool added. 17 | * 18 | */ 19 | -------------------------------------------------------------------------------- /NativeDebugWrappers/mdbg.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/NativeDebugWrappers/mdbg.snk -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MinimalDebuggerForEnC 2 | All in pursuit of ICorDebugModule2::ApplyChanges... 3 | 4 | 5 | ![st](http://i.imgur.com/xVyoSl.jpg) 6 | -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/SampleExeWithILAndMetadata/SampleProcess.exe -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.exe.1.dil: -------------------------------------------------------------------------------- 1 | /"(*r( 2 | ( 3 | &( 4 | ( 5 | &*"( 6 | * -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.exe.1.dmeta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/SampleExeWithILAndMetadata/SampleProcess.exe.1.dmeta -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.exe.1.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/SampleExeWithILAndMetadata/SampleProcess.exe.1.pdb -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.exe.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.il: -------------------------------------------------------------------------------- 1 | 2 | // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | 6 | 7 | // Metadata version: v4.0.30319 8 | .assembly extern mscorlib 9 | { 10 | .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. 11 | .ver 4:0:0:0 12 | } 13 | .assembly SampleProcess 14 | { 15 | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 16 | .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx 17 | 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. 18 | 19 | // --- The following custom attribute is added automatically, do not uncomment ------- 20 | // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) 21 | 22 | .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0D 53 61 6D 70 6C 65 50 72 6F 63 65 73 73 // ...SampleProcess 23 | 00 00 ) 24 | .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 ) 25 | .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 ) 26 | .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 ) 27 | .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0D 53 61 6D 70 6C 65 50 72 6F 63 65 73 73 // ...SampleProcess 28 | 00 00 ) 29 | .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9 20 // ...Copyright .. 30 | 20 32 30 31 36 00 00 ) // 2016.. 31 | .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 ) 32 | .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 ) 33 | .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 62 37 38 62 33 36 31 63 2D 37 30 66 66 // ..$b78b361c-70ff 34 | 2D 34 66 62 61 2D 61 33 39 37 2D 62 64 61 31 66 // -4fba-a397-bda1f 35 | 64 63 63 39 31 64 39 00 00 ) // dcc91d9.. 36 | .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 ) // ...1.0.0.0.. 37 | .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1C 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B // ....NETFramework 38 | 2C 56 65 72 73 69 6F 6E 3D 76 34 2E 35 2E 32 01 // ,Version=v4.5.2. 39 | 00 54 0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 // .T..FrameworkDis 40 | 70 6C 61 79 4E 61 6D 65 14 2E 4E 45 54 20 46 72 // playName..NET Fr 41 | 61 6D 65 77 6F 72 6B 20 34 2E 35 2E 32 ) // amework 4.5.2 42 | .hash algorithm 0x00008004 43 | .ver 1:0:0:0 44 | } 45 | .module SampleProcess.exe 46 | // MVID: {E27D993A-95C3-402C-8F7B-64C1628B3171} 47 | .imagebase 0x00400000 48 | .file alignment 0x00000200 49 | .stackreserve 0x00100000 50 | .subsystem 0x0003 // WINDOWS_CUI 51 | .corflags 0x00020003 // ILONLY 32BITPREFERRED 52 | // Image base: 0x01150000 53 | 54 | 55 | // =============== CLASS MEMBERS DECLARATION =================== 56 | 57 | .class public auto ansi beforefieldinit C 58 | extends [mscorlib]System.Object 59 | { 60 | .method public hidebysig static void Main() cil managed 61 | { 62 | .entrypoint 63 | // Code size 8 (0x8) 64 | .maxstack 8 65 | IL_0000: nop 66 | IL_0001: call void C::F() 67 | IL_0006: nop 68 | IL_0007: ret 69 | } // end of method C::Main 70 | 71 | .method public hidebysig static void F() cil managed 72 | { 73 | // Code size 28 (0x1c) 74 | .maxstack 8 75 | IL_0000: nop 76 | IL_0001: ldc.i4.1 77 | IL_0002: call void [mscorlib]System.Console::WriteLine(int32) 78 | IL_0007: nop 79 | IL_0008: call string [mscorlib]System.Console::ReadLine() 80 | IL_000d: pop 81 | IL_000e: ldc.i4.1 82 | IL_000f: call void [mscorlib]System.Console::WriteLine(int32) 83 | IL_0014: nop 84 | IL_0015: call string [mscorlib]System.Console::ReadLine() 85 | IL_001a: pop 86 | IL_001b: ret 87 | } // end of method C::F 88 | 89 | .method public hidebysig specialname rtspecialname 90 | instance void .ctor() cil managed 91 | { 92 | // Code size 8 (0x8) 93 | .maxstack 8 94 | IL_0000: ldarg.0 95 | IL_0001: call instance void [mscorlib]System.Object::.ctor() 96 | IL_0006: nop 97 | IL_0007: ret 98 | } // end of method C::.ctor 99 | 100 | } // end of class C 101 | 102 | 103 | // ============================================================= 104 | 105 | // *********** DISASSEMBLY COMPLETE *********************** 106 | // WARNING: Created Win32 resource file SampleProcess.res 107 | -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/SampleExeWithILAndMetadata/SampleProcess.pdb -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/SampleExeWithILAndMetadata/SampleProcess.res -------------------------------------------------------------------------------- /SampleExeWithILAndMetadata/SampleProcess_v1.il: -------------------------------------------------------------------------------- 1 | 2 | // Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0 3 | // Copyright (c) Microsoft Corporation. All rights reserved. 4 | 5 | 6 | 7 | // Metadata version: v4.0.30319 8 | .assembly extern mscorlib 9 | { 10 | .publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. 11 | .ver 4:0:0:0 12 | } 13 | .assembly SampleProcess 14 | { 15 | .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) 16 | .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx 17 | 63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows. 18 | 19 | // --- The following custom attribute is added automatically, do not uncomment ------- 20 | // .custom instance void [mscorlib]System.Diagnostics.DebuggableAttribute::.ctor(valuetype [mscorlib]System.Diagnostics.DebuggableAttribute/DebuggingModes) = ( 01 00 07 01 00 00 00 00 ) 21 | 22 | .custom instance void [mscorlib]System.Reflection.AssemblyTitleAttribute::.ctor(string) = ( 01 00 0D 53 61 6D 70 6C 65 50 72 6F 63 65 73 73 // ...SampleProcess 23 | 00 00 ) 24 | .custom instance void [mscorlib]System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = ( 01 00 00 00 00 ) 25 | .custom instance void [mscorlib]System.Reflection.AssemblyConfigurationAttribute::.ctor(string) = ( 01 00 00 00 00 ) 26 | .custom instance void [mscorlib]System.Reflection.AssemblyCompanyAttribute::.ctor(string) = ( 01 00 00 00 00 ) 27 | .custom instance void [mscorlib]System.Reflection.AssemblyProductAttribute::.ctor(string) = ( 01 00 0D 53 61 6D 70 6C 65 50 72 6F 63 65 73 73 // ...SampleProcess 28 | 00 00 ) 29 | .custom instance void [mscorlib]System.Reflection.AssemblyCopyrightAttribute::.ctor(string) = ( 01 00 12 43 6F 70 79 72 69 67 68 74 20 C2 A9 20 // ...Copyright .. 30 | 20 32 30 31 36 00 00 ) // 2016.. 31 | .custom instance void [mscorlib]System.Reflection.AssemblyTrademarkAttribute::.ctor(string) = ( 01 00 00 00 00 ) 32 | .custom instance void [mscorlib]System.Runtime.InteropServices.ComVisibleAttribute::.ctor(bool) = ( 01 00 00 00 00 ) 33 | .custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 62 37 38 62 33 36 31 63 2D 37 30 66 66 // ..$b78b361c-70ff 34 | 2D 34 66 62 61 2D 61 33 39 37 2D 62 64 61 31 66 // -4fba-a397-bda1f 35 | 64 63 63 39 31 64 39 00 00 ) // dcc91d9.. 36 | .custom instance void [mscorlib]System.Reflection.AssemblyFileVersionAttribute::.ctor(string) = ( 01 00 07 31 2E 30 2E 30 2E 30 00 00 ) // ...1.0.0.0.. 37 | .custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) = ( 01 00 1C 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B // ....NETFramework 38 | 2C 56 65 72 73 69 6F 6E 3D 76 34 2E 35 2E 32 01 // ,Version=v4.5.2. 39 | 00 54 0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 // .T..FrameworkDis 40 | 70 6C 61 79 4E 61 6D 65 14 2E 4E 45 54 20 46 72 // playName..NET Fr 41 | 61 6D 65 77 6F 72 6B 20 34 2E 35 2E 32 ) // amework 4.5.2 42 | .hash algorithm 0x00008004 43 | .ver 1:0:0:0 44 | } 45 | .module SampleProcess.exe 46 | // MVID: {E27D993A-95C3-402C-8F7B-64C1628B3171} 47 | .imagebase 0x00400000 48 | .file alignment 0x00000200 49 | .stackreserve 0x00100000 50 | .subsystem 0x0003 // WINDOWS_CUI 51 | .corflags 0x00020003 // ILONLY 32BITPREFERRED 52 | // Image base: 0x01150000 53 | 54 | 55 | // =============== CLASS MEMBERS DECLARATION =================== 56 | 57 | .class public auto ansi beforefieldinit C 58 | extends [mscorlib]System.Object 59 | { 60 | .method public hidebysig static void Main() cil managed 61 | { 62 | .entrypoint 63 | // Code size 8 (0x8) 64 | .maxstack 8 65 | IL_0000: nop 66 | IL_0001: call void C::F() 67 | IL_0006: nop 68 | IL_0007: ret 69 | } // end of method C::Main 70 | 71 | .method public hidebysig static void F() cil managed 72 | { 73 | // Code size 28 (0x1c) 74 | .maxstack 8 75 | IL_0000: nop 76 | IL_0001: ldc.i4.2 77 | IL_0002: call void [mscorlib]System.Console::WriteLine(int32) 78 | IL_0007: nop 79 | IL_0008: call string [mscorlib]System.Console::ReadLine() 80 | IL_000d: pop 81 | IL_000e: ldc.i4.2 82 | IL_000f: call void [mscorlib]System.Console::WriteLine(int32) 83 | IL_0014: nop 84 | IL_0015: call string [mscorlib]System.Console::ReadLine() 85 | IL_001a: pop 86 | IL_001b: ret 87 | } // end of method C::F 88 | 89 | .method public hidebysig specialname rtspecialname 90 | instance void .ctor() cil managed 91 | { 92 | // Code size 8 (0x8) 93 | .maxstack 8 94 | IL_0000: ldarg.0 95 | IL_0001: call instance void [mscorlib]System.Object::.ctor() 96 | IL_0006: nop 97 | IL_0007: ret 98 | } // end of method C::.ctor 99 | 100 | } // end of class C 101 | 102 | 103 | // ============================================================= 104 | 105 | // *********** DISASSEMBLY COMPLETE *********************** 106 | // WARNING: Created Win32 resource file SampleProcess.res 107 | -------------------------------------------------------------------------------- /SampleProcess/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /SampleProcess/Program.cs: -------------------------------------------------------------------------------- 1 | public class C 2 | { 3 | public static void Main() { F(); } 4 | public static void F() { System.Console.WriteLine(1); System.Console.ReadLine(); System.Console.WriteLine(1); System.Console.ReadLine(); } 5 | } -------------------------------------------------------------------------------- /SampleProcess/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SampleProcess")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SampleProcess")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b78b361c-70ff-4fba-a397-bda1fdcc91d9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /SampleProcess/SampleProcess.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B78B361C-70FF-4FBA-A397-BDA1FDCC91D9} 8 | Exe 9 | Properties 10 | SampleProcess 11 | SampleProcess 12 | v4.5.2 13 | 512 14 | true 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 60 | -------------------------------------------------------------------------------- /corapi/AppDomain.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | using System.Text; 9 | 10 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 11 | 12 | namespace Microsoft.Samples.Debugging.CorDebug 13 | { 14 | public sealed class CorAppDomain : CorController 15 | { 16 | /** Create an CorAppDomain object. */ 17 | internal CorAppDomain (ICorDebugAppDomain appDomain) 18 | : base (appDomain) 19 | { 20 | } 21 | 22 | [CLSCompliant(false)] 23 | public ICorDebugAppDomain Raw 24 | { 25 | get 26 | { 27 | return _ad(); 28 | } 29 | } 30 | 31 | /** Get the ICorDebugAppDomain interface back from the Controller. */ 32 | private ICorDebugAppDomain _ad () 33 | { 34 | return (ICorDebugAppDomain) GetController(); 35 | } 36 | 37 | /** Get the process containing the CorAppDomain. */ 38 | public CorProcess Process 39 | { 40 | get 41 | { 42 | ICorDebugProcess proc = null; 43 | _ad().GetProcess (out proc); 44 | return CorProcess.GetCorProcess (proc); 45 | } 46 | } 47 | 48 | /** Get all Assemblies in the CorAppDomain. */ 49 | public IEnumerable Assemblies 50 | { 51 | get 52 | { 53 | ICorDebugAssemblyEnum eas = null; 54 | _ad().EnumerateAssemblies (out eas); 55 | return new CorAssemblyEnumerator (eas); 56 | } 57 | } 58 | 59 | /** All active breakpoints in the CorAppDomain */ 60 | public IEnumerable Breakpoints 61 | { 62 | get 63 | { 64 | ICorDebugBreakpointEnum bpoint = null; 65 | _ad().EnumerateBreakpoints (out bpoint); 66 | return new CorBreakpointEnumerator (bpoint); 67 | } 68 | } 69 | 70 | /** All active steppers in the CorAppDomain */ 71 | public IEnumerable Steppers 72 | { 73 | get 74 | { 75 | ICorDebugStepperEnum step = null; 76 | _ad().EnumerateSteppers (out step); 77 | return new CorStepperEnumerator (step); 78 | } 79 | } 80 | 81 | /** Is the debugger attached to the CorAppDomain? */ 82 | public bool IsAttached () 83 | { 84 | int attach = 0; 85 | _ad().IsAttached (out attach); 86 | return !(attach==0); 87 | } 88 | 89 | /** The name of the CorAppDomain */ 90 | public String Name 91 | { 92 | get 93 | { 94 | uint size = 0; 95 | _ad().GetName (0, out size, null); 96 | StringBuilder szName = new StringBuilder((int)size); 97 | _ad().GetName ((uint)szName.Capacity, out size, szName); 98 | return szName.ToString(); 99 | } 100 | } 101 | 102 | /** Get the runtime App domain object */ 103 | public CorValue AppDomainVariable 104 | { 105 | get 106 | { 107 | ICorDebugValue val = null; 108 | _ad().GetObject (out val); 109 | return new CorValue (val); 110 | } 111 | } 112 | 113 | /** 114 | * Attach the AppDomain to receive all CorAppDomain related events (e.g. 115 | * load assembly, load module, etc.) in order to debug the AppDomain. 116 | */ 117 | public void Attach () 118 | { 119 | _ad().Attach (); 120 | } 121 | 122 | /** Get the ID of this CorAppDomain */ 123 | public int Id 124 | { 125 | get 126 | { 127 | uint id = 0; 128 | _ad().GetID (out id); 129 | return (int) id; 130 | } 131 | } 132 | 133 | /** Returns CorType object for an array of or pointer to the given type */ 134 | public CorType GetArrayOrPointerType(CorElementType elementType, int rank, CorType parameterTypes) 135 | { 136 | ICorDebugType ct = null; 137 | uint urank = (uint) rank; 138 | (_ad() as ICorDebugAppDomain2).GetArrayOrPointerType(elementType, urank, parameterTypes.m_type, out ct); 139 | return ct==null?null:new CorType (ct); 140 | } 141 | 142 | /** Returns CorType object for a pointer to a function */ 143 | public CorType GetFunctionPointerType(CorType[] parameterTypes) 144 | { 145 | ICorDebugType[] types = null; 146 | if (parameterTypes != null) 147 | { 148 | types = new ICorDebugType[parameterTypes.Length]; 149 | for (int i = 0; i < parameterTypes.Length; i++) 150 | types[i] = parameterTypes[i].m_type; 151 | } 152 | 153 | ICorDebugType ct = null; 154 | (_ad() as ICorDebugAppDomain2).GetFunctionPointerType((uint)types.Length, types, out ct); 155 | return ct==null?null:new CorType (ct); 156 | } 157 | 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /corapi/AppDomainEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for AppDomains. */ 14 | internal class CorAppDomainEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugAppDomainEnum m_enum; 17 | private CorAppDomain m_ad; 18 | 19 | internal CorAppDomainEnumerator (ICorDebugAppDomainEnum appDomainEnumerator) 20 | { 21 | m_enum = appDomainEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorAppDomainEnumerator ((ICorDebugAppDomainEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugAppDomain[] a = new ICorDebugAppDomain [1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | m_ad = new CorAppDomain (a[0]); 52 | else 53 | m_ad = null; 54 | return m_ad != null; 55 | } 56 | 57 | public void Reset () 58 | { 59 | m_enum.Reset (); 60 | m_ad = null; 61 | } 62 | 63 | public Object Current 64 | { 65 | get 66 | { 67 | return m_ad; 68 | } 69 | } 70 | } /* class AppDomainEnumerator */ 71 | } /* namespace */ 72 | -------------------------------------------------------------------------------- /corapi/Assembly.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** 14 | * Information about an Assembly being debugged. 15 | */ 16 | public sealed class CorAssembly : WrapperBase 17 | { 18 | private ICorDebugAssembly m_asm; 19 | 20 | internal CorAssembly (ICorDebugAssembly managedAssembly) 21 | :base(managedAssembly) 22 | { 23 | m_asm = managedAssembly; 24 | } 25 | 26 | [CLSCompliant(false)] 27 | public ICorDebugAssembly Raw 28 | { 29 | get 30 | { 31 | return m_asm; 32 | } 33 | } 34 | 35 | /** Get the process containing the Assembly. */ 36 | public CorProcess Process 37 | { 38 | get 39 | { 40 | ICorDebugProcess proc = null; 41 | m_asm.GetProcess (out proc); 42 | return CorProcess.GetCorProcess(proc); 43 | } 44 | } 45 | 46 | /** Get the AppDomain containing the assembly. */ 47 | public CorAppDomain AppDomain 48 | { 49 | get 50 | { 51 | ICorDebugAppDomain ad = null; 52 | m_asm.GetAppDomain (out ad); 53 | return new CorAppDomain (ad); 54 | } 55 | } 56 | 57 | /** All the modules in the assembly. */ 58 | public IEnumerable Modules 59 | { 60 | get 61 | { 62 | ICorDebugModuleEnum emod = null; 63 | m_asm.EnumerateModules (out emod); 64 | return new CorModuleEnumerator (emod); 65 | } 66 | } 67 | 68 | /** Get the name of the code base used to load the assembly. */ 69 | public String CodeBase 70 | { 71 | get 72 | { 73 | char[] name = new char[300]; 74 | uint sz = 0; 75 | m_asm.GetCodeBase ((uint) name.Length, out sz, name); 76 | // ``sz'' includes terminating null; String doesn't handle null, 77 | // so we "forget" it. 78 | return new String (name, 0, (int) (sz-1)); 79 | } 80 | } 81 | 82 | /** The name of the assembly. */ 83 | public String Name 84 | { 85 | get 86 | { 87 | char[] name = new char[300]; 88 | uint sz = 0; 89 | m_asm.GetName ((uint) name.Length, out sz, name); 90 | // ``sz'' includes terminating null; String doesn't handle null, 91 | // so we "forget" it. 92 | return new String (name, 0, (int) (sz-1)); 93 | } 94 | } 95 | 96 | public Boolean IsFullyTrusted 97 | { 98 | get 99 | { 100 | ICorDebugAssembly2 asm2 = m_asm as ICorDebugAssembly2; 101 | if( asm2 == null ) 102 | { 103 | throw new NotSupportedException("This version of the CLR does not support IsFullyTrusted"); 104 | } 105 | 106 | int trustFlag; 107 | asm2.IsFullyTrusted( out trustFlag ); 108 | if( trustFlag == 0 ) 109 | { 110 | return false; 111 | } 112 | else 113 | { 114 | return true; 115 | } 116 | } 117 | } 118 | } /* class Assembly */ 119 | } /* namespace debugging */ 120 | -------------------------------------------------------------------------------- /corapi/AssemblyEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Assemblies. */ 14 | internal class CorAssemblyEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugAssemblyEnum m_enum; 17 | private CorAssembly m_asm; 18 | 19 | internal CorAssemblyEnumerator (ICorDebugAssemblyEnum assemblyEnumerator) 20 | { 21 | m_enum = assemblyEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorAssemblyEnumerator ((ICorDebugAssemblyEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugAssembly[] a = new ICorDebugAssembly[1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | m_asm = new CorAssembly (a[0]); 52 | else 53 | m_asm = null; 54 | return m_asm != null; 55 | } 56 | 57 | public void Reset () 58 | { 59 | m_enum.Reset (); 60 | m_asm = null; 61 | } 62 | 63 | public Object Current 64 | { 65 | get 66 | { 67 | return m_asm; 68 | } 69 | } 70 | } /* class AssemblyEnumerator */ 71 | } /* namespace */ 72 | -------------------------------------------------------------------------------- /corapi/Breakpoint.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Diagnostics; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | public abstract class CorBreakpoint : WrapperBase 14 | { 15 | [CLSCompliant(false)] 16 | protected CorBreakpoint(ICorDebugBreakpoint managedBreakpoint) : base(managedBreakpoint) 17 | { 18 | Debug.Assert(managedBreakpoint!=null); 19 | m_corBreakpoint = managedBreakpoint; 20 | } 21 | 22 | [CLSCompliant(false)] 23 | public ICorDebugBreakpoint Raw 24 | { 25 | get 26 | { 27 | return m_corBreakpoint; 28 | } 29 | } 30 | 31 | public virtual void Activate(bool active) 32 | { 33 | m_corBreakpoint.Activate (active ? 1 : 0); 34 | } 35 | 36 | public virtual bool IsActive 37 | { 38 | get 39 | { 40 | int r = 0; 41 | m_corBreakpoint.IsActive (out r); 42 | return !(r==0); 43 | } 44 | } 45 | 46 | private ICorDebugBreakpoint m_corBreakpoint; 47 | } 48 | } /* namespace */ 49 | -------------------------------------------------------------------------------- /corapi/BreakpointEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Assemblies. */ 14 | internal class CorBreakpointEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugBreakpointEnum m_enum; 17 | private CorBreakpoint m_br; 18 | 19 | internal CorBreakpointEnumerator (ICorDebugBreakpointEnum breakpointEnumerator) 20 | { 21 | m_enum = breakpointEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorBreakpointEnumerator ((ICorDebugBreakpointEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugBreakpoint[] a = new ICorDebugBreakpoint[1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | { 52 | ICorDebugBreakpoint br = a[0]; 53 | throw new NotImplementedException(); 54 | /* 55 | if(a is ICorDebugFunctionBreakpoint) 56 | m_br = new CorFunctionBreakpoint((ICorDebugFunctionBreakpoint)br); 57 | else if( a is ICorDebugModuleBreakpoint) 58 | m_br = new CorModuleBreakpoint((ICorDebugModuleBreakpoint)br); 59 | else if( a is ICorDebugValueBreakpoint) 60 | m_br = new ValueBreakpoint((ICorDebugValueBreakpoint)m_br); 61 | else 62 | Debug.Assert(false); 63 | */ 64 | } 65 | else 66 | m_br = null; 67 | return m_br != null; 68 | } 69 | 70 | public void Reset () 71 | { 72 | m_enum.Reset (); 73 | m_br = null; 74 | } 75 | 76 | public Object Current 77 | { 78 | get 79 | { 80 | return m_br; 81 | } 82 | } 83 | } /* class BreakpointEnumerator */ 84 | } /* namespace */ 85 | -------------------------------------------------------------------------------- /corapi/ChainEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** 14 | * Exposes an enumerator for Chains. 15 | * 16 | * This is horribly broken at this point, as Chains aren't implemented yet. 17 | */ 18 | internal class CorChainEnumerator : IEnumerable, IEnumerator, ICloneable 19 | { 20 | private ICorDebugChainEnum m_enum; 21 | 22 | private CorChain m_chain; 23 | 24 | internal CorChainEnumerator (ICorDebugChainEnum chainEnumerator) 25 | { 26 | m_enum = chainEnumerator; 27 | } 28 | 29 | // 30 | // ICloneable interface 31 | // 32 | public Object Clone () 33 | { 34 | ICorDebugEnum clone = null; 35 | m_enum.Clone (out clone); 36 | return new CorChainEnumerator ((ICorDebugChainEnum)clone); 37 | } 38 | 39 | // 40 | // IEnumerable interface 41 | // 42 | public IEnumerator GetEnumerator () 43 | { 44 | return this; 45 | } 46 | 47 | // 48 | // IEnumerator interface 49 | // 50 | public bool MoveNext () 51 | { 52 | ICorDebugChain[] a = new ICorDebugChain[1]; 53 | uint c = 0; 54 | int r = m_enum.Next ((uint)a.Length, a, out c); 55 | if (r==0 && c==1) // S_OK && we got 1 new element 56 | m_chain = new CorChain (a[0]); 57 | else 58 | m_chain = null; 59 | return m_chain != null; 60 | } 61 | 62 | public void Reset () 63 | { 64 | m_enum.Reset (); 65 | m_chain = null; 66 | } 67 | 68 | public Object Current 69 | { 70 | get 71 | { 72 | return m_chain; 73 | } 74 | } 75 | } /* class ChainEnumerator */ 76 | } /* namespace */ 77 | -------------------------------------------------------------------------------- /corapi/Class.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | namespace Microsoft.Samples.Debugging.CorDebug 11 | { 12 | public sealed class CorClass : WrapperBase 13 | { 14 | internal ICorDebugClass m_class; 15 | 16 | internal CorClass (ICorDebugClass managedClass) 17 | : base(managedClass) 18 | { 19 | m_class = managedClass; 20 | } 21 | 22 | [CLSCompliant(false)] 23 | public ICorDebugClass Raw 24 | { 25 | get 26 | { 27 | return m_class; 28 | } 29 | } 30 | 31 | /** The module containing the class */ 32 | public CorModule Module 33 | { 34 | get 35 | { 36 | ICorDebugModule m = null; 37 | m_class.GetModule (out m); 38 | return new CorModule (m); 39 | } 40 | } 41 | 42 | /** The metadata typedef token of the class. */ 43 | public int Token 44 | { 45 | get 46 | { 47 | uint td = 0; 48 | m_class.GetToken (out td); 49 | return (int) td; 50 | } 51 | } 52 | 53 | public bool JMCStatus 54 | { 55 | set 56 | { 57 | (m_class as ICorDebugClass2).SetJMCStatus(value?1:0); 58 | } 59 | } 60 | 61 | public CorType GetParameterizedType(CorElementType elementType, CorType[] typeArguments) 62 | { 63 | ICorDebugType[] types = null; 64 | uint length = 0; 65 | if (typeArguments != null) 66 | { 67 | types = new ICorDebugType[typeArguments.Length]; 68 | for (int i = 0; i < typeArguments.Length; i++) 69 | types[i] = typeArguments[i].m_type; 70 | length = (uint)typeArguments.Length; 71 | } 72 | 73 | ICorDebugType pType; 74 | (m_class as ICorDebugClass2).GetParameterizedType(elementType, length, types, out pType); 75 | return pType==null?null:new CorType (pType); 76 | } 77 | 78 | public CorValue GetStaticFieldValue(int fieldToken, CorFrame managedFrame) 79 | { 80 | ICorDebugValue pValue; 81 | m_class.GetStaticFieldValue((uint)fieldToken, (managedFrame==null)?null:managedFrame.m_frame, out pValue); 82 | return pValue==null?null:new CorValue(pValue); 83 | } 84 | 85 | } /* class Class */ 86 | 87 | } /* namespace */ 88 | -------------------------------------------------------------------------------- /corapi/Constants.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Diagnostics; 8 | using System.Globalization; 9 | 10 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 11 | 12 | namespace Microsoft.Samples.Debugging.CorDebug 13 | { 14 | 15 | public enum CorDebuggerVersion 16 | { 17 | RTM = 1, //v1.0 18 | Everett = 2, //v1.1 19 | Whidbey = 3, //v2.0 20 | } 21 | 22 | // copied from Cordebug.idl 23 | [Flags] 24 | public enum CorDebugJITCompilerFlags 25 | { 26 | CORDEBUG_JIT_DEFAULT = 0x1, 27 | CORDEBUG_JIT_DISABLE_OPTIMIZATION = 0x3, 28 | CORDEBUG_JIT_ENABLE_ENC = 0x7 29 | } 30 | 31 | // keep in sync with CorHdr.h 32 | public enum CorTokenType 33 | { 34 | mdtModule = 0x00000000, // 35 | mdtTypeRef = 0x01000000, // 36 | mdtTypeDef = 0x02000000, // 37 | mdtFieldDef = 0x04000000, // 38 | mdtMethodDef = 0x06000000, // 39 | mdtParamDef = 0x08000000, // 40 | mdtInterfaceImpl = 0x09000000, // 41 | mdtMemberRef = 0x0a000000, // 42 | mdtCustomAttribute = 0x0c000000, // 43 | mdtPermission = 0x0e000000, // 44 | mdtSignature = 0x11000000, // 45 | mdtEvent = 0x14000000, // 46 | mdtProperty = 0x17000000, // 47 | mdtModuleRef = 0x1a000000, // 48 | mdtTypeSpec = 0x1b000000, // 49 | mdtAssembly = 0x20000000, // 50 | mdtAssemblyRef = 0x23000000, // 51 | mdtFile = 0x26000000, // 52 | mdtExportedType = 0x27000000, // 53 | mdtManifestResource = 0x28000000, // 54 | mdtGenericParam = 0x2a000000, // 55 | mdtMethodSpec = 0x2b000000, // 56 | mdtGenericParamConstraint = 0x2c000000, 57 | 58 | mdtString = 0x70000000, // 59 | mdtName = 0x71000000, // 60 | mdtBaseType = 0x72000000, // Leave this on the high end value. This does not correspond to metadata table 61 | } 62 | 63 | public abstract class TokenUtils 64 | { 65 | public static CorTokenType TypeFromToken(int token) 66 | { 67 | return (CorTokenType) ((UInt32)token & 0xff000000); 68 | } 69 | 70 | public static int RidFromToken(int token) 71 | { 72 | return (int)( (UInt32)token & 0x00ffffff); 73 | } 74 | 75 | public static bool IsNullToken(int token) 76 | { 77 | return (RidFromToken(token)==0); 78 | } 79 | } 80 | 81 | 82 | abstract class HRUtils 83 | { 84 | public static bool IsFailingHR(int hr) 85 | { 86 | return hr<0; 87 | } 88 | 89 | public static bool IsSOK(int hr) 90 | { 91 | return hr==0; 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /corapi/Controller.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** 14 | * Represents a scope at which program execution can be controlled. 15 | */ 16 | public class CorController : WrapperBase 17 | { 18 | internal CorController (ICorDebugController controller) 19 | :base(controller) 20 | { 21 | m_controller = controller; 22 | } 23 | 24 | /** 25 | * Cooperative stop on all threads running managed code in the process. 26 | */ 27 | public virtual void Stop (int timeout) 28 | { 29 | m_controller.Stop ((uint)timeout); 30 | } 31 | 32 | /** 33 | * Continue processes after a call to Stop. 34 | * 35 | * outOfBand is true if continuing from an unmanaged event that 36 | * was sent with the outOfBand flag in the unmanaged callback; 37 | * false if continueing from a managed event or normal unmanaged event. 38 | */ 39 | public virtual void Continue (bool outOfBand) 40 | { 41 | m_controller.Continue (outOfBand ? 1 : 0); 42 | } 43 | 44 | /** 45 | * Are the threads in the process running freely? 46 | */ 47 | public bool IsRunning () 48 | { 49 | int running = 0; 50 | m_controller.IsRunning (out running); 51 | return !(running == 0); 52 | } 53 | 54 | /** 55 | * Are there managed callbacks queued up for the requested thread? 56 | */ 57 | public bool HasQueuedCallbacks (CorThread managedThread) 58 | { 59 | int queued = 0; 60 | m_controller.HasQueuedCallbacks( (managedThread==null)?null:managedThread.GetInterface(), 61 | out queued 62 | ); 63 | return !(queued == 0); 64 | } 65 | 66 | /** Enumerate over all threads in active in the process. */ 67 | public IEnumerable Threads 68 | { 69 | get 70 | { 71 | ICorDebugThreadEnum ethreads = null; 72 | m_controller.EnumerateThreads (out ethreads); 73 | return new CorThreadEnumerator (ethreads); 74 | } 75 | } 76 | 77 | /** 78 | * Set the current debug state of each thread. 79 | */ 80 | [CLSCompliant(false)] 81 | public void SetAllThreadsDebugState (CorDebugThreadState state, CorThread exceptThis) 82 | { 83 | m_controller.SetAllThreadsDebugState (state, exceptThis != null ? exceptThis.GetInterface() : null); 84 | } 85 | 86 | /** Detach the debugger from the process/appdomain. */ 87 | public void Detach () 88 | { 89 | m_controller.Detach (); 90 | } 91 | 92 | /** Terminate the current process. */ 93 | public void Terminate (int exitCode) 94 | { 95 | m_controller.Terminate ((uint)exitCode); 96 | } 97 | 98 | /* Can the delta PEs be applied to the running process? */ 99 | /* 100 | public IEnumerable CanCommitChanges (uint number, EditAndContinueSnapshot[] snapshots) 101 | { 102 | ICorDebugErrorInfoEnum error = null; 103 | m_controller.CanCommitChanges (number, snapshots, out error); 104 | if (error == null) 105 | return null; 106 | return new ErrorInfoEnumerator (error); 107 | } 108 | */ 109 | 110 | /* Apply the delta PEs to the running process. */ 111 | /* 112 | public IEnumerable CommitChanges (uint number, EditAndContinueSnapshot[] snapshots) 113 | { 114 | ICorDebugErrorInfoEnum error = null; 115 | m_controller.CommitChanges (number, snapshots, out error); 116 | if (error == null) 117 | return null; 118 | return new ErrorInfoEnumerator (error); 119 | } 120 | */ 121 | [CLSCompliant(false)] 122 | protected ICorDebugController GetController () 123 | { 124 | return m_controller; 125 | } 126 | 127 | private ICorDebugController m_controller; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /corapi/CorAPIAssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | 2 | // Attributes for the CorApiAssembly 3 | using System; 4 | using System.Runtime.InteropServices; 5 | using System.Runtime.InteropServices.ComTypes; 6 | using System.Security.Permissions; 7 | 8 | 9 | 10 | // Expose non-CLS-compliant types, so we can't be CLS-compliant 11 | [assembly:CLSCompliant(true)] 12 | [assembly:System.Runtime.InteropServices.ComVisible(false)] 13 | [assembly:SecurityPermission(SecurityAction.RequestMinimum, Unrestricted=true)] -------------------------------------------------------------------------------- /corapi/CorPublish.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | using System.Text; 9 | 10 | using Microsoft.Samples.Debugging.CorPublish.NativeApi; 11 | 12 | namespace Microsoft.Samples.Debugging.CorPublish 13 | { 14 | public sealed class CorPublish 15 | { 16 | public CorPublish() 17 | { 18 | m_publish = new CorpubPublishClass(); 19 | } 20 | 21 | public IEnumerable EnumProcesses() 22 | { 23 | ICorPublishProcessEnum pIEnum; 24 | m_publish.EnumProcesses(COR_PUB_ENUMPROCESS.COR_PUB_MANAGEDONLY,out pIEnum); 25 | return (pIEnum==null)?null:new CorPublishProcessEnumerator(pIEnum); 26 | } 27 | 28 | public CorPublishProcess GetProcess(int pid) 29 | { 30 | ICorPublishProcess proc; 31 | m_publish.GetProcess((uint)pid,out proc); 32 | return (proc==null)?null:new CorPublishProcess(proc); 33 | } 34 | 35 | 36 | private ICorPublish m_publish; 37 | } 38 | 39 | public sealed class CorPublishProcess 40 | { 41 | internal CorPublishProcess(ICorPublishProcess iprocess) 42 | { 43 | m_process = iprocess; 44 | } 45 | 46 | public IEnumerable EnumAppDomains() 47 | { 48 | ICorPublishAppDomainEnum pIEnum; 49 | m_process.EnumAppDomains(out pIEnum); 50 | return (pIEnum==null)?null:new CorPublishAppDomainEnumerator(pIEnum); 51 | } 52 | 53 | public string DisplayName 54 | { 55 | get 56 | { 57 | uint size; 58 | m_process.GetDisplayName(0, out size, null); 59 | StringBuilder szName = new StringBuilder((int)size); 60 | m_process.GetDisplayName((uint)szName.Capacity, out size, szName); 61 | return szName.ToString(); 62 | } 63 | } 64 | 65 | public int ProcessId 66 | { 67 | get 68 | { 69 | uint pid; 70 | m_process.GetProcessID(out pid); 71 | return (int)pid; 72 | } 73 | } 74 | 75 | public bool IsManaged 76 | { 77 | get 78 | { 79 | int bManaged; 80 | m_process.IsManaged(out bManaged); 81 | return (bManaged!=0); 82 | } 83 | } 84 | 85 | private ICorPublishProcess m_process; 86 | } 87 | 88 | internal class CorPublishProcessEnumerator : 89 | IEnumerable, IEnumerator, ICloneable 90 | { 91 | internal CorPublishProcessEnumerator(ICorPublishProcessEnum e) 92 | { 93 | m_enum = e; 94 | } 95 | 96 | // 97 | // ICloneable interface 98 | // 99 | public Object Clone () 100 | { 101 | ICorPublishEnum clone = null; 102 | m_enum.Clone (out clone); 103 | return new CorPublishProcessEnumerator((ICorPublishProcessEnum)clone); 104 | } 105 | 106 | // 107 | // IEnumerable interface 108 | // 109 | public IEnumerator GetEnumerator () 110 | { 111 | return this; 112 | } 113 | 114 | // 115 | // IEnumerator interface 116 | // 117 | public bool MoveNext () 118 | { 119 | ICorPublishProcess a; 120 | uint c = 0; 121 | int r = m_enum.Next ((uint) 1,out a, out c); 122 | if (r==0 && c==1) // S_OK && we got 1 new element 123 | m_proc = new CorPublishProcess(a); 124 | else 125 | m_proc = null; 126 | return m_proc != null; 127 | } 128 | 129 | public void Reset () 130 | { 131 | m_enum.Reset(); 132 | m_proc = null; 133 | } 134 | 135 | public Object Current 136 | { 137 | get 138 | { 139 | return m_proc; 140 | } 141 | } 142 | 143 | private ICorPublishProcessEnum m_enum; 144 | private CorPublishProcess m_proc; 145 | } 146 | 147 | public sealed class CorPublishAppDomain 148 | { 149 | internal CorPublishAppDomain(ICorPublishAppDomain appDomain) 150 | { 151 | m_appDomain = appDomain; 152 | } 153 | 154 | public int Id 155 | { 156 | get 157 | { 158 | uint id; 159 | m_appDomain.GetID(out id); 160 | return (int)id; 161 | } 162 | } 163 | 164 | public string Name 165 | { 166 | get 167 | { 168 | uint size; 169 | m_appDomain.GetName(0,out size, null); 170 | StringBuilder szName = new StringBuilder((int)size); 171 | m_appDomain.GetName((uint)szName.Capacity,out size, szName); 172 | return szName.ToString(); 173 | } 174 | } 175 | 176 | private ICorPublishAppDomain m_appDomain; 177 | } 178 | 179 | 180 | internal class CorPublishAppDomainEnumerator : 181 | IEnumerable, IEnumerator, ICloneable 182 | { 183 | internal CorPublishAppDomainEnumerator(ICorPublishAppDomainEnum appDomainEnumerator) 184 | { 185 | m_enum = appDomainEnumerator; 186 | } 187 | 188 | // 189 | // ICloneable interface 190 | // 191 | public Object Clone () 192 | { 193 | ICorPublishEnum clone = null; 194 | m_enum.Clone (out clone); 195 | return new CorPublishAppDomainEnumerator((ICorPublishAppDomainEnum)clone); 196 | } 197 | 198 | // 199 | // IEnumerable interface 200 | // 201 | public IEnumerator GetEnumerator () 202 | { 203 | return this; 204 | } 205 | 206 | // 207 | // IEnumerator interface 208 | // 209 | public bool MoveNext () 210 | { 211 | ICorPublishAppDomain a; 212 | uint c = 0; 213 | int r = m_enum.Next ((uint) 1, out a, out c); 214 | if (r==0 && c==1) // S_OK && we got 1 new element 215 | m_appDomain = new CorPublishAppDomain(a); 216 | else 217 | m_appDomain = null; 218 | return m_appDomain != null; 219 | } 220 | 221 | public void Reset () 222 | { 223 | m_enum.Reset(); 224 | m_appDomain = null; 225 | } 226 | 227 | public Object Current 228 | { 229 | get 230 | { 231 | return m_appDomain; 232 | } 233 | } 234 | 235 | private ICorPublishAppDomainEnum m_enum; 236 | private CorPublishAppDomain m_appDomain; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /corapi/ErrorInfoEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** 14 | * Exposes an enumerator for ErrorInfo objects. 15 | * 16 | * This is horribly broken at this point, as ErrorInfo isn't implemented yet. 17 | */ 18 | internal class CorErrorInfoEnumerator : IEnumerable, IEnumerator, ICloneable 19 | { 20 | private ICorDebugErrorInfoEnum m_enum; 21 | 22 | private Object m_einfo; 23 | 24 | internal CorErrorInfoEnumerator (ICorDebugErrorInfoEnum erroInfoEnumerator) 25 | { 26 | m_enum = erroInfoEnumerator; 27 | } 28 | 29 | // 30 | // ICloneable interface 31 | // 32 | public Object Clone () 33 | { 34 | ICorDebugEnum clone = null; 35 | m_enum.Clone (out clone); 36 | return new CorErrorInfoEnumerator ((ICorDebugErrorInfoEnum)clone); 37 | } 38 | 39 | // 40 | // IEnumerable interface 41 | // 42 | public IEnumerator GetEnumerator () 43 | { 44 | return this; 45 | } 46 | 47 | // 48 | // IEnumerator interface 49 | // 50 | public bool MoveNext () 51 | { 52 | return false; 53 | } 54 | 55 | public void Reset () 56 | { 57 | m_enum.Reset (); 58 | m_einfo = null; 59 | } 60 | 61 | public Object Current 62 | { 63 | get 64 | { 65 | return m_einfo; 66 | } 67 | } 68 | } /* class ErrorInfoEnumerator */ 69 | } /* namespace */ 70 | -------------------------------------------------------------------------------- /corapi/FunctionBreakpoint.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | namespace Microsoft.Samples.Debugging.CorDebug 11 | { 12 | public sealed class CorFunctionBreakpoint : CorBreakpoint 13 | { 14 | private ICorDebugFunctionBreakpoint m_breakpoint; 15 | 16 | internal CorFunctionBreakpoint (ICorDebugFunctionBreakpoint breakpoint) : base(breakpoint) 17 | { 18 | m_breakpoint = breakpoint; 19 | } 20 | 21 | public CorFunction Function 22 | { 23 | get 24 | { 25 | ICorDebugFunction f = null; 26 | m_breakpoint.GetFunction (out f); 27 | return new CorFunction (f); 28 | } 29 | } 30 | 31 | public int Offset 32 | { 33 | get 34 | { 35 | uint off = 0; 36 | m_breakpoint.GetOffset (out off); 37 | return (int) off; 38 | } 39 | } 40 | } /* class FunctionBreakpoint */ 41 | } /* namespace */ 42 | -------------------------------------------------------------------------------- /corapi/IDiaReadExeAtRVACallback.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace Microsoft.Samples.Debugging.CorSymbolStore 5 | { 6 | [ 7 | ComImport, 8 | Guid("8E3F80CA-7517-432a-BA07-285134AAEA8E"), 9 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 10 | ComVisible(true), 11 | CLSCompliant(false) 12 | ] 13 | public interface IDiaReadExeAtRVACallback 14 | { 15 | /// 16 | /// Reads module data at the specified relative virtual address 17 | /// 18 | /// The RVA to begin reading from 19 | /// The number of bytes of data to read 20 | /// The number of bytes of data actually read 21 | /// A buffer of size at least cbData which is filled with the read data 22 | /// DIA would prefer to have the following pseudo implementation of this interface: 23 | /// 1) If not enough of the file is available to validate image RVAs, throw any exception and return 0 bytes read 24 | /// 2) else if relativeVirtualAddress is not valid, throw any exception and return 0 bytes read 25 | /// 3) else if relativeVirtualAddress is valid, but not readable, throw any exception and return 0 bytes read 26 | /// 4) else if cbData is 0, return with 0 bytes read 27 | /// 5) else let X be the count of contiguous bytes in the virtual address space starting at relativeVirtualAddress 28 | /// that are at valid, readable addresses. 29 | /// a) If X >= cbData return S_OK and cbData bytes read. 30 | /// b) else if relativeVirtualAddress + X + 1 is an invalid RVA, optionally throw any exception and return X bytes read 31 | /// c) else if relativeVirtualAddress + X + 1 is not readable, throw any exception and return X bytes read 32 | /// 33 | void ReadExecutableAtRVA( 34 | uint relativeVirtualAddress, 35 | uint cbData, 36 | ref uint pcbData, 37 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] data); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /corapi/ISymBinder2.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | using System; 14 | using System.Text; 15 | using System.Runtime.InteropServices; 16 | using System.Runtime.InteropServices.ComTypes; 17 | 18 | [ 19 | ComVisible(false) 20 | ] 21 | public interface ISymbolBinder2 22 | { 23 | ISymbolReader GetReaderForFile(Object importer, String filename, String searchPath); 24 | 25 | ISymbolReader GetReaderForFile(Object importer, String fileName, 26 | String searchPath, SymSearchPolicies searchPolicy); 27 | 28 | ISymbolReader GetReaderForFile(Object importer, String fileName, 29 | String searchPath, SymSearchPolicies searchPolicy, 30 | object callback); 31 | 32 | ISymbolReader GetReaderFromStream(Object importer, IStream stream); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /corapi/ISymConstant.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | 18 | // Interface does not need to be marked with the serializable attribute 19 | // Interface is returned by ISymbolScope2.GetConstants() so must be public 20 | [ 21 | ComVisible(false) 22 | ] 23 | public interface ISymbolConstant 24 | { 25 | String GetName(); 26 | 27 | Object GetValue(); 28 | 29 | byte[] GetSignature(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /corapi/ISymENCUpdate.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | using System.Runtime.InteropServices.ComTypes; 18 | 19 | /// 20 | [StructLayout(LayoutKind.Sequential)] 21 | public struct SymbolLineDelta 22 | { 23 | SymbolToken mdMethod; 24 | int delta; 25 | }; 26 | 27 | /// 28 | [ 29 | ComVisible(false) 30 | ] 31 | public interface ISymbolEncUpdate 32 | { 33 | /// 34 | 35 | void UpdateSymbolStore(IStream stream, SymbolLineDelta[] symbolLineDeltas); 36 | /// 37 | 38 | int GetLocalVariableCount(SymbolToken mdMethodToken); 39 | /// 40 | 41 | ISymbolVariable[] GetLocalVariables(SymbolToken mdMethodToken); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /corapi/ISymEncMethod.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | using System.Runtime.InteropServices; 14 | using System; 15 | 16 | // This interface isn't directly returned or used by any of the classes, 17 | // but the implementation of the ISymbolMethod also implements ISymEncMethod 18 | // so you could explicitly cast it to that. 19 | [ 20 | ComVisible(false) 21 | ] 22 | public interface ISymbolEnCMethod: ISymbolMethod 23 | { 24 | String GetFileNameFromOffset(int dwOffset); 25 | 26 | int GetLineFromOffset(int dwOffset, 27 | out int column, 28 | out int endLine, 29 | out int endColumn, 30 | out int startOffset); 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /corapi/ISymReader2.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Runtime.InteropServices; 16 | using System.Runtime.InteropServices.ComTypes; 17 | 18 | [ 19 | ComVisible(false) 20 | ] 21 | public interface ISymbolReader2 : ISymbolReader, IDisposable 22 | { 23 | // Initialize the symbol reader with the metadata importer interface 24 | // that this reader will be associated with, along with the filename 25 | // of the module. This can only be called once, and must be called 26 | // before any other reader methods are called. 27 | // 28 | // Note: you need only specify one of the filename or the stream, 29 | // not both. The searchPath parameter is optional. 30 | // 31 | void Initialize(Object importer, String filename, 32 | String searchPath, IStream stream); 33 | 34 | // Update the existing symbol reader with a delta symbol store. This 35 | // is used in EnC scenarios as a way to update the symbol store to 36 | // match deltas to the original PE file. 37 | // 38 | // Only one of the filename or stream parameters need be specified. 39 | // If a filename is specified, the symbol store will be updated with 40 | // the symbols in that file. If a IStream is specified, the store will 41 | // be updated with the data from the IStream. 42 | // 43 | void UpdateSymbolStore(String fileName, IStream stream); 44 | 45 | // Update the existing symbol reader with a delta symbol 46 | // store. This is much like UpdateSymbolStore, but the given detla 47 | // acts as a complete replacement rather than an update. 48 | // 49 | // Only one of the filename or stream parameters need be specified. 50 | // If a filename is specified, the symbol store will be updated with 51 | // the symbols in that file. If a IStream is specified, the store will 52 | // be updated with the data from the IStream. 53 | // 54 | void ReplaceSymbolStore(String fileName, IStream stream); 55 | 56 | // Provides the on disk filename of the symbol store. 57 | // 58 | String GetSymbolStoreFileName(); 59 | 60 | // Given a position in a document, return the ISymUnmanagedMethods that 61 | // contains that position. 62 | // 63 | ISymbolMethod[] GetMethodsFromDocumentPosition( 64 | ISymbolDocument document, int line, int column); 65 | 66 | // The document version starts at 1 and is incremented each time 67 | // the document is updated via UpdateSymbols. 68 | // bCurrent is true is this is the latest version of the document. 69 | // 70 | int GetDocumentVersion(ISymbolDocument document, 71 | out Boolean isCurrent); 72 | 73 | // The method version starts at 1 and is incremented each time 74 | // the method is recompiled. (This can happen changes to the method.) 75 | // 76 | int GetMethodVersion(ISymbolMethod method); 77 | } 78 | 79 | // This interface is implemented by the internal SymReader 80 | // so it could be converted to this and have it's methods called. 81 | [ 82 | ComVisible(false) 83 | ] 84 | public interface ISymbolReaderSymbolSearchInfo 85 | { 86 | int GetSymbolSearchInfoCount(); 87 | 88 | ISymbolSearchInfo[] GetSymbolSearchInfo(); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /corapi/ISymScope2.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | 18 | 19 | // This interface isn't directly returned, but SymbolScope which implements ISymbolScope 20 | // also implements ISymbolScope2 and thus you may want to explicitly cast it to use these methods. 21 | [ 22 | ComVisible(false) 23 | ] 24 | public interface ISymbolScope2 : ISymbolScope 25 | { 26 | 27 | int LocalCount{ get; } 28 | 29 | int ConstantCount{ get; } 30 | 31 | ISymbolConstant[] GetConstants(); 32 | 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /corapi/ISymSearchInfo.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | 18 | // This interface is returned by ISymbolReaderSymbolSearchInfo 19 | // and thus must be public 20 | [ 21 | ComVisible(false) 22 | ] 23 | public interface ISymbolSearchInfo 24 | { 25 | int SearchPathLength{ get; } 26 | 27 | String SearchPath{ get; } 28 | 29 | int HResult{ get; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /corapi/ISymWriter2.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | 14 | using System; 15 | using System.Text; 16 | using System.Reflection; 17 | using System.Runtime.InteropServices; 18 | using System.Runtime.InteropServices.ComTypes; 19 | 20 | [StructLayout(LayoutKind.Sequential)] 21 | public struct ImageDebugDirectory { 22 | int Characteristics; 23 | int TimeDateStamp; 24 | short MajorVersion; 25 | short MinorVersion; 26 | int Type; 27 | int SizeOfData; 28 | int AddressOfRawData; 29 | int PointerToRawData; 30 | 31 | public override string ToString() 32 | { 33 | return String.Format( @"Characteristics: {0} 34 | TimeDateStamp: {1} 35 | MajorVersion: {2} 36 | MinorVersion: {3} 37 | Type: {4} 38 | SizeOfData: {5} 39 | AddressOfRawData: {6} 40 | PointerToRawData: {7} 41 | ", 42 | Characteristics, 43 | TimeDateStamp, 44 | MajorVersion, 45 | MinorVersion, 46 | Type, 47 | SizeOfData, 48 | AddressOfRawData, 49 | PointerToRawData); 50 | } 51 | }; 52 | 53 | [ 54 | ComVisible(false) 55 | ] 56 | public interface ISymbolWriter2 : ISymbolWriter, IDisposable 57 | { 58 | void Initialize(Object emitter, 59 | String fileName, 60 | Boolean fullBuild); 61 | 62 | void Initialize(Object emitter, 63 | String fileName, 64 | IStream stream, 65 | Boolean fullBuild); 66 | 67 | void Initialize(Object emitter, 68 | String temporaryFileName, 69 | IStream stream, 70 | Boolean fullBuild, 71 | String finalFileName); 72 | 73 | byte[] GetDebugInfo(out ImageDebugDirectory imageDebugDirectory); 74 | 75 | void RemapToken(SymbolToken oldToken, 76 | SymbolToken newToken); 77 | 78 | void DefineConstant(String name, 79 | Object value, 80 | byte[] signature); 81 | 82 | void Abort(); 83 | 84 | void DefineLocalVariable(String name, 85 | int attributes, 86 | SymbolToken sigToken, 87 | int addressKind, 88 | int addr1, 89 | int addr2, 90 | int addr3, 91 | int startOffset, 92 | int endOffset); 93 | 94 | void DefineGlobalVariable(String name, 95 | int attributes, 96 | SymbolToken sigToken, 97 | int addressKind, 98 | int addr1, 99 | int addr2, 100 | int addr3); 101 | 102 | 103 | void DefineConstant(String name, 104 | Object value, 105 | SymbolToken sigToken); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /corapi/IldbSymbols.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Runtime.InteropServices; 5 | 6 | namespace Microsoft.Samples.Debugging.CorSymbolStore 7 | { 8 | /// 9 | /// A specialization of SymbolBinder to using ildbsymbols.dll (ILDB symbol format) 10 | /// Note that ildbsymbols.dll must be available in the current directory or on the path. 11 | /// 12 | internal class IldbSymbolBinder : SymbolBinder 13 | { 14 | public IldbSymbolBinder() : base(GetIldbBinderObject()) 15 | { 16 | } 17 | 18 | /// 19 | /// Get the CorSymBinder object from ildbsymbols.dll 20 | /// 21 | /// 22 | private static ISymUnmanagedBinder GetIldbBinderObject() 23 | { 24 | return (ISymUnmanagedBinder)IldbNativeMethods.IldbCoCreateInstance(CLSID_CorSymBinder, typeof(ISymUnmanagedBinder).GUID); 25 | } 26 | 27 | } 28 | 29 | /// 30 | /// A specialization of SymbolWriter to using ildbsymbols.dll (ILDB symbol format) 31 | /// 32 | internal class IldbSymbolWriter : SymbolWriter 33 | { 34 | public IldbSymbolWriter() 35 | : base(GetIldbWriterObject()) 36 | { 37 | } 38 | 39 | /// 40 | /// Get the CorSymWriter object from ildbsymbols.dll 41 | /// 42 | /// 43 | private static ISymUnmanagedWriter GetIldbWriterObject() 44 | { 45 | return (ISymUnmanagedWriter)IldbNativeMethods.IldbCoCreateInstance(CLSID_CorSymWriter, typeof(ISymUnmanagedWriter).GUID); 46 | } 47 | 48 | } 49 | 50 | internal class IldbNativeMethods 51 | { 52 | [ComImport] 53 | [Guid("00000001-0000-0000-C000-000000000046")] 54 | [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 55 | private interface IClassFactory 56 | { 57 | [return:MarshalAs(UnmanagedType.Interface)] 58 | object CreateInstance( 59 | [MarshalAs(UnmanagedType.IUnknown)] object punkOuter, 60 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid); 61 | 62 | void LockServer(bool fLock); 63 | } 64 | 65 | public static object IldbCoCreateInstance(System.Guid clsid, System.Guid iid) 66 | { 67 | IClassFactory fac = (IClassFactory)DllGetClassObject(clsid, typeof(IClassFactory).GUID); 68 | return fac.CreateInstance(null, iid); 69 | } 70 | 71 | /// 72 | /// PInvoke signature for the GetClassObject function 73 | /// 74 | /// 75 | /// 76 | /// 77 | [DllImport("ildbsymbols.dll", PreserveSig = false)] 78 | [return: MarshalAs(UnmanagedType.Interface)] 79 | public static extern object DllGetClassObject( 80 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid clsid, 81 | [In, MarshalAs(UnmanagedType.LPStruct)] Guid iid); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /corapi/MetadataLocator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.IO; 8 | using System.Diagnostics; 9 | using System.Runtime.InteropServices; 10 | 11 | // Implements ICorDebugMetadataLocator interface 12 | namespace Microsoft.Samples.Debugging.MetaDataLocator 13 | { 14 | [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("7cef8ba9-2ef7-42bf-973f-4171474f87d9")] 15 | public interface ICorDebugMetaDataLocator //REM straighten this up later : IUnknown 16 | { 17 | void GetMetaData( 18 | [In, MarshalAs(UnmanagedType.LPWStr)] string imagePath, 19 | [In] uint dwImageTimeStamp, 20 | [In] uint dwImageSize, 21 | [In] uint cchPathBuffer, 22 | [Out] out uint pcchPathBuffer, 23 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=3)] char[] wszPathBuffer); 24 | } 25 | 26 | public sealed class CorDebugMetaDataLocator : ICorDebugMetaDataLocator 27 | { 28 | private string m_clrPath; 29 | private Guid IID_ICorDebugMetaDataLocator = new Guid("7cef8ba9-2ef7-42bf-973f-4171474f87d9"); 30 | private const uint m_sizeOfWchar = 2; 31 | 32 | struct HResultConsts 33 | { 34 | public const uint S_Ok = 0x00000000; 35 | public const uint E_Not_Sufficient_Buffer = 0x8007007A; 36 | public const uint E_Fail = 0x80004005; 37 | } 38 | 39 | public void GetMetaData(string imagePath, 40 | uint dwImageTimeStamp, 41 | uint dwImageSize, 42 | uint cchPathBuffer, 43 | out uint pcchPathBuffer, 44 | char[] wszPathBuffer) 45 | { 46 | Trace.WriteLineIf(Verbose, "ICDMDL::GetMetaData called for " + imagePath + " with timestamp=" + 47 | dwImageTimeStamp + " and size=" + dwImageSize); 48 | 49 | string filePath = SearchPath + "\\" + imagePath.Substring(imagePath.LastIndexOf('\\')); 50 | 51 | bool fFileExist = false; 52 | 53 | // If we have a complete path to an existing file, just return it. 54 | // Otherwise, check the SearchPath for the file. 55 | if (File.Exists(imagePath)) 56 | { 57 | filePath = imagePath; 58 | fFileExist = true; 59 | } 60 | 61 | if (!fFileExist && File.Exists(filePath)) 62 | { 63 | fFileExist = true; 64 | } 65 | 66 | if (!fFileExist) 67 | { 68 | Trace.WriteLineIf(Verbose, "ICDMDL::GetMetaData could not find file."); 69 | throw new COMException("File not found", unchecked((int)0x80070002)); 70 | } 71 | 72 | // Return number of chars, include the terminating NULL. 73 | pcchPathBuffer = (uint)filePath.Length + 1; 74 | 75 | if (pcchPathBuffer <= cchPathBuffer) 76 | { 77 | filePath.CopyTo(0, wszPathBuffer, 0, filePath.Length); 78 | wszPathBuffer[filePath.Length] = '\0'; 79 | } 80 | else 81 | { 82 | Trace.WriteLineIf(Verbose, "ICDMDL::GetMetaData found file, but string buffer is too small to use. " + 83 | "Length given=" + pcchPathBuffer + " Length needed=" + cchPathBuffer + " Filename=\"" + filePath + "\""); 84 | throw new COMException("Buffer too small", unchecked((int)0x8007007A)); 85 | } 86 | 87 | Trace.WriteLineIf(Verbose, "ICDMDL::GetMetaData found " + wszPathBuffer + "\""); 88 | } 89 | 90 | public CorDebugMetaDataLocator()//MdbgEngine.MDbgOptions options) 91 | { 92 | // Default to searching in current directory. 93 | // Could certainly have multiple search paths, use a symbol server, etc. 94 | SearchPath = ".\\"; 95 | // m_options = options; 96 | } 97 | 98 | public CorDebugMetaDataLocator(string searchPath)//, MdbgEngine.MDbgOptions options) 99 | { 100 | SearchPath = searchPath; 101 | //m_options = options; 102 | } 103 | 104 | public string SearchPath 105 | { 106 | get 107 | { 108 | return m_clrPath; 109 | } 110 | set 111 | { 112 | m_clrPath = value; 113 | } 114 | } 115 | 116 | // private readonly MdbgEngine.MDbgOptions m_options; 117 | public bool Verbose 118 | { 119 | get 120 | { 121 | return false; 122 | } 123 | // Don't allow changing the engine's options from this class! 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /corapi/MetadataParameterInfo.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Reflection; 8 | using System.Collections; 9 | using System.Text; 10 | using System.Runtime.InteropServices; 11 | using System.Runtime.Serialization; 12 | using System.Globalization; 13 | using System.Diagnostics; 14 | 15 | using Microsoft.Samples.Debugging.CorDebug; 16 | using Microsoft.Samples.Debugging.CorMetadata.NativeApi; 17 | 18 | namespace Microsoft.Samples.Debugging.CorMetadata 19 | { 20 | public sealed class MetadataParameterInfo : ParameterInfo 21 | { 22 | internal MetadataParameterInfo(IMetadataImport importer,int paramToken, 23 | MemberInfo memberImpl,Type typeImpl) 24 | { 25 | int parentToken; 26 | uint pulSequence,pdwAttr,pdwCPlusTypeFlag,pcchValue,size; 27 | 28 | IntPtr ppValue; 29 | importer.GetParamProps(paramToken, 30 | out parentToken, 31 | out pulSequence, 32 | null, 33 | 0, 34 | out size, 35 | out pdwAttr, 36 | out pdwCPlusTypeFlag, 37 | out ppValue, 38 | out pcchValue 39 | ); 40 | StringBuilder szName = new StringBuilder((int)size); 41 | importer.GetParamProps(paramToken, 42 | out parentToken, 43 | out pulSequence, 44 | szName, 45 | (uint)szName.Capacity, 46 | out size, 47 | out pdwAttr, 48 | out pdwCPlusTypeFlag, 49 | out ppValue, 50 | out pcchValue 51 | ); 52 | NameImpl = szName.ToString(); 53 | ClassImpl = typeImpl; 54 | PositionImpl = (int)pulSequence; 55 | AttrsImpl = (ParameterAttributes)pdwAttr; 56 | 57 | MemberImpl=memberImpl; 58 | } 59 | 60 | private MetadataParameterInfo(SerializationInfo info, StreamingContext context) 61 | { 62 | 63 | } 64 | 65 | public override String Name 66 | { 67 | get 68 | { 69 | return NameImpl; 70 | } 71 | } 72 | 73 | public override int Position 74 | { 75 | get 76 | { 77 | return PositionImpl; 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /corapi/MetadataType.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/corapi/MetadataType.cs -------------------------------------------------------------------------------- /corapi/ModuleBreakpoint.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | namespace Microsoft.Samples.Debugging.CorDebug 11 | { 12 | public sealed class CorModuleBreakpoint : CorBreakpoint 13 | { 14 | private ICorDebugModuleBreakpoint m_br; 15 | 16 | internal CorModuleBreakpoint (ICorDebugModuleBreakpoint managedModule): base(managedModule) 17 | { 18 | m_br = managedModule; 19 | } 20 | 21 | public CorModule Module 22 | { 23 | get 24 | { 25 | ICorDebugModule m = null; 26 | m_br.GetModule (out m); 27 | return new CorModule (m); 28 | } 29 | } 30 | } /* class ModuleBreakpoint */ 31 | } /* namespace */ 32 | -------------------------------------------------------------------------------- /corapi/ModuleEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Modules. */ 14 | internal class CorModuleEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugModuleEnum m_enum; 17 | private CorModule m_mod; 18 | 19 | internal CorModuleEnumerator (ICorDebugModuleEnum moduleEnumerator) 20 | { 21 | m_enum = moduleEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorModuleEnumerator ((ICorDebugModuleEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugModule[] a = new ICorDebugModule[1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | m_mod = new CorModule (a[0]); 52 | else 53 | m_mod = null; 54 | return m_mod != null; 55 | } 56 | 57 | public void Reset () 58 | { 59 | m_enum.Reset (); 60 | m_mod = null; 61 | } 62 | 63 | public Object Current 64 | { 65 | get 66 | { 67 | return m_mod; 68 | } 69 | } 70 | } /* class ModuleEnumerator */ 71 | } /* namespace */ 72 | -------------------------------------------------------------------------------- /corapi/ModuleRVAReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Diagnostics; 5 | using Microsoft.Samples.Debugging.CorSymbolStore; 6 | 7 | namespace Microsoft.Samples.Debugging.CorDebug 8 | { 9 | /// 10 | /// This class tries to read a given module at certain RVAs by assuming 11 | /// that it is layed out in memory in the way LoadLibrary would place it. This 12 | /// means that a given RVA can be located in the process memory space merely 13 | /// by adding the module base address as an offset. In practice the CLR does 14 | /// use this mapping up through .Net FX 3.5 SP1 and for silverlight 2 for 15 | /// modules which it loaded from disk. WARNING: Nothing guarantees that the 16 | /// CLR must do this so this is unreliable going forward. 17 | /// 18 | [CLSCompliant(false)] 19 | public class ModuleRVAReader : IDiaReadExeAtRVACallback 20 | { 21 | CorModule m_module; 22 | 23 | public ModuleRVAReader(CorModule moduleToRead) 24 | { 25 | if(moduleToRead == null) 26 | throw new ArgumentNullException("moduleToRead"); 27 | m_module = moduleToRead; 28 | } 29 | 30 | #region IDiaReadExeAtRVACallback Members 31 | 32 | 33 | 34 | /// 35 | /// Reads module data at the specified relative virtual address 36 | /// 37 | /// The RVA to begin reading from 38 | /// The number of bytes of data to read 39 | /// The number of bytes of data actually read 40 | /// A buffer of size at least cbData which is filled with the read data 41 | /// See the interface for the spec on this method. Note that this impl isn't the best 42 | /// as it doesn't validate reading at relativeVirtualAddress when cbData = 0 and even when it 43 | /// does validate RVAs, it only does cursory bounds checking. There are dead spots within the 44 | /// image that are not checked for here (though hopefully reading would fail because the pages 45 | /// won't be mapped) 46 | void IDiaReadExeAtRVACallback.ReadExecutableAtRVA(uint relativeVirtualAddress, uint cbData, 47 | ref uint pcbData, byte[] data) 48 | { 49 | pcbData = 0; 50 | 51 | // validate RVA 52 | if(relativeVirtualAddress > m_module.Size) 53 | throw new ArgumentOutOfRangeException("relativeVirtualAddress"); 54 | // validate data 55 | if(data == null) 56 | throw new ArgumentNullException("data"); 57 | if(data.Length < cbData) 58 | throw new ArgumentException("data"); 59 | 60 | // truncate read if it would otherwise extend into invalid RVA range 61 | uint bytesToRead = cbData; 62 | checked 63 | { 64 | if(cbData + relativeVirtualAddress > m_module.Size) 65 | { 66 | // we know bytesToRead is >= 0 because of the first check above 67 | bytesToRead = (uint)m_module.Size - relativeVirtualAddress; 68 | } 69 | } 70 | 71 | // early bail out if not reading any bytes 72 | if(bytesToRead == 0) 73 | { 74 | // if we read nothing because of clipping the range then throw otherwise return normally 75 | if(bytesToRead != cbData) 76 | throw new ArgumentOutOfRangeException("cbData"); 77 | else 78 | return; 79 | } 80 | 81 | // read the data 82 | // although we are allowed to do a partial read I think it is safer not to. If this winds up 83 | // being some sort of perf issue we can revist this, but I doubt it is a problem 84 | uint bytesRead = 0; 85 | long bytesLastRead = 0; 86 | try 87 | { 88 | do 89 | { 90 | Debug.Assert(bytesRead < bytesToRead); 91 | uint bytesLeft = bytesToRead - bytesRead; 92 | byte[] buffer = new byte[bytesLeft]; 93 | bytesLastRead = m_module.Process.ReadMemory(relativeVirtualAddress + m_module.BaseAddress, buffer); 94 | Array.Copy(buffer, 0, data, bytesRead, bytesLastRead); 95 | bytesRead += (uint)bytesLastRead; 96 | } while( bytesRead < bytesToRead && bytesLastRead != 0); 97 | } 98 | finally 99 | { 100 | pcbData = bytesRead; 101 | } 102 | 103 | // if we did not read everything because of clipping the range then throw 104 | if(pcbData != cbData) 105 | throw new ArgumentOutOfRangeException("cbData"); 106 | } 107 | 108 | #endregion 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /corapi/ObjectEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** 14 | * Exposes an enumerator for Objects. 15 | * 16 | * Apparently the "Object"'s this enumerator returns is the address of 17 | * each object, not a description of the object itself. 18 | * 19 | * At least, the ``Next'' method in the IDL returns a uint64, so there 20 | * isn't much else it could be returning... 21 | */ 22 | internal class CorObjectEnumerator : IEnumerable, IEnumerator, ICloneable 23 | { 24 | private ICorDebugObjectEnum m_enum; 25 | 26 | private ulong m_obj; 27 | 28 | internal CorObjectEnumerator (ICorDebugObjectEnum objectEnumerator) 29 | { 30 | m_enum = objectEnumerator; 31 | } 32 | 33 | // 34 | // ICloneable interface 35 | // 36 | public Object Clone () 37 | { 38 | ICorDebugEnum clone = null; 39 | m_enum.Clone (out clone); 40 | return new CorObjectEnumerator ((ICorDebugObjectEnum)clone); 41 | } 42 | 43 | // 44 | // IEnumerable interface 45 | // 46 | public IEnumerator GetEnumerator () 47 | { 48 | return this; 49 | } 50 | 51 | // 52 | // IEnumerator interface 53 | // 54 | public bool MoveNext () 55 | { 56 | ulong[] a = new ulong[1]; 57 | uint c = 0; 58 | int r = m_enum.Next ((uint)a.Length, a, out c); 59 | if (r==0 && c==1) // S_OK && we got 1 new element 60 | { 61 | m_obj = a[0]; 62 | return true; 63 | } 64 | return false; 65 | } 66 | 67 | public void Reset () 68 | { 69 | m_enum.Reset (); 70 | m_obj = 0; 71 | } 72 | 73 | public Object Current 74 | { 75 | get 76 | { 77 | return m_obj; 78 | } 79 | } 80 | } /* class CorObjectEnumerator */ 81 | } /* namespace */ 82 | -------------------------------------------------------------------------------- /corapi/ProcessEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Processes. */ 14 | internal class CorProcessEnumerator : 15 | IEnumerable, IEnumerator, ICloneable 16 | { 17 | private ICorDebugProcessEnum m_enum; 18 | private CorProcess m_proc; 19 | 20 | internal CorProcessEnumerator (ICorDebugProcessEnum processEnumerator) 21 | { 22 | m_enum = processEnumerator; 23 | } 24 | 25 | // 26 | // ICloneable interface 27 | // 28 | public Object Clone () 29 | { 30 | ICorDebugEnum clone = null; 31 | m_enum.Clone (out clone); 32 | return new CorProcessEnumerator ((ICorDebugProcessEnum)clone); 33 | } 34 | 35 | // 36 | // IEnumerable interface 37 | // 38 | public IEnumerator GetEnumerator () 39 | { 40 | return this; 41 | } 42 | 43 | // 44 | // IEnumerator interface 45 | // 46 | public bool MoveNext () 47 | { 48 | ICorDebugProcess[] a = new ICorDebugProcess[1]; 49 | uint c = 0; 50 | int r = m_enum.Next ((uint) a.Length, a, out c); 51 | if (r==0 && c==1) // S_OK && we got 1 new element 52 | m_proc = CorProcess.GetCorProcess(a[0]); 53 | else 54 | m_proc = null; 55 | return m_proc != null; 56 | } 57 | 58 | public void Reset () 59 | { 60 | m_enum.Reset (); 61 | m_proc = null; 62 | } 63 | 64 | public Object Current 65 | { 66 | get 67 | { 68 | return m_proc; 69 | } 70 | } 71 | } /* class ProcessEnumerator */ 72 | } /* namespace */ 73 | -------------------------------------------------------------------------------- /corapi/ReadMe.txt: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | ReadMe.txt for corapi project. 8 | 9 | The corapi project represents a managed view of Debugging API. It covers all the functionality of native COM API, and makes its use simpler at the same time. 10 | For every COM object there is a managed class that managed code is using instead. 11 | Following are main differences between native and managed versions of the API: 12 | - Managed version is using properties instead of functions calls for certain methods. 13 | - Managed version has only one class declaring all methods as opposed to native version that has typically 2 interfaces to access functions. E.g. ICorDebugProcess and ICorDebugProcess2. 14 | - Managed version dispatches debugging events as managed events to individual CorProcess classes. Native version needs to register a global callback interfaces. 15 | 16 | These wrappers should not require any modifications unless you find a bug. 17 | -------------------------------------------------------------------------------- /corapi/RemoteTarget.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Text; 8 | using System.Runtime.InteropServices; 9 | 10 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 11 | 12 | namespace Microsoft.Samples.Debugging.CorDebug 13 | { 14 | public sealed class CorRemoteTarget : ICorDebugRemoteTarget 15 | { 16 | private string m_hostName; 17 | 18 | public CorRemoteTarget(string hostName) 19 | { 20 | m_hostName = hostName; 21 | } 22 | 23 | [CLSCompliant(false)] 24 | public void GetHostName(uint cchHostName, out uint pcchHostName, char[] szHostName) 25 | { 26 | if ((cchHostName == 0) != (szHostName == null)) 27 | { 28 | throw new ArgumentException(); 29 | } 30 | 31 | // This function is expected to be called by a native caller, which expects the number of 32 | // characters to include the null character. 33 | pcchHostName = (uint)m_hostName.Length + 1; 34 | 35 | if (cchHostName > 0) 36 | { 37 | if (cchHostName < pcchHostName) 38 | { 39 | // HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) 40 | throw new COMException("Buffer too small", unchecked((int)0x8007007A)); 41 | } 42 | m_hostName.CopyTo(0, szHostName, 0, m_hostName.Length); 43 | szHostName[m_hostName.Length] = '\0'; 44 | } 45 | } 46 | } /* class CorRemoteTarget */ 47 | } /* namespace */ 48 | -------------------------------------------------------------------------------- /corapi/Stepper.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | namespace Microsoft.Samples.Debugging.CorDebug 11 | { 12 | /** Represents a stepping operation performed by the debugger. */ 13 | public sealed class CorStepper : WrapperBase 14 | { 15 | internal CorStepper (ICorDebugStepper stepper) 16 | :base(stepper) 17 | { 18 | m_step = stepper; 19 | } 20 | 21 | [CLSCompliant(false)] 22 | public ICorDebugStepper Raw 23 | { 24 | get 25 | { 26 | return m_step; 27 | } 28 | } 29 | 30 | /** Is the stepper active and stepping? */ 31 | public bool IsActive () 32 | { 33 | int a = 9; 34 | m_step.IsActive (out a); 35 | return !(a==0); 36 | } 37 | 38 | /** cancel the last stepping command received. */ 39 | public void Deactivate () 40 | { 41 | m_step.Deactivate (); 42 | } 43 | 44 | /** which intercept code will be stepped into by the debugger? */ 45 | [CLSCompliant(false)] 46 | public void SetInterceptMask (CorDebugIntercept mask) 47 | { 48 | m_step.SetInterceptMask (mask); 49 | } 50 | 51 | /** Should the stepper stop in jitted code not mapped to IL? */ 52 | [CLSCompliant(false)] 53 | public void SetUnmappedStopMask (CorDebugUnmappedStop mask) 54 | { 55 | m_step.SetUnmappedStopMask (mask); 56 | } 57 | 58 | /** single step the tread. */ 59 | public void Step (bool into) 60 | { 61 | m_step.Step (into ? 1 : 0); 62 | } 63 | 64 | /** Step until code outside of the range is reached. */ 65 | [CLSCompliant(false)] 66 | public void StepRange (bool stepInto, COR_DEBUG_STEP_RANGE[] stepRanges) 67 | { 68 | m_step.StepRange (stepInto ? 1 : 0, stepRanges, (uint) stepRanges.Length); 69 | } 70 | 71 | /* 72 | * Completes after the current frame is returned from normally & the 73 | * previous frame is reactivated. 74 | */ 75 | public void StepOut () 76 | { 77 | m_step.StepOut (); 78 | } 79 | 80 | /** 81 | * Set whether the ranges passed to StepRange are relative to the 82 | * IL code or the native code for the method being stepped in. 83 | */ 84 | public void SetRangeIL (bool value) 85 | { 86 | m_step.SetRangeIL (value ? 1 : 0); 87 | } 88 | 89 | /// 90 | /// Enable Just-my-code stepping for this stepper. The default is 'false. 91 | /// 92 | /// true to make this a JMC-stepper, false to make it a traditional stepper. 93 | public void SetJmcStatus(bool isJustMyCode) 94 | { 95 | ICorDebugStepper2 stepper2 = m_step as ICorDebugStepper2; 96 | if (stepper2 != null) 97 | { 98 | stepper2.SetJMC(isJustMyCode ? 1 : 0); 99 | } 100 | } 101 | 102 | private ICorDebugStepper m_step; 103 | } /* class Stepper */ 104 | } /* namespace */ 105 | -------------------------------------------------------------------------------- /corapi/StepperEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Steppers. */ 14 | internal class CorStepperEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugStepperEnum m_enum; 17 | private CorStepper m_step; 18 | 19 | internal CorStepperEnumerator (ICorDebugStepperEnum stepEnumerator) 20 | { 21 | m_enum = stepEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorStepperEnumerator ((ICorDebugStepperEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugStepper[] a = new ICorDebugStepper[1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | m_step = new CorStepper (a[0]); 52 | else 53 | m_step = null; 54 | return m_step != null; 55 | } 56 | 57 | public void Reset () 58 | { 59 | m_enum.Reset (); 60 | m_step= null; 61 | } 62 | 63 | public Object Current 64 | { 65 | get 66 | { 67 | return m_step; 68 | } 69 | } 70 | } /* class StepperEnumerator */ 71 | } /* namespace */ 72 | -------------------------------------------------------------------------------- /corapi/SymConstant.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | 14 | // Interface does not need to be marked with the serializable attribute 15 | using System; 16 | using System.Text; 17 | using System.Runtime.InteropServices; 18 | using System.Runtime.InteropServices.ComTypes; 19 | 20 | [ 21 | ComImport, 22 | Guid("48B25ED8-5BAD-41bc-9CEE-CD62FABC74E9"), 23 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 24 | ComVisible(false) 25 | ] 26 | internal interface ISymUnmanagedConstant 27 | { 28 | void GetName(int cchName, 29 | out int pcchName, 30 | [MarshalAs(UnmanagedType.LPWStr)] StringBuilder name); 31 | 32 | void GetValue(out Object pValue); 33 | 34 | void GetSignature(int cSig, 35 | out int pcSig, 36 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] sig); 37 | } 38 | 39 | internal class SymConstant : ISymbolConstant 40 | { 41 | ISymUnmanagedConstant m_target; 42 | 43 | public SymConstant(ISymUnmanagedConstant target) 44 | { 45 | // We should not wrap null instances 46 | if (target == null) 47 | throw new ArgumentNullException("target"); 48 | 49 | m_target = target; 50 | } 51 | 52 | public String GetName() 53 | { 54 | int count; 55 | m_target.GetName(0, out count, null); 56 | StringBuilder name = new StringBuilder(count); 57 | m_target.GetName(count, out count, name); 58 | return name.ToString(); 59 | } 60 | 61 | public Object GetValue() 62 | { 63 | Object value = null; 64 | m_target.GetValue(out value); 65 | return value; 66 | } 67 | 68 | public byte[] GetSignature() 69 | { 70 | int count = 0; 71 | m_target.GetSignature(0, out count, null); 72 | byte[] sig = new byte[count]; 73 | m_target.GetSignature(count, out count, sig); 74 | return sig; 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /corapi/SymDocument.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | 18 | [ 19 | ComImport, 20 | Guid("40DE4037-7C81-3E1E-B022-AE1ABFF2CA08"), 21 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 22 | ComVisible(false) 23 | ] 24 | internal interface ISymUnmanagedDocument 25 | { 26 | void GetURL(int cchUrl, 27 | out int pcchUrl, 28 | [MarshalAs(UnmanagedType.LPWStr)] StringBuilder szUrl); 29 | 30 | void GetDocumentType(ref Guid pRetVal); 31 | 32 | void GetLanguage(ref Guid pRetVal); 33 | 34 | void GetLanguageVendor(ref Guid pRetVal); 35 | 36 | void GetCheckSumAlgorithmId(ref Guid pRetVal); 37 | 38 | void GetCheckSum(int cData, 39 | out int pcData, 40 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] data); 41 | 42 | void FindClosestLine(int line, 43 | out int pRetVal); 44 | 45 | void HasEmbeddedSource(out Boolean pRetVal); 46 | 47 | void GetSourceLength(out int pRetVal); 48 | 49 | void GetSourceRange(int startLine, 50 | int startColumn, 51 | int endLine, 52 | int endColumn, 53 | int cSourceBytes, 54 | out int pcSourceBytes, 55 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=4)] byte[] source); 56 | 57 | }; 58 | 59 | /// 60 | internal class SymbolDocument : ISymbolDocument 61 | { 62 | ISymUnmanagedDocument m_unmanagedDocument; 63 | 64 | internal SymbolDocument(ISymUnmanagedDocument document) 65 | { 66 | if (document == null) 67 | { 68 | throw new ArgumentNullException("document"); 69 | } 70 | m_unmanagedDocument = document; 71 | } 72 | 73 | /// 74 | public String URL 75 | { 76 | get 77 | { 78 | StringBuilder URL; 79 | int cchUrl; 80 | m_unmanagedDocument.GetURL(0, out cchUrl, null); 81 | URL = new StringBuilder(cchUrl); 82 | m_unmanagedDocument.GetURL(cchUrl, out cchUrl, URL); 83 | return URL.ToString(); 84 | } 85 | } 86 | 87 | /// 88 | public Guid DocumentType 89 | { 90 | get 91 | { 92 | Guid guid = new Guid(); 93 | m_unmanagedDocument.GetDocumentType(ref guid); 94 | return guid; 95 | } 96 | } 97 | 98 | /// 99 | public Guid Language 100 | { 101 | get 102 | { 103 | Guid guid = new Guid(); 104 | m_unmanagedDocument.GetLanguage(ref guid); 105 | return guid; 106 | } 107 | } 108 | 109 | /// 110 | public Guid LanguageVendor 111 | { 112 | get 113 | { 114 | Guid guid = new Guid(); 115 | m_unmanagedDocument.GetLanguageVendor(ref guid); 116 | return guid; 117 | } 118 | } 119 | 120 | /// 121 | public Guid CheckSumAlgorithmId 122 | { 123 | get 124 | { 125 | Guid guid = new Guid(); 126 | m_unmanagedDocument.GetCheckSumAlgorithmId(ref guid); 127 | return guid; 128 | } 129 | } 130 | 131 | /// 132 | public byte[] GetCheckSum() 133 | { 134 | byte[] Data; 135 | int cData = 0; 136 | m_unmanagedDocument.GetCheckSum(0, out cData, null); 137 | Data = new byte[cData]; 138 | m_unmanagedDocument.GetCheckSum(cData, out cData, Data); 139 | return Data; 140 | } 141 | 142 | 143 | /// 144 | public int FindClosestLine(int line) 145 | { 146 | int closestLine = 0; 147 | m_unmanagedDocument.FindClosestLine(line, out closestLine); 148 | return closestLine; 149 | } 150 | 151 | /// 152 | public bool HasEmbeddedSource 153 | { 154 | get 155 | { 156 | bool retVal = false; 157 | m_unmanagedDocument.HasEmbeddedSource(out retVal); 158 | return retVal; 159 | } 160 | } 161 | 162 | /// 163 | public int SourceLength 164 | { 165 | get 166 | { 167 | int retVal = 0; 168 | m_unmanagedDocument.GetSourceLength(out retVal); 169 | return retVal; 170 | } 171 | } 172 | 173 | 174 | 175 | /// 176 | public byte[] GetSourceRange(int startLine, int startColumn, 177 | int endLine, int endColumn) 178 | { 179 | byte[] Data; 180 | int count = 0; 181 | m_unmanagedDocument.GetSourceRange(startLine, startColumn, endLine, endColumn, 0, out count, null); 182 | Data = new byte[count]; 183 | m_unmanagedDocument.GetSourceRange(startLine, startColumn, endLine, endColumn, count, out count, Data); 184 | return Data; 185 | } 186 | 187 | internal ISymUnmanagedDocument InternalDocument 188 | { 189 | get 190 | { 191 | return m_unmanagedDocument; 192 | } 193 | } 194 | 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /corapi/SymDocumentWriter.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | using System.Runtime.InteropServices.ComTypes; 18 | 19 | // Interface does not need to be marked with the serializable attribute 20 | /// 21 | [ 22 | ComImport, 23 | Guid("B01FAFEB-C450-3A4D-BEEC-B4CEEC01E006"), 24 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 25 | ComVisible(false) 26 | ] 27 | internal interface ISymUnmanagedDocumentWriter 28 | { 29 | void SetSource(int sourceSize, 30 | [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] source); 31 | 32 | void SetCheckSum(Guid algorithmId, 33 | int checkSumSize, 34 | [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte[] checkSum); 35 | }; 36 | 37 | 38 | internal class SymDocumentWriter: ISymbolDocumentWriter 39 | { 40 | ISymUnmanagedDocumentWriter m_unmanagedDocumentWriter; 41 | 42 | public SymDocumentWriter(ISymUnmanagedDocumentWriter unmanagedDocumentWriter) 43 | { 44 | // We should not wrap null instances 45 | if (unmanagedDocumentWriter == null) 46 | throw new ArgumentNullException("unmanagedDocumentWriter"); 47 | 48 | m_unmanagedDocumentWriter = unmanagedDocumentWriter; 49 | } 50 | 51 | public void SetSource(byte[] source) 52 | { 53 | m_unmanagedDocumentWriter.SetSource(source.Length, source); 54 | } 55 | 56 | public void SetCheckSum(Guid algorithmId, byte[] checkSum) 57 | { 58 | m_unmanagedDocumentWriter.SetCheckSum(algorithmId, checkSum.Length, checkSum); 59 | } 60 | 61 | // Public API 62 | internal ISymUnmanagedDocumentWriter InternalDocumentWriter 63 | { 64 | get 65 | { 66 | return m_unmanagedDocumentWriter; 67 | } 68 | } 69 | 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /corapi/SymNamespace.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | using System; 14 | using System.Text; 15 | using System.Runtime.InteropServices; 16 | using System.Runtime.InteropServices.ComTypes; 17 | 18 | // Interface does not need to be marked with the serializable attribute 19 | /// 20 | [ 21 | ComImport, 22 | Guid("0DFF7289-54F8-11d3-BD28-0000F80849BD"), 23 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 24 | ComVisible(false) 25 | ] 26 | internal interface ISymUnmanagedNamespace 27 | { 28 | void GetName(int cchName, 29 | out int pcchName, 30 | [MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); 31 | 32 | void GetNamespaces(int cNameSpaces, 33 | out int pcNameSpaces, 34 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ISymUnmanagedNamespace[] namespaces); 35 | 36 | void GetVariables(int cVars, 37 | out int pcVars, 38 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] ISymUnmanagedVariable[] pVars); 39 | } 40 | 41 | 42 | 43 | internal class SymNamespace : ISymbolNamespace 44 | { 45 | ISymUnmanagedNamespace m_unmanagedNamespace; 46 | 47 | internal SymNamespace(ISymUnmanagedNamespace nameSpace) 48 | { 49 | // We should not wrap null instances 50 | if (nameSpace == null) 51 | throw new ArgumentNullException("nameSpace"); 52 | 53 | m_unmanagedNamespace = nameSpace; 54 | } 55 | 56 | public String Name 57 | { 58 | get 59 | { 60 | StringBuilder Name; 61 | int cchName = 0; 62 | m_unmanagedNamespace.GetName(0, out cchName, null); 63 | Name = new StringBuilder(cchName); 64 | m_unmanagedNamespace.GetName(cchName, out cchName, Name); 65 | return Name.ToString(); 66 | } 67 | } 68 | 69 | public ISymbolNamespace[] GetNamespaces() 70 | { 71 | uint i; 72 | int cNamespaces = 0; 73 | m_unmanagedNamespace.GetNamespaces(0, out cNamespaces, null); 74 | ISymUnmanagedNamespace[] unmamagedNamespaces = new ISymUnmanagedNamespace[cNamespaces]; 75 | m_unmanagedNamespace.GetNamespaces(cNamespaces, out cNamespaces, unmamagedNamespaces); 76 | 77 | ISymbolNamespace[] Namespaces = new ISymbolNamespace[cNamespaces]; 78 | for (i = 0; i < cNamespaces; i++) 79 | { 80 | Namespaces[i] = new SymNamespace(unmamagedNamespaces[i]); 81 | } 82 | return Namespaces; 83 | } 84 | 85 | public ISymbolVariable[] GetVariables() 86 | { 87 | int cVars = 0; 88 | uint i; 89 | m_unmanagedNamespace.GetVariables(0, out cVars, null); 90 | ISymUnmanagedVariable[] unmanagedVariables = new ISymUnmanagedVariable[cVars]; 91 | m_unmanagedNamespace.GetVariables(cVars, out cVars, unmanagedVariables); 92 | 93 | ISymbolVariable[] Variables = new ISymbolVariable[cVars]; 94 | for (i = 0; i < cVars; i++) 95 | { 96 | Variables[i] = new SymVariable(unmanagedVariables[i]); 97 | } 98 | return Variables; 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /corapi/SymSearchInfo.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | using System.Runtime.InteropServices.ComTypes; 18 | 19 | [ 20 | ComImport, 21 | Guid("F8B3534A-A46B-4980-B520-BEC4ACEABA8F"), 22 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 23 | ComVisible(false) 24 | ] 25 | internal interface ISymUnmanagedSymbolSearchInfo 26 | { 27 | void GetSearchPathLength(out int pcchPath); 28 | 29 | void GetSearchPath(int cchPath, 30 | out int pcchPath, 31 | [MarshalAs(UnmanagedType.LPWStr)] StringBuilder szPath); 32 | 33 | void GetHRESULT(out int hr); 34 | } 35 | 36 | internal class SymSymbolSearchInfo : ISymbolSearchInfo 37 | { 38 | ISymUnmanagedSymbolSearchInfo m_target; 39 | 40 | public SymSymbolSearchInfo(ISymUnmanagedSymbolSearchInfo target) 41 | { 42 | m_target = target; 43 | } 44 | 45 | public int SearchPathLength 46 | { 47 | get 48 | { 49 | int length; 50 | m_target.GetSearchPathLength(out length); 51 | return length; 52 | } 53 | } 54 | 55 | public String SearchPath 56 | { 57 | get 58 | { 59 | int length; 60 | m_target.GetSearchPath(0, out length, null); 61 | StringBuilder path = new StringBuilder(length); 62 | m_target.GetSearchPath(length, out length, path); 63 | return path.ToString(); 64 | } 65 | } 66 | 67 | public int HResult 68 | { 69 | get 70 | { 71 | int hr; 72 | m_target.GetHRESULT(out hr); 73 | return hr; 74 | } 75 | } 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /corapi/SymSearchPolicyAttributes.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Only statics, does not need to be marked with the serializable attribute 14 | using System; 15 | 16 | [Serializable(), FlagsAttribute()] 17 | public enum SymSearchPolicies 18 | { 19 | // query the registry for symbol search paths 20 | AllowRegistryAccess = 1, 21 | 22 | // access a symbol server 23 | AllowSymbolServerAccess = 2, 24 | 25 | // Look at the path specified in Debug Directory 26 | AllowOriginalPathAccess = 4, 27 | 28 | // look for PDB in the place where the exe is. 29 | AllowReferencePathAccess = 8, 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /corapi/ThreadEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Threads. */ 14 | internal class CorThreadEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugThreadEnum m_enum; 17 | private CorThread m_th; 18 | 19 | internal CorThreadEnumerator (ICorDebugThreadEnum threadEnumerator) 20 | { 21 | m_enum = threadEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | m_enum.Clone (out clone); 31 | return new CorThreadEnumerator ((ICorDebugThreadEnum)clone); 32 | } 33 | 34 | // 35 | // IEnumerable interface 36 | // 37 | public IEnumerator GetEnumerator () 38 | { 39 | return this; 40 | } 41 | 42 | // 43 | // IEnumerator interface 44 | // 45 | public bool MoveNext () 46 | { 47 | ICorDebugThread[] a = new ICorDebugThread[1]; 48 | uint c = 0; 49 | int r = m_enum.Next ((uint) a.Length, a, out c); 50 | if (r==0 && c==1) // S_OK && we got 1 new element 51 | m_th = new CorThread (a[0]); 52 | else 53 | m_th = null; 54 | return m_th != null; 55 | } 56 | 57 | public void Reset () 58 | { 59 | m_enum.Reset (); 60 | m_th = null; 61 | } 62 | 63 | public Object Current 64 | { 65 | get 66 | { 67 | return m_th; 68 | } 69 | } 70 | } /* class ThreadEnumerator */ 71 | } /* namespace */ 72 | -------------------------------------------------------------------------------- /corapi/Type.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | public sealed class CorType : WrapperBase 14 | { 15 | internal ICorDebugType m_type; 16 | 17 | internal CorType (ICorDebugType type) 18 | : base(type) 19 | { 20 | m_type = type; 21 | } 22 | 23 | 24 | internal ICorDebugType GetInterface () 25 | { 26 | return m_type; 27 | } 28 | 29 | [CLSCompliant(false)] 30 | public ICorDebugType Raw 31 | { 32 | get 33 | { 34 | return m_type; 35 | } 36 | } 37 | 38 | /** Element type of the type. */ 39 | public CorElementType Type 40 | { 41 | get 42 | { 43 | CorElementType type; 44 | m_type.GetType (out type); 45 | return type; 46 | } 47 | } 48 | 49 | /** Class of the type */ 50 | public CorClass Class 51 | { 52 | get 53 | { 54 | ICorDebugClass c = null; 55 | m_type.GetClass(out c); 56 | return c==null?null:new CorClass (c); 57 | } 58 | } 59 | 60 | public int Rank 61 | { 62 | get 63 | { 64 | uint pRank= 0; 65 | m_type.GetRank (out pRank); 66 | return (int)pRank; 67 | } 68 | } 69 | 70 | // Provide the first CorType parameter in the TypeParameters collection. 71 | // This is a convenience operator. 72 | public CorType FirstTypeParameter 73 | { 74 | get 75 | { 76 | ICorDebugType dt = null; 77 | m_type.GetFirstTypeParameter(out dt); 78 | return dt==null?null:new CorType (dt); 79 | } 80 | } 81 | 82 | public CorType Base 83 | { 84 | get 85 | { 86 | ICorDebugType dt = null; 87 | m_type.GetBase(out dt); 88 | return dt==null?null:new CorType (dt); 89 | } 90 | } 91 | 92 | public CorValue GetStaticFieldValue(int fieldToken, CorFrame frame) 93 | { 94 | ICorDebugValue dv = null; 95 | m_type.GetStaticFieldValue((uint)fieldToken, frame.m_frame, out dv); 96 | return dv==null?null:new CorValue (dv); 97 | } 98 | 99 | // Expose IEnumerable, which can be used with for-each constructs. 100 | // This will provide an collection of CorType parameters. 101 | public IEnumerable TypeParameters 102 | { 103 | get 104 | { 105 | ICorDebugTypeEnum etp = null; 106 | m_type.EnumerateTypeParameters (out etp); 107 | if (etp==null) return null; 108 | return new CorTypeEnumerator (etp); 109 | } 110 | } 111 | } /* class Type */ 112 | } /* namespace */ 113 | -------------------------------------------------------------------------------- /corapi/TypeEnumerator.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Collections; 8 | 9 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 10 | 11 | namespace Microsoft.Samples.Debugging.CorDebug 12 | { 13 | /** Exposes an enumerator for Types. */ 14 | public class CorTypeEnumerator : IEnumerable, IEnumerator, ICloneable 15 | { 16 | private ICorDebugTypeEnum m_enum; 17 | private CorType m_ty; 18 | 19 | internal CorTypeEnumerator (ICorDebugTypeEnum typeEnumerator) 20 | { 21 | m_enum = typeEnumerator; 22 | } 23 | 24 | // 25 | // ICloneable interface 26 | // 27 | public Object Clone () 28 | { 29 | ICorDebugEnum clone = null; 30 | if( m_enum!=null ) 31 | m_enum.Clone (out clone); 32 | return new CorTypeEnumerator ((ICorDebugTypeEnum)clone); 33 | } 34 | 35 | // 36 | // IEnumerable interface 37 | // 38 | public IEnumerator GetEnumerator () 39 | { 40 | return this; 41 | } 42 | 43 | // 44 | // IEnumerator interface 45 | // 46 | public bool MoveNext () 47 | { 48 | if( m_enum==null ) 49 | return false; 50 | 51 | ICorDebugType[] a = new ICorDebugType[1]; 52 | uint c = 0; 53 | int r = m_enum.Next ((uint) a.Length, a, out c); 54 | if (r==0 && c==1) // S_OK && we got 1 new element 55 | m_ty = new CorType (a[0]); 56 | else 57 | m_ty = null; 58 | return m_ty != null; 59 | } 60 | 61 | public void Reset () 62 | { 63 | if( m_enum!=null ) 64 | m_enum.Reset (); 65 | m_ty = null; 66 | } 67 | 68 | public void Skip (int celt) 69 | { 70 | m_enum.Skip ((uint)celt); 71 | m_ty = null; 72 | } 73 | 74 | public Object Current 75 | { 76 | get 77 | { 78 | return m_ty; 79 | } 80 | } 81 | 82 | // Returns total elements in the collection. 83 | public int Count 84 | { 85 | get 86 | { 87 | if (m_enum == null) return 0; 88 | uint count = 0; 89 | m_enum.GetCount(out count); 90 | return (int) count; 91 | 92 | } 93 | } 94 | } /* class TypeEnumerator */ 95 | } /* namespace */ 96 | -------------------------------------------------------------------------------- /corapi/ValueBreakpoint.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | 8 | using Microsoft.Samples.Debugging.CorDebug.NativeApi; 9 | 10 | namespace Microsoft.Samples.Debugging.CorDebug 11 | { 12 | public sealed class CorValueBreakpoint : CorBreakpoint 13 | { 14 | private ICorDebugValueBreakpoint m_br; 15 | 16 | internal CorValueBreakpoint (ICorDebugValueBreakpoint breakpoint) : base(breakpoint) 17 | { 18 | m_br = breakpoint; 19 | } 20 | 21 | public CorValue Value 22 | { 23 | get 24 | { 25 | ICorDebugValue m = null; 26 | m_br.GetValue (out m); 27 | return new CorValue (m); 28 | } 29 | } 30 | } /* class ValueBreakpoint */ 31 | } /* namespace */ 32 | -------------------------------------------------------------------------------- /corapi/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.Reflection.AssemblyTitle("Managed Debugger Sample")] 2 | [assembly: System.Reflection.AssemblyCompany("Microsoft Corporation")] 3 | [assembly: System.Reflection.AssemblyCopyright("Copyright © Microsoft Corporation. All rights reserved.")] 4 | [assembly: System.Reflection.AssemblyTrademark("Microsoft® is a registered trademark of Microsoft Corporation.")] 5 | [assembly: System.Reflection.AssemblyVersion("2.1.0")] 6 | /* 7 | * ******************* 8 | * Maintenance History 9 | * ******************* 10 | * 11 | * - Version 2.1.0 12 | * - More advanced debug event control and logging is now available via "ca" and "log" commands. 13 | * - Breaking change in IMdbgIO.WriteOutput. This no longer includes a new line. 14 | * - IronPython extension added. 15 | * - Managed wrappers for native debug APIs added. 16 | * - Pdb to Xml conversion tool added. 17 | * 18 | */ 19 | -------------------------------------------------------------------------------- /corapi/WrapperBase.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | using System; 7 | using System.Diagnostics; 8 | 9 | namespace Microsoft.Samples.Debugging.CorDebug 10 | { 11 | /* This class is base class for all the wrapper classes we have. 12 | * We overload equivalance operators, so that we can figure out, 13 | * compare object. 14 | * 15 | * The reason why we have to have this is described here: 16 | * Suppose we have a Wrapper WX for COM object X. We create an object WX 17 | * with operator new. The wrapper will create in it's constructor real 18 | * instance of native object X. 19 | * Now suppose that some oter native object Y have callback with an argument 20 | * X. We create a wrapper for it WY, which will implment the 21 | * callback that way that it converts argument X to WX and calls some event 22 | * defined in WY OnXXX. The conversion from X to WX is usually done by 23 | * creating new wrapper WX and attaching it to X. 24 | * 25 | * But now we cannot determine if the object WX returned from callback in WY 26 | * is the same as the one we have a reference to. We cannot use == operator 27 | * becuase we have two different wrappers. 28 | * 29 | * This class WrapperBase overloads ==,GetHashCode and Equals classes that 30 | * way that they operate on the inner pointers to native interfaces rather 31 | * than on wrapper object themselves. 32 | * 33 | * Also note that the COMobject is of type Object. This will actually cast 34 | * an object to IUnknown, which is the only realiable way to compare two 35 | * COM objects 36 | * 37 | * An alternative to the design of overloading == opeartor would be to have 38 | * a hash table of X=>WX and on each callback instead of creating new 39 | * wrapper, lookup an existing wrapper for an object. 40 | * I didn't use this technique here, because the debugger interfaces are 41 | * havily based on callbacks an looking up something in hashtable is more 42 | * expansive operation than creating new wrapper. Further the wrappers are 43 | * really light-weight -- they generally contain only pointer to the COM 44 | * obejct. 45 | */ 46 | 47 | public abstract class WrapperBase : MarshalByRefObject 48 | { 49 | protected WrapperBase(Object value) 50 | { 51 | Debug.Assert(value!=null); 52 | m_comObject = value; 53 | } 54 | 55 | public override bool Equals(Object value) 56 | { 57 | if(!(value is WrapperBase)) 58 | return false; 59 | return ((value as WrapperBase).m_comObject == this.m_comObject); 60 | } 61 | 62 | public override int GetHashCode() 63 | { 64 | return m_comObject.GetHashCode(); 65 | } 66 | 67 | public static bool operator ==( WrapperBase operand,WrapperBase operand2) 68 | { 69 | if(Object.ReferenceEquals(operand,operand2)) 70 | return true; 71 | 72 | if(Object.ReferenceEquals(operand, null)) // this means that operand==null && operand2 is not null 73 | return false; 74 | 75 | return operand.Equals(operand2); 76 | } 77 | 78 | public static bool operator !=( WrapperBase operand,WrapperBase operand2) 79 | { 80 | return !(operand==operand2); 81 | } 82 | 83 | private Object m_comObject; 84 | } 85 | 86 | } /* namespace */ 87 | -------------------------------------------------------------------------------- /corapi/corapi.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | 8.0.50727 6 | 2.0 7 | {04EF9865-E1B1-403D-802B-E4FAEA50A634} 8 | Library 9 | corapi 10 | corapi 11 | 4 12 | 13 | 14 | mdbg.snk 15 | File 16 | true 17 | v4.0 18 | 19 | 20 | 2.0 21 | 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | Client 38 | 39 | 40 | true 41 | full 42 | false 43 | ..\..\..\bin\Debug\ 44 | TRACE;DEBUG;CODE_ANALYSIS 45 | true 46 | MinimumRecommendedRules.ruleset 47 | true 48 | 49 | 50 | false 51 | true 52 | ..\..\..\bin\Release\ 53 | TRACE 54 | true 55 | AllRules.ruleset 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | ..\..\..\..\..\..\..\..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | {3991AB6C-468B-4C28-95FC-3188CFB34180} 137 | NativeDebugWrappers 138 | 139 | 140 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447} 141 | raw 142 | 143 | 144 | 145 | 146 | False 147 | .NET Framework 3.5 SP1 Client Profile 148 | false 149 | 150 | 151 | False 152 | .NET Framework 3.5 SP1 153 | true 154 | 155 | 156 | False 157 | Windows Installer 3.1 158 | true 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /corapi/mdbg.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/corapi/mdbg.snk -------------------------------------------------------------------------------- /corapi/symvariable.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | 8 | // These interfaces serve as an extension to the BCL's SymbolStore interfaces. 9 | namespace Microsoft.Samples.Debugging.CorSymbolStore 10 | { 11 | using System.Diagnostics.SymbolStore; 12 | 13 | // Interface does not need to be marked with the serializable attribute 14 | using System; 15 | using System.Text; 16 | using System.Runtime.InteropServices; 17 | using System.Runtime.InteropServices.ComTypes; 18 | 19 | [ 20 | ComImport, 21 | Guid("9F60EEBE-2D9A-3F7C-BF58-80BC991C60BB"), 22 | InterfaceType(ComInterfaceType.InterfaceIsIUnknown), 23 | ComVisible(false) 24 | ] 25 | internal interface ISymUnmanagedVariable 26 | { 27 | void GetName(int cchName, 28 | out int pcchName, 29 | [MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); 30 | 31 | void GetAttributes(out int pRetVal); 32 | 33 | void GetSignature(int cSig, 34 | out int pcSig, 35 | [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] byte[] sig); 36 | 37 | void GetAddressKind(out int pRetVal); 38 | 39 | void GetAddressField1(out int pRetVal); 40 | 41 | void GetAddressField2(out int pRetVal); 42 | 43 | void GetAddressField3(out int pRetVal); 44 | 45 | void GetStartOffset(out int pRetVal); 46 | 47 | void GetEndOffset(out int pRetVal); 48 | } 49 | 50 | /// 51 | 52 | internal class SymVariable : ISymbolVariable 53 | { 54 | ISymUnmanagedVariable m_unmanagedVariable; 55 | 56 | internal SymVariable(ISymUnmanagedVariable variable) 57 | { 58 | // We should not wrap null instances 59 | if (variable == null) 60 | throw new ArgumentNullException("variable"); 61 | 62 | m_unmanagedVariable = variable; 63 | } 64 | 65 | public String Name 66 | { 67 | get 68 | { 69 | StringBuilder Name; 70 | int cchName; 71 | m_unmanagedVariable.GetName(0, out cchName, null); 72 | Name = new StringBuilder(cchName); 73 | m_unmanagedVariable.GetName(cchName, out cchName, Name); 74 | return Name.ToString(); 75 | } 76 | } 77 | 78 | public Object Attributes 79 | { 80 | get 81 | { 82 | int RetVal; 83 | m_unmanagedVariable.GetAttributes(out RetVal); 84 | return (object)RetVal; 85 | } 86 | } 87 | 88 | public byte[] GetSignature() 89 | { 90 | byte[] Data; 91 | int cData; 92 | m_unmanagedVariable.GetSignature(0, out cData, null); 93 | Data = new byte[cData]; 94 | m_unmanagedVariable.GetSignature(cData, out cData, Data); 95 | return Data; 96 | } 97 | 98 | public SymAddressKind AddressKind 99 | { 100 | get 101 | { 102 | int RetVal; 103 | m_unmanagedVariable.GetAddressKind(out RetVal); 104 | return (SymAddressKind)RetVal; 105 | } 106 | } 107 | 108 | public int AddressField1 109 | { 110 | get 111 | { 112 | int RetVal; 113 | m_unmanagedVariable.GetAddressField1(out RetVal); 114 | return RetVal; 115 | } 116 | } 117 | 118 | public int AddressField2 119 | { 120 | get 121 | { 122 | int RetVal; 123 | m_unmanagedVariable.GetAddressField2(out RetVal); 124 | return RetVal; 125 | } 126 | } 127 | 128 | public int AddressField3 129 | { 130 | get 131 | { 132 | int RetVal; 133 | m_unmanagedVariable.GetAddressField3(out RetVal); 134 | return RetVal; 135 | } 136 | } 137 | 138 | public int StartOffset 139 | { 140 | get 141 | { 142 | int RetVal; 143 | m_unmanagedVariable.GetStartOffset(out RetVal); 144 | return RetVal; 145 | } 146 | } 147 | 148 | public int EndOffset 149 | { 150 | get 151 | { 152 | int RetVal; 153 | m_unmanagedVariable.GetEndOffset(out RetVal); 154 | return RetVal; 155 | } 156 | } 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /mdbg.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/mdbg.snk -------------------------------------------------------------------------------- /raw/ICorPublishWrappers.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | // 6 | // Imports ICorPublish interface from CorPublish.idl into managed code 7 | //--------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Text; 11 | using System.Runtime.CompilerServices; 12 | using System.Runtime.InteropServices; 13 | 14 | using IStream=System.Runtime.InteropServices.ComTypes.IStream; 15 | using Microsoft.Win32.SafeHandles; 16 | 17 | namespace Microsoft.Samples.Debugging.CorPublish.NativeApi 18 | { 19 | public enum __MIDL___MIDL_itf_corpub_0000_0001 20 | { 21 | // Fields 22 | COR_PUB_MANAGEDONLY = 1 23 | } 24 | 25 | public enum COR_PUB_ENUMPROCESS 26 | { 27 | // Fields 28 | COR_PUB_MANAGEDONLY = 1 29 | } 30 | 31 | [ComImport, Guid("9613A0E7-5A68-11D3-8F84-00A0C9B4D50C"), CoClass(typeof(CorpubPublishClass))] 32 | public interface CorpubPublish : ICorPublish 33 | { 34 | } 35 | 36 | [ComImport, TypeLibType(2), Guid("047a9a40-657e-11d3-8d5b-00104b35e7ef"), ClassInterface(ClassInterfaceType.None)] 37 | public class CorpubPublishClass : ICorPublish, CorpubPublish 38 | { 39 | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 40 | public virtual extern void EnumProcesses( 41 | [In, ComAliasName("CorpubProcessLib.COR_PUB_ENUMPROCESS")] COR_PUB_ENUMPROCESS Type, 42 | [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishProcessEnum ppIEnum); 43 | 44 | [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] 45 | public virtual extern void GetProcess([In] uint pid, [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess ppProcess); 46 | } 47 | 48 | [ComImport, Guid("9613A0E7-5A68-11D3-8F84-00A0C9B4D50C"), InterfaceType(1)] 49 | public interface ICorPublish 50 | { 51 | 52 | void EnumProcesses([In, ComAliasName("CorpubProcessLib.COR_PUB_ENUMPROCESS")] COR_PUB_ENUMPROCESS Type, [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishProcessEnum ppIEnum); 53 | 54 | void GetProcess([In] uint pid, [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess ppProcess); 55 | } 56 | 57 | [ComImport, Guid("D6315C8F-5A6A-11D3-8F84-00A0C9B4D50C"), InterfaceType(1)] 58 | public interface ICorPublishAppDomain 59 | { 60 | 61 | void GetID([Out] out uint puId); 62 | 63 | void GetName([In] uint cchName, [Out] out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); 64 | } 65 | 66 | [ComImport, InterfaceType(1), Guid("9F0C98F5-5A6A-11D3-8F84-00A0C9B4D50C")] 67 | public interface ICorPublishAppDomainEnum : ICorPublishEnum 68 | { 69 | 70 | new void Skip([In] uint celt); 71 | 72 | new void Reset(); 73 | 74 | new void Clone([Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); 75 | 76 | new void GetCount([Out] out uint pcelt); 77 | [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] 78 | int Next([In] uint celt, [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomain objects, [Out] out uint pceltFetched); 79 | } 80 | 81 | [ComImport, InterfaceType(1), Guid("C0B22967-5A69-11D3-8F84-00A0C9B4D50C")] 82 | public interface ICorPublishEnum 83 | { 84 | 85 | void Skip([In] uint celt); 86 | 87 | void Reset(); 88 | 89 | void Clone([Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); 90 | 91 | void GetCount([Out] out uint pcelt); 92 | } 93 | 94 | [ComImport, InterfaceType(1), Guid("18D87AF1-5A6A-11D3-8F84-00A0C9B4D50C")] 95 | public interface ICorPublishProcess 96 | { 97 | 98 | void IsManaged([Out] out int pbManaged); 99 | 100 | void EnumAppDomains([Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishAppDomainEnum ppEnum); 101 | 102 | void GetProcessID([Out] out uint pid); 103 | 104 | void GetDisplayName([In] uint cchName, [Out] out uint pcchName, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder szName); 105 | } 106 | 107 | [ComImport, InterfaceType(1), Guid("A37FBD41-5A69-11D3-8F84-00A0C9B4D50C")] 108 | public interface ICorPublishProcessEnum : ICorPublishEnum 109 | { 110 | 111 | new void Skip([In] uint celt); 112 | 113 | new void Reset(); 114 | 115 | new void Clone([Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishEnum ppEnum); 116 | 117 | new void GetCount([Out] out uint pcelt); 118 | [PreserveSig, MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime)] 119 | int Next([In] uint celt, [Out, MarshalAs(UnmanagedType.Interface)] out ICorPublishProcess objects, [Out] out uint pceltFetched); 120 | } 121 | } 122 | 123 | 124 | -------------------------------------------------------------------------------- /raw/RawAssemblyAttributes.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | // 6 | // Imports ICorDebug interface into managed code 7 | //--------------------------------------------------------------------- 8 | 9 | 10 | // Assembly attributes for Raw native imports. 11 | using System; 12 | [assembly:CLSCompliant(false)] 13 | -------------------------------------------------------------------------------- /raw/ReadMe.txt: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | //--------------------------------------------------------------------- 6 | 7 | ReadMe.txt for raw project. 8 | 9 | The files in this project should not be modified. They represent a COM marshaling code used by the sample. COM marshaling code is used to call 10 | native Managed Debugging COM API functions. 11 | 12 | The functions available in this dll should primarily be called from the corapi Managed Wrappers. See that ReadMe for details. 13 | -------------------------------------------------------------------------------- /raw/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.Reflection.AssemblyTitle("Managed Debugger Sample")] 2 | [assembly: System.Reflection.AssemblyCompany("Microsoft Corporation")] 3 | [assembly: System.Reflection.AssemblyCopyright("Copyright © Microsoft Corporation. All rights reserved.")] 4 | [assembly: System.Reflection.AssemblyTrademark("Microsoft® is a registered trademark of Microsoft Corporation.")] 5 | [assembly: System.Reflection.AssemblyVersion("2.1.0")] 6 | /* 7 | * ******************* 8 | * Maintenance History 9 | * ******************* 10 | * 11 | * - Version 2.1.0 12 | * - More advanced debug event control and logging is now available via "ca" and "log" commands. 13 | * - Breaking change in IMdbgIO.WriteOutput. This no longer includes a new line. 14 | * - IronPython extension added. 15 | * - Managed wrappers for native debug APIs added. 16 | * - Pdb to Xml conversion tool added. 17 | * 18 | */ 19 | -------------------------------------------------------------------------------- /raw/WindowsImports.cs: -------------------------------------------------------------------------------- 1 | //--------------------------------------------------------------------- 2 | // This file is part of the CLR Managed Debugger (mdbg) Sample. 3 | // 4 | // Copyright (C) Microsoft Corporation. All rights reserved. 5 | // 6 | // Imports the win32 structures needed by the ICorDebug interfaces. 7 | //--------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Text; 11 | using System.Runtime.CompilerServices; 12 | using System.Runtime.InteropServices; 13 | 14 | using Microsoft.Samples.Debugging.CorMetadata.NativeApi; 15 | using Microsoft.Samples.Debugging.Native; 16 | using Microsoft.Win32.SafeHandles; 17 | 18 | 19 | namespace Microsoft.Samples.Debugging.CorDebug.NativeApi 20 | { 21 | #region X86 Context 22 | [StructLayout(LayoutKind.Sequential)] 23 | public struct WIN32_CONTEXT 24 | { 25 | public uint ContextFlags; 26 | public uint Dr0; 27 | public uint Dr1; 28 | public uint Dr2; 29 | public uint Dr3; 30 | public uint Dr6; 31 | public uint Dr7; 32 | public WIN32_FLOATING_SAVE_AREA FloatSave; 33 | public uint SegGs; 34 | public uint SegFs; 35 | public uint SegEs; 36 | public uint SegDs; 37 | public uint Edi; 38 | public uint Esi; 39 | public uint Ebx; 40 | public uint Edx; 41 | public uint Ecx; 42 | public uint Eax; 43 | public uint Ebp; 44 | public uint Eip; 45 | public uint SegCs; 46 | public uint EFlags; 47 | public uint Esp; 48 | public uint SegSs; 49 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x200)] 50 | public byte[] ExtendedRegisters; 51 | } 52 | 53 | [StructLayout(LayoutKind.Sequential)] 54 | public struct WIN32_FLOATING_SAVE_AREA 55 | { 56 | public uint ControlWord; 57 | public uint StatusWord; 58 | public uint TagWord; 59 | public uint ErrorOffset; 60 | public uint ErrorSelector; 61 | public uint DataOffset; 62 | public uint DataSelector; 63 | [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] 64 | public byte[] RegisterArea; 65 | public uint Cr0NpxState; 66 | } 67 | 68 | #endregion // X86 Context 69 | 70 | 71 | #region Structures for CreateProcess 72 | [StructLayout(LayoutKind.Sequential, Pack = 8), ComVisible(false)] 73 | public class PROCESS_INFORMATION 74 | { 75 | public IntPtr hProcess; 76 | public IntPtr hThread; 77 | public int dwProcessId; 78 | public int dwThreadId; 79 | public PROCESS_INFORMATION() { } 80 | } 81 | 82 | [StructLayout(LayoutKind.Sequential, Pack = 8), ComVisible(false)] 83 | public class SECURITY_ATTRIBUTES 84 | { 85 | public int nLength; 86 | private IntPtr lpSecurityDescriptor; 87 | public bool bInheritHandle; 88 | public SECURITY_ATTRIBUTES() { } 89 | } 90 | 91 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 8), ComVisible(false)] 92 | public class STARTUPINFO 93 | { 94 | public int cb; 95 | public string lpReserved; 96 | public string lpDesktop; 97 | public string lpTitle; 98 | public int dwX; 99 | public int dwY; 100 | public int dwXSize; 101 | public int dwYSize; 102 | public int dwXCountChars; 103 | public int dwYCountChars; 104 | public int dwFillAttribute; 105 | public int dwFlags; 106 | public short wShowWindow; 107 | public short cbReserved2; 108 | private IntPtr lpReserved2; 109 | public SafeFileHandle hStdInput; 110 | public SafeFileHandle hStdOutput; 111 | public SafeFileHandle hStdError; 112 | public STARTUPINFO() { } 113 | } 114 | 115 | #endregion // Structures for CreateProcess 116 | 117 | } // Microsoft.Samples.Debugging.CorDebug.NativeApi 118 | -------------------------------------------------------------------------------- /raw/mdbg.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JoshVarty/MinimalDebuggerForEnC/5647a431987fc3f62a9904f1bc508d71a6996372/raw/mdbg.snk -------------------------------------------------------------------------------- /raw/raw.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | 8.0.50727 6 | 2.0 7 | {C18D303B-2C55-43EB-A3DF-39CF3FB1D447} 8 | Library 9 | raw 10 | raw 11 | 4 12 | 13 | 14 | mdbg.snk 15 | File 16 | true 17 | v4.0 18 | 19 | 20 | 2.0 21 | 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | Client 38 | 39 | 40 | true 41 | full 42 | false 43 | ..\..\..\bin\Debug\ 44 | DEBUG;TRACE 45 | true 46 | MinimumRecommendedRules.ruleset 47 | true 48 | 49 | 50 | false 51 | true 52 | ..\..\..\bin\Release\ 53 | TRACE 54 | true 55 | AllRules.ruleset 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ..\..\..\..\..\..\..\..\..\..\..\..\..\WINDOWS\Microsoft.NET\Framework\v2.0.50727\System.dll 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | False 77 | .NET Framework 3.5 SP1 Client Profile 78 | false 79 | 80 | 81 | False 82 | .NET Framework 3.5 SP1 83 | true 84 | 85 | 86 | False 87 | Windows Installer 3.1 88 | true 89 | 90 | 91 | 92 | 93 | {3991ab6c-468b-4c28-95fc-3188cfb34180} 94 | NativeDebugWrappers 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | --------------------------------------------------------------------------------