Condividi tramite


Esempio EEAddIn: debug del componente aggiuntivo dell'analizzatore di espressioni

Nell'esempio EEAddin viene illustrato come estendere l'analizzatore di espressioni nativo del debugger utilizzando l'API del componente aggiuntivo dell'analizzatore di espressioni.

Nota sulla sicurezzaNota sulla sicurezza

In questo esempio di codice viene illustrato un concetto e viene presentato solo il codice rilevante. È possibile che questo esempio non soddisfi i requisiti di sicurezza per un ambiente specifico ed è opportuno non utilizzarlo così come viene riportato. È consigliabile aggiungere codice relativo alla sicurezza e alla gestione degli errori per rendere i progetti più sicuri e potenti. Microsoft fornisce questo codice di esempio "così come è", senza garanzie.

Per ottenere gli esempi e le istruzioni per l'installazione:

Per accedere agli esempi di Visual Studio

  • Scegliere Esempi dal menu ?.

    Il percorso di installazione predefinito degli esempi è unità:\Programmi\Microsoft Visual Studio 10.0\Samples\.

  • Per la versione più recente di questo esempio e per un elenco di altri esempi, vedere Visual Studio Samples (informazioni in lingua inglese) sul sito Web di MSDN.

API del componente aggiuntivo dell'analizzatore di espressioni

L'analizzatore di espressioni è la parte del debugger che interpreta, o valuta, le espressioni. Quando si inserisce un punto di interruzione in un'espressione o si digita un'espressione in una finestra del debugger, l'analizzatore di espressioni interpreta l'input. Per ulteriori informazioni, vedere Espressioni nel debugger. L'API del componente aggiuntivo dell'analizzatore di espressioni consente di estendere l'analizzatore di espressioni per gestire nuovi tipi di dati.

Per estendere l'analizzatore di espressioni per un nuovo tipo, è necessario scrivere una funzione all'interno di una dll Win32, salvarla nella stessa directory di autoexp.dat ed esportarla per nome. È necessario inoltre aggiungere una riga al file autoexp.dat. Per estendere l'analizzatore di espressioni per più di un tipo, esportare più funzioni dalla dll.

Compilazione ed esecuzione dell'esempio

I passaggi necessari per compilare ed eseguire l'esempio possono essere suddivisi in tre gruppi.

Per compilare ed eseguire l'esempio

  1. Compilare una dll (eeaddin.dll) del componente aggiuntivo dell'analizzatore di espressioni.

  2. Modificare il file autoexp.dat in funzione della dll del componente aggiuntivo dell'analizzatore di espressioni.

  3. Eseguire il test del componente aggiuntivo creando un progetto in cui venga utilizzato il tipo di dati personalizzato valutato da autoexp.dat.

Nelle procedure riportate di seguito sono illustrati i passaggi in dettaglio.

Per compilare la dll del componente aggiuntivo dell'analizzatore di espressioni

  1. In Visual Studio, aprire il file di soluzione eeaddin.sln.

  2. Scegliere Compila dal menu Compila.

  3. Copiare il file eeaddin.dll risultante nella directory common7\ide, la stessa in cui si trova il file devenv.exe.

  4. Scegliere Chiudi soluzione dal menu File.

Per modificare autoexp.dat

  1. Dal menu File scegliere Apri, quindi File.

  2. Nella finestra di dialogo Apri file individuare il file autoexp.dat, che si trova nella directory common7\packages\debugger, e scegliere Apri.

  3. Modificare il file autoexp.dat aggiungendo le righe seguenti:

    _SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime@28)
    _FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime@28)
    

    Salvare autoexp.dat.

Per creare un progetto in cui vengono utilizzati tipi di dati personalizzati

  1. Dal menu File scegliere New, quindi Progetto.

  2. Nella finestra di dialogo Nuovo progetto selezionare Progetti di Visual C++, quindi Applicazione MFC. Immettere un nome per il progetto e scegliere OK.

  3. Nella finestra Creazione guidata applicazione MFC scegliere Fine. È necessario che il progetto sia un'applicazione MFC, perché nel passaggio successivo verranno aggiunte funzioni MFC.

  4. Nell'applicazione MFC aggiungere un oggetto SYSTEMTIME o FILETIME.

    SYSTEMTIME *s = new SYSTEMTIME();
    FILETIME *f = new FILETIME();
    GetSystemTime(s);
    SystemTimeToFileTime(s,f);
    
  5. Scegliere Compila dal menu Compila.

  6. Avviare il debug e analizzare l'oggetto SYSTEMTIME o FILETIME nella finestra Espressioni di controllo.

