当我想问一个问题时,例如stackoverflow我通常要发布源代码。
问题是,我使用了相当大的自定义框架,类结构等,并且问题相关的部分可能在很多地方进行了本地化(有时很难检测到哪些部分的代码对于题)。我无法发布完整的源代码(它太大而无法有效阅读)。
出于这个原因,我通常会努力编写一个最小的代码(通常在一个main.cpp
而不是吨的类中)来重现问题。
我想知道 - 是否有可能实现该流程的自动化?
这里典型的做法是替换方法/功能'用他们的身体调用,将文件合并到一个.cpp
,删除所有"未调用"方法和类,未使用的变量等。
答案 0 :(得分:3)
这里的真正困难在于告诉我们之间的区别"它没有做我想要的事情","因为我删除了基本代码而导致错误消失了#34;它的情况现在崩溃,因为我删除了一些重要的东西"。实际上,在标记一些代码之后点击删除键"不需要它"是容易的部分。
找出显示问题的必要条件是困难的部分,并且很难实现自动化 - 因为有必要了解代码应该做什么和实际做什么之间的区别。只是随机删除代码将无法正常工作,因为" new"代码可能会被破坏,因为你删除了一些必要的步骤,而不是因为你删除了未使用过的crud - 只有那些了解问题的人才能做到这一点。
考虑一下:
Object* something;
void Initialize()
{
something = new Object(1, 2, 3);
}
int main()
{
Initialize();
// Some more code, some of which SOMETIMES sets something = NULL.
something->doStuff(); // Will crash if object is NULL.
}
如果我们删除Initialize
,代码每次都会失败,而不是每隔三次失败。但这是因为Object尚未初始化,而不是代码中的错误[可能是我们应该在if (something)
之前添加something->doStuff()
,或者因为我们不应该设置它会导致NULL
更多代码",所以"不要这样做"]。
当我处理一个棘手的问题时,特别是在我们拥有自动生成代码以便在不同条件下测试不同功能的测试系统的工作中,我的第一步是将[或采用一些现有的]代码设置为"小独立测试",这是一个小而简单的,只有"什么是必要的",而不是试图减少数千行复杂的代码,这些代码可以做很多额外的事情。
对于某些项目,有一些工具可以帮助识别"代码的哪一部分是问题",例如[bugpoint
] [1]找到哪个"通过" LLVM非常值得引起崩溃。
如果您的版本控制系统支持此功能,您可以" bisect"代码来提出引入特定错误的版本[至少有时]。然而,我在工作中有一个案例,其中我的一些代码显然已经破坏了东西"但事实证明,其他一些代码在很长一段时间后一直被打破"因为其他代码没有清除API手册中应该设置为NULL
的指针字段,而我的代码正在检查指针以查明它是否指向正确的类型的东西 - 这在可怕的时候出错了值是"无论发生在堆栈的那一部分",所以它不是NULL
而不是有效指针。我刚刚添加了使这个bug显而易见而不是隐藏自己的代码。