(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
最近做了一段时间的VS上的调测插件看法,简单聊一下我得看法:
调测相关的处理,用于调试到断点位置后,相关的查看处理:
1. 使用Shift+F9添加断点查看实现的,Addin都可以进行快速实现;
2. 通过VS断点查看实现要分多步的,通过Addin可以一步实现;
3. Addin可以对读取出的内存信息附加逻辑和附件展示效果
4. Addin可以生成信息,通过调用函数传递给程序
在我们调测的时候,pdb文件提供了编译相关的信息材料,例如
1. 函数的定义,参数分别有几个,都是什么类型
2. 函数中变量名称,变量的类型
等等信息
调测的时候,我们开发的Addin插件,就可以读取这些信息:通过
// 获取Debuger EnvDTE.Debugger debugger = env.Debugger; // 获取pTest变量的信息: 类型、当前的内存值信息 Expression exp = debugger.GetExpression("pTest", false, 2000);
我个人判断的话:
pTest变量Type类型是根据变量名称从pdb文件中读取出来的,
pTest变量的Value值的话,是根据变量的标记从内存中读取出来的
为什么要通过debugger.GetExpression查变量 或 调用pdb中的函数? 如果有这个疑问的话,回答如下:
因为debugger.GetExpression回调回去的,相当于调试进程在执行,进程中的内存可以访问的,包括堆栈中的内存;像变量的值,之前赋值过的,通过这个方法可以访问;
这个是其它方法无法替代的。
addin插件调用函数,实际上和Shift+F9,添加查看的效果类似:
1. 在查看窗口能够做到的,addin通过调用debugger.GetExpression都可以做到;
2. 在查看窗口需要分成一步、二步、三步才能间接做到的,addin可以把这几步封装起来,一次性做到
VS查看 & Addin调用PDB中函数分为两种情况:
一种是非当前debug断点位置的其它库中dllexport函数,调用形如:
{,, xxxxd}GetResult(0x123243) 也或 :{,, xxxxd.dll}GetResult(0x123243) / :{,, xxxxd.pdb}GetResult(0x123243) 均可
另一种是调用Debug断点位置所在库dllexport函数,调用形如
GetResult(0x123243) 也或 :{,, ,}GetResult(0x123243) 均可
另外,调用函数,也可以传递简单字符串char*,
例如传入地址的类型const CTest*,
GetExpression传入参数如:
debugger.GetExpression("GetResult(0x123243, \"const CTest*\")", false, 2000);
接收端可以使用形如如下声明:
__declspec(dllexport) char *GetResult(int nAddr, char pType[])
addin插件可以基于获取到的变量内存地址:读取全部信息,例如知道了char* pStr 指向的地址
可以通过
参数-地址:nAddr
参数-调试进程的ProcessID: debugger.CurrentProcess.ProcessID
包含kernel32.dll相关函数定义
1. 打开进程 OpenProcess(dwWord, true, ProcessId)
2. 读取内存信息 ReadProcessMemory
3. 关闭进程 CloseHandle(hProcess)
这样进程中的内存char*串就读取到了Addin插件中,可以进行处理或展示了
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)