假设有一个名为LongFunction的1000行代码的函数,我们使用它:
bool bSuccess = LongFunction();
assert(bSuccess);
Run Code Online (Sandbox Code Playgroud)
这里我在调试时得到一个断言,我知道LongFunction有问题,所以我需要找到函数遇到问题的地方并返回:
我可以一步一步地调试它,它可以工作,但是很费时,我们不这样做.
我可以搜索关键字"返回"(或者更精确的搜索使用RegExp),并在那些返回时设置断点,它应该更快,但它仍然是乏味的手动工作,无法自动化.
#define返回TRACE(LINE); 返回
它有效,但有以下问题:
您对如何查明问题还有其他创意吗?
编辑: 这里有一些细节让我们专注于这个问题.
它是关于C++,而不是平台规范.
我们不想重构函数(是的,我知道我们应该),我们甚至不想更改任何代码 - 此时我们只想提供一些工具来使我们的应用程序调试更容易.我也相信这应该是一个共同的要求,难道你不碰到这个吗?
LongFunction()有多个退出点,返回类型不是必需的bool(HRESULT,用户定义的错误代码......)
编辑:当前讨论的摘要:
我们有一些争议:
你应该重构这个功能.
是的,每个人都知道我们应该,但这不是重点.如果我打电话重构函数,我不会在这里问这个问题.
找到LongFunction()返回失败的地方没有帮助.
我总是首先找到错误发生的地方,知道发生了什么,我很好奇为什么这没有用,你在这种情况下做了什么?(假设我已经熟悉该函数的工作原理)
我们有2个合理的解决方案:
来自Crashworks的ReturnMarker,函数中的堆栈对象将在函数返回时进行破坏,在析构函数中设置断点将显示它在debuger中返回的位置
来自Binary&Sadsido的CMyBool(x),将LongFunction的返回类型更改为可以从bool构造的CMyBool,从LongFunction返回将构造该对象,因此只需在构造函数中设置断点即可.
Cra*_*rks 13
显然你应该重构这个函数,但是在C++中你可以使用这个简单的权宜之计在五分钟内解决这个问题:
class ReturnMarker
{
public:
ReturnMarker() {};
~ReturnMarker()
{
dummy += 1; //<-- put your breakpoint here
}
static int dummy;
}
int ReturnMarker::dummy = 0;
Run Code Online (Sandbox Code Playgroud)
然后在函数顶部实例化一个ReturnMarker.当它返回时,该实例将超出范围,您将点击析构函数.
void LongFunction()
{
ReturnMarker foo;
// ...
}
Run Code Online (Sandbox Code Playgroud)
听起来好像是重构LongFunction()的时候了......
一个1000行功能是一个坏代码气味.花时间将其重构为更小,更易维护的功能.您可以在遇到错误时找到错误,这对未来来说是值得的投资.