65.9K
CodeProject 正在变化。 阅读更多。
Home

Visual C++ 的 STL 错误消息解密器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2001 年 9 月 13 日

13分钟阅读

viewsIcon

78345

downloadIcon

483

一套工具,用于缩短 VC++ STL 相关错误消息的长度,以便消息中最关键的信息能够显示在 VS 的状态栏中。

Sample Image - image.jpg

目的

该想法是为了缩短 VC++ STL 相关错误消息的长度,以便消息中最关键的信息能够显示在 Visual Studio IDE 底部状态栏可见的区域内(有关启用状态栏的说明,请参见本文档顶部的“4.”项)。

许多您通常不需要看到的内容都被删除了,例如:

  • 修饰符“std::”、“class”、“struct”、“__thiscall”和“__cdecl”消失了
  • 迭代器被极大地缩短,仅为“IT”、“iter”或容器的“cont”、“cont::iter”(您可以选择使用哪种形式)。然后,您可以根据错误消息的其余上下文推断出类型详细信息。
  • 形式为 less<whatever> 的任何仿函数都被删除;其他仿函数则保持不变。这样,在使用关联容器时,默认的“less<...>”仿函数就不会弄乱消息。
  • 字符串、istreams 和 ostreams <char>、它们的特性等都简化为“string”、“istream”、“ostream”等。太棒了!
  • iostream 迭代器被识别并缩写。
  • 类型名称中的分配器完全消失,函数参数列表中的分配器则简化为“alloc”(谢天谢地……)。

目前,所有*标准*容器都已得到处理,适用于 VC++6 库的发行版本、Dinkumware 库的 3.08 版本和 STLPort 的 4.x 版本。注意:非标准容器(如 Dinkumware 的 hash 和 slist)目前不受支持。

当然,我肯定会忽略一些情况,有些情况是我不知道如何过滤的。欢迎反馈,但这里是免责声明:

我写这个的目的是使用 Koenig/Moo 方法来教授 C++,而不会因为异常复杂化的 STL 错误消息吓跑学生。因此,过滤器保留了足够的信息来隔离*最常见的*错误(参数数量错误、参数类型错误等),这些错误出现在标准容器操作涉及大多数日常数据类型时。STL 高级用户始终可以禁用过滤来查找需要删除详细信息的错误,然后在不再需要这些详细信息时重新启用过滤。提供了两种启用/禁用过滤的方法:

  1. STLFilt.BAT 文件带宽占用少。
  2. STLTask 托盘图标程序使用方便,并且允许随时即时安装/卸载/重装代理 CL。

工作原理

1. 细节

安装/激活后,MSVC IDE 会找到代理 CL 并像调用本机 CL.EXE 程序一样调用它。代理 CL 会检查控制切换文件(FILTERING.ON)是否存在。如果*未*检测到切换文件,代理 CL 只会用它自己收到的命令参数调用本机 CL.EXE(通常重命名为 CL2.EXE)。这会产生普通的错误消息输出。

如果检测到切换文件*并且*正在编译的文件类型符合过滤条件(有关代理 CL 如何进行此判断的详细信息,请参阅下文“Bug/限制”部分的第 4 项),则代理 CL 会在原生 CL.EXE 和 Perl 调用之间设置一个进程间管道。原生 CL 的输出流将被管道传输到 Perl 进程的标准输入(执行 STLFilt.pl 脚本),以简化 STL 相关消息。然后,Perl 脚本的输出会被 MSVC IDE 捕获并在其输出区域显示,而*原生* CL 进程的进程状态码将控制 IDE 构建序列的后续行为。

2. 理由

虽然代理 CL 需要执行的命令行处理有些棘手,但它现在似乎能很好地处理大多数 MSVC 生成的构建脚本(第三方基础构建除外,例如使用 TrueTime 等工具时)。我使用的切换文件方案在启用/禁用过滤方面的主要好处是它不需要频繁重命名文件——我的理论是,如果主要的可执行文件经常需要重命名,那是在自找麻烦。

