在C++中爲Visual Studio 2012調試器編寫自定義本機可視化器DLL需要什麼?我想顯示一個只能從類/結構按需計算的值,因此需要本地可視化DLL。 Visual Studio 2012使用一種新方法來實現稱爲Natvis的本機可視化器。到目前爲止,Natvis上的正確信息很少,特別是在使用Natvis調用可視化DLL時。該DLL將根據類/結構成員值計算顯示字符串。如何爲Visual Studio 2012調試器編寫自定義本機可視化器DLL?
回答
這裏是包含AddIn DLL的C++代碼。我將文件命名爲NatvisAddIn.cpp,並且項目創建了NatvisAddIn.dll。
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#define ADDIN_API __declspec(dllexport)
typedef struct tagDEBUGHELPER
{
DWORD dwVersion;
HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
// from here only when dwVersion >= 0x20000
DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis);
HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis);
} DEBUGHELPER;
typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
class MyClass
{
public:
int publicInt;
};
struct MyStruct { int i; };
ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyClass c;
DWORD nGot;
pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyClass),&c,&nGot);
sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%x publicInt=%d",max,nGot,dwAddress,c.publicInt);
return S_OK;
}
ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyStruct s;
DWORD nGot;
pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyStruct),&s,&nGot);
sprintf_s(pResult,max,"Dll MyStruct: max=%d nGot=%d MyStruct=%x i=%d",max,nGot,dwAddress,s.i);
return S_OK;
}
這是Visual Studio 2012調試器用來顯示值的.natvis文件。將它放在.natvis文件中。我將它命名爲NatvisAddIn.natvis。該文件指示VS 2012調試器調用NatvisAddIn.dll。該dll包含兩個可視化器方法調用; MyClassFormatter格式化MyClass和MyStructFormatter以格式化MyStruct。調試器將在Auto,Watch或tooltip顯示中爲每個指定類型的實例(MyClass,MyStruct)顯示方法的格式化值。
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="MyClass">
<DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyClassFormatter"></DisplayString>
</Type>
<Type Name="MyStruct">
<DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyStructFormatter"></DisplayString>
</Type>
</AutoVisualizer>
地方都編譯NatvisAddIn.dll文件和文件NatvisAddIn.natvis分爲以下三個位置之一:
%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
VS extension folders
您將需要確保以下注冊表項存在和價值1:
[HKEY_CURRENT_USER \軟件\微軟\ VisualStudio的\ 11.0_Config \調試]
「EnableNatvisDiagnostics」= dword:00000001
如果一切順利,您將看到natvis消息出現在Visual Studio的調試器Output窗口中。這些消息將顯示Natvis是否能夠解析.natvis文件。在輸出窗口中顯示解析每個.natvis文件的結果。如果出現錯誤,請使用命令「dumpbin/exports」仔細檢查DLL方法的名稱是否與.navis文件的Type =完全匹配。還要確保當前的.dll和.natvis文件已被複制到相應的目錄中。
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis.
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis.
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis.
測試程序:
#include "stdafx.h"
#include <iostream>
class MyClass
{
public:
int publicInt;
};
struct MyStruct { int i; };
int _tmain(int argc, _TCHAR* argv[])
{
struct MyStruct s = {1234};
std::cout << s.i << std::endl;
MyClass *c = new MyClass;
c->publicInt = 1234;
std::cout << c->publicInt << std::endl;
return 0;
}
信息資源:
\ XML \架構\ natvis。XSD
http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2
http://blogs.msdn.com/b/vcblog/archive/2012/07/12/10329460.aspx
對於64位版本的調試,應使用以下行:
auto realAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot);
對於前面的例子中,64位版本可能看起來像這個:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
#define ADDIN_API __declspec(dllexport)
typedef struct tagDEBUGHELPER
{
DWORD dwVersion;
HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
// from here only when dwVersion >= 0x20000
DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis);
HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot);
int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis);
} DEBUGHELPER;
typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved);
class MyClass
{
public:
int publicInt;
};
ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved)
{
MyClass c;
DWORD nGot;
auto realAddress = pHelper->GetRealAddress(pHelper);
pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot);
sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%llx publicInt=%d",max, nGot, realAddress, c.publicInt);
return S_OK;
}
- 1. Visual Studio 2012 - 調試器隨機跳轉
- 2. 如何編寫非常簡單的Visual Studio調試器可視化工具?
- 3. 如何防止Visual Studio調試器可視化器超時?
- 4. 如何在調用Visual Studio調試器可視化器之間保留自定義對象?
- 5. 自定義Visual Studio 2012
- 6. visual studio 2012調試器不起作用
- 7. Windows 8 Visual Studio 2012調試器問題
- 8. Visual Studio不加載我的調試器可視化器
- 9. Visual Studio 2012 - 調試
- 10. 調試器可視化器提升multi_array
- 11. 「DLL missing」visual studio 2012?
- 12. 如何編寫自定義文本着色的Visual Studio插件?
- 13. Visual Studio測試機調試器
- 14. Visual Studio調試器 - 可視化Intel四倍精度(_Quad)
- 15. 我可以自定義autoexp.dat以在Visual Studio 2010調試器中啓用QT QDomNode可視化
- 16. 編寫調試器。如何調試通過LoadLibray訪問的DLL?
- 17. Visual Studio 2012卡在調試
- 18. Visual Studio 2015調試自定義控件
- 19. Visual Studio 2012「智能」縮進自定義
- 20. 自動崩潰到定義visual studio 2012
- 21. 如何在Visual Studio 2010中使用位圖調試可視化器?
- 22. Visual Studio 2008調試器隨機死亡
- 23. 保持文本可視化器打開並在Visual Studio中繼續調試
- 24. Python可視化調試器
- 25. 如何使用Visual Studio 2012 C++爲VIX API配置編譯器?
- 26. 調試器可視化器[Visual Studio 2010] - System.Linq.Expressions.Expression - 不顯示放大鏡
- 27. Visual Studio調試器步入編譯源
- 28. 自定義容器在調試器中可瀏覽
- 29. 爲php編寫調試器
- 30. Visual Studio圖形調試器
http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2 – 2012-07-18 18:18:31
這是一個偉大的natvis後,這也是我下面提到的,但它沒有關於寫一個字一個自定義的本地可視化工具DLL。我會慷慨地說,現在在微軟的遊戲中,爲了覆蓋整個話題還爲時過早。 – BSalita 2012-07-18 18:38:47