【问题标题】:Can't use newline in OutputDebugStringW, weird behavior in DbgView无法在 OutputDebugStringW 中使用换行符,在 DbgView 中出现奇怪的行为
【发布时间】:2021-09-20 05:53:56
【问题描述】:

我在我的应用程序中使用 OutputDebugStringW。由于 WinDBG 不会自动添加换行符,因此我必须在输出缓冲区中添加 \n

#include <iostream>
#include <windows.h>

int main()
{
    wchar_t buff[100];
    ZeroMemory(buff, sizeof(buff));
    _snwprintf_s(buff, sizeof(buff) / sizeof(wchar_t) - 1, L"[test] %d", GetCurrentThreadId());
    buff[wcslen(buff)] = L'\n';
    OutputDebugStringW(buff);

    char buff2[100];
    ZeroMemory(buff2, sizeof(buff2));
    snprintf(buff2, sizeof(buff2), "[test2] %d", GetCurrentThreadId());
    buff2[strlen(buff2)] = '\n';
    OutputDebugStringA(buff2);
}

它可以工作,但 DbgView 打印出意想不到的东西:

  1. 对于 OutputDebugStringA,换行符可以正常工作
  2. 对于 OutputDebugStringW,换行符无法识别

如果我不附加换行符,它们都可以正常工作。这里有什么问题?

【问题讨论】:

  • @KenWhite 缓冲区大小为 100 * sizeof(wchar_t) 并且在使用前被清空。而且我只使用前 10 个字节,所以没有覆盖 NULL 终止符之类的东西。
  • @KenWhite 实际功能要复杂得多。新行最后要加,格式串不能用,更新问题
  • 我最初的想法是也覆盖终结符,因为这看起来确实像那样。我不会惊讶地发现在调试构建中整个缓冲区都填充了一个已知值,例如 0xFD,因此即使在调用之前它被归零,它在它之后也不是 0。测试起来很容易,可以在\n 之后添加一个 0,或者转储缓冲区的字节。
  • 原来是_snwprintf_s之后的0xfefe。无法通过快速搜索找到它的文档,但有这样的:stackoverflow.com/questions/61135165/… 0xfe 是调试堆用来填充闲置内存的已知值:stackoverflow.com/a/370362/920069
  • @RetiredNinja 有趣...snprintf 家族未在_CrtSetDebugFillThreshold 下列出,但一定是它。

标签: c++ windows wchar-t


【解决方案1】:

正如 Retired Ninja 所指出的,如果程序是在 DEBUG 模式下构建的,_snwprintf_s 会用另一个值填充缓冲区。在这种情况下,wchar_t 被 0xFEFE 填充:

如果我在 Release 模式下编译程序,字符串将以 NULL 结尾。

【讨论】:

  • 你应该永远依赖缓冲区的先前内容,明确地将空终止符放在那里。
  • "在 Release 模式下,字符串将以 NULL 结尾" — 除非wcslen(buff) == 99,否则要挑剔。
猜你喜欢
  • 2012-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
  • 1970-01-01
  • 1970-01-01
  • 2012-04-21
  • 1970-01-01
相关资源
最近更新 更多