在过滤器的早期,MSVC 生成的构建脚本处理中存在几个持续的 bug,所以我给了 STLTask(任务栏实用程序)安装/卸载过滤器的功能(参见 GLOSSARY.txt 中“Active/Inactive”的描述),以便更轻松地运行不带代理 CL bug 的原生构建。这种安装/卸载会将代理 CL (CL.STL) 或原生 CL (CL2.EXE) 复制到 CL.EXE。由于在这些操作过程中可能发生崩溃等情况,STLTask 会*非常努力*地确保文件保持一致状态。如果启动时对过滤器的当前状态(已安装还是未安装?)有任何疑问,STLTask 默认会将所有内容重置为原生的 MSVC 配置(未安装代理 CL)。

发布详情

STLFilt 网页:www.bdsoft.com/tools/stlfilt.html
STLFilt.pl(Perl 脚本):版本 1.1(2001 年 9 月 2 日)
CL.CPP(代理 CL):版本 2.12(2001 年 9 月 8 日)
STLTask 任务栏图标控制器:版本 2.02(2001 年 9 月 9 日)

有关简要概述和快速设置说明,请参阅 QUICKSTART.txt。

请勿直接重新分发此软件包的任何部分;相反,为了确保人们获得最新版本,请引导所有感兴趣的人直接从其网页 www.bdsoft.com/tools/stlfilt.html  下载最新的 stlfilt.zip。

CUJ 网站上提供的 stlfilt.zip 版本*不是*最新版本。

要接收更新通知并有机会参与与其他过滤器用户的论坛,请发送电子邮件至:majordomo@www.bdsoft.com ,并在消息正文中包含“subscribe stlfilter”一行。

此存档包含什么

README.txt

您正在阅读它:目的、Bug/限制、清单、致谢和无耻的自我推销都在这里。

GLOSSARY.txt   

此软件和文档中使用的术语定义。

QUICKSTART.txt

快速入门设置说明,适合急性子。仅包含必要的说明(从该发行版中的其他文档编译而成),这些说明对于快速启动解密器组件至关重要。

STLTask-README.txt

有关使用 STLTask.EXE 程序的补充文档。

CL.EXE   

 模仿 CL 的代理编译器。在 Visual Studio 编译期间替换原生的 CL.EXE,并间接调用它。

STLTask.EXE   

基于任务栏的代理 CL 控制实用程序。STLTask 控制代理 CL 的安装/卸载、过滤器切换、剪贴板过滤以及准备应用 Visual Studio Service Pack。STLTask 提供 STLFilt.BAT 的替代方案来切换过滤器控制文件。STLTask 的安装/卸载功能适用于代理 CL 不能正常工作的情况,例如复杂项目、使用第三方工具(如 TrueTime)构建的项目、同一命令行上混合 C++ 和非 C++(idl/odl?)目标的项目等。“卸载”功能可以轻松地在这些类型的构建中将代理 CL 完全移除,然后通过选择“安装”将其重新引入以便后续工作。

PROXY-CL.INI   

供 CL.EXE 和 STLTask.EXE 使用的 ASCII 配置文件。根据您的系统情况编辑此文件,将其放置在 Windows 目录(C:\Windows 或 C:\Winnt 等)中,它将覆盖 CL.EXE 和 STLTask.EXE 的内置设置。

STLFilt.pl

 Perl 脚本。

STLFilt.BAT

低带宽批处理文件实用程序,用于切换过滤控制文件。说

stlfilt on 

stlfilt off 

来控制过滤。在 Visual Studio 中工作时最有用(您可以从 DOS 窗口运行 STLFilt.BAT,或安装选项将其直接调用到 VC++“工具”菜单)或使用 makefiles。当直接从命令行编译时,只需选择运行 CL 或 CL2(CL2.EXE 是原生 CL.EXE 副本的推荐名称)。

