WEB开发网
开发学院软件开发VC 定制调试诊断工具和实用程序(6) 阅读

定制调试诊断工具和实用程序(6)

 2006-07-20 11:42:24 来源:WEB开发网   
核心提示: 事实上,LoadDll.lpImageName 域是一个 LOAD_DLL_DEBUG_INFO 结构成员,定制调试诊断工具和实用程序(6)(5),LOAD_DLL_DEBUG_INFO 来自 DEBUG_EVENT 结构中的联合 u(参见 Figure 2),LoadDll.lpImag

事实上,LoadDll.lpImageName 域是一个 LOAD_DLL_DEBUG_INFO 结构成员,LOAD_DLL_DEBUG_INFO 来自 DEBUG_EVENT 结构中的联合 u(参见 Figure 2),LoadDll.lpImageName 总是指向被调试程序地址空间中一块具备读/写/执行权限的奇怪的内存区域,LOAD_DLL_DEBUG_INFO 结构定义如下:

typedef struct _LOAD_DLL_DEBUG_INFO {
 HANDLE hFile;
 LPVOID lpBaseOfDll;
 DWORD dwDebugInfoFileOffset;
 DWORD nDebugInfoSize;
 LPVOID lpImageName;
 WORD fUnicode;
} LOAD_DLL_DEBUG_INFO, *LPLOAD_DLL_DEBUG_INFO;     

被加载的DLL的路径名就包含在此内存块中。MSDN 在线帮助文档是这样描述 IpImageName 的:

“...与 hFile 关联的文件名指针。该成员可能为 NULL,也可能包含被调试进程地址空间中的串指针地址。这个地址可能为 NULL 或者指向实际的文件名。

如果 fUnicode 是一个非零值,则名字串是 Unicode,否则是 ANSI 串。该成员是可选项。调试器必须考虑处理 lpImageName 为 NULL 或 *lpImageName(在被调试进程的地址空间中)为 NULL 的情况。很显然,系统决不会为某个创建进程事件提供映像名,同时它也不可能为第一个 DLL 事件传递映像名。系统也决不会在源于 DebugActiveProcess 函数调用的调试事件中提供这个信息。”

OnLoadDLLDebugEvent 可重写方法将上述解释翻译为在 99% 的情况下可工作的纯 C++ 代码。其余 1% 不工作的情况是指加载 ntdll.dll:这种情况既是文档中所说的第一个 DLL 事件。即使延迟到下一个被调试程序事件发生时(参见 CLoadLibraryDebugger 的 OnDebugEvent)才获取路径名。在文档的描述中,可以调用 SearchPath 从模块名获得全路径名,“system32”对于 ntdll.dll 并不感到惊讶。这个 API 函数使用与 LoadLibrary 同样的算法在文件系统中查找某个 DLL。从理论上讲,因为它是由调试器调用的,有可能返回的文件并不是被调试程序加载的那个文件——例如,在调试器文件夹中存在另外一个版本的 ntdll.dll。在实际应用中,ntdll.dll 得不到打补丁的机会,并且被拷贝到了某个与 system32 不同的目录。

上一页  1 2 3 4 5 6  下一页

Tags:定制 调试 诊断

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接