将Debug调试信息输出到控制台或文件

        时常会碰到这种情况,策划们跑过来说程序出错了,然后呱呱啦啦的描述了一大堆也没把问题说清楚。若是能将程序的运行信息自动的记录起来,找bug就方便多了,也就是log功能。

        另外为调试程序,时常需要在程序里打入一些调试信息,这样可以更方便的发现BUG。这些调试信息只能在编辑器的调试模式下才能看到,或者借助第三方软件比如debugview等,但是会受到编译环境的限制,又不可能每次都带着debugview运行程序。。。若能将调试信息自动记录到log文件就方便多了。

        在调试模式下,调试器之所以能够得到信息,是因为捕捉了程序中的 OutputDebugString() 输出的信息。所以如果我们能够自己写程序捕捉OutputDebugString()函数输出的信息,就能解决上述的需求了。有关OutputDebugString()函数的原理请看这里:http://www.unixwiz.net/techtips/outputdebugstring.html,也可在本blog查看翻译版本。

        原理看明白后,实现起来就很容易了。下面给出具体代码:

 1const MAX_DebugBuffer = 4096;    // 应用程序和调试器之间传递数据是通过一个 4KB 大小的共享内存块完成的
 2
 3typedef struct dbwin_buffer {
 4    DWORD   dwProcessId;
 5    char    data[4096-sizeof(DWORD)];
 6}
DEBUGBUFFER,*PDEBUGBUFFER;
 7
 8// 线程函数
 9void 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, 000);  
42  
43    // 循环  
44    whiletrue )
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