注意:STLFilt.BAT 和 STLTask.EXE 协同工作,可以互换使用来启用/禁用代理 CL 过滤。

CL.cpp

 代理 CL 程序的源代码。

STLTask-src.zip   

 STLTask 实用程序的源代码。构建 STLTask.EXE 需要安装 wxWindows 库。

CUSTOMIZE.txt

 关于从源代码重建 CL.EXE 和 STLTask.EXE 以及使用 STLFilt.bat 批处理文件启用/禁用过滤的说明。

Samples.zip

 大量 CPP 文件,可生成各种 STL 相关错误。尝试在有和没有过滤器的状态下运行它们!

CL-log.txt

 CL.cpp 和 STLFilt.pl 的修订日志。

STLTASK-log.txt

 STLTask.cpp 的修订日志。

README.STLport

 有关 Perl 脚本中 STLPort 特定过滤问题的注释。

CUJ 文章

有关此软件包的起源和理念的背景信息,请参阅我在 2001 年 7 月的《The C/C++ Users Journal》杂志上的文章。该文章是 2001 年 7 月的网络特色文章——这意味着它现在并且永远可以在 CUJ 网站上完整查看,网址如下:http://www.cuj.com/articles/2001/0107/0107b/0107b.htm?topic=articles

自从 CUJ 文章在出版前定稿以来,对软件进行了一些实质性的更改,使得文章中的部分内容已过时。它们是:

  1. STLFilt.pl 中的迭代器策略设置已从数值(1、2 或 3)更改为符号值(S、M 或 L)。原始的“1”设置对应新的“L”(“Long”或“Large”扩展),原始的“3”对应新的“S”(“Small”或“Short”扩展)。新的“M”顾名思义,表示“Medium”扩展。(感谢 Scott Meyers 建议使用符号而不是
    数值命名。)
  2. 作为 STLFilt.BAT 批处理文件的 GUI 替代方案,添加了基于任务栏的 STLTask 实用程序。
  3. 已向 STLFilt.pl 添加了 STLPort 库支持。同一个 Perl 脚本现在可以与所有三个库一起工作。
  4. 我在文章中提到的“细则状态行”终于有了名字:它被称为“状态栏”,在 Visual Studio 中通过“工具...选项...工作区”复选框“显示状态栏”来打开和关闭。我建议您保持开启状态;大多数时候,这将消除滚动输出窗口的需要。
  5. 文章中的安装说明要求将代理 CL.EXE “放在系统 PATH 的某个位置”。从 CL.CPP 的 v2.1 版本(和 STLTask 的 v2.0 版本)开始,代理 CL 应该直接放入 MSVC 的 bin 目录(...\VC98\bin)。有关当前安装程序,请参阅 QUICKSTART.txt。
  6. 现在发行版中包含了 CL.EXE 和 STLTask.EXE 的预编译版本。这两个程序在启动时都从放置在 Windows 目录中的配置文件(Proxy-CL.INI)读取配置信息。如果配置文件不存在,则所有选项都将默认为源代码中配置并编译到程序中的值。

