Skip to content

Instantly share code, notes, and snippets.

@mmozeiko
Created April 16, 2019 19:20
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mmozeiko/bfe0ce5762c496f92d8c775983c41694 to your computer and use it in GitHub Desktop.
Save mmozeiko/bfe0ce5762c496f92d8c775983c41694 to your computer and use it in GitHub Desktop.
Example how to capture OutputDebugString on Windows
#include <windows.h>
#include <intrin.h>
#define Assert(x) do { if (!(x)) __debugbreak(); } while (0)
static struct
{
DWORD process_id;
char data[4096 - sizeof(DWORD)];
}* ods_buffer;
static HANDLE ods_data_ready;
static HANDLE ods_buffer_ready;
static DWORD WINAPI ods_proc(LPVOID arg)
{
DWORD ret = 0;
HANDLE stderr = GetStdHandle(STD_ERROR_HANDLE);
Assert(stderr);
for (;;)
{
SetEvent(ods_buffer_ready);
DWORD wait = WaitForSingleObject(ods_data_ready, INFINITE);
Assert(wait == WAIT_OBJECT_0);
DWORD length = 0;
while (length < sizeof(ods_buffer->data) && ods_buffer->data[length] != 0)
{
length++;
}
if (length != 0)
{
DWORD written;
WriteFile(stderr, ods_buffer->data, length, &written, NULL);
}
}
}
void ods_capture()
{
if (IsDebuggerPresent())
{
return;
}
HANDLE file = CreateFileMappingA(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(*ods_buffer), "DBWIN_BUFFER");
Assert(file != INVALID_HANDLE_VALUE);
ods_buffer = MapViewOfFile(file, SECTION_MAP_READ, 0, 0, 0);
Assert(ods_buffer);
ods_buffer_ready = CreateEventA(NULL, FALSE, FALSE, "DBWIN_BUFFER_READY");
Assert(ods_buffer_ready);
ods_data_ready = CreateEventA(NULL, FALSE, FALSE, "DBWIN_DATA_READY");
Assert(ods_data_ready);
HANDLE thread = CreateThread(NULL, 0, ods_proc, NULL, 0, NULL);
Assert(thread);
}
int main()
{
ods_capture();
OutputDebugStringA("hello\n");
OutputDebugStringW(L"unicode?\n");
OutputDebugStringA("...\n");
}
@sir-pinecone
Copy link

Thanks for this. Do you know if it's possible to only capture OutputDebugString calls from the current process? I was just running my app, opened Steam and saw logs coming in from Steam :P

@mmozeiko
Copy link
Author

When ods_data_ready event is signaled you can compare process_id with your process id, if it does not match, then ignore it - skip WriteFile in my example.

@sir-pinecone
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment