gpt4 book ai didi

c++ - 单线程 C++ 函数调用中不可调试的非确定性 heisenbug

转载 作者:搜寻专家 更新时间:2023-10-31 00:42:58 24 4
gpt4 key购买 nike

我已无路可走:我有一个单线程 C++ 程序。这里有一些经验数据和背景信息,我试图突出最重要的关键词;

  • 我所说的整个部分没有任何系统调用,除了标准 C++ 库 可能执行的内存(取消)分配调用(std::set 涉及)。这是一种纯逻辑算法。
  • 这个的行为应该是确定性的,取决于输入,我不会改变。
  • 如果错误出现,程序就会陷入看起来像无限循环的状态,似乎开始超出任何界限分配内存
  • 该错误不会可预测地表现出来,我可以从命令行运行程序,有时(可能 30%-50%)错误会表现出来,否则,据我所知,一切运行顺利且正确。
  • 一旦我不是直接从提示符而是在 gdb 或 valgrind 中运行程序,错误就消失了,程序就永远不会死。
  • 现在是最精彩的部分:我将问题追溯到(模板化的)非虚拟成员函数调用。就在调用之前,我向std::cout 打印了一条消息,我可以在终端中看到。函数内的第一行还有一条调试消息,该消息从未显示

我再也看不到任何合理的解释了。也许您可以想出如何进行的想法。


编辑:重要的代码行,我更改了行号以便我们可以引用它们并省略了不相关的部分,因此似乎并非所有内容都最有意义。

a.cpp

 10     std::set<Array const*>* symbols;
11 std::set<Array const*> allSymbols;
12 symbols = &allSymbols;
// ... allSymbols are populated with std::inserter
15 std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
16 senderConstraints = cd.cg.eval(*symbols);

b.cpp

 31     template <typename ArrayContainer>
32 ConstraintList eval(ArrayContainer const request) {
33 std::cout << "inside eval ... going to update graph now" << std::endl;

最后一行输出是:

eval; cd = 0x2e6ebb0, cg = 0x2e6ebc0

然后就陷入了死循环。

最佳答案

我敢打赌,当你改变时,第二行被打印

ConstraintList eval(ArrayContainer const request)

ConstraintList eval(ArrayContainer const & request)

如果是这样,要么 allSymbols 的状态在第 12 行和第 15 行之间被破坏,要么您的代码实际上看起来更像这样:

std::set<Array const*>* symbols;
{
std::set<Array const*> allSymbols;
symbols = &allSymbols;
// ... allSymbols are populated with std::inserter
}
std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
senderConstraints = cd.cg.eval(*symbols);

这是 UB,因为 symbols 指的是一个已经被破坏的对象。

关于c++ - 单线程 C++ 函数调用中不可调试的非确定性 heisenbug,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11205046/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com