Bug/限制

  • 在各种 Perl 实现中,ActiveState 似乎效果最好。我收到了几份关于将过滤器与其他 Perl(如 MKS 和 Cygwin)结合使用时出现进程间 bug 的报告。因此,如果您遇到涉及僵尸 Perl 进程等的奇怪错误,请首先尝试安装并使用 ActiveState Perl 进行过滤。然后您仍然可以像往常一样使用您的*其他* Perl。
  • 我还没有弄清楚如何过滤一些与字符串相关的 STL 错误(例如,请参阅 samples.zip 存档中的 tstring.cpp)。如果您能提出处理这类构造的方法,我很乐意尝试处理它们……
  • 对间接(@filename)命令行的支持仅限于相当典型的情况;代理 CL 在检测到 @filename 是命令行上的*唯一*参数时,会打开间接文件,并且只查看它*最后一行*上的*最后一个*项目。仅当此项目具有可接受的 C++ 扩展名(filterExt 字符串数组中的条目之一)时,才会执行过滤。该名称可能带有引号。因此,如果有多行源代码文件名(或者源文件名不是最后一行的最后一个内容),并且混合了启用了过滤和未启用过滤的扩展名,那么间接命令行文件可能会表现不正确。到目前为止,还没有人向我报告 VC 生成的项目我无法正确处理,但这并不一定意味着它不会发生……
  • 当 CL 的第一个命令行参数*不是*间接“@”文件名时,它会从右到左扫描 argv,查找第一个既不是具有“对象文件”扩展名(objExt 数组中的字符串之一)的文件名,也不是没有任何扩展名的字符串(假定它们是选项)的参数。是否过滤的决定是基于第一个(从右到左)不是这些东西的参数。

  • 包含转义双引号的命令行,例如 /D 定义,可能无法被 CL 正确处理。它现在通过在所有“"”字符前添加反斜杠来处理它们。更进一步,为了普遍处理如下行:

    ... /DHAIRY="Here's a double quote: \" and a backslash: \\"

    将需要一个全功能的、状态驱动的解析器来处理*所有*的排列组合……至少目前来说,编译这些行的唯一方法是卸载过滤器。

当出现上述任何问题并且您希望恢复到标准错误消息时,最简单的方法是使用 STLTask“卸载”代理 CL,直到您再次需要过滤。然后使用 STLTask 再次“安装”。

如果您在上面描述的项目文件问题方面遇到困难,可以尝试在 Visual Studio 中启用过滤后进行“仅编译”,而不是构建项目。

调试功能

CL.CPP 和 STLTask.EXE 内置了调试功能。CL.CPP 支持运行时调试配置:将 DEBUG 配置选项设置为 true,会将状态消息记录到名为 CL-dblog.txt 的文件中,该文件位于 DEBUG_DIR 选项配置的目录中。对于项目文件,启用调试时,CL.EXE 还会创建一个名为“atfile.txt”的临时 @ 文件副本。这有助于确定 CL 未能正确处理项目构建的原因。

STLTask.CPP 调试必须在编译时配置。将 DEBUG 符号设置为 1,并将 DEBUG_DIR 符号定义为所需日志文件目录的名称,STLTask 将把各种状态信息记录到指定目录中名为“debug.out”的文件中。

如果您遇到代理 CL 失败的情况,请告知我,以便我修复它。如果您理解问题并且能够描述具体情况,那就太好了……如果不能,我很乐意帮助找出问题并希望修复 CL 以便将来使用;请将项目简化到导致 CL 失败的最小可能配置,将其压缩并通过电子邮件发送给我(leor@bdsoft.com)。我会尽力确定
问题并纠正它。这个程序之所以现在如此可靠,*完全*是因为像您这样的人向我报告了问题(而且在许多情况下甚至为我修复了问题!)。

致谢

感谢

  • Dave Smallberg 提出错误过滤的想法(真希望我能自己想到)。
  • Scott Meyers 主持了 ESTL 研讨会——这次活动启发了这个项目。
  • Thomas Becker 编写了 CL.CPP 中的 win32 进程间通信代码。
  • 那些花费时间给我发送 Bug 和建议邮件的人,以及/或帮助调试的人。
  • Thomas Becker
    Wilka
    Sam Saariste
    Scott Lewandowski
    Scott Meyers
    Tom Malcolmson
    Jan Stette
    Dominic Mathieu
    Michael Cook
    Andy Philpotts
    Rob Bishop
    John Hattan
    Derek Price
    Bill Torpey
    John Penney
    Jonathan Sambrook 
    Argos
    Matthew Douglass
    Dave Conrad
    Scott McCaskill
    Paul Suggs
    Karl Lean

历史

2002 年 11 月 7 日 - 更新了下载。

© . All rights reserved.