假设有一个名为 LongFunction 的 1000 行代码的函数,我们使用了它:
bool bSuccess = LongFunction();
assert(bSuccess);
这里在调试的时候得到了一个断言,我知道LongFunction有问题,所以我需要找到函数在哪里遇到问题并返回:
我可能会逐步调试它,它可以工作但很耗时,我们不知道该怎么做。
我可以搜索关键字“return”(或者使用 RegExp 进行更精细的搜索),并在这些返回处设置断点,应该会更快,但仍然是一项繁琐的手动工作,无法自动化。
#define return TRACE(LINE);返回
它有效但有以下问题:
- 由于经常使用return,它会打印出过多的冗余信息。(或者我们可以使用一些EnvVar来打开或关闭它)
- 不适用于以下情况:if(bOK) return true;
对于如何查明问题,您还有其他创意吗?
编辑: 这里有一些细节可以让我们专注于问题。
它是关于 C++ 的,而不是特定于平台的。
我们不想重构函数(是的,我知道我们应该重构),我们甚至不想更改任何代码 - 此时我们只想提供一些便利来调试我们的应用程序更轻松。我也相信这应该是一个常见的要求,你没遇到过吗?
LongFunction() 有多个导出点,返回类型不是必需的 bool(HRESULT, user defined errorcode...)
编辑:当前讨论的总结:
我们有一些争议:
您应该重构函数。
是的,每个人都知道我们应该这样做,但这不是重点。如果我调用重构函数,我就不会在这里问这个问题。查找 LongFunction() 返回失败的位置没有帮助。
我总是首先要做的是定位错误发生的位置以了解发生了什么,我很好奇为什么这没有帮助,在这种情况下你做了什么? (假设我已经熟悉该功能的工作原理)
我们有 2 个合理的解决方案:
来自 Crashworks 的 ReturnMarker,函数中的一个堆栈对象会在函数返回时析构,在析构函数处设置断点将显示它在调试器中返回的位置
Binary & Sadsido 的 CMyBool(x),将 LongFunction 的返回类型更改为 CMyBool,它可以从 bool 构造,从 LongFunction 返回将构造该对象,因此只需在构造函数处设置断点即可。
最佳答案
显然你应该重构这个函数,但在 C++ 中你可以使用这个简单的权宜之计在五分钟内处理这个问题:
class ReturnMarker
{
public:
ReturnMarker() {};
~ReturnMarker()
{
dummy += 1; //<-- put your breakpoint here
}
static int dummy;
}
int ReturnMarker::dummy = 0;
然后在您的函数顶部实例化一个 ReturnMarker。当它返回时,该实例将超出范围,您将触发析构函数。
void LongFunction()
{
ReturnMarker foo;
// ...
}
关于c++ - 如何查明长函数返回的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1311166/