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

Dr.*_*eon 2 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"); 

    }

} 
Run Code Online (Sandbox Code Playgroud)

几点说明:

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

现在,它的奇怪之处:

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

这是怎么回事???


更多细节:

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

Vla*_*eev 7

如果要将D代码中分配的对象的唯一引用从D堆传递给非D代码,则必须将注册为GC根,或者将代码更改为使用malloc而不是从托管D堆分配.否则,GC会认为该对象未使用,并将其收集到空闲内存中.