Esempio EEAddIn: debug del componente aggiuntivo dell'analizzatore di espressioni
Aggiornamento: novembre 2007
Nell'esempio EEAddin viene illustrato come estendere l'analizzatore di espressioni nativo del debugger utilizzando l'API del componente aggiuntivo dell'analizzatore di espressioni.
![]() |
---|
Il codice di esempio viene fornito per illustrare un concetto e non deve essere utilizzato in applicazioni o siti Web in quanto potrebbe non rappresentare le procedure di codifica più sicure. Microsoft esclude qualsiasi responsabilità di danni diretti o indiretti qualora il codice di esempio venga utilizzato per scopi diversi da quelli a cui è destinato. |
Per ottenere gli esempi e le istruzioni per l'installazione:
In Visual Studio scegliere Esempi dal menu ?.
Per ulteriori informazioni, vedere Individuazione dei file di esempio.
La versione più recente e l'elenco completo degli esempi sono disponibili in linea alla pagina Visual Studio 2008 Samples.
È anche possibile trovare gli esempi sul disco rigido del computer. Per impostazione predefinita, gli esempi e il file Leggimi vengono copiati in una cartella nel percorso \Programmi\Visual Studio 9.0\Samples\. Per le versioni Express di Visual Studio, tutti gli esempi sono disponibili in linea.
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.
Generazione ed esecuzione dell'esempio
I passaggi necessari per generare ed eseguire l'esempio possono essere suddivisi in tre gruppi.
Per generare ed eseguire l'esempio
Generare una dll (eeaddin.dll) del componente aggiuntivo dell'analizzatore di espressioni.
Modificare il file autoexp.dat in funzione della dll del componente aggiuntivo dell'analizzatore di espressioni.
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 generare la dll del componente aggiuntivo dell'analizzatore di espressioni
In Visual Studio, aprire il file di soluzione eeaddin.sln.
Scegliere Genera dal menu Genera.
Copiare il file eeaddin.dll risultante nella directory common7\ide, la stessa in cui si trova il file devenv.exe.
Scegliere Chiudi soluzione dal menu File.
Per modificare autoexp.dat
Dal menu File scegliere Apri, quindi File.
Nella finestra di dialogo Apri file individuare il file autoexp.dat, che si trova nella directory common7\packages\debugger, e scegliere Apri.
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
Dal menu File scegliere New, quindi Progetto.
Nella finestra di dialogo Nuovo progetto selezionare Progetti di Visual C++, quindi Applicazione MFC. Immettere un nome per il progetto e scegliere OK.
Nella finestra Creazione guidata applicazione MFC scegliere Fine. È necessario che il progetto sia un'applicazione MFC, perché nel passaggio successivo verranno aggiunte funzioni MFC.
Nell'applicazione MFC aggiungere un oggetto SYSTEMTIME o FILETIME.
SYSTEMTIME *s = new SYSTEMTIME(); FILETIME *f = new FILETIME(); GetSystemTime(s); SystemTimeToFileTime(s,f);
Scegliere Genera dal menu Genera.
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 prevede due implementazioni di questo tipo di funzione, AddIn_SystemTime e AddIn_FileTime in timeaddin.cpp. La struttura DEBUGHELPER, definita in custview.h, è costituita da puntatori a funzioni utili per la 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. Per la lettura della memoria sono disponibili due metodi, pHelper->ReadDebuggeeMemory e pHelper->ReadDebuggeeMemoryEx. ReadDebuggeeMemoryEx consente di gestire indirizzi a 64 bit ed è supportato dal debugger di Visual Studio .NET. ReadDebuggeeMemory non consente di gestire indirizzi a 64 bit ed è supportato dai debugger di Visual Studio .NET e 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.