public
Description: managed debugger for IronPython
Homepage: http://devhawk.net/2009/02/27/Writing+An+IronPython+Debugger+Introduction.aspx
Clone URL: git://github.com/devhawk/ipydbg.git
commit  5858695ff85ed4740ad06466d4f54394e7f00f9b
tree    27b5c818df9335a54365defd832fb63bb63cde3f
parent  d198f5713fceeb762ecb60e4d406ddd2006e0138
ipydbg / CorDebug / CorSymbolStore / symbinder.cs
d198f571 » Harry Pierson 2009-02-27 Initial commit of CorDebug ... 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 [
20 ComImport,
21 Guid("AA544d42-28CB-11d3-bd22-0000f80849bd"),
22 InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
23 ComVisible(false)
24 ]
25 internal interface ISymUnmanagedBinder
26 {
27 // These methods will often return error HRs in common cases.
28 // If there are no symbols for the given target, a failing hr is returned.
29 // This is pretty common.
30 //
31 // Using PreserveSig and manually handling error cases provides a big performance win.
32 // Far fewer exceptions will be thrown and caught.
33 // Exceptions should be reserved for truely "exceptional" cases.
34 [PreserveSig]
35 int GetReaderForFile(IntPtr importer,
36 [MarshalAs(UnmanagedType.LPWStr)] String filename,
37 [MarshalAs(UnmanagedType.LPWStr)] String SearchPath,
38 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
39
40 [PreserveSig]
41 int GetReaderFromStream(IntPtr importer,
42 IStream stream,
43 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
44 }
45
46 [
47 ComImport,
48 Guid("ACCEE350-89AF-4ccb-8B40-1C2C4C6F9434"),
49 InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
50 ComVisible(false)
51 ]
52 internal interface ISymUnmanagedBinder2 : ISymUnmanagedBinder
53 {
54 // ISymUnmanagedBinder methods (need to define the base interface methods also, per COM interop requirements)
55 [PreserveSig]
56 new int GetReaderForFile(IntPtr importer,
57 [MarshalAs(UnmanagedType.LPWStr)] String filename,
58 [MarshalAs(UnmanagedType.LPWStr)] String SearchPath,
59 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
60
61 [PreserveSig]
62 new int GetReaderFromStream(IntPtr importer,
63 IStream stream,
64 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
65
66 // ISymUnmanagedBinder2 methods
67 [PreserveSig]
68 int GetReaderForFile2(IntPtr importer,
69 [MarshalAs(UnmanagedType.LPWStr)] String fileName,
70 [MarshalAs(UnmanagedType.LPWStr)] String searchPath,
71 int searchPolicy,
72 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal);
73 }
74
75 [
76 ComImport,
77 Guid("28AD3D43-B601-4d26-8A1B-25F9165AF9D7"),
78 InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
79 ComVisible(false)
80 ]
81 internal interface ISymUnmanagedBinder3 : ISymUnmanagedBinder2
82 {
83 // ISymUnmanagedBinder methods (need to define the base interface methods also, per COM interop requirements)
84 [PreserveSig]
85 new int GetReaderForFile(IntPtr importer,
86 [MarshalAs(UnmanagedType.LPWStr)] String filename,
87 [MarshalAs(UnmanagedType.LPWStr)] String SearchPath,
88 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
89
90 [PreserveSig]
91 new int GetReaderFromStream(IntPtr importer,
92 IStream stream,
93 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader retVal);
94
95 // ISymUnmanagedBinder2 methods (need to define the base interface methods also, per COM interop requirements)
96 [PreserveSig]
97 new int GetReaderForFile2(IntPtr importer,
98 [MarshalAs(UnmanagedType.LPWStr)] String fileName,
99 [MarshalAs(UnmanagedType.LPWStr)] String searchPath,
100 int searchPolicy,
101 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal);
102
103 // ISymUnmanagedBinder3 methods
104 [PreserveSig]
105 int GetReaderFromCallback(IntPtr importer,
106 [MarshalAs(UnmanagedType.LPWStr)] String fileName,
107 [MarshalAs(UnmanagedType.LPWStr)] String searchPath,
108 int searchPolicy,
109 IntPtr callback,
110 [MarshalAs(UnmanagedType.Interface)] out ISymUnmanagedReader pRetVal);
111 }
112
113 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder"]/*' />
114
115 public class SymbolBinder: ISymbolBinder1, ISymbolBinder2
116 {
117 ISymUnmanagedBinder m_binder;
118
119 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.SymbolBinder"]/*' />
120 public SymbolBinder()
121 {
122 Guid CLSID_CorSymBinder = new Guid("0A29FF9E-7F9C-4437-8B11-F424491E3931");
123 m_binder = (ISymUnmanagedBinder3)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_CorSymBinder));
124 }
125
126 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReader"]/*' />
127 public ISymbolReader GetReader(IntPtr importer, String filename,
128 String searchPath)
129 {
130 ISymUnmanagedReader reader = null;
131 int hr = m_binder.GetReaderForFile(importer, filename, searchPath, out reader);
132 if (IsFailingResultNormal(hr))
133 {
134 return null;
135 }
136 Marshal.ThrowExceptionForHR(hr);
137 return new SymReader(reader);
138 }
139
140 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile"]/*' />
141 public ISymbolReader GetReaderForFile(Object importer, String filename,
142 String searchPath)
143 {
144 ISymUnmanagedReader reader = null;
145 IntPtr uImporter = IntPtr.Zero;
146 try
147 {
148 uImporter = Marshal.GetIUnknownForObject(importer);
149 int hr = m_binder.GetReaderForFile(uImporter, filename, searchPath, out reader);
150 if (IsFailingResultNormal(hr))
151 {
152 return null;
153 }
154 Marshal.ThrowExceptionForHR(hr);
155 }
156 finally
157 {
158 if (uImporter != IntPtr.Zero)
159 Marshal.Release(uImporter);
160 }
161 return new SymReader(reader);
162 }
163
164 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile1"]/*' />
165 public ISymbolReader GetReaderForFile(Object importer, String fileName,
166 String searchPath, SymSearchPolicies searchPolicy)
167 {
168 ISymUnmanagedReader symReader = null;
169 IntPtr uImporter = IntPtr.Zero;
170 try
171 {
172 uImporter = Marshal.GetIUnknownForObject(importer);
173 int hr = ((ISymUnmanagedBinder2)m_binder).GetReaderForFile2(uImporter, fileName, searchPath, (int)searchPolicy, out symReader);
174 if (IsFailingResultNormal(hr))
175 {
176 return null;
177 }
178 Marshal.ThrowExceptionForHR(hr);
179 }
180 finally
181 {
182 if (uImporter != IntPtr.Zero)
183 Marshal.Release(uImporter);
184 }
185 return new SymReader(symReader);
186 }
187
188 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderForFile2"]/*' />
189 public ISymbolReader GetReaderForFile(Object importer, String fileName,
190 String searchPath, SymSearchPolicies searchPolicy,
191 IntPtr callback)
192 {
193 ISymUnmanagedReader reader = null;
194 IntPtr uImporter = IntPtr.Zero;
195 try
196 {
197 uImporter = Marshal.GetIUnknownForObject(importer);
198 int hr = ((ISymUnmanagedBinder3)m_binder).GetReaderFromCallback(uImporter, fileName, searchPath, (int)searchPolicy, callback, out reader);
199 if (IsFailingResultNormal(hr))
200 {
201 return null;
202 }
203 Marshal.ThrowExceptionForHR(hr);
204 }
205 finally {
206 if (uImporter != IntPtr.Zero)
207 Marshal.Release(uImporter);
208 }
209 return new SymReader(reader);
210 }
211
212 /// <include file='doc\symbinder.uex' path='docs/doc[@for="SymbolBinder.GetReaderFromStream"]/*' />
213 public ISymbolReader GetReaderFromStream(Object importer, IStream stream)
214 {
215 ISymUnmanagedReader reader = null;
216 IntPtr uImporter = IntPtr.Zero;
217 try
218 {
219 uImporter = Marshal.GetIUnknownForObject(importer);
220 int hr = ((ISymUnmanagedBinder2)m_binder).GetReaderFromStream(uImporter, stream, out reader);
221 if (IsFailingResultNormal(hr))
222 {
223 return null;
224 }
225 Marshal.ThrowExceptionForHR(hr);
226 }
227 finally
228 {
229 if (uImporter != IntPtr.Zero)
230 Marshal.Release(uImporter);
231 }
232 return new SymReader(reader);
233 }
234
235 private static bool IsFailingResultNormal(int hr)
236 {
237 // If a pdb is not found, that's a pretty common thing.
238 if (hr == unchecked((int)0x806D0005)) // E_PDB_NOT_FOUND
239 {
240 return true;
241 }
242 // Other fairly common things may happen here, but we don't want to hide
243 // this from the programmer.
244 // You may get 0x806D0014 if the pdb is there, but just old (mismatched)
245 // Or if you ask for the symbol information on something that's not an assembly.
246 // If that may happen for your application, wrap calls to GetReaderForFile in
247 // try-catch(COMException) blocks and use the error code in the COMException to report error.
248 return false;
249 }
250 }
251 }