调试多线程程序

问题描述:

我一直是C程序员多年,我最喜欢的“调试器”一直是printf()函数 - 当绝对强制使用时,我只使用visual studio的调试器,因此从未非常熟练地使用它。最近我不得不修改一个程序,从C到C++(尽管当然printf仍然正常工作),并且程序的一部分现在已经出现在多个线程中(一个针对多核机器上的每个内核)以使程序运行更快。现在,我毫无疑问会遇到类似死锁这样的尴尬的多线程相关错误,并且我想知道我可以调用哪些调试方法。视觉工作室(2008)有我能合理需要的一切帮助我解决与线程有关的错误吗?我现在应该花点时间学习如何使用第三方调试器吗?我可以用我的老式printf来解决大多数问题吗?调试多线程程序

我可以写代码,如果一直等待进入临界区时会打印类似于“线程X等待输入......但由于被线程Y使用而被阻塞”的代码?

Visual Studio在一定程度上支持线程调试。通过线程窗口,您可以选择线程,挂起和恢复线程等。当您在线程之间切换时,相应地更新调用堆栈窗口,以便您可以检查每个线程正在做什么。你也可以限制断点到特定的线程。

如果你想要一个替代的WinDbg(它是微软提供的免费Debugging Tools for Windows包的一部分)提供了很多选项,但是稍微有一些更深奥的用户界面。

至于使用printf,存在同步输出的问题。如果你不这样做,你的输出很可能是胡言乱语。如果您同步它,则基本上会更改应用程序的并发性,这可能会影响您尝试解决的问题。

如果你可以将你的项目移植到Linux上,Valgrind(尤其是'helgrind'工具)将完全按照你的要求进行操作。 http://valgrind.org/

我不确定这是否正是你所问的,但是,为了帮助调试,你可以编写代码给每个线程一个“名称”,以便将调试消息打印到调试窗口(或一个日志文件或其他)包含该线程“名称”以及您规定的其他信息。下面的代码是在C#中,但这是,即使在非托管C++

Thread T = new Thread(RunSchedule); 
    T.Name = "Scheduler"; // <=== Thread given a name here... 
    T.Start(); 
+1

这可以通过使用WIN32 API函数void SetThreadName(DWORD dwThreadID,LPCSTR szThreadName)在“纯”本机C和C++中实现。这些名称也应该显示在VS调试器中(我没有检查过)。 – mmmmmmmm 2009-09-28 16:11:14

英特尔提供了多种工具,找出线程相关的问题可供选择:数据竞争,死锁,性能损失。这些工具是:英特尔线程检查器,英特尔线程分析器。