这太气人了!>_<
我编写了一个庞大而复杂的 Haskell 库。我写了一个小测试程序,到目前为止,我已经花了大约 8 个小时试图弄清楚为什么它一直在我身上崩溃。有时 GHC 会抱怨“奇怪的封闭类型”。有时我只是得到一个段错误。显然问题是内存损坏。
库本身是 100% 纯 Haskell。但是,测试程序使用了几个与数组相关的不安全 GHC 原语。这显然是导致问题的原因。事实上,如果我注释掉该writeArray#
行,程序就会停止崩溃。但这完全是在炒我的面条……据我所知,我使用的所有数组边界都是完全有效的。程序将它们全部打印出来,它们都是正数并且小于数组大小。
我编写了第二个程序,它与第一个程序做同样的事情,但不涉及庞大而复杂的库。我已经尝试了又尝试了,但我根本无法让它崩溃。我所做的一切似乎都不会让它崩溃,但它对实际数组的作用几乎完全相同。
有没有人有任何进一步的故障排除提示?有什么方法可以追踪内存损坏的确切时刻吗?(而不仅仅是系统注意到损坏的那一刻。)
更新:
问题有什么作用?
好吧,本质上,它创建了一个表示像素缓冲区的数组。它生成一个线程,该线程遍历每个像素并将相应的值写入其中。它会产生第二个线程来读取数组,并使用相当复杂的协议将像素写入网络套接字。(因此我要测试的大型图书馆。)
如果我不生成作者线程,崩溃就会消失。如果我在作者线程中注释掉writeArray'
调用,崩溃就会消失。在写入每个像素之前,写入器线程会打印出像素坐标和数组索引。它打印出来的所有东西看起来都很完美。然而......它不会停止崩溃。
我几乎想知道 GHC 的数组原语是否不是线程安全的。(如果有任何不同,读取器线程看起来像的数组副本已被不安全地冻结,而写入器线程继续同时对其进行变异。)
但是,我编写了一个程序,它做同样的事情,但不通过网络发送流量。这个程序在每一个细节上都能完美运行。只有真正复杂的程序是行不通的。这有多烦人?!