@ -23,7 +23,8 @@ namespace Debugger
Process process ;
Process process ;
bool unloaded = false ;
bool unloaded = false ;
string fullPath ;
string name ;
string fullPath = string . Empty ;
int orderOfLoading = 0 ;
int orderOfLoading = 0 ;
ICorDebugModule corModule ;
ICorDebugModule corModule ;
@ -32,14 +33,10 @@ namespace Debugger
internal Dictionary < string , DebugType > LoadedDebugTypes = new Dictionary < string , DebugType > ( ) ;
internal Dictionary < string , DebugType > LoadedDebugTypes = new Dictionary < string , DebugType > ( ) ;
public event EventHandler < ModuleEventArgs > SymbolsLoaded ;
/// <summary>
/// Occurs when symbols are loaded or unloaded (for memory modules)
protected virtual void OnSymbolsLoaded ( ModuleEventArgs e )
/// </summary>
{
public event EventHandler < ModuleEventArgs > SymbolsUpdated ;
if ( SymbolsLoaded ! = null ) {
SymbolsLoaded ( this , e ) ;
}
}
public AppDomain AppDomain {
public AppDomain AppDomain {
get { return appDomain ; }
get { return appDomain ; }
@ -120,17 +117,16 @@ namespace Debugger
}
}
}
}
[Debugger.Tests.Ignore]
public string Name {
public string FullPath {
get {
get {
return fullPath ;
return name ;
}
}
}
}
public string Filename {
[Debugger.Tests.Ignore]
public string FullPath {
get {
get {
if ( IsDynamic | | IsInMemory ) return String . Empty ;
return fullPath ;
return System . IO . Path . GetFileName ( FullPath ) ;
}
}
}
}
@ -188,38 +184,96 @@ namespace Debugger
metaData = new MetaDataImport ( corModule ) ;
metaData = new MetaDataImport ( corModule ) ;
if ( IsDynamic | | IsInMemory ) {
name = corModule . GetName ( ) ;
} else {
fullPath = corModule . GetName ( ) ;
fullPath = corModule . GetName ( ) ;
name = System . IO . Path . GetFileName ( FullPath ) ;
}
LoadSymbols ( process . Options . SymbolsSearchPaths ) ;
LoadSymbolsFromDisk ( process . Options . SymbolsSearchPaths ) ;
ResetJustMyCodeStatus ( ) ;
ResetJustMyCodeStatus ( ) ;
}
}
/// <summary> Try to load the debugging symbols (.pdb) from the given path </summary>
public void UnloadSymbols ( )
public void LoadSymbols ( string [ ] searchPath )
{
{
if ( symReader ! = null ) {
( ( ISymUnmanagedDispose ) symReader ) . Destroy ( ) ;
symReader = null ;
}
}
/// <summary>
/// Load symblos for on-disk module
/// </summary>
public void LoadSymbolsFromDisk ( string [ ] searchPath )
{
if ( ! IsDynamic & & ! IsInMemory ) {
if ( symReader = = null ) {
if ( symReader = = null ) {
symReader = metaData . GetSymReader ( fullPath , string . Join ( "; " , searchPath ? ? new string [ 0 ] ) ) ;
symReader = metaData . GetSymReader ( fullPath , string . Join ( "; " , searchPath ? ? new string [ 0 ] ) ) ;
if ( symReader ! = null ) {
if ( symReader ! = null ) {
OnSymbolsLoaded ( new ModuleEventArgs ( this ) ) ;
process . TraceMessage ( "Loaded symbols from disk for " + this . Name ) ;
OnSymbolsUpdated ( ) ;
ResetJustMyCodeStatus ( ) ;
}
}
}
}
}
}
}
public void UpdateSymbolsFromStream ( IStream pSymbolStream )
/// <summary>
/// Load symbols for in-memory module
/// </summary>
public void LoadSymbolsFromMemory ( IStream pSymbolStream )
{
{
if ( symReader ! = null ) {
if ( this . IsInMemory ) {
( ( ISymUnmanagedDispose ) symReader ) . Destroy ( ) ;
UnloadSymbols ( ) ;
}
symReader = metaData . GetSymReader ( pSymbolStream ) ;
symReader = metaData . GetSymReader ( pSymbolStream ) ;
if ( symReader ! = null ) {
if ( symReader ! = null ) {
OnSymbolsLoaded ( new ModuleEventArgs ( this ) ) ;
process . TraceMessage ( "Loaded symbols from memory for " + this . Name ) ;
} else {
process . TraceMessage ( "Failed to load symbols from memory" ) ;
}
OnSymbolsUpdated ( ) ;
}
}
}
/// <summary>
/// Load symbols for dynamic module
/// (as of .NET 4.0)
/// </summary>
public void LoadSymbolsDynamic ( )
{
if ( this . CorModule is ICorDebugModule3 & & this . IsDynamic ) {
Guid guid = new Guid ( 0 , 0 , 0 , 0xc0 , 0 , 0 , 0 , 0 , 0 , 0 , 7 0 ) ;
symReader = ( ISymUnmanagedReader ) ( ( ICorDebugModule3 ) this . CorModule ) . CreateReaderForInMemorySymbols ( guid ) ;
TrackedComObjects . Track ( symReader ) ;
process . TraceMessage ( "Loaded dynamic symbols for " + this . Name ) ;
OnSymbolsUpdated ( ) ;
}
}
void OnSymbolsUpdated ( )
{
SetBreakpoints ( ) ;
ResetJustMyCodeStatus ( ) ;
ResetJustMyCodeStatus ( ) ;
if ( SymbolsUpdated ! = null ) {
SymbolsUpdated ( this , new ModuleEventArgs ( this ) ) ;
}
}
void SetBreakpoints ( )
{
if ( this . HasSymbols ) {
// This is in case that the client modifies the collection as a response to set breakpoint
// NB: If client adds new breakpoint, it will be set directly as a result of his call, not here (because module is already loaded)
List < Breakpoint > collection = new List < Breakpoint > ( ) ;
collection . AddRange ( this . Debugger . Breakpoints ) ;
foreach ( Breakpoint b in collection ) {
b . SetBreakpoint ( this ) ;
}
}
}
}
/// <summary> Sets all code as being 'my code'. The code will be gradually
/// <summary> Sets all code as being 'my code'. The code will be gradually
@ -251,17 +305,15 @@ namespace Debugger
public void Dispose ( )
public void Dispose ( )
{
{
UnloadSymbols ( ) ;
metaData . Dispose ( ) ;
metaData . Dispose ( ) ;
if ( symReader ! = null ) {
( ( ISymUnmanagedDispose ) symReader ) . Destroy ( ) ;
}
unloaded = true ;
unloaded = true ;
}
}
public override string ToString ( )
public override string ToString ( )
{
{
return string . Format ( "{0}" , this . Filen ame) ;
return string . Format ( "{0}" , this . N ame) ;
}
}
}
}