Calypso icon indicating copy to clipboard operation
Calypso copied to clipboard

FastFlow test case

Open wilsonk opened this issue 10 years ago • 56 comments

Hello Elie,

There is an issue with trying to instantiate an abstract class from the FastFlow C++ library in a D test program. If I use this simple test program:

modmap (C++) "ff/farm.hpp"; import (C++) ff.ff_node; class Worker : ff_node { //alias svc = cpp.ff.ff_node.ff_node.svc; public: override void* svc(void * task) { return task; } } void main() {}

I get this error:

test.d(10): Error: function test.Worker.svc does not override any function, did you mean to override 'cpp.ff.ff_node.ff_node.svc'?

You can see I tried to use an alias to get the override to work (and I tried a few other things to no avail). I tried making a cpp file and overriding in a simple class and then using that class also, bit it didn't work either.

Thanks, Kelly

wilsonk avatar Apr 23 '15 15:04 wilsonk

Hey Kelly,

The issue is with the types' deco:

  • D void * => "Pv"
  • C++ void * => "~Pv" (see cpp::TypePointer)

To preserve C++'s logical const the deco of pointer types are altered, and I didn't realize that this would break function overriding. I'm working on a fix right now (which is going to be ugly but I can't see good alternatives for now).

Syniurge avatar Apr 24 '15 15:04 Syniurge

Hello Elie,

Ok, right…I can see the writeByte(‘~’) in ::TypePointer. Too bad there only seems to be an ugly solution, but at least you can see one :)

I think this might be the same issue holding back threads in Dlib also. I will keep posting new issues, as I have run into a couple different ones for other libs also.

Thanks,

Kelly

From: Elie Morisse [mailto:[email protected]] Sent: Friday, April 24, 2015 9:27 AM To: Syniurge/Calypso Cc: wilsonk Subject: Re: [Calypso] FastFlow test case (#12)

Hey Kelly,

The issue is with the types' deco:

  • D void * => "Pv"
  • C++ void * => "~Pv" (see cpp::TypePointer)

To preserve C++'s logical const the deco of pointer types are altered, and I didn't realize that this would break function overriding. I'm working on a fix right now (which is going to be ugly but I can't see good alternatives for now).

— Reply to this email directly or view it on GitHub https://github.com/Syniurge/Calypso/issues/12#issuecomment-95966169 .

wilsonk avatar Apr 24 '15 15:04 wilsonk

Does beb67eafccbc896500f4cbedb317097e4d326c5b fix it?

Your test works if I use the following as C++ header:

class ff_node
{
public:
    virtual void* svc(void* task) = 0;
};

Syniurge avatar Apr 24 '15 17:04 Syniurge

Hello Elie,

Yes, that seems to have gotten us past that particular error. Unfortunately I am seeing a new one with compiling the simple FastFlow example. I am getting this error now when just compiling the simplest ‘Worker : ff_node’ class:

