1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4//*****************************************************************************
5// DacDbiInterface.h
6//
7
8//
9// Define the interface between the DAC and DBI.
10//*****************************************************************************
11
12#ifndef _DACDBI_INTERFACE_H_
13#define _DACDBI_INTERFACE_H_
14
15#include <metahost.h>
16
17// The DAC/DBI interface can use structures and LSPTR declarations from the
18// existing V2 interfaces
19#include "dbgipcevents.h"
20
21//-----------------------------------------------------------------------------
22// Deallocation function for memory allocated with the global IAllocator object.
23//
24// Arguments:
25// p - pointer to delete. Allocated with IAllocator::Alloc
26//
27// Notes:
28// This should invoke the dtor and then call IAllocator::Free.
29// In the DAC implementation, this will call via IAllocator.
30// In the DBI implementation, this can directly call delete (assuming the IAllocator::Free
31// directly called new).
32template<class T> void DeleteDbiMemory(T *p);
33// Need a class to serve as a tag that we can use to overload New/Delete.
34class forDbiWorker {};
35extern forDbiWorker forDbi;
36extern void * operator new(size_t lenBytes, const forDbiWorker &);
37extern void * operator new[](size_t lenBytes, const forDbiWorker &);
38extern void operator delete(void *p, const forDbiWorker &);
39extern void operator delete[](void *p, const forDbiWorker &);
40
41// The dac exposes a way to walk all GC references in the process. This
42// includes both strong references and weak references. This is done
43// through a referece walk.
44typedef void* * RefWalkHandle;
45
46#include "dacdbistructures.h"
47
48// This is the current format of code:DbiVersion. It needs to be rev'ed when we decide to store something
49// else other than the product version of the DBI in DbiVersion (e.g. a timestamp). See
50// code:CordbProcess::CordbProcess#DBIVersionChecking for more information.
51const DWORD kCurrentDbiVersionFormat = 1;
52
53//-----------------------------------------------------------------------------
54// This is a low-level interface between DAC and DBI.
55// The DAC is the raw DAC-ized code from the EE.
56// DBI is the implementation of ICorDebug on top of that.
57//
58// This interface should be:
59// - Stateless: The DAC component should not have any persistent state. It should not have any resources
60// that it needs to clean up. DBI can store all the state (eg, list of of modules).
61// Using IAllocator/IStringHolder interfaces to allocate data to pass back out is ok because DBI owns
62// the resources, not the DAC layer.
63// - blittable: The types on the interface should be blittable. For example, use TIDs instead of OS Thread handles.
64// Passing pointers to be used as out-parameters is ok.
65// - lightweight: it will inevitably have many methods on it and should be very fluid to use.
66// - very descriptive: heavily call out liabilities on the runtime. For example, don't just have a method like
67// "GetName" where Name is ambiguous. Heavily comment exactly what Name is, when it may fail, if it's 0-length,
68// if it's unique, etc. This serves two purposes:
69// a) it helps ensure the right invariants flow up to the public API level.
70// b) it helps ensure that the debugger is making the right assumptions about the runtime's behavior.
71//
72// #Marshaling:
73// This interface should be marshalable such that the caller (the Right Side) can exist in one
74// process, while the implementation of Dac could be on another machine.
75// - All types need to be marshable.
76// - Use OUT and OPTIONAL as defined in windef.h to guide the marshaler. Here are how types are marshaled:
77// T : value-type, copied on input.
78// T* : will be marshaled as non-null by-ref (copy on input, copy on return),
79// const T*: non-null, copy on input only.
80// OUT T*: non-null copy-on-return only.
81// OPTIONAL T*: by-ref, could be null.
82// - The marshaler has special knowledge of IStringHolder and DacDbiArrayList<T>.
83// - You can write custom marshalers for non-blittable structures defined in DacDbiStructures.h.
84// - There is custom handling for marshalling callbacks.
85//
86//
87// Threading: The interface (and the underlying DataTarget) are free-threaded to leverage
88// concurrency.
89//
90// Allocation:
91// This interface can use IAllocator to allocate objects and hand them back. The allocated objects should be:
92// - closed, serializable object graphs.
93// - should have private fields and public accessors
94// - have dtors that free any allocated the memory via calling DeleteDbiMemory.
95// Objects can be declared in a header and shared between both dbi and dac.
96// Consider using DacDbiArrayList<T> instead of custom allocations.
97
98// Error handling:
99// Any call on the interface may fail. For example, the data-target may not have access to the necessary memory.
100// Methods should throw on error.
101//
102// #Enumeration
103// General rules about Enumerations:
104// - Do not assume that enumerations exposed here are in any particular order.
105// - many enumerations also correspond to Load/Unload events. Since load/unload aren't atomic with publishing
106// in an enumeration, this is a Total Ordering of things:
107// a) object shows up in enumeration
108// b) load event.
109// c) ... steady state ...
110// d) object removed from DacDbi enumeration;
111// Any existing handles we get beyond this are explicitly associated with a Cordb* object; which can be
112// neutered on the unload event by Dbi.
113// e) unload event.
114// - Send after it's reachability from other objects is broken. (Eg, For AppDomain unload
115// means no threads left in that appdomain)
116// - Send before it's deleted (so VMPTR is still valid; not yet recycled).
117// - Send early enough that property access can at least gracefully fail. (eg,
118// Module::GetName should either return the name, or fail)
119//
120// Cordb must neuter any Cordb objects that have any pre-existing handles to the object.
121// After this point, gauranteed that nobody can discover the VMPTR any more:
122// - doesn't show up in enumerations (so can't be discoverered implicitly)
123// - object should not be discoverable by other objects in VM.
124// - any Cordb object that already had it would be neutered by Dbi.
125// - Therefore nothing should even be asking Dac for it.
126// f) object deleted.
127// Think of it like this: The event occurs to let you know that the enumeration has been updated.
128//
129// A robust debugger should not rely on events for correctness. For example,
130// a corrupt debuggee may send:
131// 1) multiple load events. (if target repeats due to an issue)
132// 2) no load event and only an unload event. (if target fails inbetween
133// publish (a) and load (b), and then backout code sends the unload).
134// 3) no unload event. (eg, if target is rudely killed)
135// 4) multiple unload events (if target repeats due to bug)
136//
137// This satisfies the following rules:
138// - once you get the load event, you can find the object via enumeration
139// - once an item is discoverable, it must immediately show up in the enumeration.
140// - once you get the unload event, the object is dead and can't be rediscovered via enumeration.
141//
142// This is an issue even for well-behaved targets. Imagine if a debugger attaches right after
143// an unload event is sent. We don't want the debugger to enumerate and re-discover the
144// unloaded object because now that the unload event is already sent, the debugger won't get
145// any further notification of when the object is deleted in the target.
146// Thus it's valuable for the debugger to have debug-only checks after unload events to assert
147// that the object is no longer discoverable.
148//
149//.............................................................................
150// The purpose of this object is to provide EE funcationality back to
151// the debugger. This represents the entire set of EE functions used
152// by the debugger.
153//
154// We will make this interface larger over time to grow the functionality
155// between the EE and the Debugger.
156//
157//
158//-----------------------------------------------------------------------------
159class IDacDbiInterface
160{
161public:
162 class IStringHolder;
163
164 // The following tag tells the DD-marshalling tool to start scanning.
165 // BEGIN_MARSHAL
166
167 //-----------------------------------------------------------------------------
168 // Functions to control the behavior of the DacDbi implementation itself.
169 //-----------------------------------------------------------------------------
170
171 //
172 // Check whether the version of the DBI matches the version of the runtime.
173 // This is only called when we are remote debugging. On Windows, we should have checked all the
174 // versions before we call any API on the IDacDbiInterface. See
175 // code:CordbProcess::CordbProcess#DBIVersionChecking for more information on version checks.
176 //
177 // Return Value:
178 // S_OK on success.
179 //
180 // Notes:
181 // THIS MUST BE THE FIRST API ON THE INTERFACE!
182 //
183 virtual
184 HRESULT CheckDbiVersion(const DbiVersion * pVersion) = 0;
185
186 //
187 // Flush the DAC cache. This should be called when target memory changes.
188 //
189 //
190 // Return Value:
191 // S_OK on success.
192 //
193 // Notes:
194 // If this fails, the interface is in an undefined state.
195 // This must be called anytime target memory changes, else all other functions
196 // (besides Destroy) may yield out-of-date or semantically incorrect results.
197 //
198 virtual
199 HRESULT FlushCache() = 0;
200
201 //
202 // Control DAC's checking of the target's consistency. Specifically, if this is disabled then
203 // ASSERTs in VM code are ignored. The default is disabled, since DAC should do it's best to
204 // return results even with a corrupt or unsyncrhonized target. See
205 // code:ClrDataAccess::TargetConsistencyAssertsEnabled for more details.
206 //
207 // When testing with a non-corrupt and properly syncrhonized target, this should be enabled to
208 // help catch bugs.
209 //
210 // Arguments:
211 // fEnableAsserts - whether ASSERTs should be raised when consistency checks fail (_DEBUG
212 // builds only)
213 //
214 // Notes:
215 // In the future we may want to extend DAC target consistency checks to be retail checks
216 // (exceptions) as well. We'll also need a mechanism for disabling them (eg. when an advanced
217 // user wants to try to get a result anyway even though the target is inconsistent). In that
218 // case we'll want an additional argument here for enabling/disabling the throwing of
219 // consistency failures exceptions (this is independent from asserts - there are legitimate
220 // scenarios for all 4 combinations).
221 //
222 virtual
223 void DacSetTargetConsistencyChecks(bool fEnableAsserts) = 0;
224
225 //
226 // Destroy the interface object. The client should call this when it's done
227 // with the IDacDbiInterface to free up any resources.
228 //
229 // Return Value:
230 // None.
231 //
232 // Notes:
233 // The client should not call anything else on this interface after Destroy.
234 //
235 virtual
236 void Destroy() = 0;
237
238 //-----------------------------------------------------------------------------
239 // General purpose target inspection functions
240 //-----------------------------------------------------------------------------
241
242 //
243 // Query if Left-side is started up?
244 //
245 //
246 // Return Value:
247 // BOOL whether Left-side is intialized.
248 //
249 // Notes:
250 // If the Left-side is not yet started up, then data in the LS is not yet initialized enough
251 // for us to make meaningful queries, but the runtime will fire "Startup Exception" when it is.
252 //
253 // If the left-side is started up, then data is ready. (Although data may be temporarily inconsistent,
254 // see DataSafe). We may still get a Startup Exception in these cases, but it can be ignored.
255 //
256 virtual
257 BOOL IsLeftSideInitialized() = 0;
258
259
260 //
261 // Get an LS Appdomain via an AppDomain unique ID.
262 // Fails if the AD is not found or if the ID is invalid.
263 //
264 // Arguments:
265 // appdomainId - "unique appdomain ID". Must be a valid Id.
266 //
267 // Return Value:
268 // VMPTR_AppDomain for the corresponding AppDomain ID. Else throws.
269 //
270 // Notes:
271 // This query is based off the lifespan of the AppDomain from the VM's perspective.
272 // The AppDomainId is most likely obtained from an AppDomain-Created debug events.
273 // An AppDomainId is unique for the lifetime of the VM.
274 // This is the inverse function of GetAppDomainId().
275 //
276 virtual
277 VMPTR_AppDomain GetAppDomainFromId(ULONG appdomainId) = 0;
278
279
280 //
281 // Get the AppDomain ID for an AppDomain.
282 //
283 // Arguments:
284 // vmAppDomain - VM pointer to the AppDomain object of interest
285 //
286 // Return Value:
287 // AppDomain ID for appdomain. Else throws.
288 //
289 // Notes:
290 // An AppDomainId is unique for the lifetime of the VM. It is non-zero.
291 //
292 virtual
293 ULONG GetAppDomainId(VMPTR_AppDomain vmAppDomain) = 0;
294
295 //
296 // Get the managed AppDomain object for an AppDomain.
297 //
298 // Arguments:
299 // vmAppDomain - VM pointer to the AppDomain object of interest
300 //
301 // Return Value:
302 // objecthandle for the managed app domain object or the Null VMPTR if there is no
303 // object created yet
304 //
305 // Notes:
306 // The AppDomain managed object is lazily constructed on the AppDomain the first time
307 // it is requested. It may be NULL.
308 //
309 virtual
310 VMPTR_OBJECTHANDLE GetAppDomainObject(VMPTR_AppDomain vmAppDomain) = 0;
311
312 //
313 // Determine if the specified AppDomain is the default domain
314 //
315 // Arguments:
316 // vmAppDomain - VM pointer to the AppDomain ojbect of interest
317 //
318 // Return Value:
319 // TRUE if this is the default appdomain, else FALSE.
320 //
321 // Notes:
322 // The default domain is the only one which cannot be unloaded and exists for the life
323 // of the process.
324 // A well behaved target only has 1 default domain.
325 //
326 virtual
327 BOOL IsDefaultDomain(VMPTR_AppDomain vmAppDomain) = 0;
328
329
330 virtual
331 void GetAssemblyFromDomainAssembly(VMPTR_DomainAssembly vmDomainAssembly, OUT VMPTR_Assembly * vmAssembly) = 0;
332
333 //
334 // Determines whether the runtime security system has assigned full-trust to this assembly.
335 //
336 // Arguments:
337 // vmDomainAssembly - VM pointer to the assembly in question.
338 //
339 // Return Value:
340 // Returns trust status for the assembly.
341 // Throws on error.
342 //
343 // Notes:
344 // Of course trusted malicious code in the process could always cause this API to lie. However,
345 // an assembly loaded without full-trust should have no way of causing this API to return true.
346 //
347 virtual
348 BOOL IsAssemblyFullyTrusted(VMPTR_DomainAssembly vmDomainAssembly) = 0;
349
350
351 //
352 // Get the full AD friendly name for the given EE AppDomain.
353 //
354 // Arguments:
355 // vmAppDomain - VM pointer to the AppDomain.
356 // pStrName - required out parameter where the name will be stored.
357 //
358 // Return Value:
359 // None. On success, sets the string via the holder. Throws on error.
360 // This either sets pStrName or Throws. It won't do both.
361 //
362 // Notes:
363 // AD names have an unbounded length. AppDomain friendly names can also change, and
364 // so callers should be prepared to listen for name-change events and requery.
365 // AD names are specified by the user.
366 //
367 virtual
368 void GetAppDomainFullName(
369 VMPTR_AppDomain vmAppDomain,
370 IStringHolder * pStrName) = 0;
371
372
373 //
374 // #ModuleNames
375 //
376 // Modules / Assemblies have many different naming schemes:
377 //
378 // 1) Metadata Scope name: All modules have metadata, and each metadata scope has a name assigned
379 // by the creator of that scope (eg, the compiler). This usually is similar to the filename, but could
380 // be arbitrary.
381 // eg: "Foo"
382 //
383 // 2) FileRecord: the File record entry in the manifest module's metadata (table 0x26) for this module.
384 // eg: "Foo"
385 //
386 // 3) Managed module path: This is path that the image was loaded from. Eg, "c:\foo.dll". For non-file
387 // based modules (like in-memory, dynamic), there is no file path. The specific path is determined by
388 // fusion / loader policy.
389 // eg: "c:\foo.dll"
390 //
391 // 4) GAC path: If the module is loaded from the GAC, this is the path on disk into the gac cache that
392 // the image was pulled from.
393 // eg: "
394 //
395 // 5) Ngen path: If the module was ngenned, this is the path on disk into the ngen cache that the image
396 // was pulled from.
397 // eg:
398 //
399 // 6) Fully Qualified Assembly Name: this is an abstract name, which the CLR (fusion / loader) will
400 // resolve (to a filename for file-based modules). Managed apps may need to deal in terms of FQN,
401 // but the debugging services generally avoid them.
402 // eg: "Foo, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL".
403 //
404
405
406 //
407 // Get the "simple name" of a module. This is a heuristic within the CLR to return a simple,
408 // not-well-specified, but meaningful, name for a module.
409 //
410 // Arguments:
411 // vmModule - module to query
412 // pStrFileName - string holder to get simple name.
413 //
414 // Return Value:
415 // None, but pStrFilename will be initialized upon return.
416 // Throws if there was a problem reading the data with DAC or if there is an OOM exception,
417 // in which case no string was stored into pStrFilename.
418 //
419 // Notes:
420 // See code:#ModuleNames for an overview on module names.
421 //
422 // This is really just using code:Module::GetSimpleName.
423 // This gives back a meaningful name, which is generally some combination of the metadata
424 // name of the FileRecord name. This is important because it's valid even when a module
425 // doesn't have a filename.
426 //
427 // The simple name does not have any meaning. It is not a filename, does not necessarily have any
428 // relationship to the filename, and it's not necesarily the metadata name.
429 // Do not use the simple name for anything other than as a pretty string to give the an end user.
430 //
431 virtual
432 void GetModuleSimpleName(VMPTR_Module vmModule, IStringHolder * pStrFilename) = 0;
433
434
435 //
436 // Get the full path and file name to the assembly's manifest module.
437 //
438 // Arguments:
439 // vmAssembly - VM pointer to the Assembly.
440 // pStrFilename - required out parameter where the filename will be stored.
441 //
442 // Return Value:
443 // TRUE on success, in which case the filename was stored into pStrFilename
444 // FALSE if the assembly has no filename (eg. for in-memory assemblies), in which
445 // case an empty string was stored into pStrFilename.
446 // Throws if there was a problem reading the data with DAC, in which case
447 // no string was stored into pStrFilename.
448 //
449 // Notes:
450 // See code:#ModuleNames for an overview on module names.
451 //
452 // Normally this is just the filename from which the dll containing the assembly was
453 // loaded. In the case of multi-module assemblies, this is the filename for the
454 // manifest module (the one containing the assembly manifest). For in-memory
455 // assemblies (eg. those loaded from a Byte[], and those created by Reflection.Emit
456 // which will not be saved to disk) there is no filename. In that case this API
457 // returns an empty string.
458 //
459 virtual
460 BOOL GetAssemblyPath(VMPTR_Assembly vmAssembly,
461 IStringHolder * pStrFilename) = 0;
462
463
464 // get a type def resolved across modules
465 // Arguments:
466 // input: pTypeRefInfo - domain file and type ref from the referencing module
467 // output: pTargetRefInfo - domain file and type def from the referenced type (this may
468 // come from a module other than the referencing module)
469 // Note: throws
470 virtual
471 void ResolveTypeReference(const TypeRefData * pTypeRefInfo,
472 TypeRefData * pTargetRefInfo) = 0;
473 //
474 // Get the full path and file name to the module (if any).
475 //
476 // Arguments:
477 // vmModule - VM pointer to the module.
478 // pStrFilename - required out parameter where the filename will be stored.
479 //
480 // Return Value:
481 // TRUE on success, in which case the filename was stored into pStrFilename
482 // FALSE the module has no filename (eg. for in-memory assemblies), in which
483 // case an empty string was stored into pStrFilename.
484 // Throws an exception if there was a problem reading the data with DAC, in which case
485 // no string was stored into pStrFilename.
486 //
487 // Notes:
488 // See code:#ModuleNames for an overview on module names.
489 //
490 // Normally this is just the filename from which the module was loaded.
491 // For in-memory module (eg. those loaded from a Byte[], and those created by Reflection.Emit
492 // which will not be saved to disk) there is no filename. In that case this API
493 // returns an empty string. Consider GetModuleSimpleName in those cases.
494 //
495 // We intentionally don't use the function name "GetModuleFileName" here because
496 // winbase #defines that token (along with many others) to have an A or W suffix.
497 //
498 virtual
499 BOOL GetModulePath(VMPTR_Module vmModule,
500 IStringHolder * pStrFilename) = 0;
501
502
503 //
504 // Get the full path and file name to the ngen image for the module (if any).
505 //
506 // Arguments:
507 // vmModule - VM pointer to the module.
508 // pStrFilename - required out parameter where the filename will be stored.
509 //
510 // Return Value:
511 // TRUE on success, in which case the filename was stored into pStrFilename
512 // FALSE the module has no filename (eg. for in-memory assemblies), in which
513 // case an empty string was stored into pStrFilename.
514 // Throws an exception if there was a problem reading the data with DAC, in which case
515 // no string was stored into pStrFilename.
516 //
517 // Notes:
518 // See code:#ModuleNames for an overview on module names.
519 //
520 virtual
521 BOOL GetModuleNGenPath(VMPTR_Module vmModule,
522 IStringHolder * pStrFilename) = 0;
523
524
525
526 // Get the metadata for the target module
527 //
528 // Arguments:
529 // vmModule - target module to get metadata for.
530 // pTargetBuffer - Out parameter to get target-buffer for metadata. Gauranteed to be non-empty on
531 // return. This will throw CORDBG_E_MISSING_METADATA hr if the buffer is empty.
532 // This does not gaurantee that the buffer is readable. For example, in a minidump, buffer's
533 // memory may not be present.
534 //
535 // Notes:
536 // Each module's metadata exists as a raw buffer in the target. This finds that target buffer and
537 // returns it. The host can then use OpenScopeOnMemory to create an instance of the metadata in
538 // the host process space.
539 //
540 // For dynamic modules, the CLR will eagerly serialize the metadata at "debuggable" points. This
541 // could be after each type is loaded; or after a bulk update.
542 // For non-dynamic modules (both in-memory and file-based), the metadata exists in the PEFile's image.
543 //
544 // Failure cases:
545 // This should succeed in normal, live-debugging scenarios. However, common failure paths here would be:
546 //
547 // 1. Data structures are intact, but Unable to even find the TargetBuffer in the target. In this
548 // case Metadata is truly missing. Likely means:
549 // - target is in the middle of generating metadata for a large bulk operation. (For example, attach
550 // to a TypeLibConverter using Ref.Emit to emit a module for a very large .tlb file).
551 // - corrupted target,
552 // - or the target had some error(out-of-memory?) generating the metadata.
553 // This throws CORDBG_E_MISSING_METADATA.
554 //
555 // 2. Target buffer is found, but memory it describes is not present. Likely means a minidump
556 // scenario with missing memory. Client should use alternative metadata location techniques (such as
557 // an ImagePath to locate the original image and then pulling metadata from that file).
558 //
559 virtual
560 void GetMetadata(VMPTR_Module vmModule, OUT TargetBuffer * pTargetBuffer) = 0;
561
562
563 // Definitions for possible symbol formats
564 // This is equivalent to code:ESymbolFormat in the runtime
565 typedef enum
566 {
567 kSymbolFormatNone, // No symbols available
568 kSymbolFormatPDB, // PDB symbol format - use diasymreader.dll
569 kSymbolFormatILDB, // ILDB symbol format - use ildbsymlib
570 } SymbolFormat;
571
572 //
573 // Get the in-memory symbol (PDB/ILDB) buffer in the target if present.
574 //
575 // Arguments:
576 // vmModule- module to query for.
577 // pTargetBuffer - out parameter to get buffer in target of symbols. If no symbols, pTargetBuffer is empty on return.
578 // pSymbolFormat - out parameter to get the format of the symbols.
579 //
580 // Returns:
581 // 1) If there are in-memory symbols for the given module, pTargetBuffer is set to the buffer describing
582 // the symbols and pSymbolFormat is set to indicate PDB or ILDB format. This buffer can then be read,
583 // converted into an IStream, and passed to ISymUnmanagedBinder::CreateReaderForStream.
584 // 2) If the target is valid, but there is no symbols for the module, then pTargetBuffer->IsEmpty() == true
585 // and *pSymbolFormat == kSymbolFormatNone.
586 // 3) Else, throws exception.
587 //
588 //
589 // Notes:
590 // For file-based modules, PDBs are normally on disk and the debugger retreieves them via a symbol
591 // path without any help from ICorDebug.
592 // However, in some cases, the PDB is stored in-memory and so the debugger needs ICorDebug. Common
593 // cases include:
594 // - dynamic modules generated with reflection-emit.
595 // - in-memory modules loaded by Load(Byte[],Byte[]), which provide the PDB as a byte[].
596 // - hosted modules where the host (such as SQL) store the PDB.
597 //
598 // In all cases, this can commonly fail. Executable code does not need to have a PDB.
599 virtual
600 void GetSymbolsBuffer(VMPTR_Module vmModule, OUT TargetBuffer * pTargetBuffer, OUT SymbolFormat * pSymbolFormat) = 0;
601
602 //
603 // Get properties for a module
604 //
605 // Arguments:
606 // vmModule - vm handle to a module
607 // pData - required out parameter which will be filled out with module properties
608 //
609 // Notes:
610 // See definition of DomainFileInfo for more details about what properties
611 // this gives back.
612 virtual
613 void GetModuleData(VMPTR_Module vmModule, OUT ModuleInfo * pData) = 0;
614
615
616 //
617 // Get properties for a DomainFile
618 //
619 // Arguments:
620 // vmDomainFile - vm handle to a DomainFile
621 // pData - required out parameter which will be filled out with module properties
622 //
623 // Notes:
624 // See definition of DomainFileInfo for more details about what properties
625 // this gives back.
626 virtual
627 void GetDomainFileData(VMPTR_DomainFile vmDomainFile, OUT DomainFileInfo * pData) = 0;
628
629 virtual
630 void GetModuleForDomainFile(VMPTR_DomainFile vmDomainFile, OUT VMPTR_Module * pModule) = 0;
631
632 //.........................................................................
633 // These methods were the methods that DBI was calling from IXClrData in V2.
634 // We imported them over to this V3 interface so that we can sever all ties between DBI and the
635 // old IXClrData.
636 //
637 // The exact semantics of these are whatever their V2 IXClrData counterpart did.
638 // We may eventually migrate these to their real V3 replacements.
639 //.........................................................................
640
641 // "types" of addresses. This is taken exactly from the definition, but renamed to match
642 // CLR coding conventions.
643 typedef enum
644 {
645 kAddressUnrecognized,
646 kAddressManagedMethod,
647 kAddressRuntimeManagedCode,
648 kAddressRuntimeUnmanagedCode,
649 kAddressGcData,
650 kAddressRuntimeManagedStub,
651 kAddressRuntimeUnmanagedStub,
652 } AddressType;
653
654 //
655 // Get the "type" of address.
656 //
657 // Arguments:
658 // address - address to query type.
659 //
660 // Return Value:
661 // Type of address. Throws on error.
662 //
663 // Notes:
664 // This is taken exactly from the IXClrData definition.
665 // This is provided for V3 compatibility to support Interop-debugging.
666 // This should eventually be deprecated.
667 //
668 virtual
669 AddressType GetAddressType(CORDB_ADDRESS address) = 0;
670
671
672 //
673 // Query if address is a CLR stub.
674 //
675 // Arguments:
676 // address - Target address to query for.
677 //
678 //
679 // Return Value:
680 // true if the address is a CLR stub.
681 //
682 // Notes:
683 // This is used to implement ICorDebugProcess::IsTransitionStub
684 // This yields true if the address is claimed by a CLR stub manager, or if the IP is in mscorwks.
685 // Conceptually, This should eventually be merged with GetAddressType().
686 //
687 virtual
688 BOOL IsTransitionStub(CORDB_ADDRESS address) = 0;
689
690 //.........................................................................
691 // Get the values of the JIT Optimization and EnC flags.
692 //
693 // Arguments:
694 // vmDomainFile - (input) VM DomainFile (module) for which we are retrieving flags
695 // pfAllowJITOpts - (mandatory output) true iff this is not compiled for debug,
696 // i.e., without optimization
697 // pfEnableEnc - (mandatory output) true iff this module has EnC enabled
698 //
699 // Return Value:
700 // Returns on success. Throws on failure.
701 //
702 // Notes:
703 // This is used to implement both ICorDebugModule2::GetJitCompilerFlags and
704 // ICorDebugCode2::GetCompilerFlags.
705 //.........................................................................
706
707 virtual
708 void GetCompilerFlags(
709 VMPTR_DomainFile vmDomainFile,
710 OUT BOOL * pfAllowJITOpts,
711 OUT BOOL * pfEnableEnC) = 0;
712
713 //.........................................................................
714 // Set the values of the JIT optimization and EnC flags.
715 //
716 // Arguments:
717 // vmDomainFile - (input) VM DomainFile (module) for which we are retrieving flags
718 // pfAllowJITOpts - (input) true iff this should not be compiled for debug,
719 // i.e., without optimization
720 // pfEnableEnc - (input) true iff this module should have EnC enabled. If this is
721 // false, no change is made to the EnC flags. In other words, once EnC is enabled,
722 // there is no way to disable it.
723 //
724 // Return Value:
725 // S_OK on success and all bits were set.
726 // CORDBG_S_NOT_ALL_BITS_SET - if not all bits are set. Must use GetCompileFlags to
727 // determine which bits were set.
728 // CORDBG_E_CANT_CHANGE_JIT_SETTING_FOR_ZAP_MODULE - if module is ngenned.
729 // Throw on other errors.
730 //
731 // Notes:
732 // Caller can only use this at module-load before any methods are jitted.
733 // This may be called multiple times.
734 // This is used to implement both ICorDebugModule2::SetJitCompilerFlags and
735 // ICorDebugModule::EnableJITDebugging.
736 //.........................................................................
737
738 virtual
739 HRESULT SetCompilerFlags(VMPTR_DomainFile vmDomainFile,
740 BOOL fAllowJitOpts,
741 BOOL fEnableEnC) = 0;
742
743 //
744 // Enumerate all AppDomains in the process.
745 //
746 // Arguments:
747 // fpCallback - callback to invoke on each appdomain
748 // pUserData - user data to supply for each callback.
749 //
750 // Return Value:
751 // Returns on success. Throws on error.
752 //
753 // Notes:
754 // Enumerates all appdomains in the process, including the Default-domain.
755 // Appdomains must show up in this list before the AD Load event is sent, and before
756 // that appdomain is discoverable from the debugger.
757 // See enumeration rules for details.
758 //
759 typedef void (*FP_APPDOMAIN_ENUMERATION_CALLBACK)(VMPTR_AppDomain vmAppDomain, CALLBACK_DATA pUserData);
760 virtual
761 void EnumerateAppDomains(FP_APPDOMAIN_ENUMERATION_CALLBACK fpCallback,
762 CALLBACK_DATA pUserData) = 0;
763
764
765 //
766 // Eunmerate all Assemblies in an appdomain. Enumerations is in load-order
767 //
768 // Arguments:
769 // vmAppDomain - domain in which to enumerate
770 // fpCallback - address to query type.
771 // pUserData - required out parameter for type of address.
772 //
773 // Return Value:
774 // Returns on success. Throws on error.
775 //
776 // Notes:
777 // Enumerates all executable assemblies (both shared and unshared) within an appdomain.
778 // This does not include inspection-only assemblies because those are just data and
779 // not executable (eg, they'll never show up on the stack and you can't set a breakpoint in them).
780 // This enumeration needs to be consistent with load/unload events.
781 // See enumeration rules for details.
782 //
783 // The order of the enumeration is the order the assemblies where loaded.
784 // Ultimately, the debugger needs to be able to tell the user the load
785 // order of assemblies (it can do this with native dlls). Since
786 // managed assembliees don't 1:1 correspond to native dlls, debuggers
787 // need this information from the runtime.
788 //
789
790 typedef void (*FP_ASSEMBLY_ENUMERATION_CALLBACK)(VMPTR_DomainAssembly vmDomainAssembly, CALLBACK_DATA pUserData);
791 virtual
792 void EnumerateAssembliesInAppDomain(VMPTR_AppDomain vmAppDomain,
793 FP_ASSEMBLY_ENUMERATION_CALLBACK fpCallback,
794 CALLBACK_DATA pUserData) = 0;
795
796
797
798 //
799 // Callback function for EnumerateModulesInAssembly
800 //
801 // This can throw on error.
802 //
803 // Arguments:
804 // vmModule - new module from the enumeration
805 // pUserData - user data passed to EnumerateModulesInAssembly
806 typedef void (*FP_MODULE_ENUMERATION_CALLBACK)(VMPTR_DomainFile vmModule, CALLBACK_DATA pUserData);
807
808 //
809 // Enumerates all the code Modules in an assembly.
810 //
811 // Arguments:
812 // vmAssembly - assembly to enumerate within
813 // fpCallback - callback function to invoke on each module
814 // pUserData - arbitrary data passed to the callback
815 //
816 // Notes:
817 // This only enumerates "code" modules (ie, modules that have executable code in them). That
818 // includes normal file-based, ngenned, in-memory, and even dynamic modules.
819 // That excludes:
820 // - Resource modules (which have no code or metadata)
821 // - Inspection-only modules. These are viewed as pure data from the debugger's perspective.
822 //
823 virtual
824 void EnumerateModulesInAssembly(
825 VMPTR_DomainAssembly vmAssembly,
826 FP_MODULE_ENUMERATION_CALLBACK fpCallback,
827 CALLBACK_DATA pUserData) = 0;
828
829
830
831 //
832 // When stopped at an event, request a synchronization.
833 //
834 //
835 // Return Value:
836 // Returns on success. Throws on error.
837 //
838 // Notes:
839 // Call this when an event is dispatched (eg, LoadModule) to request the runtime
840 // synchronize. This does a cooperative sync with the LS. This is not an async break
841 // and can not be called at arbitrary points.
842 // This primitive lets the LS always take the V3 codepath and defer decision making to the RS.
843 // The V2 behavior is to call this after every event (Since that's what V2 did).
844 // The V3 behavior is to never call this.
845 //
846 // If this is called, the LS will sync and we will get a SyncComplete.
847 //
848 // This is also like a precursor to "AsyncBreakAllOtherThreads"
849 //
850 virtual
851 void RequestSyncAtEvent() = 0;
852
853 // Sets a flag inside LS.Debugger that indicates that
854 // 1. all "first chance exception" events should not be sent to the debugger
855 // 2. "exception handler found" events for exceptions never crossing JMC frames should not be sent to the debugger
856 //
857 // Arguments:
858 // sendExceptionsOutsideOfJMC - new value for the flag Debugger::m_sendExceptionsOutsideOfJMC.
859 //
860 // Return Value:
861 // Returns error code, never throws.
862 //
863 // Note: This call is used by ICorDebugProcess8.EnableExceptionCallbacksOutsideOfMyCode.
864 virtual
865 HRESULT SetSendExceptionsOutsideOfJMC(BOOL sendExceptionsOutsideOfJMC) = 0;
866
867 //
868 // Notify the debuggee that a debugger atach is pending.
869 //
870 // Arguments:
871 // None
872 //
873 // Return Value:
874 // Returns on success. Throws on error.
875 //
876 // Notes:
877 // Attaching means that CORDebuggerPendingAttach() will now return true.
878 // This doesn't do anything else (eg, no fake events).
879 //
880 // @dbgtodo- still an open Feature-Crew decision how this is exposed publicly.
881 virtual
882 void MarkDebuggerAttachPending() = 0;
883
884 //
885 // Notify the debuggee that a debugger is attached / detached.
886 //
887 // Arguments:
888 // fAttached - true if we're attaching, false if we're detaching.
889 //
890 // Return Value:
891 // Returns on success. Throws on error.
892 //
893 // Notes:
894 // Attaching means that CorDebuggerAttached() will now return true.
895 // This doesn't do anything else (eg, no fake events).
896 // This lets the V3 codepaths invade the LS to subscribe to events.
897 //
898 // @dbgtodo- still an open Feature-Crew decision how this is exposed publicly.
899 virtual
900 void MarkDebuggerAttached(BOOL fAttached) = 0;
901
902
903
904 //
905 // Hijack a thread. This will effectively do a native func-eval of the thread to set the IP
906 // to a hijack stub and push the parameters.
907 //
908 // Arguments:
909 // dwThreadId - OS thread to hijack. This must be consistent with pRecord and pOriginalContext
910 // pRecord - optional pointer to Exception record. Required if this is hijacked at an exception.
911 // NULL if this is hijacked at a managed IP.
912 // pOriginalContext - optional pointer to buffer to receive the context that the thread is hijacked from.
913 // The caller can use this to either restore the hijack or walk the hijack.
914 // cbSizeContext - size in bytes of buffer pointed to by pContext
915 // reason - reason code for the hijack. The hijack stub can then delegate to the proper hijack.
916 // pUserData - arbitrary data passed through to hijack. This is reason-depedendent.
917 // pRemoteContextAddr - If non-NULL this receives the remote address where the CONTEXT was written in the
918 // in the debuggee.
919 //
920 // Assumptions:
921 // Caller must guarantee this is safe.
922 // This is intended to be used at a thread that either just had an exception or is at a managed IP.
923 // If this is hijacked at an exception, client must cancel the exception (gh / DBG_CONTINUE)
924 // so that the OS exception processing doesn't interfere with the hijack.
925 //
926 // Notes:
927 // Hijack is hard, so we want 1 hijack stub that handles all our hijacking needs.
928 // This lets us share:
929 // - assembly stubs (which are very platform specific)
930 // - hijacking / restoration mechanics,
931 // - making the hijack walkable via the stackwalker.
932 //
933 // Hijacking can be used to implement: func-eval, FE abort, Synchronizing,
934 // dispatching Unhandled Exception notifications.
935 //
936 // Nesting: Since Hijacking passes the key state off to the hijacked thread, (such as original
937 // context to be used with restoring the hijack), the raw hijacking nests just like function
938 // calls. However, the client may need to keep additional state to handle nesting. For example,
939 // nested hijacks will require the client to track multiple CONTEXT*.
940 //
941 // If the thread is in jitted code, then the hijack needs to cooperate with the in-process
942 // stackwalker that the GC uses. It must be in cooperative mode, and push a Frame on the
943 // frame chain to protect the managed frames it hijacked from before it goes to preemptive mode.
944
945 virtual
946 void Hijack(
947 VMPTR_Thread vmThread,
948 ULONG32 dwThreadId,
949 const EXCEPTION_RECORD * pRecord,
950 T_CONTEXT * pOriginalContext,
951 ULONG32 cbSizeContext,
952 EHijackReason::EHijackReason reason,
953 void * pUserData,
954 CORDB_ADDRESS * pRemoteContextAddr) = 0;
955
956
957 //
958 // Callback function for connection enumeration.
959 //
960 // Arguments:
961 // id - the connection ID.
962 // pName - the name of the connection.
963 // pUserData - user data supplied to EnumerateConnections
964 typedef void (*FP_CONNECTION_CALLBACK)(DWORD id, LPCWSTR pName, CALLBACK_DATA pUserData);
965
966 //
967 // Enumerate all the Connections in the process.
968 //
969 // Arguments:
970 // fpCallback - callback to invoke for each connection
971 // pUserData - random user data to pass to callback.
972 //
973 // Notes:
974 // This enumerates all the connections. The host notifies the debugger of Connections
975 // via the ICLRDebugManager interface.
976 // ICorDebug has no interest in connections. It's merely the transport between the host and the debugger.
977 // Ideally, that transport would be more general.
978 //
979 // V2 Attach would provide faked up CreateConnection, ChangeConnection events on attach.
980 // This enumeration ability allows V3 to emulate that behavior.
981 //
982
983 //
984 // Enumerate all threads in the target.
985 //
986 // Arguments:
987 // fpCallback - callback function to invoke on each thread.
988 // pUserData - arbitrary user data supplied to each callback.
989 //
990 // Notes:
991 // This enumerates the ThreadStore in the target, which is all the Thread* objects.
992 // This includes threads that have entered the runtime. This may include threads
993 // even before that thread has executed IL and after that thread no longer has managed
994 // code on its stack.
995
996 // Callback invoked for each thread.
997 typedef void (*FP_THREAD_ENUMERATION_CALLBACK)(VMPTR_Thread vmThread, CALLBACK_DATA pUserData);
998
999 virtual
1000 void EnumerateThreads(FP_THREAD_ENUMERATION_CALLBACK fpCallback, CALLBACK_DATA pUserData) = 0;
1001
1002
1003 // Check if the thread is dead
1004 //
1005 // Arguments:
1006 // vmThread - valid thread to check if it's dead.
1007 //
1008 // Returns: true if the thread is "dead", which means it can never call managed code again.
1009 //
1010 // Notes:
1011 // #IsThreadMarkedDead
1012 // Threads shutdown states are:
1013 // 1) Thread is running managed code normally. Thread eventually exits all managed code and
1014 // gets to a point where it will never call managed code again.
1015 // 2) Thread is marked as dead.
1016 // - For threads created outside of the runtime (such as a native thread that wanders into
1017 // managed code), this mark can happen in DllMain(ThreadDetach)
1018 // - For threads created by the runtime (eg, System.Threading.Thread.Start), this may be done
1019 // at the top of the threads stack after it calls the user's Thread-Proc.
1020 // 3) MAYBE Native thread exits at this point (or it may not). This would be the common case
1021 // for threads created outside the runtime.
1022 // 4) Thread exit event is sent.
1023 // - For threads created by the runtime, this may be sent at the top of the thread's
1024 // stack (or even when we know that the thread will never execute managed code again)
1025 // - For threads created outside the runtime, this is more difficult. A thread can
1026 // call into managed code and then return, and then call back into managed code at a
1027 // later time (The finalizer does this!). So it's not clear when the native thread
1028 // actually exits and will never call managed code again. The only hook we have for
1029 // this is DllMain(Thread-Detach). We can mark bits in DllMain, but we can't send
1030 // debugger notifications (too dangerous from such a restricted context).
1031 // So we may mark the thread as dead, but then sweep later (perhaps on the finalizer
1032 // thread), and thus send the Exit events later.
1033 // 5) Native thread may exit at this point. This is the common case for threads created by
1034 // the runtime.
1035 //
1036 // The underlying native thread may have exited at eitehr #3 or #5. Because of this
1037 // flexibility, we don't want to rely on native thread exit events.
1038 // This function checks if a Thread is passed state #2 (marked as dead). The key invariant
1039 // is that once a thread is marked as dead:
1040 // - it can never call managed code again.
1041 // - it should not be discoverable by DacDbi enumerations.
1042 //
1043 // DBI should prefer relying on IsThreadMarkedDead rather than event notifications (either
1044 // managed or native) because tracking events requires that DBI maintain state, which means
1045 // that attach + dump cases may break. For example, we want a full dump at the ExitThread
1046 // event to have the same view as a live process at the ExitThread event.
1047 //
1048 // We avoid relying on the native thread exit notifications because:
1049 // - that's a specific feature of the Win32 debugging API that may not be available on other platforms.
1050 // - the only native events the pipeline gets are Exceptions.
1051 //
1052 // Whether a thread is dead can be inferred from the ICorDebug API. However, we have this
1053 // on DacDbi to ensure that this definition is consistent with the other DacDbi methods,
1054 // especially the enumeration and discovery rules.
1055 virtual
1056 bool IsThreadMarkedDead(VMPTR_Thread vmThread) = 0;
1057
1058
1059 //
1060 // Return the handle of the specified thread.
1061 //
1062 // Arguments:
1063 // vmThread - the specified thread
1064 //
1065 // Return Value:
1066 // the handle of the specified thread
1067 //
1068 // @dbgtodo- this should go away in V3. This is useless on a dump.
1069
1070 virtual
1071 HANDLE GetThreadHandle(VMPTR_Thread vmThread) = 0;
1072
1073 //
1074 // Return the object handle for the managed Thread object corresponding to the specified thread.
1075 //
1076 // Arguments:
1077 // vmThread - the specified thread
1078 //
1079 // Return Value:
1080 // This function returns the object handle for the managed Thread object corresponding to the
1081 // specified thread. The return value may be NULL if a managed Thread object has not been created
1082 // for the specified thread yet.
1083 //
1084
1085 virtual
1086 VMPTR_OBJECTHANDLE GetThreadObject(VMPTR_Thread vmThread) = 0;
1087
1088 //
1089 // Set and reset the TSNC_DebuggerUserSuspend bit on the state of the specified thread
1090 // according to the CorDebugThreadState.
1091 //
1092 // Arguments:
1093 // vmThread - the specified thread
1094 // debugState - the desired CorDebugThreadState
1095 //
1096
1097 virtual
1098 void SetDebugState(VMPTR_Thread vmThread,
1099 CorDebugThreadState debugState) = 0;
1100
1101 //
1102 // Returns TRUE if this thread has an unhandled exception
1103 //
1104 // Arguments:
1105 // vmThread - the thread to query
1106 //
1107 // Return Value
1108 // TRUE iff this thread has an unhandled exception
1109 //
1110 virtual
1111 BOOL HasUnhandledException(VMPTR_Thread vmThread) = 0;
1112
1113 //
1114 // Return the user state of the specified thread. Most of the state are derived from
1115 // the ThreadState of the specified thread, e.g. TS_Background, TS_Unstarted, etc.
1116 // The exception is USER_UNSAFE_POINT, which we need to do a one-frame stackwalk to figure out.
1117 //
1118 // Arguments:
1119 // vmThread - the specified thread
1120 //
1121 // Return Value:
1122 // the user state of the specified thread
1123 //
1124
1125 virtual
1126 CorDebugUserState GetUserState(VMPTR_Thread vmThread) = 0;
1127
1128
1129 //
1130 // Returns most of the user state of the specified thread,
1131 // i.e. flags which can be derived from the ThreadState:
1132 // USER_STOP_REQUESTED, USER_SUSPEND_REQUESTED, USER_BACKGROUND, USER_UNSTARTED
1133 // USER_STOPPED, USER_WAIT_SLEEP_JOIN, USER_SUSPENDED, USER_THREADPOOL
1134 //
1135 // Only USER_UNSAFE_POINT is always set to 0, since it takes additional stackwalk.
1136 // If you need USER_UNSAFE_POINT, use GetUserState(VMPTR_Thread);
1137 //
1138 // Arguments:
1139 // vmThread - the specified thread
1140 //
1141 // Return Value:
1142 // the user state of the specified thread
1143 //
1144 virtual
1145 CorDebugUserState GetPartialUserState(VMPTR_Thread vmThread) = 0;
1146
1147
1148 //
1149 // Return the connection ID of the specified thread.
1150 //
1151 // Arguments:
1152 // vmThread - the specified thread
1153 //
1154 // Return Value:
1155 // the connection ID of the specified thread
1156 //
1157
1158 virtual
1159 CONNID GetConnectionID(VMPTR_Thread vmThread) = 0;
1160
1161 //
1162 // Return the task ID of the specified thread.
1163 //
1164 // Arguments:
1165 // vmThread - the specified thread
1166 //
1167 // Return Value:
1168 // the task ID of the specified thread
1169 //
1170
1171 virtual
1172 TASKID GetTaskID(VMPTR_Thread vmThread) = 0;
1173
1174 //
1175 // Return the OS thread ID of the specified thread
1176 //
1177 // Arguments:
1178 // vmThread - the specified thread; cannot be NULL
1179 //
1180 // Return Value:
1181 // the OS thread ID of the specified thread. Returns 0 if not scheduled.
1182 //
1183
1184 virtual
1185 DWORD TryGetVolatileOSThreadID(VMPTR_Thread vmThread) = 0;
1186
1187 //
1188 // Return the unique thread ID of the specified thread. The value used for the thread ID changes
1189 // depending on whether the runtime is being hosted. In non-hosted scenarios, a managed thread will
1190 // always be associated with the same native thread, and so we can use the OS thread ID as the thread ID
1191 // for the managed thread. In hosted scenarios, however, a managed thread may run on multiple native
1192 // threads. It may not even have a backing native thread if it's switched out. Therefore, we can't use
1193 // the OS thread ID as the thread ID. Instead, we use the internal managed thread ID.
1194 //
1195 // Arguments:
1196 // vmThread - the specified thread; cannot be NULL
1197 //
1198 // Return Value:
1199 // Returns a stable and unique thread ID for the lifetime of the specified managed thread.
1200 //
1201
1202 virtual
1203 DWORD GetUniqueThreadID(VMPTR_Thread vmThread) = 0;
1204
1205 //
1206 // Return the object handle to the managed Exception object of the current exception
1207 // on the specified thread. The return value could be NULL if there is no current exception.
1208 //
1209 // Arguments:
1210 // vmThread - the specified thread
1211 //
1212 // Return Value:
1213 // This function returns the object handle to the managed Exception object of the current exception.
1214 // The return value may be NULL if there is no exception being processed, or if the specified thread
1215 // is an unmanaged thread which has entered and exited the runtime.
1216 //
1217
1218 virtual
1219 VMPTR_OBJECTHANDLE GetCurrentException(VMPTR_Thread vmThread) = 0;
1220
1221 //
1222 // Return the object handle to the managed object for a given CCW pointer.
1223 //
1224 // Arguments:
1225 // ccwPtr - the specified ccw pointer
1226 //
1227 // Return Value:
1228 // This function returns the object handle to the managed object for a given CCW pointer.
1229 //
1230
1231 virtual
1232 VMPTR_OBJECTHANDLE GetObjectForCCW(CORDB_ADDRESS ccwPtr) = 0;
1233
1234 //
1235 // Return the object handle to the managed CustomNotification object of the current notification
1236 // on the specified thread. The return value could be NULL if there is no current notification.
1237 //
1238 // Arguments:
1239 // vmThread - the specified thread on which the notification occurred
1240 //
1241 // Return Value:
1242 // This function returns the object handle to the managed CustomNotification object of the current notification.
1243 // The return value may be NULL if there is no current notification.
1244 //
1245
1246 virtual
1247 VMPTR_OBJECTHANDLE GetCurrentCustomDebuggerNotification(VMPTR_Thread vmThread) = 0;
1248
1249
1250 //
1251 // Return the current appdomain the specified thread is in.
1252 //
1253 // Arguments:
1254 // vmThread - the specified thread
1255 //
1256 // Return Value:
1257 // the current appdomain of the specified thread
1258 //
1259 // Notes:
1260 // This function throws if the current appdomain is NULL for whatever reason.
1261 //
1262
1263 virtual
1264 VMPTR_AppDomain GetCurrentAppDomain(VMPTR_Thread vmThread) = 0;
1265
1266
1267 //
1268 // Resolve an assembly
1269 //
1270 // Arguments:
1271 // vmScope - module containing metadata that the token is scoped to.
1272 // tkAssemblyRef - assembly ref token to lookup.
1273 //
1274 // Returns:
1275 // Assembly that the loader/fusion has bound to the given assembly ref.
1276 // Returns NULL if the assembly has not yet been loaded (a common case).
1277 // Throws on error.
1278 //
1279 // Notes:
1280 // A single module has metadata that specifies references via tokens. The
1281 // loader/fusion goes through tremendous and random policy hoops to determine
1282 // which specific file actually gets bound to the reference. This policy includes
1283 // things like config files, registry settings, and many other knobs.
1284 //
1285 // The debugger can't duplicate this policy with 100% accuracy, and
1286 // so we need DAC to lookup the assembly that was actually loaded.
1287 virtual
1288 VMPTR_DomainAssembly ResolveAssembly(VMPTR_DomainFile vmScope, mdToken tkAssemblyRef) = 0;
1289
1290 //-----------------------------------------------------------------------------
1291 // Interface for initializing the native/IL sequence points and native var info
1292 // for a function.
1293 // Arguments:
1294 // input:
1295 // vmMethodDesc MethodDesc of the function
1296 // startAddr starting address of the function--this serves to
1297 // differentiate various EnC versions of the function
1298 // fCodePitched indicates whether code for the function has been pitched
1299 // fJitComplete indicates whether the function has been jitted
1300 // output:
1301 // pNativeVarData space for the native code offset information for locals
1302 // pSequencePoints space for the IL/native sequence points
1303 // Return value:
1304 // none, but may throw an exception
1305 // Assumptions:
1306 // vmMethodDesc, pNativeVarInfo and pSequencePoints are non-NULL
1307
1308 // Notes:
1309 //-----------------------------------------------------------------------------
1310
1311 virtual
1312 void GetNativeCodeSequencePointsAndVarInfo(VMPTR_MethodDesc vmMethodDesc,
1313 CORDB_ADDRESS startAddress,
1314 BOOL fCodeAvailabe,
1315 OUT NativeVarData * pNativeVarData,
1316 OUT SequencePoints * pSequencePoints) = 0;
1317
1318 //
1319 // Return the filter CONTEXT on the LS. Once we move entirely over to the new managed pipeline
1320 // built on top of the Win32 debugging API, this won't be necessary.
1321 //
1322 // Arguments:
1323 // vmThread - the specified thread
1324 //
1325 // Return Value:
1326 // the filter CONTEXT of the specified thread
1327 //
1328 // Notes:
1329 // This function should go away when everything is moved OOP and
1330 // we don't have a filter CONTEXT on the LS anymore.
1331 //
1332
1333 virtual
1334 VMPTR_CONTEXT GetManagedStoppedContext(VMPTR_Thread vmThread) = 0;
1335
1336 typedef enum
1337 {
1338 kInvalid,
1339 kManagedStackFrame,
1340 kExplicitFrame,
1341 kNativeStackFrame,
1342 kNativeRuntimeUnwindableStackFrame,
1343 kAtEndOfStack,
1344 } FrameType;
1345
1346 // The stackwalker functions allocate persistent state within DDImpl. Clients can hold onto
1347 // this via an opaque StackWalkHandle.
1348 typedef void* * StackWalkHandle;
1349
1350 //
1351 // Create a stackwalker on the specified thread and return a handle to it.
1352 // Initially, the stackwalker is at the filter CONTEXT if there is one.
1353 // Otherwise it is at the leaf CONTEXT. It DOES NOT fast forward to the first frame of interest.
1354 //
1355 // Arguments:
1356 // vmThread - the specified thread
1357 // pInternalContextBuffer - a CONTEXT buffer for the stackwalker to work with
1358 // ppSFIHandle - out parameter; return a handle to the stackwalker
1359 //
1360 // Notes:
1361 // Call DeleteStackWalk() to delete the stackwalk buffer.
1362 // This is a special case that violates the 'no state' tenant.
1363 //
1364
1365 virtual
1366 void CreateStackWalk(VMPTR_Thread vmThread,
1367 DT_CONTEXT * pInternalContextBuffer,
1368 OUT StackWalkHandle * ppSFIHandle) = 0;
1369
1370 // Delete the stackwalk object created from CreateStackWalk.
1371 virtual
1372 void DeleteStackWalk(StackWalkHandle ppSFIHandle) = 0;
1373
1374 //
1375 // Get the CONTEXT of the current frame where the stackwalker is stopped at.
1376 //
1377 // Arguments:
1378 // pSFIHandle - the handle to the stackwalker
1379 // pContext - OUT: the CONTEXT to be filled out. The context control flags are ignored.
1380 //
1381
1382 virtual
1383 void GetStackWalkCurrentContext(StackWalkHandle pSFIHandle,
1384 DT_CONTEXT * pContext) = 0;
1385
1386 //
1387 // Set the stackwalker to the given CONTEXT. The CorDebugSetContextFlag indicates whether
1388 // the CONTEXT is "active", meaning that the IP is point at the current instruction,
1389 // not the return address of some function call.
1390 //
1391 // Arguments:
1392 // vmThread - the current thread
1393 // pSFIHandle - the handle to the stackwalker
1394 // flag - flag to indicate whether the specified CONTEXT is "active"
1395 // pContext - the specified CONTEXT. This may make correctional adjustments to the context's IP.
1396 //
1397
1398 virtual
1399 void SetStackWalkCurrentContext(VMPTR_Thread vmThread,
1400 StackWalkHandle pSFIHandle,
1401 CorDebugSetContextFlag flag,
1402 DT_CONTEXT * pContext) = 0;
1403
1404 //
1405 // Unwind the stackwalker to the next frame. The next frame could be any actual stack frame,
1406 // explicit frame, native marker frame, etc. Call GetStackWalkCurrentFrameInfo() to find out
1407 // more about the frame.
1408 //
1409 // Arguments:
1410 // pSFIHandle - the handle to the stackwalker
1411 //
1412 // Return Value:
1413 // Return TRUE if we successfully unwind to the next frame.
1414 // Return FALSE if there is no more frames to walk.
1415 // Throw on error.
1416 //
1417
1418 virtual
1419 BOOL UnwindStackWalkFrame(StackWalkHandle pSFIHandle) = 0;
1420
1421 //
1422 // Check whether the specified CONTEXT is valid. The only check we perform right now is whether the
1423 // SP in the specified CONTEXT is in the stack range of the thread.
1424 //
1425 // Arguments:
1426 // vmThread - the specified thread
1427 // pContext - the CONTEXT to be checked
1428 //
1429 // Return Value:
1430 // Return S_OK if the CONTEXT passes our checks.
1431 // Returns CORDBG_E_NON_MATCHING_CONTEXT if the SP in the specified CONTEXT doesn't fall in the stack
1432 // range of the thread.
1433 // Throws on error.
1434 //
1435
1436 virtual
1437 HRESULT CheckContext(VMPTR_Thread vmThread,
1438 const DT_CONTEXT * pContext) = 0;
1439
1440 //
1441 // Fill in the DebuggerIPCE_STRData structure with information about the current frame
1442 // where the stackwalker is stopped at.
1443 //
1444 // Arguments:
1445 // pSFIHandle - the handle to the stackwalker
1446 // pFrameData - the DebuggerIPCE_STRData to be filled out;
1447 // it can be NULL if you just want to know the frame type
1448 //
1449 // Return Value:
1450 // Return the type of the current frame
1451 //
1452
1453 virtual
1454 FrameType GetStackWalkCurrentFrameInfo(StackWalkHandle pSFIHandle,
1455 OPTIONAL DebuggerIPCE_STRData * pFrameData) = 0;
1456
1457 //
1458 // Return the number of internal frames on the specified thread.
1459 //
1460 // Arguments:
1461 // vmThread - the thread whose internal frames are being retrieved
1462 //
1463 // Return Value:
1464 // Return the number of internal frames.
1465 //
1466 // Notes:
1467 // Explicit frames are "marker objects" the runtime pushes on the stack to mark special places, e.g.
1468 // appdomain transition, managed-to- unmanaged transition, etc. Internal frames are only a subset of
1469 // explicit frames. Explicit frames which are not interesting to the debugger are not exposed (e.g.
1470 // GCFrame). Internal frames are interesting to the debugger if they have a CorDebugInternalFrameType
1471 // other than STUBFRAME_NONE.
1472 //
1473 // The user should call this function before code:IDacDbiInterface::EnumerateInternalFrames to figure
1474 // out how many interesting internal frames there are.
1475 //
1476
1477 virtual
1478 ULONG32 GetCountOfInternalFrames(VMPTR_Thread vmThread) = 0;
1479
1480 //
1481 // Enumerate the internal frames on the specified thread and invoke the provided callback on each of
1482 // them. Information about the internal frame is stored in the DebuggerIPCE_STRData.
1483 //
1484 // Arguments:
1485 // vmThread - the thread to be walked fpCallback - callback function invoked on each internal frame
1486 // pUserData - user-specified custom data
1487 //
1488 // Notes:
1489 // The user can call code:IDacDbiInterface::GetCountOfInternalFrames to figure out how many internal
1490 // frames are on the thread before calling this function. Also, refer to the comment of that function
1491 // to find out more about internal frames.
1492 //
1493
1494 typedef void (*FP_INTERNAL_FRAME_ENUMERATION_CALLBACK)(const DebuggerIPCE_STRData * pFrameData, CALLBACK_DATA pUserData);
1495
1496 virtual
1497 void EnumerateInternalFrames(VMPTR_Thread vmThread,
1498 FP_INTERNAL_FRAME_ENUMERATION_CALLBACK fpCallback,
1499 CALLBACK_DATA pUserData) = 0;
1500
1501 //
1502 // Given the FramePointer of the parent frame and the FramePointer of the current frame,
1503 // check if the current frame is the parent frame. fpParent should have been returned
1504 // previously by the DacDbiInterface via GetStackWalkCurrentFrameInfo().
1505 //
1506 // Arguments:
1507 // fpToCheck - the FramePointer of the current frame
1508 // fpParent - the FramePointer of the parent frame; should have been returned earlier by the DDI
1509 //
1510 // Return Value:
1511 // Return TRUE if the current frame is indeed the parent frame
1512 //
1513 // Note:
1514 // Because of the complexity involved in checking for the parent frame, we should always
1515 // ask the ExceptionTracker to do it.
1516 //
1517
1518 virtual
1519 BOOL IsMatchingParentFrame(FramePointer fpToCheck, FramePointer fpParent) = 0;
1520
1521 //
1522 // Return the stack parameter size of a given method. This is necessary on x86 for unwinding.
1523 //
1524 // Arguments:
1525 // controlPC - any address in the specified method; you can use the current PC of the stack frame
1526 //
1527 // Return Value:
1528 // Return the size of the stack parameters of the given method.
1529 // Return 0 for vararg methods.
1530 //
1531 // Assumptions:
1532 // The callee stack parameter size is constant throughout a method.
1533 //
1534
1535 virtual
1536 ULONG32 GetStackParameterSize(CORDB_ADDRESS controlPC) = 0;
1537
1538 //
1539 // Return the FramePointer of the current frame where the stackwalker is stopped at.
1540 //
1541 // Arguments:
1542 // pSFIHandle - the handle to the stackwalker
1543 //
1544 // Return Value:
1545 // the FramePointer of the current frame
1546 //
1547 // Notes:
1548 // The FramePointer of a stack frame is:
1549 // the stack address of the return address on x86,
1550 // the current SP on AMD64,
1551 //
1552 // On x86, to get the stack address of the return address, we need to unwind one more frame
1553 // and use the SP of the caller frame as the FramePointer of the callee frame. This
1554 // function does NOT do that. It just returns the SP. The caller needs to handle the
1555 // unwinding.
1556 //
1557 // The FramePointer of an explicit frame is just the stack address of the explicit frame.
1558 //
1559
1560 virtual
1561 FramePointer GetFramePointer(StackWalkHandle pSFIHandle) = 0;
1562
1563 //
1564 // Check whether the specified CONTEXT is the CONTEXT of the leaf frame. This function doesn't care
1565 // whether the leaf frame is native or managed.
1566 //
1567 // Arguments:
1568 // vmThread - the specified thread
1569 // pContext - the CONTEXT to check
1570 //
1571 // Return Value:
1572 // Return TRUE if the specified CONTEXT is the leaf CONTEXT.
1573 //
1574 // Notes:
1575 // Currently we check the specified CONTEXT against the filter CONTEXT first.
1576 // This will be deprecated in V3.
1577 //
1578
1579 virtual
1580 BOOL IsLeafFrame(VMPTR_Thread vmThread,
1581 const DT_CONTEXT * pContext) = 0;
1582
1583 // Get the context for a particular thread of the target process.
1584 // Arguments:
1585 // input: vmThread - the thread for which the context is required
1586 // output: pContextBuffer - the address of the CONTEXT to be initialized.
1587 // The memory for this belongs to the caller. It must not be NULL.
1588 // Note: throws
1589 virtual
1590 void GetContext(VMPTR_Thread vmThread, DT_CONTEXT * pContextBuffer) = 0;
1591
1592 //
1593 // This is a simple helper function to convert a CONTEXT to a DebuggerREGDISPLAY. We need to do this
1594 // inside DDI because the RS has no notion of REGDISPLAY.
1595 //
1596 // Arguments:
1597 // pInContext - the CONTEXT to be converted
1598 // pOutDRD - the converted DebuggerREGDISPLAY
1599 // fActive - Indicate whether the CONTEXT is active or not. An active CONTEXT means that the
1600 // IP is the next instruction to be executed, not the return address of a function call.
1601 // The opposite of an active CONTEXT is an unwind CONTEXT, which is obtained from
1602 // unwinding.
1603 //
1604
1605 virtual
1606 void ConvertContextToDebuggerRegDisplay(const DT_CONTEXT * pInContext,
1607 DebuggerREGDISPLAY * pOutDRD,
1608 BOOL fActive) = 0;
1609
1610 typedef enum
1611 {
1612 kNone,
1613 kILStub,
1614 kLCGMethod,
1615 } DynamicMethodType;
1616
1617 //
1618 // Check whether the specified method is an IL stub or an LCG method. This answer determines if we
1619 // need to expose the method in a V2-style stackwalk.
1620 //
1621 // Arguments:
1622 // vmMethodDesc - the method to be checked
1623 //
1624 // Return Value:
1625 // Return kNone if the method is neither an IL stub or an LCG method.
1626 // Return kILStub if the method is an IL stub.
1627 // Return kLCGMethod if the method is an LCG method.
1628 //
1629
1630 virtual
1631 DynamicMethodType IsILStubOrLCGMethod(VMPTR_MethodDesc vmMethodDesc) = 0;
1632
1633 //
1634 // Return a TargetBuffer for the raw vararg signature.
1635 // Also return the address of the first argument in the vararg signature.
1636 //
1637 // Arguments:
1638 // VASigCookieAddr - the target address of the VASigCookie pointer (double indirection)
1639 // pArgBase - out parameter; return the target address of the first word of the arguments
1640 //
1641 // Return Value:
1642 // Return a TargetBuffer for the raw vararg signature.
1643 //
1644 // Notes:
1645 // We can't take a VMPTR here because VASigCookieAddr does not come from the DDI. Instead,
1646 // we use the native variable information to figure out which stack slot contains the
1647 // VASigCookie pointer. So a remote address is all we have got.
1648 //
1649 // Ideally we should be able to return just a SigParser, but doing so has a not-so-trivial problem.
1650 // The memory used for the signature pointed to by the SigParser cannot be allocated in the DAC cache,
1651 // since it'll be used by mscordbi. We don't have a clean way to allocate memory in mscordbi without
1652 // breaking the Signature abstraction.
1653 //
1654 // The other option would be to create a new sub-type like "SignatureCopy" which allocates and frees
1655 // its own backing memory. Currently we don't want to share heaps between mscordacwks.dll and
1656 // mscordbi.dll, and so we would have to jump through some hoops to allocate with an allocator
1657 // in mscordbi.dll.
1658 //
1659
1660 virtual
1661 TargetBuffer GetVarArgSig(CORDB_ADDRESS VASigCookieAddr,
1662 OUT CORDB_ADDRESS * pArgBase) = 0;
1663
1664 //
1665 // Indicates if the specified type requires 8-byte alignment.
1666 //
1667 // Arguments:
1668 // thExact - the exact TypeHandle of the type to query
1669 //
1670 // Return Value:
1671 // TRUE if the type requires 8-byte alignment.
1672 //
1673
1674 virtual
1675 BOOL RequiresAlign8(VMPTR_TypeHandle thExact) = 0;
1676
1677 //
1678 // Resolve the raw generics token to the real generics type token. The resolution is based on the
1679 // given index. See Notes below.
1680 //
1681 // Arguments:
1682 // dwExactGenericArgsTokenIndex - the variable index of the generics type token
1683 // rawToken - the raw token to be resolved
1684 //
1685 // Return Value:
1686 // Return the actual generics type token.
1687 //
1688 // Notes:
1689 // DDI tells the RS which variable stores the generics type token, but DDI doesn't retrieve the value
1690 // of the variable itself. Instead, the RS retrieves the value of the variable. However,
1691 // in some cases, the variable value is not the generics type token. In this case, we need to
1692 // "resolve" the variable value to the generics type token. The RS should call this API to do that.
1693 //
1694 // If the index is 0, then the generics type token is the MethodTable of the "this" object.
1695 // rawToken will be the address of the "this" object.
1696 //
1697 // If the index is TYPECTXT_ILNUM, the generics type token is a secret argument.
1698 // It could be a MethodDesc or a MethodTable, and in this case no resolution is actually necessary.
1699 // rawToken will be the actual secret argument, and this API really is just a nop.
1700 //
1701 // However, we don't want the RS to know all this logic.
1702 //
1703
1704 virtual
1705 GENERICS_TYPE_TOKEN ResolveExactGenericArgsToken(DWORD dwExactGenericArgsTokenIndex,
1706 GENERICS_TYPE_TOKEN rawToken) = 0;
1707
1708 //-----------------------------------------------------------------------------
1709 // Functions to get information about code objects
1710 //-----------------------------------------------------------------------------
1711
1712 // GetILCodeAndSig returns the function's ILCode and SigToken given
1713 // a module and a token. The info will come from a MethodDesc, if
1714 // one exists or from metadata.
1715 //
1716 // Arguments:
1717 // Input:
1718 // vmDomainFile - module containing metadata for the method
1719 // functionToken - metadata token for the function
1720 // Output (required):
1721 // codeInfo - start address and size of the IL
1722 // pLocalSigToken - signature token for the method
1723 virtual
1724 void GetILCodeAndSig(VMPTR_DomainFile vmDomainFile,
1725 mdToken functionToken,
1726 OUT TargetBuffer * pCodeInfo,
1727 OUT mdToken * pLocalSigToken) = 0;
1728
1729 // Gets information about a native code blob:
1730 // it's method desc, whether it's an instantiated generic, its EnC version number
1731 // and hot and cold region information.
1732 // Arguments:
1733 // Input:
1734 // vmDomainFile - module containing metadata for the method
1735 // functionToken - token for the function for which we need code info
1736 // Output (required):
1737 // pCodeInfo - data structure describing the native code regions.
1738 // Notes: If the function is unjitted, the method desc will be NULL and the
1739 // output parameter will be invalid. In general, if the native start address
1740 // is unavailable for any reason, the output parameter will also be
1741 // invalid (i.e., pCodeInfo->IsValid is false).
1742
1743 virtual
1744 void GetNativeCodeInfo(VMPTR_DomainFile vmDomainFile,
1745 mdToken functionToken,
1746 OUT NativeCodeFunctionData * pCodeInfo) = 0;
1747
1748 // Gets information about a native code blob:
1749 // it's method desc, whether it's an instantiated generic, its EnC version number
1750 // and hot and cold region information.
1751 // This is similar to function above, just works from a different starting point
1752 // Also this version can get info for any particular EnC version instance
1753 // because they all have different start addresses whereas the above version gets
1754 // the most recent one
1755 // Arguments:
1756 // Input:
1757 // hotCodeStartAddr - the beginning of the code hot code region
1758 // Output (required):
1759 // pCodeInfo - data structure describing the native code regions.
1760
1761 virtual
1762 void GetNativeCodeInfoForAddr(VMPTR_MethodDesc vmMethodDesc,
1763 CORDB_ADDRESS hotCodeStartAddr,
1764 NativeCodeFunctionData * pCodeInfo) = 0;
1765
1766 //-----------------------------------------------------------------------------
1767 // Functions to get information about types
1768 //-----------------------------------------------------------------------------
1769
1770 // Determine if a type is a ValueType
1771 //
1772 // Arguments:
1773 // input: vmTypeHandle - the type being checked (works even on unrestored types)
1774 //
1775 // Return:
1776 // TRUE iff the type is a ValueType
1777
1778 virtual
1779 BOOL IsValueType (VMPTR_TypeHandle th) = 0;
1780
1781 // Determine if a type has generic parameters
1782 //
1783 // Arguments:
1784 // input: vmTypeHandle - the type being checked (works even on unrestored types)
1785 //
1786 // Return:
1787 // TRUE iff the type has generic parameters
1788
1789 virtual
1790 BOOL HasTypeParams (VMPTR_TypeHandle th) = 0;
1791
1792 // Get type information for a class
1793 //
1794 // Arguments:
1795 // input: vmAppDomain - appdomain where we will fetch field data for the type
1796 // thExact - exact type handle for type
1797 // output:
1798 // pData - structure containing information about the class and its
1799 // fields
1800
1801 virtual
1802 void GetClassInfo (VMPTR_AppDomain vmAppDomain,
1803 VMPTR_TypeHandle thExact,
1804 ClassInfo * pData) = 0;
1805
1806 // get field information and object size for an instantiated generic
1807 //
1808 // Arguments:
1809 // input: vmDomainFile - module containing metadata for the type
1810 // thExact - exact type handle for type (may be NULL)
1811 // thApprox - approximate type handle for the type
1812 // output:
1813 // pFieldList - array of structures containing information about the fields. Clears any previous
1814 // contents. Allocated and initialized by this function.
1815 // pObjectSize - size of the instantiated object
1816 //
1817 virtual
1818 void GetInstantiationFieldInfo (VMPTR_DomainFile vmDomainFile,
1819 VMPTR_TypeHandle vmThExact,
1820 VMPTR_TypeHandle vmThApprox,
1821 OUT DacDbiArrayList<FieldData> * pFieldList,
1822 OUT SIZE_T * pObjectSize) = 0;
1823
1824 // use a type handle to get the information needed to create the corresponding RS CordbType instance
1825 //
1826 // Arguments:
1827 // input: boxed - indicates what, if anything, is boxed. See code:AreValueTypesBoxed for more
1828 // specific information
1829 // vmAppDomain - module containing metadata for the type
1830 // vmTypeHandle - type handle for the type
1831 // output: pTypeInfo - holds information needed to build the corresponding CordbType
1832 //
1833 virtual
1834 void TypeHandleToExpandedTypeInfo(AreValueTypesBoxed boxed,
1835 VMPTR_AppDomain vmAppDomain,
1836 VMPTR_TypeHandle vmTypeHandle,
1837 DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
1838
1839 virtual
1840 void GetObjectExpandedTypeInfo(AreValueTypesBoxed boxed,
1841 VMPTR_AppDomain vmAppDomain,
1842 CORDB_ADDRESS addr,
1843 OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
1844
1845
1846 virtual
1847 void GetObjectExpandedTypeInfoFromID(AreValueTypesBoxed boxed,
1848 VMPTR_AppDomain vmAppDomain,
1849 COR_TYPEID id,
1850 OUT DebuggerIPCE_ExpandedTypeData * pTypeInfo) = 0;
1851
1852
1853 // Get type handle for a TypeDef token, if one exists. For generics this returns the open type.
1854 // Note there is no guarantee the returned handle will be fully restored (in pre-jit scenarios),
1855 // only that it exists. Later functions that use this type handle should fail if they require
1856 // information not yet available at the current restoration level
1857 //
1858 // Arguments:
1859 // input: vmModule - the module scope in which to look up the type def
1860 // metadataToken - the type definition to retrieve
1861 //
1862 // Return value: the type handle if it exists or throws CORDBG_E_CLASS_NOT_LOADED if it isn't loaded
1863 //
1864 virtual
1865 VMPTR_TypeHandle GetTypeHandle(VMPTR_Module vmModule,
1866 mdTypeDef metadataToken) = 0;
1867
1868 // Get the approximate type handle for an instantiated type. This may be identical to the exact type handle,
1869 // but if we have code sharing for generics, it may differ in that it may have canonical type parameters.
1870 // This will occur if we have not yet loaded an exact type but we have loaded the canonical form of the
1871 // type.
1872 //
1873 // Arguments:
1874 // input: pTypeData - information needed to get the type handle, this includes a list of type parameters
1875 // and the number of entries in the list. Allocated and initialized by the caller.
1876 // Return value: the approximate type handle
1877 //
1878 virtual
1879 VMPTR_TypeHandle GetApproxTypeHandle(TypeInfoList * pTypeData) = 0;
1880
1881 // Get the exact type handle from type data.
1882 // Arguments:
1883 // input: pTypeData - type information for the type. includes information about
1884 // the top-level type as well as information
1885 // about the element type for array types, the referent for
1886 // pointer types, or actual parameters for generic class or
1887 // valuetypes, as appropriate for the top-level type.
1888 // pArgInfo - This is preallocated and initialized by the caller and contains two fields:
1889 // genericArgsCount - number of type parameters (these may be actual type parameters
1890 // for generics or they may represent the element type or referent
1891 // type.
1892 // pGenericArgData - list of type parameters
1893 // vmTypeHandle - the exact type handle derived from the type information
1894 // Return Value: an HRESULT indicating the result of the operation
1895 virtual
1896 HRESULT GetExactTypeHandle(DebuggerIPCE_ExpandedTypeData * pTypeData,
1897 ArgInfoList * pArgInfo,
1898 VMPTR_TypeHandle& vmTypeHandle) = 0;
1899
1900 //
1901 // Retrieve the generic type params for a given MethodDesc. This function is specifically
1902 // for stackwalking because it requires the generic type token on the stack.
1903 //
1904 // Arguments:
1905 // vmAppDomain - the appdomain of the MethodDesc
1906 // vmMethodDesc - the method in question
1907 // genericsToken - the generic type token in the stack frame owned by the method
1908 //
1909 // pcGenericClassTypeParams - out parameter; returns the number of type parameters for the class
1910 // containing the method in question; must not be NULL
1911 // pGenericTypeParams - out parameter; returns an array of type parameters and
1912 // the count of the total number of type parameters; must not be NULL
1913 //
1914 // Notes:
1915 // The memory for the array is allocated by this function on the Dbi heap.
1916 // The caller is responsible for releasing it.
1917 //
1918
1919 virtual
1920 void GetMethodDescParams(VMPTR_AppDomain vmAppDomain,
1921 VMPTR_MethodDesc vmMethodDesc,
1922 GENERICS_TYPE_TOKEN genericsToken,
1923 OUT UINT32 * pcGenericClassTypeParams,
1924 OUT TypeParamsList * pGenericTypeParams) = 0;
1925
1926 // Get the target field address of a thread local static.
1927 // Arguments:
1928 // input: vmField - pointer to the field descriptor for the static field
1929 // vmRuntimeThread - thread to which the static field belongs. This must
1930 // NOT be NULL
1931 // Return Value: The target address of the field if the field is allocated.
1932 // NULL if the field storage is not yet allocated.
1933 //
1934 // Note:
1935 // Static field storage is lazily allocated, so this may commonly return NULL.
1936 // This is an inspection only method and can not allocate the static storage.
1937 // Field storage is constant once allocated, so this value can be cached.
1938
1939 virtual
1940 CORDB_ADDRESS GetThreadStaticAddress(VMPTR_FieldDesc vmField,
1941 VMPTR_Thread vmRuntimeThread) = 0;
1942
1943 // Get the target field address of a collectible types static.
1944 // Arguments:
1945 // input: vmField - pointer to the field descriptor for the static field
1946 // vmAppDomain - AppDomain to which the static field belongs. This must
1947 // NOT be NULL
1948 // Return Value: The target address of the field if the field is allocated.
1949 // NULL if the field storage is not yet allocated.
1950 //
1951 // Note:
1952 // Static field storage may not exist yet, so this may commonly return NULL.
1953 // This is an inspection only method and can not allocate the static storage.
1954 // Field storage is not constant once allocated so this value can not be cached
1955 // across a Continue
1956
1957 virtual
1958 CORDB_ADDRESS GetCollectibleTypeStaticAddress(VMPTR_FieldDesc vmField,
1959 VMPTR_AppDomain vmAppDomain) = 0;
1960
1961 // Get information about a field added with Edit And Continue.
1962 // Arguments:
1963 // intput: pEnCFieldInfo - information about the EnC added field including:
1964 // object to which it belongs (if this is null the field is static)
1965 // the field token
1966 // the class token for the class to which the field was added
1967 // the offset to the fields
1968 // the domain file
1969 // an indication of the type: whether it's a class or value type
1970 // output: pFieldData - information about the EnC added field
1971 // pfStatic - flag to indicate whether the field is static
1972 virtual
1973 void GetEnCHangingFieldInfo(const EnCHangingFieldInfo * pEnCFieldInfo,
1974 OUT FieldData * pFieldData,
1975 OUT BOOL * pfStatic) = 0;
1976
1977
1978 // GetTypeHandleParams gets the necessary data for a type handle, i.e. its
1979 // type parameters, e.g. "String" and "List<int>" from the type handle
1980 // for "Dict<String,List<int>>", and sends it back to the right side.
1981 // Arguments:
1982 // input: vmAppDomain - app domain to which the type belongs
1983 // vmTypeHandle - type handle for the type
1984 // output: pParams - list of instances of DebuggerIPCE_ExpandedTypeData,
1985 // one for each type parameter. These will be used on the
1986 // RS to build up an instantiation which will allow
1987 // building an instance of CordbType for the top-level
1988 // type. The memory for this list is allocated on the dbi
1989 // heap in this function.
1990 // This will not fail except for OOM
1991
1992 virtual
1993 void GetTypeHandleParams(VMPTR_AppDomain vmAppDomain,
1994 VMPTR_TypeHandle vmTypeHandle,
1995 OUT TypeParamsList * pParams) = 0;
1996
1997 // GetSimpleType
1998 // gets the metadata token and domain file corresponding to a simple type
1999 // Arguments:
2000 // input: vmAppDomain - Appdomain in which simpleType resides
2001 // simpleType - CorElementType value corresponding to a simple type
2002 // output: pMetadataToken - the metadata token corresponding to simpleType,
2003 // in the scope of vmDomainFile.
2004 // vmDomainFile - the domainFile for simpleType
2005 // Notes:
2006 // This is inspection-only. If the type is not yet loaded, it will throw CORDBG_E_CLASS_NOT_LOADED.
2007 // It will not try to load a type.
2008 // If the type has been loaded, vmDomainFile will be non-null unless the target is somehow corrupted.
2009 // In that case, we will throw CORDBG_E_TARGET_INCONSISTENT.
2010
2011 virtual
2012 void GetSimpleType(VMPTR_AppDomain vmAppDomain,
2013 CorElementType simpleType,
2014 OUT mdTypeDef * pMetadataToken,
2015 OUT VMPTR_Module * pVmModule,
2016 OUT VMPTR_DomainFile * pVmDomainFile) = 0;
2017
2018 // for the specified object returns TRUE if the object derives from System.Exception
2019 virtual
2020 BOOL IsExceptionObject(VMPTR_Object vmObject) = 0;
2021
2022 // gets the list of raw stack frames for the specified exception object
2023 virtual
2024 void GetStackFramesFromException(VMPTR_Object vmObject, DacDbiArrayList<DacExceptionCallStackData>& dacStackFrames) = 0;
2025
2026 // Returns true if the argument is a runtime callable wrapper
2027 virtual
2028 BOOL IsRcw(VMPTR_Object vmObject) = 0;
2029
2030 // retrieves the list of COM interfaces implemented by vmObject, as it is known at
2031 // the time of the call (the list may change as new interface types become available
2032 // in the runtime)
2033 virtual
2034 void GetRcwCachedInterfaceTypes(
2035 VMPTR_Object vmObject,
2036 VMPTR_AppDomain vmAppDomain,
2037 BOOL bIInspectableOnly,
2038 OUT DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pDacInterfaces) = 0;
2039
2040 // retrieves the list of interfaces pointers implemented by vmObject, as it is known at
2041 // the time of the call (the list may change as new interface types become available
2042 // in the runtime)
2043 virtual
2044 void GetRcwCachedInterfacePointers(
2045 VMPTR_Object vmObject,
2046 BOOL bIInspectableOnly,
2047 OUT DacDbiArrayList<CORDB_ADDRESS> * pDacItfPtrs) = 0;
2048
2049 // retrieves a list of interface types corresponding to the passed in
2050 // list of IIDs. the interface types are retrieved from an app domain
2051 // IID / Type cache, that is updated as new types are loaded. will
2052 // have NULL entries corresponding to unknown IIDs in "iids"
2053 virtual
2054 void GetCachedWinRTTypesForIIDs(
2055 VMPTR_AppDomain vmAppDomain,
2056 DacDbiArrayList<GUID> & iids,
2057 OUT DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes) = 0;
2058
2059 // retrieves the whole app domain cache of IID / Type mappings.
2060 virtual
2061 void GetCachedWinRTTypes(
2062 VMPTR_AppDomain vmAppDomain,
2063 OUT DacDbiArrayList<GUID> * piids,
2064 OUT DacDbiArrayList<DebuggerIPCE_ExpandedTypeData> * pTypes) = 0;
2065
2066
2067 // ----------------------------------------------------------------------------
2068 // functions to get information about reference/handle referents for ICDValue
2069 // ----------------------------------------------------------------------------
2070
2071 // Get object information for a TypedByRef object. Initializes the objRef and typedByRefType fields of
2072 // pObjectData (type info for the referent).
2073 // Arguments:
2074 // input: pTypedByRef - pointer to a TypedByRef struct
2075 // vmAppDomain - AppDomain for the type of the object referenced
2076 // output: pObjectData - information about the object referenced by pTypedByRef
2077 // Note: Throws
2078 virtual
2079 void GetTypedByRefInfo(CORDB_ADDRESS pTypedByRef,
2080 VMPTR_AppDomain vmAppDomain,
2081 DebuggerIPCE_ObjectData * pObjectData) = 0;
2082
2083 // Get the string length and offset to string base for a string object
2084 // Arguments:
2085 // input: objPtr - address of a string object
2086 // output: pObjectData - fills in the string fields stringInfo.offsetToStringBase and
2087 // stringInfo.length
2088 // Note: throws
2089 virtual
2090 void GetStringData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData) = 0;
2091
2092 // Get information for an array type referent of an objRef, including rank, upper and lower bounds,
2093 // element size and type, and the number of elements.
2094 // Arguments:
2095 // input: objectAddress - the address of an array object
2096 // output: pObjectData - fills in the array-related fields:
2097 // arrayInfo.offsetToArrayBase,
2098 // arrayInfo.offsetToLowerBounds,
2099 // arrayInfo.offsetToUpperBounds,
2100 // arrayInfo.componentCount,
2101 // arrayInfo.rank,
2102 // arrayInfo.elementSize,
2103 // Note: throws
2104 virtual
2105 void GetArrayData(CORDB_ADDRESS objectAddress, DebuggerIPCE_ObjectData * pObjectData) = 0;
2106
2107 // Get information about an object for which we have a reference, including the object size and
2108 // type information.
2109 // Arguments:
2110 // input: objectAddress - address of the object for which we want information
2111 // type - the basic type of the object (we may find more specific type
2112 // information for the object)
2113 // vmAppDomain - the appdomain to which the object belong
2114 // output: pObjectData - fills in the size and type information fields
2115 // Note: throws
2116 virtual
2117 void GetBasicObjectInfo(CORDB_ADDRESS objectAddress,
2118 CorElementType type,
2119 VMPTR_AppDomain vmAppDomain,
2120 DebuggerIPCE_ObjectData * pObjectData) = 0;
2121
2122 // --------------------------------------------------------------------------------------------
2123#ifdef TEST_DATA_CONSISTENCY
2124 // Determine whether a crst is held by the left side. When the DAC is executing VM code that takes a
2125 // lock, we want to know whether the LS already holds that lock. If it does, we will assume the locked
2126 // data is in an inconsistent state and will throw an exception, rather than relying on this data. This
2127 // function is part of a self-test that will ensure we are correctly detecting when the LS holds a lock
2128 // on data the RS is trying to inspect.
2129 // Argument:
2130 // input: vmCrst - the lock to test
2131 // output: none
2132 // Notes:
2133 // Throws
2134 // For this code to run, the environment variable TestDataConsistency must be set to 1.
2135 virtual
2136 void TestCrst(VMPTR_Crst vmCrst) = 0;
2137
2138 // Determine whether a crst is held by the left side. When the DAC is executing VM code that takes a
2139 // lock, we want to know whether the LS already holds that lock. If it does, we will assume the locked
2140 // data is in an inconsistent state and will throw an exception, rather than relying on this data. This
2141 // function is part of a self-test that will ensure we are correctly detecting when the LS holds a lock
2142 // on data the RS is trying to inspect.
2143 // Argument:
2144 // input: vmRWLock - the lock to test
2145 // output: none
2146 // Notes:
2147 // Throws
2148 // For this code to run, the environment variable TestDataConsistency must be set to 1.
2149
2150 virtual
2151 void TestRWLock(VMPTR_SimpleRWLock vmRWLock) = 0;
2152#endif
2153 // --------------------------------------------------------------------------------------------
2154 // Get the address of the Debugger control block on the helper thread. The debugger control block
2155 // contains information about the status of the debugger, handles to various events and space to hold
2156 // information sent back and forth between the debugger and the debuggee's helper thread.
2157 // Arguments: none
2158 // Return Value: The remote address of the Debugger control block allocated on the helper thread
2159 // if it has been successfully allocated or NULL otherwise.
2160 virtual
2161 CORDB_ADDRESS GetDebuggerControlBlockAddress() = 0;
2162
2163 // Creates a VMPTR of an Object. The Object is found by dereferencing ptr
2164 // as though it is a target address to an OBJECTREF. This is similar to
2165 // GetObject with another level of indirection.
2166 //
2167 // Arguments:
2168 // ptr - A target address pointing to an OBJECTREF
2169 //
2170 // Return Value:
2171 // A VMPTR to the Object which ptr points to
2172 //
2173 // Notes:
2174 // The VMPTR this produces can be deconstructed by GetObjectContents.
2175 // This function will throw if given a NULL or otherwise invalid pointer,
2176 // but if given a valid address to an invalid pointer, it will produce
2177 // a VMPTR_Object which points to invalid memory.
2178 virtual
2179 VMPTR_Object GetObjectFromRefPtr(CORDB_ADDRESS ptr) = 0;
2180
2181 // Creates a VMPTR of an Object. The Object is assumed to be at the target
2182 // address supplied by ptr
2183 //
2184 // Arguments:
2185 // ptr - A target address to an Object
2186 //
2187 // Return Value:
2188 // A VMPTR to the Object which was at ptr
2189 //
2190 // Notes:
2191 // The VMPTR this produces can be deconstructed by GetObjectContents.
2192 // This will produce a VMPTR_Object regardless of whether the pointer is
2193 // valid or not.
2194 virtual
2195 VMPTR_Object GetObject(CORDB_ADDRESS ptr) = 0;
2196
2197 // Sets state in the native binder.
2198 //
2199 // Arguments:
2200 // ePolicy - the NGEN policy to change
2201 //
2202 // Return Value:
2203 // HRESULT indicating if the state was successfully updated
2204 //
2205 virtual
2206 HRESULT EnableNGENPolicy(CorDebugNGENPolicy ePolicy) = 0;
2207
2208 // Sets the NGEN compiler flags. This restricts NGEN to only use images with certain
2209 // types of pregenerated code. With respect to debugging this is used to specify that
2210 // the NGEN image must be debuggable aka non-optimized code. Note that these flags
2211 // are merged with other sources of configuration so it is possible that the final
2212 // result retrieved from GetDesiredNGENCompilerFlags does not match what was specfied
2213 // in this call.
2214 //
2215 // If an NGEN image of the appropriate type isn't available then one of two things happens:
2216 // a) the NGEN image isn't loaded and CLR loads the MSIL image instead
2217 // b) the NGEN image is loaded, but we don't use the pregenerated code it contains
2218 // and instead use only the MSIL and metadata
2219 //
2220 // This function is only legal to call at app startup before any decisions have been
2221 // made about NGEN image loading. Once we begin loading this configuration is immutable.
2222 //
2223 //
2224 // Arguments:
2225 // dwFlags - the new NGEN compiler flags that should go into effect
2226 //
2227 // Return Value:
2228 // HRESULT indicating if the state was successfully updated. On error the
2229 // current flags in effect will not have changed.
2230 //
2231 virtual
2232 HRESULT SetNGENCompilerFlags(DWORD dwFlags) = 0;
2233
2234 // Gets the NGEN compiler flags currently in effect. This accounts for settings that
2235 // were caused by SetDesiredNGENCompilerFlags as well as other configuration sources.
2236 // See SetDesiredNGENCompilerFlags for more info
2237 //
2238 // Arguments:
2239 // pdwFlags - the NGEN compiler flags currently in effect
2240 //
2241 // Return Value:
2242 // HRESULT indicating if the state was successfully retrieved.
2243 //
2244 virtual
2245 HRESULT GetNGENCompilerFlags(DWORD *pdwFlags) = 0;
2246
2247 // Create a VMPTR_OBJECTHANDLE from a CORDB_ADDRESS pointing to an object handle
2248 //
2249 // Arguments:
2250 // handle: target address of a GC handle
2251 //
2252 // ReturnValue:
2253 // returns a VMPTR_OBJECTHANDLE with the handle as the m_addr field
2254 //
2255 // Notes:
2256 // This will produce a VMPTR_OBJECTHANDLE regardless of whether handle is
2257 // valid.
2258 // Ideally we'd be using only strongly-typed variables on the RS, and then this would be unnecessary
2259 virtual
2260 VMPTR_OBJECTHANDLE GetVmObjectHandle(CORDB_ADDRESS handleAddress) = 0;
2261
2262 // Validate that the VMPTR_OBJECTHANDLE refers to a legitimate managed object
2263 //
2264 // Arguments:
2265 // handle: the GC handle to be validated
2266 //
2267 // Return value:
2268 // TRUE if the object appears to be valid (its a heuristic), FALSE if it definately is not valid
2269 //
2270 virtual
2271 BOOL IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle) = 0;
2272
2273 // indicates if the specified module is a WinRT module
2274 //
2275 // Arguments:
2276 // vmModule: the module to check
2277 // isWinRT: out parameter indicating state of module
2278 //
2279 // Return value:
2280 // S_OK indicating that the operation succeeded
2281 //
2282 virtual
2283 HRESULT IsWinRTModule(VMPTR_Module vmModule, BOOL& isWinRT) = 0;
2284
2285 // Determines the app domain id for the object refered to by a given VMPTR_OBJECTHANDLE
2286 //
2287 // Arguments:
2288 // handle: the GC handle which refers to the object of interest
2289 //
2290 // Return value:
2291 // The app domain id of the object of interest
2292 //
2293 // This may throw if the object handle is corrupt (it doesn't refer to a managed object)
2294 virtual
2295 ULONG GetAppDomainIdFromVmObjectHandle(VMPTR_OBJECTHANDLE vmHandle) = 0;
2296
2297
2298 // Get the target address from a VMPTR_OBJECTHANDLE, i.e., the handle address
2299 // Arguments:
2300 // vmHandle - (input) the VMPTR_OBJECTHANDLE from which we need the target address
2301 // Return value: the target address from the VMPTR_OBJECTHANDLE
2302 //
2303 virtual
2304 CORDB_ADDRESS GetHandleAddressFromVmHandle(VMPTR_OBJECTHANDLE vmHandle) = 0;
2305
2306 // Given a VMPTR to an Object return the target address
2307 //
2308 // Arguments:
2309 // obj - the Object VMPTR to get the address from
2310 //
2311 // Return Value:
2312 // Return the target address which obj is using
2313 //
2314 // Notes:
2315 // The VMPTR this consumes can be reconstructed using GetObject and
2316 // providing the address stored in the returned TargetBuffer. This has
2317 // undefined behavior for invalid VMPTR_Objects.
2318
2319 virtual
2320 TargetBuffer GetObjectContents(VMPTR_Object obj) = 0;
2321
2322 // The callback used to enumerate blocking objects
2323 typedef void (*FP_BLOCKINGOBJECT_ENUMERATION_CALLBACK)(DacBlockingObject blockingObject,
2324 CALLBACK_DATA pUserData);
2325
2326 //
2327 // Enumerate all monitors blocking a thread
2328 //
2329 // Arguments:
2330 // vmThread - the thread to get monitor data for
2331 // fpCallback - callback to invoke on the blocking data for each monitor
2332 // pUserData - user data to supply for each callback.
2333 //
2334 // Return Value:
2335 // Returns on success. Throws on error.
2336 //
2337 //
2338 virtual
2339 void EnumerateBlockingObjects(VMPTR_Thread vmThread,
2340 FP_BLOCKINGOBJECT_ENUMERATION_CALLBACK fpCallback,
2341 CALLBACK_DATA pUserData) = 0;
2342
2343
2344
2345 //
2346 // Returns the thread which owns the monitor lock on an object and the acquisition
2347 // count
2348 //
2349 // Arguments:
2350 // vmObject - The object to check for ownership
2351
2352 //
2353 // Return Value:
2354 // Throws on error. Inside the structure we have:
2355 // pVmThread - the owning or thread or VMPTR_Thread::NullPtr() if unowned
2356 // pAcquisitionCount - the number of times the lock would need to be released in
2357 // order for it to be unowned
2358 //
2359 virtual
2360 MonitorLockInfo GetThreadOwningMonitorLock(VMPTR_Object vmObject) = 0;
2361
2362 //
2363 // Enumerate all threads waiting on the monitor event for an object
2364 //
2365 // Arguments:
2366 // vmObject - the object whose monitor event we are interested in
2367 // fpCallback - callback to invoke on each thread in the queue
2368 // pUserData - user data to supply for each callback.
2369 //
2370 // Return Value:
2371 // Returns on success. Throws on error.
2372 //
2373 //
2374 virtual
2375 void EnumerateMonitorEventWaitList(VMPTR_Object vmObject,
2376 FP_THREAD_ENUMERATION_CALLBACK fpCallback,
2377 CALLBACK_DATA pUserData) = 0;
2378
2379 //
2380 // Returns the managed debugging flags for the process (a combination
2381 // of the CLR_DEBUGGING_PROCESS_FLAGS flags). This function specifies,
2382 // beyond whether or not a managed debug event is pending, also if the
2383 // event (if one exists) is caused by a Debugger.Launch(). This is
2384 // important b/c Debugger.Launch calls should *NOT* cause the debugger
2385 // to terminate the process when the attach is canceled.
2386 virtual
2387 CLR_DEBUGGING_PROCESS_FLAGS GetAttachStateFlags() = 0;
2388
2389 virtual
2390 bool GetMetaDataFileInfoFromPEFile(VMPTR_PEFile vmPEFile,
2391 DWORD & dwTimeStamp,
2392 DWORD & dwImageSize,
2393 bool & isNGEN,
2394 IStringHolder* pStrFilename) = 0;
2395
2396 virtual
2397 bool GetILImageInfoFromNgenPEFile(VMPTR_PEFile vmPEFile,
2398 DWORD & dwTimeStamp,
2399 DWORD & dwSize,
2400 IStringHolder* pStrFilename) = 0;
2401
2402
2403 virtual
2404 bool IsThreadSuspendedOrHijacked(VMPTR_Thread vmThread) = 0;
2405
2406
2407 typedef void* * HeapWalkHandle;
2408
2409 // Returns true if it is safe to walk the heap. If this function returns false,
2410 // you could still create a heap walk and attempt to walk it, but there's no
2411 // telling how much of the heap will be available.
2412 virtual
2413 bool AreGCStructuresValid() = 0;
2414
2415 // Creates a HeapWalkHandle which can be used to walk the managed heap with the
2416 // WalkHeap function. Note if this function completes successfully you will need
2417 // to delete the handle by passing it into DeleteHeapWalk.
2418 //
2419 // Arguments:
2420 // pHandle - the location to store the heap walk handle in
2421 //
2422 // Returns:
2423 // S_OK on success, an error code on failure.
2424 virtual
2425 HRESULT CreateHeapWalk(OUT HeapWalkHandle * pHandle) = 0;
2426
2427
2428 // Deletes the give HeapWalkHandle. Note you must call this function if
2429 // CreateHeapWalk returns success.
2430 virtual
2431 void DeleteHeapWalk(HeapWalkHandle handle) = 0;
2432
2433 // Walks the heap using the given heap walk handle, enumerating objects
2434 // on the managed heap. Note that walking the heap requires that the GC
2435 // data structures be in a valid state, which you can find by calling
2436 // AreGCStructuresValid.
2437 //
2438 // Arguments:
2439 // handle - a HeapWalkHandle obtained from CreateHeapWalk
2440 // count - the number of object addresses to obtain; pValues must
2441 // be at least as large as count
2442 // objects - the location to stuff the object addresses found during
2443 // the heap walk; this array should be at least "count" in
2444 // length; this field must not be null
2445 // pFetched - a location to store the actual number of values filled
2446 // into pValues; this field must not be null
2447 //
2448 // Returns:
2449 // S_OK on success, a failure HRESULT otherwise.
2450 //
2451 // Note:
2452 // You should iteratively call WalkHeap requesting more values until
2453 // *pFetched != count.. This signifies that we have reached the end
2454 // of the heap walk.
2455 virtual
2456 HRESULT WalkHeap(HeapWalkHandle handle,
2457 ULONG count,
2458 OUT COR_HEAPOBJECT * objects,
2459 OUT ULONG * pFetched) = 0;
2460
2461 virtual
2462 HRESULT GetHeapSegments(OUT DacDbiArrayList<COR_SEGMENT> * pSegments) = 0;
2463
2464 virtual
2465 bool IsValidObject(CORDB_ADDRESS obj) = 0;
2466
2467 virtual
2468 bool GetAppDomainForObject(CORDB_ADDRESS obj, OUT VMPTR_AppDomain * pApp,
2469 OUT VMPTR_Module * pModule,
2470 OUT VMPTR_DomainFile * pDomainFile) = 0;
2471
2472
2473 // Reference Walking.
2474
2475 // Creates a reference walk.
2476 // Parameters:
2477 // pHandle - out - the reference walk handle to create
2478 // walkStacks - in - whether or not to report stack references
2479 // walkFQ - in - whether or not to report references from the finalizer queue
2480 // handleWalkMask - in - the types of handles report (see CorGCReferenceType, cordebug.idl)
2481 // Returns:
2482 // An HRESULT indicating whether it succeded or failed.
2483 // Exceptions:
2484 // Does not throw, but does not catch exceptions either.
2485 virtual
2486 HRESULT CreateRefWalk(OUT RefWalkHandle * pHandle, BOOL walkStacks, BOOL walkFQ, UINT32 handleWalkMask) = 0;
2487
2488 // Deletes a reference walk.
2489 // Parameters:
2490 // handle - in - the handle of the reference walk to delete
2491 // Excecptions:
2492 // Does not throw, but does not catch exceptions either.
2493 virtual
2494 void DeleteRefWalk(RefWalkHandle handle) = 0;
2495
2496 // Enumerates GC references in the process based on the parameters passed to CreateRefWalk.
2497 // Parameters:
2498 // handle - in - the RefWalkHandle to enumerate
2499 // count - in - the capacity of "refs"
2500 // refs - in/out - an array to write the references to
2501 // pFetched - out - the number of references written
2502 virtual
2503 HRESULT WalkRefs(RefWalkHandle handle, ULONG count, OUT DacGcReference * refs, OUT ULONG * pFetched) = 0;
2504
2505 virtual
2506 HRESULT GetTypeID(CORDB_ADDRESS obj, COR_TYPEID * pType) = 0;
2507
2508 virtual
2509 HRESULT GetTypeIDForType(VMPTR_TypeHandle vmTypeHandle, COR_TYPEID *pId) = 0;
2510
2511 virtual
2512 HRESULT GetObjectFields(COR_TYPEID id, ULONG32 celt, OUT COR_FIELD * layout, OUT ULONG32 * pceltFetched) = 0;
2513
2514 virtual
2515 HRESULT GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT * pLayout) = 0;
2516
2517 virtual
2518 HRESULT GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT * pLayout) = 0;
2519
2520 virtual
2521 void GetGCHeapInformation(OUT COR_HEAPINFO * pHeapInfo) = 0;
2522
2523 // If a PEFile has an RW capable IMDInternalImport, this returns the address of the MDInternalRW
2524 // object which implements it.
2525 //
2526 //
2527 // Arguments:
2528 // vmPEFile - target PEFile to get metadata MDInternalRW for.
2529 // pAddrMDInternalRW - If a PEFile has an RW capable IMDInternalImport, this will be set to the address
2530 // of the MDInternalRW object which implements it. Otherwise it will be NULL.
2531 //
2532 virtual
2533 HRESULT GetPEFileMDInternalRW(VMPTR_PEFile vmPEFile, OUT TADDR* pAddrMDInternalRW) = 0;
2534
2535 // DEPRECATED - use GetActiveRejitILCodeVersionNode
2536 // Retrieves the active ReJitInfo for a given module/methodDef, if it exists.
2537 // Active is defined as after GetReJitParameters returns from the profiler dll and
2538 // no call to Revert has completed yet.
2539 //
2540 //
2541 // Arguments:
2542 // vmModule - The module to search in
2543 // methodTk - The methodDef token indicates the method within the module to check
2544 // pReJitInfo - [out] The RejitInfo request, if any, that is active on this method. If no request
2545 // is active this will be pReJitInfo->IsNull() == TRUE.
2546 //
2547 // Returns:
2548 // S_OK regardless of whether a rejit request is active or not, as long as the answer is certain
2549 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2550 //
2551 virtual
2552 HRESULT GetReJitInfo(VMPTR_Module vmModule, mdMethodDef methodTk, OUT VMPTR_ReJitInfo* pReJitInfo) = 0;
2553
2554 // DEPRECATED - use GetNativeCodeVersionNode
2555 // Retrieves the ReJitInfo for a given MethodDesc/code address, if it exists.
2556 //
2557 //
2558 // Arguments:
2559 // vmMethod - The method to look for
2560 // codeStartAddress - The code start address disambiguates between multiple rejitted instances
2561 // of the method.
2562 // pReJitInfo - [out] The RejitInfo request that corresponds to this MethodDesc/code address, if it exists.
2563 // NULL otherwise.
2564 //
2565 // Returns:
2566 // S_OK regardless of whether a rejit request is active or not, as long as the answer is certain
2567 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2568 //
2569 virtual
2570 HRESULT GetReJitInfo(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeStartAddress, OUT VMPTR_ReJitInfo* pReJitInfo) = 0;
2571
2572 // DEPRECATED - use GetILCodeVersion
2573 // Retrieves the SharedReJitInfo for a given ReJitInfo.
2574 //
2575 //
2576 // Arguments:
2577 // vmReJitInfo - The ReJitInfo to inspect
2578 // pSharedReJitInfo - [out] The SharedReJitInfo that is pointed to by vmReJitInfo.
2579 //
2580 // Returns:
2581 // S_OK if no error
2582 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2583 //
2584 virtual
2585 HRESULT GetSharedReJitInfo(VMPTR_ReJitInfo vmReJitInfo, VMPTR_SharedReJitInfo* pSharedReJitInfo) = 0;
2586
2587 // DEPRECATED - use GetILCodeVersionData
2588 // Retrieves useful data from a SharedReJitInfo such as IL code and IL mapping.
2589 //
2590 //
2591 // Arguments:
2592 // sharedReJitInfo - The SharedReJitInfo to inspect
2593 // pData - [out] Various properties of the SharedReJitInfo such as IL code and IL mapping.
2594 //
2595 // Returns:
2596 // S_OK if no error
2597 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2598 //
2599 virtual
2600 HRESULT GetSharedReJitInfoData(VMPTR_SharedReJitInfo sharedReJitInfo, DacSharedReJitInfo* pData) = 0;
2601
2602 // Retrieves a bit field indicating which defines were in use when clr was built. This only includes
2603 // defines that are specified in the Debugger::_Target_Defines enumeration, which is a small subset of
2604 // all defines.
2605 //
2606 //
2607 // Arguments:
2608 // pDefines - [out] The set of defines clr.dll was built with. Bit offsets are encoded using the
2609 // enumeration Debugger::_Target_Defines
2610 //
2611 // Returns:
2612 // S_OK if no error
2613 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2614 //
2615 virtual
2616 HRESULT GetDefinesBitField(ULONG32 *pDefines) = 0;
2617
2618 // Retrieves a version number indicating the shape of the data structures used in the Metadata implementation
2619 // inside clr.dll. This number changes anytime a datatype layout changes so that they can be correctly
2620 // deserialized from out of process
2621 //
2622 //
2623 // Arguments:
2624 // pMDStructuresVersion - [out] The layout version number for metadata data structures. See
2625 // Debugger::Debugger() in Debug\ee\Debugger.cpp for a description of the options.
2626 //
2627 // Returns:
2628 // S_OK if no error
2629 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2630 //
2631 virtual
2632 HRESULT GetMDStructuresVersion(ULONG32* pMDStructuresVersion) = 0;
2633
2634 // Retrieves the active rejit ILCodeVersionNode for a given module/methodDef, if it exists.
2635 // Active is defined as after GetReJitParameters returns from the profiler dll and
2636 // no call to Revert has completed yet.
2637 //
2638 //
2639 // Arguments:
2640 // vmModule - The module to search in
2641 // methodTk - The methodDef token indicates the method within the module to check
2642 // pILCodeVersionNode - [out] The Rejit request, if any, that is active on this method. If no request
2643 // is active this will be pILCodeVersionNode->IsNull() == TRUE.
2644 //
2645 // Returns:
2646 // S_OK regardless of whether a rejit request is active or not, as long as the answer is certain
2647 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2648 //
2649 virtual
2650 HRESULT GetActiveRejitILCodeVersionNode(VMPTR_Module vmModule, mdMethodDef methodTk, OUT VMPTR_ILCodeVersionNode* pVmILCodeVersionNode) = 0;
2651
2652 // Retrieves the NativeCodeVersionNode for a given MethodDesc/code address, if it exists.
2653 // NOTE: The initial (default) code generated for a MethodDesc is a valid MethodDesc/code address pair but it won't have a corresponding
2654 // NativeCodeVersionNode.
2655 //
2656 //
2657 // Arguments:
2658 // vmMethod - The method to look for
2659 // codeStartAddress - The code start address disambiguates between multiple jitted instances of the method.
2660 // pVmNativeCodeVersionNode - [out] The NativeCodeVersionNode request that corresponds to this MethodDesc/code address, if it exists.
2661 // NULL otherwise.
2662 //
2663 // Returns:
2664 // S_OK regardless of whether a rejit request is active or not, as long as the answer is certain
2665 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2666 //
2667 virtual
2668 HRESULT GetNativeCodeVersionNode(VMPTR_MethodDesc vmMethod, CORDB_ADDRESS codeStartAddress, OUT VMPTR_NativeCodeVersionNode* pVmNativeCodeVersionNode) = 0;
2669
2670 // Retrieves the ILCodeVersionNode for a given NativeCodeVersionNode.
2671 // This may return a NULL node if the native code belongs to the default IL version for this this method.
2672 //
2673 //
2674 // Arguments:
2675 // vmNativeCodeVersionNode - The NativeCodeVersionNode to inspect
2676 // pVmILCodeVersionNode - [out] The ILCodeVersionNode that is pointed to by vmNativeCodeVersionNode, if any.
2677 //
2678 // Returns:
2679 // S_OK if no error
2680 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2681 //
2682 virtual
2683 HRESULT GetILCodeVersionNode(VMPTR_NativeCodeVersionNode vmNativeCodeVersionNode, VMPTR_ILCodeVersionNode* pVmILCodeVersionNode) = 0;
2684
2685 // Retrieves useful data from an ILCodeVersion such as IL code and IL mapping.
2686 //
2687 //
2688 // Arguments:
2689 // ilCodeVersionNode - The ILCodeVersionNode to inspect
2690 // pData - [out] Various properties of the ILCodeVersionNode such as IL code and IL mapping.
2691 //
2692 // Returns:
2693 // S_OK if no error
2694 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2695 //
2696 virtual
2697 HRESULT GetILCodeVersionNodeData(VMPTR_ILCodeVersionNode ilCodeVersionNode, DacSharedReJitInfo* pData) = 0;
2698
2699 // Enable or disable the GC notification events. The GC notification events are turned off by default
2700 // They will be delivered through ICorDebugManagedCallback4
2701 //
2702 //
2703 // Arguments:
2704 // fEnable - true to enable the events, false to disable
2705 //
2706 // Returns:
2707 // S_OK if no error
2708 // error HRESULTs such as CORDBG_READ_VIRTUAL_FAILURE are possible
2709 //
2710 virtual
2711 HRESULT EnableGCNotificationEvents(BOOL fEnable) = 0;
2712
2713 // The following tag tells the DD-marshalling tool to stop scanning.
2714 // END_MARSHAL
2715
2716 //-----------------------------------------------------------------------------
2717 // Utility interface used for passing strings out of these APIs. The caller
2718 // provides an implementation of this that uses whatever memory allocation
2719 // strategy it desires, and IDacDbiInterface APIs will call AssignCopy in order
2720 // to pass back the contents of strings.
2721 //
2722 // This permits the client and implementation of IDacDbiInterface to be in
2723 // different DLLs with their own heap allocation mechanism, while avoiding
2724 // the ugly and verbose 2-call C-style string passing API pattern.
2725 //-----------------------------------------------------------------------------
2726 class IStringHolder
2727 {
2728 public:
2729 //
2730 // Store a copy of of the provided string.
2731 //
2732 // Arguments:
2733 // psz - The null-terminated unicode string to copy.
2734 //
2735 // Return Value:
2736 // S_OK on success, typical HRESULT return values on failure.
2737 //
2738 // Notes:
2739 // The underlying object is responsible for allocating and freeing the
2740 // memory for this copy. The object must not store the value of psz,
2741 // it is no longer valid after this call returns.
2742 //
2743 virtual
2744 HRESULT AssignCopy(const WCHAR * psz) = 0;
2745 };
2746
2747
2748 //-----------------------------------------------------------------------------
2749 // Interface for allocations
2750 // This lets DD allocate buffers to pass back to DBI; and thus avoids
2751 // the common 2-step (query size/allocate/query data) pattern.
2752 //
2753 // Note that mscordacwks.dll and clients cannot share the same heap allocator,
2754 // DAC statically links the CRT to avoid run-time dependencies on non-OS libraries.
2755 //-----------------------------------------------------------------------------
2756 class IAllocator
2757 {
2758 public:
2759 // Allocate
2760 // Expected to throw on error.
2761 virtual
2762 void * Alloc(SIZE_T lenBytes) = 0;
2763
2764 // Free. This shouldn't throw.
2765 virtual
2766 void Free(void * p) = 0;
2767 };
2768
2769
2770 //-----------------------------------------------------------------------------
2771 // Callback interface to provide Metadata lookup.
2772 //-----------------------------------------------------------------------------
2773 class IMetaDataLookup
2774 {
2775 public:
2776 //
2777 // Lookup a metadata importer via PEFile.
2778 //
2779 // Returns:
2780 // A IMDInternalImport used by dac-ized VM code. The object is NOT addref-ed. See lifespan notes below.
2781 // Returns NULL if no importer is available.
2782 // Throws on exceptional circumstances (eg, detects the debuggee is corrupted).
2783 //
2784 // Notes:
2785 // IMDInternalImport is a property of PEFile. The DAC-ized code uses it as a weak reference,
2786 // and so we avoid doing an AddRef() here because that would mean we need to add Release() calls
2787 // in DAC-only paths.
2788 // The metadata importers are not DAC-ized, and thus we have a local copy in the host.
2789 // If it was dac-ized, then DAC would get the importer just like any other field.
2790 //
2791 // lifespan of returned object:
2792 // - DBI owns the metadata importers.
2793 // - DBI must not free the importer without calling Flush() on DAC first.
2794 // - DAC will only invoke this when in a DD primitive, which was in turn invoked by DBI.
2795 // - For performance reasons, we want to allow DAC to cache this between Flush() calls.
2796 // - If DAC caches the importer, it will only use it when DBI invokes a DD primitive.
2797 // - the reference count of the returned object is not adjusted.
2798 //
2799 virtual
2800 IMDInternalImport * LookupMetaData(VMPTR_PEFile addressPEFile, bool &isILMetaDataForNGENImage) = 0;
2801 };
2802
2803}; // end IDacDbiInterface
2804
2805
2806#endif // _DACDBI_INTERFACE_H_
2807