大家好,我是Visual C++库组的软件设计工程师Pat Brenner。 很久以前我写过Spy++。 今天,我将介绍另一个visualstudio调试工具ATL/MFC跟踪工具,以及它在ATL和MFC中与之交互的跟踪机制。
追踪机制
跟踪机制用于控制在程序执行期间转储到输出窗口的信息类型和信息量。 有许多类别的信息,以及不同级别的信息,可以
显示。
跟踪宏
应用程序可以通过以下方式将跟踪消息输出到输出窗口:
· 使用ATLTRACE.h中定义的ATLTRACE宏(用于ATL)。
· 使用afx.h中定义的跟踪宏(用于MFC)。
ATLTRACE和TRACE宏在ATL和MFC源代码中都有使用。 例如,在atlmfcinclude文件夹的CStringT.h中,在CStringT::CheckImplicitLoad方法中,可以找到以下代码行:
ATLTRACE(atlTraceString,2,u T)(“警告:implicit LoadString(%%u)失败“(奈德);
如果string类别中的level-2消息被打开,这将把消息转储到output窗口。
ATL/MFC跟踪工具
下面是ATL/MFC跟踪工具的屏幕截图。 名为Editor.exe的MFC应用程序正在运行。 为Editor.exe进程中的MFC100UD.DLL模块选择“atlTraceString”类别。 因为在树中选择了一个类别,所以所有三个组(流程、模块和类别)都被启用。 如果在树中选择了Editor.exe进程,则仅启用进程组;如果在树中选择了MFC100UD.DLL模块,则仅启用进程和模块组。 使用此工具,您可以准确地配置要查看跟踪消息的类别,以及这些类别中的消息量。 这里我已经指出,我希望看到整个进程的跟踪消息的数量非常少,并且模块应该从进程继承设置,但是我已经重写了这些值,并指出我希望在string类别中看到中等数量的跟踪消息。
ATL跟踪类别
ATL可以转储的跟踪信息的类别:
· atlTraceGeneral:常规和杂项跟踪消息
· atlTraceCOM:COM对象和方法跟踪消息
· atlTraceQI:查询接口跟踪消息(ATL或MFC中未使用的类别)
· atlTraceRegistrar:注册跟踪消息
· atlTraceRefcount:引用计数跟踪消息(ATL或MFC中未使用的类别)
· atlTraceWindowing:Windows消息跟踪消息
· atlTraceControls:ActiveX控件相关的跟踪消息
· atlTraceHosting:与客户端/站点相关的就地跟踪消息
· atlTraceDBClient:与数据库客户端相关的跟踪消息
· atlTraceDBProvider:与数据库提供程序相关的跟踪消息
· atlTraceSnapin:管理单元相关的跟踪消息
· atlTraceNotImpl:“接口未实现”跟踪消息
· atlTraceAllocation:内存分配跟踪消息
· atlTraceException:“抛出异常”跟踪消息
· atlTraceTime:与COleDateTime相关的跟踪消息
· atlTraceCache:缓存相关跟踪消息(ATL或MFC中未使用的类别)
· atlTraceStencil:与模具相关的跟踪消息(ATL或MFC中未使用的类别)
· atlTraceString:CStringT相关跟踪消息
· atlTraceMap:CAtlMap相关跟踪消息
· atlTraceUtil:线程和线程池相关的跟踪消息
· atlTraceSecurity:CSecurityDesc/CAccessToken相关跟踪消息
· atlTraceSync:同步与对象相关的跟踪消息
· atlTraceISAPI:与ISAPI相关的跟踪消息(ATL或MFC中未使用的类别)
· atlTraceUser:用户定义的跟踪消息(在ATL或MFC中没有使用过时的类别)
· atlTraceUser2:用户定义的跟踪消息(ATL或MFC中未使用的过时类别)
· atlTraceUser3:用户定义的跟踪消息(ATL或MFC中未使用的过时类别)
· atlTraceUser4:用户定义的跟踪消息(ATL或MFC中未使用的过时类别)
注意:ATL或MFC内部未使用的类别可能会在ATL的未来版本中删除,以便清理ATL/MFC跟踪工具中的接口。
MFC跟踪类别
MFC可以转储的跟踪信息的类别:
· traceAppMsg:主消息泵跟踪消息,包括DDE
· traceWinMsg:Windows消息跟踪消息
· traceCmdRouting:Windows命令路由跟踪消息
· traceOle:特殊的OLE回调跟踪消息
· traceDatabase:特殊数据库跟踪消息
· traceInternet:特殊的internet客户端跟踪消息
· traceDumpContext:从CDumpContext跟踪消息
· traceMemory:通用的非内核内存跟踪消息
· traceHtml:HTML跟踪消息
· traceSocket:套接字跟踪消息
跟踪级别
跟踪机制转储的信息被分配一个从0(零)到4的级别,其中0是最重要的级别,4是最不重要的级别。 这些级别对应于ATL/MFC跟踪工具中滑块上的五个记号。
把它绑在一起
因此,根据我在上面的ATL/MFC跟踪工具中设置的设置,CStringT.h中上面的源代码行将把消息转储到输出窗口,因为尽管我已经指出我只需要进程中的0级和1级消息,但是我需要字符串类别中的2级消息。
工作原理
加载使用debug ATL(ATLSD.LIB)的模块时,初始化过程的一部分是全局CAtlAllocator对象gu分配器的初始化(请参阅atlmfcsrcatls文件夹中的externs.cpp)。 此方法创建一个命名的共享内存区域,部分名称是进程ID(例如,对于进程EB0A,共享内存区域命名为“AtlDebugAllocatoru FileMappingNameStaticu 100u EB0A”)。 此共享内存区域用于包含可由ATL/MFC跟踪工具修改的进程、模块和类别的所有设置。
当ATL/MFC跟踪工具启动时,它首先枚举系统中的所有进程,并针对每个进程检查是否存在该进程的命名共享内存(使用上述命名方案)。 如果是这样,那么该工具将加载该进程的所有设置,并从那时起能够修改共享内存区域中该进程的设置,从而影响该进程的运行时跟踪行为。
一个有趣的新发现
我们在ATL和MFC中实现了对预览、缩略图和过滤器(搜索)处理程序的支持。 它们由Windows资源管理器和其他Windows组件(包括Windows搜索服务)加载。 最近我们遇到了一个问题,Windows搜索组件无法加载我们的调试DLL,因此我们从未在索引位置获得搜索筛选器结果。 事实证明,这是因为搜索过滤器主机(加载ATL过滤器处理程序DLL以进行索引)在没有任何文件系统权限的情况下运行。 然而,ATL跟踪机制尝试使用CreateFileMapping API设置共享内存区域(用于与ATL/MFC跟踪工具通信)。 缺少文件系统权限导致此操作失败,DLL初始化被中止,因此没有调用我们的筛选器处理程序。 显然,这是一个问题,一直潜伏在ATL,因为跟踪机制被发明。 因此,为了解决这个问题,如果跟踪初始化失败,我必须允许DLL初始化继续,如果初始化失败,我只需退出对跟踪机制的任何进一步调用。 这样就可以加载DLL并正确调用过滤器处理程序,从而修复了错误。
我希望这很有趣。 如果你有任何问题,请告诉我。
帕特·布伦纳
Visual C++开发