ldc2: /home/wilsonk/Downloads/llvm-3.6/llvm/lib/IR/Constants.cpp:969: llvm::ConstantStruct::ConstantStruct(llvm::StructType_, llvm::ArrayRefllvm::Constant_): Assertion `(T->isOpaque() || V[i]->getType() == T->getElementType(i)) && "Initializer for struct element doesn't match struct element type!"' failed.

Ugh. That is during codegen so the llvm output looks like this (sorry for the spam but hopefully you can see something I am missing…the class type is at the bottom to more easily compare):

declare %test.Worker* @_D4test6Worker6__ctorMFZC4test6Worker(%test.Worker*)

    • * Doing function body for: this
    • * DtoCreateNestedContext for this
    • * * DtoCreateNestedContextType for this
    • * CompoundStatement::toIR():
    • * * CompoundStatement::toIR(): test.d(7)
    • * * * CompoundStatement::toIR():
    • * * * * ExpStatement::toIR():
    • * * * * * Expression::toElemDtor(): super.this()
    • * * * * * * CallExp::toElem: super.this() @ test.Worker
    • * * * * * * * DotVarExp::toElem: super.this @ ff_node()
    • * * * * * * * * ThisExp::toElem: super @ cpp.ff.ff_node.ff_node
    • * * * * * * * * * normal this exp
    • * * * * * * * * * Casting from 'test.Worker' to 'cpp.ff.ff_node.ff_node'
    • * * * * * * * * * * DtoCastClass(test.Worker, cpp.ff.ff_node.ff_node)
    • * * * * * * * * * * * to class
    • * * * * * * * * * * * static down cast
    • * * * * * * * DtoCallFunction()
    • * * * * * * * * Building type: ff_node()
    • * * * * * * * * * DtoFunctionType(ff_node())
    • * * * * * * * * * * x86-64 ABI: Transforming return type
    • * * * * * * * * * * x86-64 ABI: Transforming argument types
    • * * * * * * * * * * Final function type: %"class.ff::ff_node"* ()
    • * * * * CompoundStatement::toIR():
    • * * * ReturnStatement::toIR(): test.d(7)
    • * * * * Expression::toElemDtor(): this
    • * * * * * ThisExp::toElem: this @ test.Worker
    • * * * * * * this exp without var declaration
    • * * * * return value is ' %5 = load %test.Worker** %this'
    • Building default initializer for test.Worker
    • * Creating initializer constant for Worker
    • * * Implicit initializer: fftree_ptr @+8
    • * * * DtoConstExpInit(targetType = fftree*, exp = null)
    • * * * * NullExp::toConstElem(type=fftree*): null
    • * * * * * Building type: fftree*
    • * * * * * * Building type: cpp.ff.fftree.fftree
    • * * * * * * * Building class type cpp.ff.fftree.fftree @ /home/wilsonk/Downloads/fastflow/ff/node.hpp(56)
    • * * * * * * * * Instance size: 40
    • * * Implicit initializer: in @+16
    • * * * DtoConstExpInit(targetType = uSWSR_Ptr_Buffer*, exp = null)
    • * * * * NullExp::toConstElem(type=uSWSR_Ptr_Buffer*): null
    • * * Implicit initializer: out @+24
    • * * * DtoConstExpInit(targetType = uSWSR_Ptr_Buffer*, exp = null)
    • * * * * NullExp::toConstElem(type=uSWSR_Ptr_Buffer*): null
    • * * Implicit initializer: myid @+32
    • * * * DtoConstExpInit(targetType = int, exp = 0)
    • * * * * IntegerExp::toConstElem: 0 @ int
    • * * * * * value = i32 0
    • * * Implicit initializer: CPUId @+36
    • * * * DtoConstExpInit(targetType = int, exp = 0)
    • * * * * IntegerExp::toConstElem: 0 @ int
    • * * * * * value = i32 0
    • * * Implicit initializer: myoutbuffer @+40
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: myinbuffer @+41
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: skip1pop @+42
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: in_active @+43
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: multiInput @+44
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: multiOutput @+45
    • * * * DtoConstExpInit(targetType = bool, exp = false)
    • * * * * IntegerExp::toConstElem: false @ bool
    • * * * * * value = i1 false
    • * * * * Fixing up unresolved implicit integer conversion.
    • * * Implicit initializer: thread @+48
    • * * * DtoConstExpInit(targetType = thWorker*, exp = null)
    • * * * * NullExp::toConstElem(type=thWorker*): null
    • * * * * * Building type: thWorker*
    • * * * * * * Building type: cpp.ff.ff_node.ff_node.thWorker
    • * * * * * * * Building class type cpp.ff.ff_node.ff_node.thWorker @ /home/wilsonk/Downloads/fastflow/ff/node.hpp(929)
    • * * * * * * * * Instance size: 264
    • * * Implicit initializer: callback @+56
    • * * * DtoConstExpInit(targetType = bool function(void_, uint, uint, void_), exp = null)
    • * * * * NullExp::toConstElem(type=bool function(void_, uint, uint, void_)): null
    • * * * * * Building type: bool function(void_, uint, uint, void_)
    • * * * * * * Building type: bool(void_, uint, uint, void_)
    • * * * * * * * DtoFunctionType(bool(void_, uint, uint, void_))
    • * * * * * * * * x86-64 ABI: Transforming return type
    • * * * * * * * * x86-64 ABI: Transforming argument types
    • * * * * * * * * Final function type: i1 (i8_, i32, i32, i8_)
    • * * Implicit initializer: callback_arg @+64
    • * * * DtoConstExpInit(targetType = void*, exp = null)
    • * * * * NullExp::toConstElem(type=void*): null
    • * * Implicit initializer: barrier @+72
    • * * * DtoConstExpInit(targetType = spinBarrier*, exp = null)
    • * * * * NullExp::toConstElem(type=spinBarrier*): null
    • * * Implicit initializer: end_callback @+80
    • * * * DtoConstExpInit(targetType = void function(void*), exp = null)
    • * * * * NullExp::toConstElem(type=void function(void*)): null
    • * * * * * Building type: void function(void*)
    • * * * * * * Building type: void(void*)
    • * * * * * * * DtoFunctionType(void(void*))
    • * * * * * * * * x86-64 ABI: Transforming argument types
    • * * * * * * * * Final function type: void (i8*)
    • * * Implicit initializer: end_callback_param @+88
    • * * * DtoConstExpInit(targetType = void*, exp = null)
    • * * * * NullExp::toConstElem(type=void*): null
    • * * Implicit initializer: tstart @+96
    • * * * DtoConstExpInit(targetType = timeval, exp = timeval)
    • * * * * VarExp::toConstElem: timeval @ timeval
    • * * * * * Sym: type=timeval
    • * * * * * Resolving struct type: timeval (/usr/include/x86_64-linux-gnu/bits/time.h(30))
    • * * * * * Building default initializer for cpp.timeval.timeval
    • * * Implicit initializer: tstop @+112
    • * * * DtoConstExpInit(targetType = timeval, exp = timeval)
    • * * * * VarExp::toConstElem: timeval @ timeval
    • * * * * * Sym: type=timeval
    • * * Implicit initializer: wtstart @+128
    • * * * DtoConstExpInit(targetType = timeval, exp = timeval)
    • * * * * VarExp::toConstElem: timeval @ timeval
    • * * * * * Sym: type=timeval
    • * * Implicit initializer: wtstop @+144
    • * * * DtoConstExpInit(targetType = timeval, exp = timeval)
    • * * * * VarExp::toConstElem: timeval @ timeval
    • * * * * * Sym: type=timeval
    • * * Implicit initializer: wttime @+160
    • * * * DtoConstExpInit(targetType = double, exp = nan)
    • * * * * RealExp::toConstElem: nan @ double | nan
    • * * adding field fftree_ptr
    • * * adding field in
    • * * adding field out
    • * * adding field myid
    • * * adding field CPUId
    • * * adding field myoutbuffer
    • * * adding field myinbuffer
    • * * adding field skip1pop
    • * * adding field in_active
    • * * adding field multiInput
    • * * adding field multiOutput
    • * * adding field thread
    • * * adding field callback
    • * * adding field callback_arg
    • * * adding field barrier
    • * * adding field end_callback
    • * * adding field end_callback_param
    • * * adding field tstart
    • * * adding field tstop
    • * * adding field wtstart
    • * * adding field wtstop
    • * * adding field wttime
    • * * final initializer: %test.Worker_init { %test.Worker.vtbl* @D4test6Worker6__vtblZ, i8* null, %"struct.ff::fftree"* null, %"class.ff::uSWSR_Ptr_Buffer"* null, %"class.ff::uSWSR_Ptr_Buffer"* null, i32 0, i32 0, i8 0, i8 0, i8 0, i8 0, i8 0, i8 0, %"class.ff::ff_node::thWorker"* null, i1 (i8, i32, i32, i8)* null, i8* null, %"class.ff::spinBarrier"** null, void (i8)_ null, i8* null, %cpp.timeval.timeval_init zeroinitializer, %cpp.timeval.timeval_init zeroinitializer, %cpp.timeval.timeval_init zeroinitializer, %cpp.timeval.timeval_init zeroinitializer, double 0x7FFC000000000000, i64 0, i64 0 }
    • * * * * * Final function type: void (%"class.ff::ff_node"*)
    • * * * class type: %test.Worker = type { %test.Worker.vtbl, i8, i32 (...), %"struct.ff::fftree", %"class.ff::uSWSR_Ptr_Buffer", %"class.ff::uSWSR_Ptr_Buffer", i32, i32, i8, i8, i8, i8, i8, i8, %"class.ff::ff_node::thWorker", i1 (i8, i32, i32, i8_), i8, %"class.ff::spinBarrier", void (i8)_, i8, %struct.timeval, %struct.timeval, %struct.timeval, %struct.timeval, double }
    • DtoDefineFunction(test.Worker.svc): test.d(10)

Thanks,

Kelly

wilsonk avatar Apr 24 '15 18:04 wilsonk

The fixes pushed today have also fixed the problem above. I am now just seeing an issue with some functions and enums being undefined from ff/utils.hpp. They are in the ff namespace, and I am importing ff._, so I am not sure what is going on there. But I'll keep looking into it.

wilsonk avatar May 10 '15 20:05 wilsonk

I am now just seeing an issue with some functions and enums being undefined from ff/utils.hpp. They are in the ff namespace, and I am importing ff._, so I am not sure what is going on there. But I'll keep looking into it.

Was it fixed since?

Syniurge avatar Jun 29 '15 15:06 Syniurge

Ugh, actually we are right back to square one on this issue. The first test case above gives the exact same error again:

test.d(10): Error: function test.Worker.svc does not override any function, did you mean to override 'cpp.ff.ff_node.ff_node.svc'?

Strange and unfortunate. :(

wilsonk avatar Jun 29 '15 16:06 wilsonk

Strange.. my smaller test case works:

// abstract.hpp
class ff_node
{
public:
    virtual void* svc(void* task) = 0;
};
// abstract.d
modmap (C++) "abstract.hpp";
import (C++) ff_node;

class Worker : ff_node {
public:
    override void* svc(void * task) { return task; }
}

Syniurge avatar Jun 29 '15 22:06 Syniurge

Woops, sorry Elie. It looks like this is the actual test case that fails:

namespace test {
    class ff_node
    {
    public:
    virtual void* svc(void* task) = 0;
    };
    void* svc(void* task) {
    return 0;
    }
}


modmap (C++) "abstract.hpp";
import (C++) test._;
import (C++) test.ff_node;

class Worker : ff_node {
public:
    override void* svc(void * task) { return task; }
}

And I get this error still:

showcase.d(7): Error: function showcase.Worker.svc does not override any function, did you mean to override 'cpp.test.ff_node.ff_node.svc'?

wilsonk avatar Jun 30 '15 00:06 wilsonk

Thanks for cornering the problem Kelly, there was a big oversight and the "equivalent deco" wasn't set for function types past the first one of a kind (I didn't know that they weren't merged during semantic() like the other types).

It was broken again when I simplified the method of checking "type equivalence" introduced by beb67eafccbc896500f4cbedb317097e4d326c5b by introducing these "equivalent deco".

Should get past those errors now.

Syniurge avatar Jun 30 '15 01:06 Syniurge

Hi Elie, it looks like things were fixed by that last commit for the problem stated above. Now, however, I am running into quite a few functions that are 'static inlined' in .hpp files being undefined like this:

test.o: In function ff::ff_node::ffTime()': test.d:(.text._ZN2ff7ff_node6ffTimeEv[_ZN2ff7ff_node6ffTimeEv]+0x2c): undefined reference toff::diffmsec(timeval const&, timeval const&)' test.o: In function ff::ff_node::wffTime()': test.d:(.text._ZN2ff7ff_node7wffTimeEv[_ZN2ff7ff_node7wffTimeEv]+0x2c): undefined reference toff::diffmsec(timeval const&, timeval const&)' test.o: In function ff::ff_node::setAffinity(int)': test.d:(.text._ZN2ff7ff_node11setAffinityEi[_ZN2ff7ff_node11setAffinityEi]+0x42): undefined reference toff::error(char const*, ...)' test.o: In function `ff::ff_node::losetime_out()':

