Super-weird issue triggering “Segmentation Fault”

2019-07-20 20:25发布

I won't go very deep into the issue (the codebase is already thousands of lines and quite complex), so I'll try to miniminise the... "window" to what I've spotted.

Here's the routine triggering the "Segmentation Fault" :

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"); 

    }

} 

A few notes :

  • The declared methods are nothing but "bindings" so that native routines can be called directly from C code (Bison actually).
  • The Statements_add function is called with a Statements object and a subclassed Statement object.

Now, the weirdness of it :

  • The error doesn't happen all the time (actually it doesn't happen like 99% of the time), but when it does, the s.add(st); statement seems the culprit.
  • Never ever is one of the 2 parameters (s,st) null.
  • Now, if I comment the 2 if... writeln... typeid statements, the error is there.
  • If I uncomment them (they don't do anything, huh?), it always works - fixed - bingo!

What's going on???


A few more details :

  • Compiler : DMD64 D Compiler v2.065
  • Debugger : lldb
  • OS : OSX 10.9.2

标签: c d dmd
1条回答
兄弟一词,经得起流年.
2楼-- · 2019-07-20 20:43

If you are passing the only reference of an object allocated in D code from the D heap to non-D code, then you must either register it as a GC root, or change your code to use malloc instead of allocating from the managed D heap. Otherwise, the GC will think that the object is unused, and collect it to free memory.

查看更多
登录 后发表回答