【问题标题】:Super-weird issue triggering "Segmentation Fault"触发“Segmentation Fault”的超奇怪问题
【发布时间】:2014-04-23 14:53:22
【问题描述】:

我不会深入探讨这个问题(代码库已经有数千行并且相当复杂),所以我将尝试将...“窗口”最小化到我发现的内容。

这是触发“分段错误”的例程:

extern (C) 
{
    void* Statements_new() { return cast(void*)(new Statements()); }
    void  Statements_add(Statements s, Statement st) 
    { 
        //writeln("In here"); 
        if (s is null) writeln("StatemenTS are null"); 
        else writeln("not null : "~ typeid(s).name); 

        if (st is null) writeln("statement is null"); 
        else writeln("not null : " ~ typeid(st).name); 

        s.add(st); 

        //writeln("Out of here"); 

    }

} 

几点说明:

  • 声明的方法只不过是“绑定”,因此可以直接从 C 代码(实际上是 Bison)调用本机例程。
  • Statements_add 函数使用 Statements 对象和子类 Statement 对象调用。

现在,它的怪异之处:

  • 错误不会一直发生(实际上它不会像 99% 那样发生),但当它发生时,s.add(st); 语句似乎是罪魁祸首。
  • 永远不会是 2 个参数之一 (s,st) null
  • 现在,如果我评论 2 个if... writeln... typeid 语句,就会出现错误。
  • 如果我取消注释它们(它们什么都不做,是吗?),它总是有效 - 已修复 - 宾果游戏!

怎么了???


更多细节:

  • 编译器: DMD64 D 编译器 v2.065
  • 调试器: lldb
  • 操作系统: OSX 10.9.2

【问题讨论】:

    标签: c d dmd


    【解决方案1】:

    如果您将在 D 代码中分配的对象的唯一引用从 D 堆传递给非 D 代码,那么您必须要么register it as a GC root,要么更改您的代码以使用@987654322 @ 而不是从托管 D 堆中分配。否则,GC 会认为该对象未被使用,并收集它以释放内存。

    【讨论】:

    • 天啊...我似乎完全忘记了垃圾收集...很棒的答案!我要花大约 100 次调试会话才能弄清楚! ;-)
    • 哦,伙计,我也遇到过这样的事情,但它并不可靠,所以我什至没有注意到它发生了,直到大约一个月后,当节目有更多的活动流量并且错误实际上开始每隔几秒钟触发一次,而不是在没有它的情况下运行几次。在我的情况下,我正在使用自我管道技巧将指针写回应用程序......我不认为他们正在离开应用程序,但是当他们坐在内核管道缓冲区中时,他们 GC 看不到它们并释放了目的!痛苦追查。我想我在书中也写过两次,一旦你看到它你就知道了
    猜你喜欢
    • 1970-01-01
    • 2012-08-12
    • 1970-01-01
    • 2022-11-22
    • 2023-03-20
    • 2020-12-19
    • 1970-01-01
    • 2019-05-05
    • 2013-03-18
    相关资源
    最近更新 更多