etc, etc...

Here is relevant part of the utils.hpp file:

namespace ff {
  static inline double diffmsec(const struct timeval & a,
                              const struct timeval & b) {
    long sec  = (a.tv_sec  - b.tv_sec);
    long usec = (a.tv_usec - b.tv_usec);

    if(usec < 0) {
        --sec;
        usec += 1000000;
    }
    return ((double)(sec*1000)+ ((double)usec)/1000.0);
  }
.
.
.
}

I am modmap'ing and importing everything in utils.hpp, but diffmsec still seems to be undefined no matter what I try. I am tired though...maybe I am just missing something simple??

Thanks, Kelly

wilsonk avatar Jun 30 '15 22:06 wilsonk

Hi Kelly,

Sorry for the late reply not a lot of free time atm, those linking errors are the last errors that prevent my Ogre demo from compiling too. I'm investigating them, but the current way of referencing and emitting functions is more like a hack for the time being which is why it's fragile.

The right way to do it would be the DMD way, i.e to traverse the function bodies and to map the function calls to DMD's CallExp which Calypso doesn't do atm, then even if the CallExp aren't used that will make DMD reference, instantiate and emit the C++ functions like it does for D functions. But that will take more time to implement, so I leave that for later.

Syniurge avatar Jul 04 '15 15:07 Syniurge

