触发“分段错误”的超奇怪问题

时间:2014-04-23 14:53:23

标签: c d dmd

我不会深入研究这个问题(代码库已经有数千行而且相当复杂),所以我会尝试将..."窗口"我所发现的。

这是例行触发"分段错误" :

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函数。

现在,它的奇怪之处:<​​/ strong>

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

发生了什么?


更多细节:

  • 编译器: DMD64 D编译器v2.065
  • 调试器: lldb
  • OS: OSX 10.9.2

1 个答案:

答案 0 :(得分:7)

如果要将D代码中分配的对象的唯一引用从D堆传递给非D代码,那么必须 register it as a GC root,或者更改代码才能使用malloc而不是从托管D堆分配。否则,GC会认为该对象未使用,并将其收集到空闲内存中。