我在Unix上使用线程已有20年了,而在Windows上使用Visual Studio 2008来学习它们。
我的应用程序是基于对话框的MFC GUI,具有四个主“对等”窗口(都不是“主”窗口)。当MyApp::InitInstance()启动时,“调试”->“Windows”->“线程”窗口仅报告单个线程MainThread。当我经过第一个CDialog::Create()
调用时,将创建3个工作线程。我不知道这些是什么,也不会喜欢,尤其是希望引用完整的解释性书或网页。我尝试在CreateThread()
上放置一个断点,但是VS2008报告:悬停在断点窗口中The function cannot be found.
图标上的!
。如果我闯入了一个调用它的函数,我也不能单步进入它。我假设它是一个系统调用,并且由于内核代码VS08无法访问它。
然后,我创建一个输出音频的工作线程,并将其设置为THREAD_PRIORITY_TIME_CRITICAL。这已经稳定了很长时间了。
但是,一旦我的应用离开MyApp::InitInstance(),在Debug Threads窗口中就会创建一个神秘线程,其“Priority”显示为-8。我不知道那个线程是什么。有什么想法或资源指向吗?我尝试在SetThreadPriority()
上设置一个断点,假设我碰到了将其设置为非原始优先级的任何代码,就像CreateThread()
一样,它不是一个已知函数。
接下来是一个实际的问题,这不仅是个谜:在关闭我的应用程序时,我正在破坏和释放我使用的所有内存,并且在这样做的同时在“-8”线程中崩溃。没有源,只有汇编,也没有堆栈跟踪或符号。该程序没有暗示其堆已损坏,例如符号出现在其堆栈或“输出”窗口中。
我能想到的关于该应用程序的唯一额外信息是:
-它可以很好地接收MIDI事件,并且已经使用了多年
-它有一个工作线程,用于计算声音缓冲区的数据;我设置了一个哨兵 bool 标志,并等待它以GetExitCodeThread()
结尾;我确实获得了退出代码,因此我确定这不是-8线程。 (无论如何,它的优先级都是“TimeCritical”,而不是-8)
-除内存泄漏外,一切都没有问题,我现在使用_CRTDBG_MAP_ALLOC
解决。如果不释放数据,我就不会崩溃。但是,找出导致问题的确切对象之后,我仍然茫然不知所措,因为我再次没有真正创建一个引用该对象的线程。
最佳答案
许多库,包括MFC,都会在其正常操作中创建额外的工作线程或线程池。不用担心。
如果您确实想确切地知道这些线程的创建位置,则在CreateThread
上设置断点的问题是调试器无法解析符号名称。您需要通过使用特殊语法{,,module}symbol
(有关here的更多信息)告诉它处于哪个模块来帮助解决问题。此外,名称可能会修饰,因此有效的实际符号名称可能是{,,kernel32.dll}CreateThread
,{,,kernel32.dll}_CreateThread}
或{,,kernel32.dll}_CreateThread@44
中的任何一种。对于SetThreadPriority()
也是如此。
如果您还没有的话,我也强烈建议您将调试器配置为use the Microsoft symbol servers。这将为您提供更多有用的Microsoft DLL(包括MFC)中函数地址的符号表示,以使您更好地了解其作用。
就是说,知道在哪里创建该线程可能不会帮助您。您很可能由于某处的缓冲区溢出而发生某种堆损坏。当您释放已经溢出的缓冲区时,由于堆管理器将遵循损坏的指针并开始写入其他随机内存位置,因此损坏将变得更加严重。而不释放损坏的缓冲区则不太可能使进程崩溃。准确跟踪堆损坏发生的位置将具有挑战性。
关于c++ - Visual Studio C++ : what's creating these threads?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35393611/