crt_dbg2 示例:C 运行时调试挂钩函数

更新:2007 年 11 月

crt_dbg2 示例演示了几种将调试挂钩函数用于多种 C 运行时库的调试版本的方法。为了增加真实性,它包含了一些实际应用程序元素(包括两处 bug)。

说明:

Intel 的 Itanium 处理器不支持此示例。

安全说明:

提供该示例代码是为了阐释一个概念,并不代表着最安全的编码实践,因此不应在应用程序或网站中使用该示例代码。对于超出本示例代码的预期用途以外的使用所造成的偶然或继发性损失,Microsoft 不承担任何责任。

获取示例和安装示例的说明:

  • 在 Visual Studio 的“帮助”菜单上,单击“示例”。

    有关更多信息,请参见定位示例文件

  • 示例的最新版本和完整列表可以从 Visual Studio 2008 Samples(Visual Studio 2008 示例)联机获取。

  • 还可以在计算机的硬盘上查找示例。默认情况下,示例和自述文件将复制到 \Program Files\Visual Studio 9.0\Samples\ 下的文件夹中。对于 Visual Studio 速成版,所有示例都位于联机位置。

生成并运行示例

生成并运行此示例

  1. 打开解决方案 crt_dbg2.sln。

  2. 从“生成”菜单中,单击“生成”。

  3. 从“调试”菜单中,选择“开始执行(不调试)”。

示例的工作机制

程序在 Client 块的链接表中存储生日信息。客户端转储挂钩函数验证这些生日数据并报告 Client 块的内容。分配挂钩函数将堆操作记录到文本文件中,报告挂钩函数将选定的报告记录到同一文本文件中。

请注意,分配挂钩函数将 CRT 块(由 C 运行时库内部分配的内存)从其日志中显式地排除。挂钩函数使用 fprintf 写入日志文件,并且 fprintf 将分配一个 CRT 块。如果在这种情况下未排除 CRT 块,则无限循环将导致溢出堆栈:fprintf 将导致调用挂钩函数,挂钩函数则调用 fprintf,fprintf 又会导致再次调用挂钩函数,以此类推。

为了能够在分配挂钩中报告 CRT 类型的块,可以使用 Windows API 函数来替代 C 运行时函数。由于 Windows API 不使用 CRT 堆,因此它们不会使挂钩函数陷入无限循环。

调试堆在第二个示例中捕获了两个 bug 和一个数据错误。一个 bug 是生日名称字段不够大,无法保存若干测试名称。该字段应当更大,应使用 strncpy 而非 strcpy。第二个 bug 是 printRecords 函数中的 While 循环在 HeadPtr 自身等于 null 之前不应停止。此 bug 不仅会导致生日显示不完整,而且会导致内存泄漏。最后,Gauss 的生日应该是 4 月 30 日,而不是 4 月 32 日。

关键字

此示例使用以下关键字:

_assert、_asserte、_crtcheckmemory、_crtmemcheckpoint、_crtmemdumpallobjectssince、_crtmemdumpstatistics、_crtsetallochook、_crtsetdbgflag、_crtsetdumpclient、_crtsetreportfile、_crtsetreporthook、_crtsetreportmode、_free_dbg、_malloc_dbg、_rpt4、_strdate、_strtime、aboutbox、clear_crt_debug_field、createinstance、createrecord、displaystring、donttouch、exit、fatalerror、fclose、fflush、fopen、fprintf、fputs、get_size、helpstring、id、iid_is、module、myallochook、mydumpclienthook、myreporthook、pointer_default、printf、printrecords、put_size、set_crt_debug_field、strcpy_s、strstr、uuid

请参见

其他资源

通用示例