【发布时间】: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 打印出意想不到的东西:
- 对于 OutputDebugStringA,换行符可以正常工作
- 对于 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下列出,但一定是它。