Unfortunately, the recent work that you mention in #25 didn't fix the issues with my fastflow example. I am still seeing the undefined reference to ff:diffmsec, etc...

Just to let you know Elie.

wilsonk avatar Jul 31 '15 04:07 wilsonk

Looks like the last few changes today have fixed the ff_msec problems. There are still a few other ones like this:

__cpp_ff_ff_node.o: In function `ff::ff_node::getstarttime() const':
__cpp/ff/ff_node:(.text._ZNK2ff7ff_node12getstarttimeEv[_ZNK2ff7ff_node12getstarttimeEv]+0x20): undefined reference to `timeval::timeval(timeval const&)'
__cpp_ff_ff_node.o: In function `ff::ff_node::getstoptime() const':
__cpp/ff/ff_node:(.text._ZNK2ff7ff_node11getstoptimeEv[_ZNK2ff7ff_node11getstoptimeEv]+0x20): undefined reference to `timeval::timeval(timeval const&)'
__cpp_ff_ff_node.o: In function `ff::ff_node::getwstartime() const':
__cpp/ff/ff_node:(.text._ZNK2ff7ff_node12getwstartimeEv[_ZNK2ff7ff_node12getwstartimeEv]+0x20): undefined reference to `timeval::timeval(timeval const&)'
__cpp_ff_ff_node.o: In function `ff::ff_node::getwstoptime() const':
__cpp/ff/ff_node:(.text._ZNK2ff7ff_node12getwstoptimeEv[_ZNK2ff7ff_node12getwstoptimeEv]+0x23): undefined reference to `timeval::timeval(timeval const&)'
__cpp_ff_ff_node.o: In function `ff::ff_node::thWorker::svc(void*)':
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x10e): undefined reference to `EOS'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x11d): undefined reference to `EOS_NOFREEZE'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x182): undefined reference to `GO_OUT'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x1bd): undefined reference to `GO_OUT'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x1dc): undefined reference to `EOS'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x1eb): undefined reference to `EOS_NOFREEZE'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x200): undefined reference to `EOS'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x21e): undefined reference to `GO_ON'
__cpp/ff/ff_node:(.text._ZN2ff7ff_node8thWorker3svcEPv[_ZN2ff7ff_node8thWorker3svcEPv]+0x22d): undefined reference to `EOS_NOFREEZE'
__cpp_ff_ff_thread.o: In function `ff::ff_thread::spawn(int)':
__cpp/ff/ff_thread:(.text._ZN2ff9ff_thread5spawnEi[_ZN2ff9ff_thread5spawnEi]+0xbb): undefined reference to `ff::proxy_thread_routine(void*)'
__cpp_ff_dynqueue.o: In function `ff::SWSR_Ptr_Buffer::~SWSR_Ptr_Buffer()':
__cpp/ff/dynqueue:(.text._ZN2ff15SWSR_Ptr_BufferD2Ev[_ZN2ff15SWSR_Ptr_BufferD2Ev]+0x11): undefined reference to `freeAlignedMemory(void*)'
collect2: error: ld returned 1 exit status

But it is pretty close now hopefully :)

wilsonk avatar Aug 15 '15 20:08 wilsonk

When I found the root cause earlier of most linking errors this week it was more like the beginning of the end of linking errors, because now the burden of referencing and emitting every used symbol falls on Calypso so there's still some work ahead, but yes pretty close we should be! :)

The first four errors (copy constructors) will go away tonight.

Syniurge avatar Aug 15 '15 21:08 Syniurge

Sweet, sounds good Elie :)

wilsonk avatar Aug 15 '15 21:08 wilsonk

A few more of those errors above were fixed with those commits tonight. The errors from the one ending with 'EOS' down are still there, but this example is almost compiling now. :)

wilsonk avatar Aug 16 '15 10:08 wilsonk

How does it look now?

Syniurge avatar Aug 16 '15 20:08 Syniurge

Great Elie. Just a couple left:

__cpp_ff_ff_thread.o: In function `ff::ff_thread::spawn(int)':
__cpp/ff/ff_thread:(.text._ZN2ff9ff_thread5spawnEi[_ZN2ff9ff_thread5spawnEi]+0xbb): undefined reference to `ff::proxy_thread_routine(void*)'
__cpp_ff_dynqueue.o: In function `ff::SWSR_Ptr_Buffer::~SWSR_Ptr_Buffer()':
__cpp/ff/dynqueue:(.text._ZN2ff15SWSR_Ptr_BufferD2Ev[_ZN2ff15SWSR_Ptr_BufferD2Ev]+0x11): undefined reference to `freeAlignedMemory(void*)'
collect2: error: ld returned 1 exit status

wilsonk avatar Aug 17 '15 00:08 wilsonk

And now?

Syniurge avatar Aug 18 '15 23:08 Syniurge

Oh so close...just that last error is still showing up. I can get things to compile if I remove the 'static' keyword for the function freeAlignedMemory, however!!

I will test things further now because at least I can massage things into place for the simplest example.

wilsonk avatar Aug 19 '15 01:08 wilsonk

Hey Elie,

The minimal example near the top of this issue compiles and runs with a blank main() or a just an instantiation of Worker() (after I fix freeAlignedMemory as above), which is cool. The next thing I tried was to convert the 'simplest.cpp' example like this:

modmap (C++) "ff/pipeline.hpp";
modmap (C++) "ff/node.hpp";

import (C++) ff._;
import (C++) ff.ff_pipeline;
import (C++) ff.ff_node;

import std.stdio;

class Stage : ff_node {
   public:
        this() { counter = 0; }
        override int svc_init() {
            writeln("Hello, I'm Stage");
            return 0;
        }
        override void* svc(void * task) {
                 if (++counter > 10) return cast(void*)0;
                 writeln("Hi");
                 return cast(void*)ulong.max-0x02;
        }
        override void svc_end() {
                 writeln("Goodbye...");
        }
   private:
        long counter;
}

int main(char[][] args) {

    auto pipe = new ff_pipeline();
    pipe.add_stage(new Stage());
    return 0;
}

It compiles fine but when I try to run this (and a couple other small examples) I get a segfault and this backtrace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b4aaaa in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
(gdb) bt
#0  0x00007ffff7b4aaaa in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#1  0x0000000000405fde in std::_Rb_tree_iterator<ff::fftree*>::operator--() ()
#2  0x0000000000405e10 in std::_Rb_tree<ff::fftree*, ff::fftree*, std::_Identity<ff::fftree*>, std::less<ff::fftree*>, std::allocator<ff::fftree*> >::_M_get_insert_unique_pos(ff::fftree* const&) ()
#3  0x0000000000405c51 in std::_Rb_tree<ff::fftree*, ff::fftree*, std::_Identity<ff::fftree*>, std::less<ff::fftree*>, std::allocator<ff::fftree*> >::_M_insert_unique(ff::fftree* const&) ()
#4  0x0000000000405b78 in std::set<ff::fftree*, std::less<ff::fftree*>, std::allocator<ff::fftree*> >::insert(ff::fftree* const&) ()
#5  0x0000000000420057 in ff::fftree::fftree(ff::ff_node*, ff::fftype) ()
#6  0x000000000041f125 in ff::fftree::fftree(ff::ff_node*, ff::fftype) ()
#7  0x0000000000425c17 in ff::ff_pipeline::ff_pipeline(bool, int, int, bool) ()
#8  0x000000000042493e in ff::ff_pipeline::ff_pipeline(bool, int, int, bool) ()
#9  0x00000000004054e1 in D main (args=...) at test.d:31
#10 0x0000000000448ea4 in rt.dmain2._d_run_main() (mainFunc=0x405450 <D main>) at dmain2.d:400
#11 0x0000000000448d69 in rt.dmain2._d_run_main() (dg={void delegate() (void)} 0x7fffffffe278) at dmain2.d:375
#12 0x0000000000448e07 in rt.dmain2._d_run_main() () at dmain2.d:400
#13 0x0000000000448d69 in rt.dmain2._d_run_main() (dg={void delegate() (void)} 0x7fffffffe2e8) at dmain2.d:375
#14 0x0000000000448ccf in _d_run_main (argc=1, argv=0x7fffffffe598, mainFunc=0x405450 <D main>) at dmain2.d:408
#15 0x00000000004056c8 in main (argc=1, argv=0x7fffffffe598) at .:3

With each example the problem appears to start at the fftree calls and then the std::set. I suppose something isn't being instantiated properly from the within the pipeline.hpp file...maybe this:

"fftree_ptr = new fftree(this, PIPE);"

when the new ff_pipeline() call is made? Just my thoughts on it anyways.

wilsonk avatar Aug 19 '15 05:08 wilsonk

Looking into it.

Syniurge avatar Aug 26 '15 00:08 Syniurge

The segfault is gone with 9ffb94ec19fdf68de59571e7a104b1c034b15ef2.

EDIT: oops nevermind, not your segfault, but another one I got during codegen.

Syniurge avatar Aug 27 '15 22:08 Syniurge

The last linking error is fixed with e56876f1627bb12a1fa108b049126c27c6a077dc, and it runs without segfaulting.

Syniurge avatar Aug 28 '15 00:08 Syniurge

Your segfault seems to be something else though, maybe a wrong default argument passed to ff_pipeline's ctor. Since I can't reproduce the crash, could you examine the arguments in the 8th stack frame?

Syniurge avatar Aug 28 '15 00:08 Syniurge

Elie, it looks like the 'this' at line 154 of pipeline.hpp is the problem. I can just instantiate a 'new ff_pipeline()' manually in my test file and then recreate line 154 like this:

    auto pipe = new ff_pipeline();
    pipe.fftree_ptr = new fftree(pipe, fftype.PIPE);

this gets me past the pipeline constructor, but then things segfault in fftree.hpp at line 69 'roots.insert(this);' ... so it looks like the 'this' is the problem here also. If I comment out line 68-69 in fftree.hpp then the pipeline test above runs fine.

Anyways, the reason I am doing this manually is because I can't get gdb to find the line numbers/symbols for pipeline.hpp to save my life!!! I am compiling with -g for clang and ldc2 (or -ggdb or -gc, etc.) and I can use readelf or nm to see that there are debug symbols in my 'test' binary...but no joy on actually getting line info or symbols for ff::ff_pipeline::ff_pipeline(bool,int,int,bool)!!

I can see symbols and line numbers/source code in my test.d file when using gdb (and other .d files), but not the .hpp files.

I can use tab to auto complete the ff::ff_pip, etc...so gdb seems to getting some symbol info together?? I can set the source directory and see a bunch of the files listed. Maybe that is the problem, though, because the .hpp files don't have any extension and are located in places like '/home/wilsonk/fastflow/__cpp/ff/pipeline'??? That doesn't look right...does it?? Gdb looks like it is trying to find __cpp_ff_pipeline.o is in that directory, instead of /home/wilsonk/fastflow???

Anyways, I can't seem to debug the the cpp code compiled with Calypso here. I suppose I am just missing something, or doing something wrong.

wilsonk avatar Aug 28 '15 04:08 wilsonk

Elie, it looks like the 'this' at line 154 of pipeline.hpp is the problem.

I've been testing with a completely different version of FastFlow from yours, mine doesn't even have fftree_ptr and I can't find a version which does (googling fftree_ptr leads here to this issue).

Which one are you using?

Syniurge avatar Aug 29 '15 19:08 Syniurge

svn info Path: . Working Copy Root Path: /home/wilsonk/Downloads/fastflow URL: https://svn.code.sf.net/p/mc-fastflow/code Relative URL: ^/ Repository Root: https://svn.code.sf.net/p/mc-fastflow/code Repository UUID: 5b2d11e7-8b83-46bf-b187-68a94c616a7d Revision: 282 Node Kind: directory Schedule: normal Last Changed Author: drocco Last Changed Rev: 282 Last Changed Date: 2015-03-06 08:06:57 -0700 (Fri, 06 Mar 2015)

wilsonk avatar Aug 29 '15 20:08 wilsonk

Didn't you have an error about "treeLock" from fftree.hpp too? It was incorrectly skipped during the mapping.

Anyway the compilation works out of the box with the latest commits, now I'm looking into the segfault.

Syniurge avatar Sep 01 '15 11:09 Syniurge