什么是最好的方法来将一个调试器的一个过程VC++在正确的时间点?
-
20-08-2019 - |
题
在调试,有时你需要附加一个已经在运行过程,而不是刚刚开始应用于一个调试器。
这是常见的自己放在一个Sleep()或消息框呼吁,以使它更容易附加一个调试器。我担心的是,其中有些人可能会犯下最终来源的控制。
什么是最好的事情要做,以避免这种情况,同时仍拖延足够时间,这样就可以把你调试器运行中的过程吗?
守着睡眠或消息框中有一个 #ifdef _DEBUG
是的一种方式,但我想知道如果有一个更好的办法。
有一个睡觉的你也有问题,你不可以附加时间。有消息框中,你有问题你可以远程调试,或者调试一个过程,有没有可见的GUI(例如为服务运行在Vista)
其他提示
要在特定点处附加调试器,则有几种选择:
最简单的就是叫DebugBreak
,这是几乎等同于__asm int 3
,但也适用于其他架构(MSVC针对x64不允许内联汇编,如果我没有记错)。这会调出刚刚在时间调试器窗口,你就可以从登记的调试器(即Visual Studio中)中选择附加到进程。
另外,你可以引入一个呼叫Sleep
,给你一个机会,附加调试。您应该使用#ifdef _DEBUG
解决这个问题,以确保你实际上并不附带包括该代码。
一个问题:为什么不能从IDE运行的代码?它是一个服务或IIS加载DLL或相似?
在这种情况下,你可以检查出ImageFileExecutionOptions
注册表项,它允许你在这个过程开始的时刻附加一个调试器。
如果您使用CDB对于这一点,你可以将其配置为任一服务器或客户端的WinDbg的实例和调试的方式。我用的WinDbg作为内核调试器,并通过使用ImageFileExecutionOptions开始与指定的进程ntsd -d
在过去做到了这一点。这会导致WinDbg中打入用户模式。这有时是一种有用的技术。
另一种变型,其中我有时使用是
while( !::IsDebuggerPresent() )
::Sleep( 100 ); // to avoid 100% CPU load
应该只是默默等待,直到你附上你的调试器的过程。
弗雷迪和Reoa有正确的解决方案。但我想增加一个理由为什么不要使用一个消息框.
显示一个消息框仅仅部分地停止你的应用程序。因为你表示UI、信息泵仍在运行至少一个螺纹在你的节目。所以如果你的代码没有任何的以下。
- 通过Windows消息
- 有非微不足道UI
- 是多线程
你将基本上能要求一个调试器在一个国家,但附加程序在一个完全不同的状态。这可能会导致令人困惑的情况和错误。
我们最近作出的改变在我们的码基永远不要显示出一个消息框为了促进打破这个原因。它产生非常不良行为对于一个不平凡的应用程序。
查找
的DebugBreak,__debugbreak和朋友
或
静态无效timeToChase(){__asm {INT 3; }; }
__asm int 3
这很难断点将弹出对话框调试,这将让你连接到进程。裹在的#ifdef _DEBUG,你会只打在调试版本。