学编程是从DOS下开始的,用了一定时间的TC2.0,使得养成了用printf输出变量值进行调试的坏习惯。到了写窗口程序时,就遇到了些麻烦。
窗口程序没有方便的进行控制台输出的方法(其实是我不知道),于是,用了几年的用MessageBox进行输出的调试手段,太麻烦了,因为MessageBox会打断程序流程,还要人为手动让它继续运行,这是最让人恼火的。
后来用上了VC.NET2003,发现有OutputDebugString这个调试API,在IDE下调试,则会把它的输出定向到IDE中的Debugger上。
再后来发现了DebugTrack,它可以截获OutputDebugString的输出,而不用开其它笨重的debugger。
于是,照着它的参考文档,自己写了个截获OutputDebugString输出的程序LLYF DebugCapture。
DebugCapture完全按照这份文档(http://www.unixwiz.net/techtips/outputdebugstring.html
)中的方法来捕捉调试输出:
先建立一个新线程,在线程中循环:
void __fastcall TCaptureDBString::Execute()
{
/********************************************************************************************
* 1. Create the shared memory segment and the two events. If we can't, exit.
* 2. Set the DBWIN_BUFFER_READY event so the applications know that the buffer is available.
* 3. Wait for the DBWIN_DATA_READY event to be signaled.
* 4. Extract the process ID NUL-terminated string from the memory buffer.
* 5. Go to step #2
********************************************************************************************/
TSharedMem sm("DBWIN_BUFFER", sizeof(struct dbwin_buffer));
TListItem *Item;
char szFileName[MAX_PATH];
hBufReadyEvent = CreateEvent(
NULL, // no security attributes
FALSE, // auto-reset event
FALSE, // initial state is nonsignaled
"DBWIN_BUFFER_READY" // object name
);
if (hBufReadyEvent == NULL)
{
MessageBox(GetActiveWindow(),
"Cannot create event of DBWIN_BUFFER_READY",
NULL,
MB_OK);
return;
}
hDataReadyEvent = CreateEvent(
NULL, // no security attributes
FALSE, // auto-reset event
FALSE, // initial state is nonsignaled
"DBWIN_DATA_READY" // object name
);
if (hBufReadyEvent == NULL)
{
MessageBox(GetActiveWindow(),
"Cannot create event of DBWIN_DATA_READY",
NULL,
MB_OK);
return;
}
while(1)
{
::SetEvent(hBufReadyEvent);
::WaitForSingleObject(hDataReadyEvent, INFINITE);
if(Terminated) //Thread terminated flag
{
::SetEvent(hBufReadyEvent);
CloseHandle(hBufReadyEvent);
CloseHandle(hDataReadyEvent);
return;
}
DebugString = *((struct dbwin_buffer*)(sm.Buffer()));
EnterCriticalSection(&CriticalSection);
//display the result string
//including PID,Output string, Process Path
Item = MainForm->DebugListView->Items->Add();
Item->Caption = IntToStr(MainForm->DebugListView->Items->Count);
Item->SubItems->Add(IntToStr(DebugString.dwProcessId));
Item->SubItems->Add(DebugString.data);
Item->SubItems->Add(GetProcessPath(DebugString.dwProcessId, szFileName));
ListView_EnsureVisible(MainForm->DebugListView->Handle,MainForm->DebugListView->Items->Count-1,false);
LeaveCriticalSection(&CriticalSection);
}
}
其中用于内存映射进行数据传递的结构如下:
struct dbwin_buffer {
DWORD dwProcessId;
char data[4096-sizeof(DWORD)];
};
这样,我也可以不用借助其它debugger进行像DOS下的调试了。
如果要更像printf一点,还可以对OutputDebugString加上一个Wrapper:
#include <stdio.h>
#include <stdarg.h>
/*************************************************
* Example usage(Just like C library function **printf**):
* ......
* OutputDebugPrintf("Error: %d.", GetLastError());
* ......
*************************************************/
void OutputDebugPrintf(LPCTSTR ptzFormat, ...)
{
va_list vlArgs;
TCHAR tzText[1024];
va_start(vlArgs, ptzFormat);
wvsprintf(tzText, ptzFormat, vlArgs);
OutputDebugString(tzText);
va_end(vlArgs);
}
调用OutputDebugPrintf就可以像printf进行格式化输出了,哈哈。
分享到:
相关推荐
的时候打印调试信息通常习惯是用自己封装好的函数利用 OutPutDebugString函数输出然后借助DbgView查看,但是有时候系统上其它程序也用OutPutDebugString在输出一些信息的时候,这样的话DbgView窗口上的信息就显得很...
当这段代码运行时,"这是个调试信息"将在调试器(如Visual Studio的调试窗口)中显示。 现在,我们关注的重点是如何捕获`OutputDebugString`的输出。这通常需要编写一个小型的系统钩子(System Hook),通过注册...
3. 运行你的程序,程序中的`OutputDebugString`调用会实时地显示在DebugView的窗口中。 这种组合方式对于测试和调试分布式系统、服务或者后台进程尤其有用,因为它无需修改代码或附加调试器即可查看调试信息。 ...
在标题中提到的"DebugVeiw程序调试工具"是指DebugView,它支持捕获来自任何使用`OutputDebugString()`函数发送调试消息的进程。`OutputDebugString()`是Windows API中一个非常实用的函数,它允许开发者在代码中插入...
在实际使用中,只需双击该文件即可开启调试窗口,然后程序中的调试信息就会自动显示出来。 3. Readme-说明.htm:通常,这个文件包含了一些关于软件的更新信息、注意事项或者使用提示。开发者应仔细阅读,以确保正确...
在遇到错误时,利用`OutputDebugString()`输出信息,结合“调试”>“窗口”>“输出”窗口查看。 6. **动态包**: 标签中提到的“动态包”可能指的是动态链接库(DLL)。如果你的项目需要使用特定的图像处理功能,...
5. **测试程序`: `Demo For DebugView`是一个示例程序,用于演示如何在代码中使用OutputDebugString函数,并观察DebugView如何显示这些调试信息。 **三、应用场景** DebugView广泛应用于软件开发、系统调试、驱动...
开发者可能使用了`OutputDebugString`来输出调试信息,以及适当的错误检查和异常处理代码。 这个初学者的时钟程序是一个很好的实践项目,它涵盖了许多基础的Windows编程概念。通过分析和理解这个程序,可以深化对...
在Windows系统中,许多程序会使用`OutputDebugString`函数来打印调试信息,这些信息通常在开发阶段用于追踪代码运行状态,但默认情况下,这些信息并不会显示在用户界面中。DebugView就是用来显示这些调试字符串的...
1. **实时调试输出查看**:DebugView可以实时显示通过`OutputDebugString`发送的调试信息,这使得开发者无需打开源代码或使用IDE,就能在程序运行过程中观察其内部状态。 2. **多线程支持**:它能够区分不同线程...
10. **调试技巧**:使用Visual Studio或其他IDE进行程序调试,`OutputDebugString`方便在调试器中查看程序内部信息,`DebugBreak`启动断点调试。 以上知识点构成了Windows程序设计的基础。在"2611190206崔培培...
例如,使用`TTimer`组件配合`AnimateWindow` API函数可以创建平滑的窗口动画效果。对于更复杂的特效,可以研究VCL库中的TPageControl和TSkinManager组件,它们提供了丰富的界面定制选项。 3. **Delphi小程序实例**...
8. **调试和错误处理**:掌握`OutputDebugString`、调试器的使用以及如何处理异常和错误,对于开发稳健的Windows应用程序是必不可少的。 9. **注册表操作**:Windows注册表存储了系统的配置信息,程序可以通过API...
源码可能会包含错误检查和调试输出,使用诸如OutputDebugString这样的函数。 总之,"windows程序设计源码"是一个丰富的学习资源,它涵盖了Windows编程的基本要素和高级特性。通过研究这些源码,开发者不仅可以学习...
8. **调试技术**:如使用DebugBreak启动调试器,或者使用OutputDebugString输出调试信息。 《Windows程序设计》一书详细介绍了以上内容,通过实例和详细解释,帮助读者理解并掌握Windows编程的核心概念和技术。通过...
10. **调试和优化**:源代码中可能包含调试信息和优化技巧,例如使用`OutputDebugString`输出调试信息,或者利用Visual Studio的性能分析工具进行代码优化。 通过研究这个源代码集合,开发者不仅可以加深对Windows...
10. **调试技术**:使用`OutputDebugString`输出调试信息,配合调试器进行程序调试。 通过《Windows程序设计》的源代码,读者可以深入理解上述知识点,并学习如何实际应用。这些源代码不仅提供了示例,也是检验理论...
它能捕获控制台窗口通常无法看到的调试输出,无论是来自用户模式的应用程序还是内核模式的驱动程序。它支持两种类型的调试输出:内核模式和用户模式。内核模式的输出捕获来自于系统内核、驱动程序和服务,而用户模式...
然而,对于一些特定情况,如使用printf或OutputDebugString输出的信息无法在VC6.0的调试窗口中直接查看,这给调试带来了困扰。这时,`TRACEWIN`工具就显得尤为实用。 `TRACEWIN`是一款专门用于VC++的调试辅助工具,...
4. **查看信息**:在`DebugView`窗口中,你会看到应用程序发送的调试信息,每行代表一次`OutputDebugString`调用。信息按照接收的顺序实时更新,你可以通过时间戳追踪程序的执行流程。 5. **过滤和保存**:`Debug...