将Debug调试信息输出到控制台或文件
时常会碰到这种情况,策划们跑过来说程序出错了,然后呱呱啦啦的描述了一大堆也没把问题说清楚。若是能将程序的运行信息自动的记录起来,找bug就方便多了,也就是log功能。
另外为调试程序,时常需要在程序里打入一些调试信息,这样可以更方便的发现BUG。这些调试信息只能在编辑器的调试模式下才能看到,或者借助第三方软件比如debugview等,但是会受到编译环境的限制,又不可能每次都带着debugview运行程序。。。若能将调试信息自动记录到log文件就方便多了。
在调试模式下,调试器之所以能够得到信息,是因为捕捉了程序中的 OutputDebugString() 输出的信息。所以如果我们能够自己写程序捕捉OutputDebugString()函数输出的信息,就能解决上述的需求了。有关OutputDebugString()函数的原理请看这里:http://www.unixwiz.net/techtips/outputdebugstring.html,也可在本blog查看翻译版本。
原理看明白后,实现起来就很容易了。下面给出具体代码:
1
const
MAX_DebugBuffer
=
4096
;
//
应用程序和调试器之间传递数据是通过一个 4KB 大小的共享内存块完成的
2
3

typedef
struct
dbwin_buffer
{
4
DWORD dwProcessId;
5
char data[4096-sizeof(DWORD)];
6
}
DEBUGBUFFER,
*
PDEBUGBUFFER;
7

8
//
线程函数
9
void
WINAPI DebugTrackProc(PVOID pvParam)
10

{
11
HANDLE hMapping = NULL;
12
HANDLE hAckEvent = NULL;
13
HANDLE hReadyEvent = NULL;
14
PDEBUGBUFFER pdbBuffer = NULL;
15
TCHAR tzBuffer[MAX_DebugBuffer];
16
17
// 打开事件句柄
18
hAckEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_BUFFER_READY"));
19
if(hAckEvent == NULL)
20
{
21
CloseHandle(hAckEvent);
22
return;
23
}
24
25
hReadyEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("DBWIN_DATA_READY"));
26
if(hReadyEvent == NULL)
27
{
28
CloseHandle(hReadyEvent);
29
return;
30
}
31
32
// 创建文件映射
33
hMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MAX_DebugBuffer, TEXT("DBWIN_BUFFER"));
34
if(hMapping == NULL)
35
{
36
CloseHandle(hMapping);
37
return;
38
}
39
40
// 映射调试缓冲区
41
pdbBuffer = (PDEBUGBUFFER) MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
42
43
// 循环
44
while( true )
45
{
46
// 激活事件
47
SetEvent(hAckEvent);
48
// 等待缓冲区数据
49
if ( WaitForSingleObject(m_hReadyEvent, INFINITE) == WAIT_OBJECT_0 )
50
{
51
// 保存信息,这就是我们想要的,有了这个信息,想打log或是输出到控制台就都可以啦
52
tzBuffer = pdbBuffer->szString;
53
}
54
}
55
56
// 释放
57
if (pdbBuffer)
58
{
59
UnmapViewOfFile(pdbBuffer);
60
}
61
CloseHandle(hMapping);
62
CloseHandle(hReadyEvent);
63
CloseHandle(hAckEvent);
64
}
版权声明:本篇为原创文章,允许转载,但转载时请务必以超链接形式标明文章的原始出处和作者信息。请尊重本人的劳动成果,谢谢!
小祥的BLOG http://xfxsworld.cnblogs.com