Funzionamento dell'esempio

Per estendere l'analizzatore di espressioni per un tipo di dati personalizzato, è necessario scrivere una funzione personalizzata del visualizzatore nella dll del componente aggiuntivo dell'analizzatore di espressioni. La funzione utilizza un puntatore a un oggetto nello spazio di memoria del programma di cui si esegue il debug, non nello spazio di memoria dell'analizzatore di espressioni che si desidera estendere. Con questo puntatore non è possibile utilizzare cast normali. Per leggere il puntatore e i dati a cui fa riferimento è necessario utilizzare una funzione di callback. Un puntatore di callback di tipo DEBUGHELPER* fa riferimento a un oggetto con diversi metodi.

Di seguito è riportato un esempio della sintassi.

HRESULT WINAPI CustomViewer(
   DWORD dwAddress,       // low 32-bits of address
   DEBUGHELPER *pHelper,  // callback pointer to access helper functions
   int nBase,             // decimal or hex
   BOOL bIgnore,          // not used
   char *pResult,         // where the result needs to go
   size_t max,            // how large the above buffer is
   DWORD dwReserved       // always pass zero
)

L'esempio dispone di due implementazioni di questo tipo di funzione, AddIn_SystemTime e AddIn_FileTime in timeaddin.cpp. Lo struct DEBUGHELPER (definito in custview.h) è costituito da puntatori a funzione che possono essere utilizzati come supporto alla scrittura dell'estensione. Il puntatore viene passato alla funzione CustomViewer e può essere utilizzato per chiamare funzioni di supporto.

È possibile ottenere il tipo di processore con pHelper->GetProcessorType. Esistono due metodi per leggere la memoria, pHelper->ReadDebuggeeMemory e pHelper->ReadDebuggeeMemoryEx. ReadDebuggeeMemoryEx gestisce gli indirizzi a 64 bit ed è supportato dal debugger di Visual Studio .NET. ReadDebuggeeMemory non gestisce gli indirizzi a 64 bit ed è supportato dai debugger di Visual Studio .NET e di Visual C++ 6.0. Se il componente aggiuntivo utilizzato è stato progettato solo per il debugger di Visual Studio .NET, è possibile utilizzare ReadDebuggeeMemoryEx. Se il componente aggiuntivo deve essere utilizzato anche con Visual C++ 6.0, è necessario controllare il campo dwVersion ed evitare che venga chiamato ReadDebuggeeMemoryEx per Visual C++ 6.0.

Il codice riportato di seguito può essere utilizzato con entrambi i debugger e consente di leggere il contenuto di un localobject, il cui tipo è MyType, dal programma di cui si esegue il debug:

DWORDLONG qwRealAddress;
DWORD dwGot;
MyType localobject;
if (pHelper->dwVersion<0x20000)
{
   // Visual C++ 6.0 version
   qwRealAddress = dwAddress;
   pHelper->ReadDebuggeeMemory( pHelper, dwAddress, 
      sizeof(localobject), &localobject, &dwGot );
}
else
{
   qwRealAddress = pHelper->GetRealAddress(pHelper);
   pHelper->ReadDebuggeeMemoryEx( pHelper, qwRealAddress, 
      sizeof(localobject), &localobject, &dwGot );
}
// TODO: display localobject here

Modifica di autoexp.dat

Nella sezione [AutoExpand] del file autoexp.dat, le righe che verranno aggiunte presentano la sintassi seguente:

type=$ADDIN(dllname.dll,exportname)

Di seguito è riportato un esempio:

_SYSTEMTIME=$ADDIN(eeaddin.dll,AddIn_SystemTime)

oppure:

_FILETIME=$ADDIN(eeaddin.dll,AddIn_FileTime)

Se la dll non si trova nella directory contenente devenv.exe o il percorso non è definito in PATH, è necessario specificare un nome di percorso completo per la dll. L'argomento exportname, in cui viene applicata la distinzione tra maiuscole e minuscole, deve corrispondere esattamente al nome esportato ottenuto dall'esecuzione di dumpbin –exports sulla dll.

Per eseguire il test del debugger con il nuovo componente aggiuntivo, interrompere innanzitutto qualsiasi operazione di debug di programmi in corso al momento dell'installazione della nuova dll, quindi avviare una nuova sessione del debugger.

Nota Poiché il componente aggiuntivo viene eseguito all'interno del debugger, in caso di blocco del codice verrà bloccato l'intero IDE.

Vedere anche

Altre risorse

Esempi generali