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

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

备注

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

安全说明安全说明

此代码示例用于阐释一个概念,并且仅显示与此概念相关的代码。该代码可能不符合特定环境的安全要求,因此不应原样搬用所显示的代码。我们建议您添加安全性代码和错误处理代码,以使项目更加安全可靠。Microsoft“原样”提供此代码示例,不提供任何保证。

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

访问 Visual Studio 中的示例

  • 在**“帮助”菜单上,单击“示例”**。

    默认情况下,这些示例安装在 drive:\Program Files\Microsoft Visual Studio 10.0\Samples\ 中。

  • 有关此示例的最新版本以及其他示例的列表,请参见 MSDN 网站上的 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

请参见

其他资源

常规示例