Jump to content
thekamz

Segfault when sc_vector deallocates memory

Recommended Posts

I am trying to use an sc_vector of modules with a custom creator to pass constructor arguments.  It seems to work and run through the entire program, but at exit causes a segfault.  GDB shows that this is due to to sc_vector calling the destructor of the module.

 

I have no dynamically-allocated memory or pointers in the module.  Here's the overview:

 

outside of sc_main (global -- but I also tried inside of sc_main):

--------------------------

struct create_mod
{
     unsigned int m_arg1;
     unsigned int m_arg2;
     create_mod(unsigned int arg1, unsigned int arg2) : m_arg1(arg1), m_arg2(arg2) {}
     mod* operator()(const char* name, size_t)
     {
          return new mod(name, m_arg1, m_arg2);
     }
};

Inside sc_main:

---------------------------

unsigned int num_of_mods = 8;
unsigned int args1 = 5, args2 = 4;

sc_vector<mod> vec_mod("mods");
vec_mod.init(num_of_mods, create_mod(args1, args2));

// ... use vec_mod, bind ports, etc ...

return 0;

So the program runs, then segfaults at the end with "core dumped".  GDB results:

 

Program received signal SIGSEGV, Segmentation fault.
__GI___libc_free (mem=0x5006e4b8e) at malloc.c:2929
2929    malloc.c: No such file or directory.

 

 

Backtracing shows:

#0  __GI___libc_free (mem=0x5006e4b8e) at malloc.c:2929
#1  0x00007ffff77e017b in sc_core::sc_module::~sc_module() ()
   from /usr/local/systemc/lib-linux64/libsystemc-2.3.1.so
#2  0x000000000042e6a0 in mod::~mod (this=0x6bf650) at ../src/mod.h:25
#3  0x000000000042e6c9 in mod::~mod (this=0x6bf650) at ../src/mod.h:25
#4  0x000000000044593b in sc_core::sc_vector<mod>::clear
(this=0x7fffffffc748)
    at /usr/local/systemc/include/sysc/utils/sc_vector.h:653
#5  0x0000000000442e6f in sc_core::sc_vector<mod>::~sc_vector (
    this=0x7fffffffc748)
    at /usr/local/systemc/include/sysc/utils/sc_vector.h:696
#6  0x0000000000441fb4 in sc_main (sc_argc=1, sc_argv=0x6a8400)
    at ../src/main.cpp:334
#7  0x00007ffff77dd674 in sc_elab_and_sim ()
   from /usr/local/systemc/lib-linux64/libsystemc-2.3.1.so
#8  0x00007ffff6e9fec5 in __libc_start_main (main=0x404b00 <main@plt>, argc=1,
    argv=0x7fffffffdf48, init=<optimized out>, fini=<optimized out>,
    rtld_fini=<optimized out>, stack_end=0x7fffffffdf38) at libc-start.c:287
#9  0x0000000000406a5c in _start ()

 

Note the bit in red.  Also note that line 334 is the closing brace of sc_main.

 

Also:

(gdb) frame 2
#2  0x000000000042e6a0 in mod::~mod (this=0x6bf650) at ../src/mod.h:25
25    class mod : public sc_module
(gdb) frame 3
#3  0x000000000042e6c9 in mod::~mod (this=0x6bf650) at ../src/mod.h:25
25    class mod : public sc_module

 

As I said, I have no dynamically-allocated memory in the class.  I have tried an empty destructor (as well as = default since I'm using C++11) but got the same result.

 

Any ideas?

 

Thanks in advance.

Share this post


Link to post
Share on other sites

I am trying to use an sc_vector of modules with a custom creator to pass constructor arguments.  It seems to work and run through the entire program, but at exit causes a segfault.  GDB shows that this is due to to sc_vector calling the destructor of the module.

 

I have no dynamically-allocated memory or pointers in the module.  Here's the overview:

 

outside of sc_main (global -- but I also tried inside of sc_main):

--------------------------

struct create_mod
{
     unsigned int m_arg1;
     unsigned int m_arg2;
     create_mod(unsigned int arg1, unsigned int arg2) : m_arg1(arg1), m_arg2(arg2) {}
     mod* operator()(const char* name, size_t)
     {
          return new mod(name, m_arg1, m_arg2);
     }
};

Inside sc_main:

---------------------------

unsigned int num_of_mods = 8;
unsigned int args1 = 5, args2 = 4;

sc_vector<mod> vec_mod("mods");
vec_mod.init(num_of_mods, create_mod(args1, args2));

// ... use vec_mod, bind ports, etc ...

return 0;

So the program runs, then segfaults at the end with "core dumped".  GDB results:

 

Backtracing shows:

Note the bit in red.  Also note that line 334 is the closing brace of sc_main.

 

Also:

As I said, I have no dynamically-allocated memory in the class.  I have tried an empty destructor (as well as = default since I'm using C++11) but got the same result.

 

Any ideas?

 

Thanks in advance.

 

Hello Sir,

There some obvious errors that you need to correct:

You say:

I have no dynamically-allocated memory or pointers in the module.  Here's the overview:

But you do use dynamic allocation:

 

struct create_mod

{

unsigned int m_arg1;

     unsigned int m_arg2;

     create_mod(unsigned int arg1, unsigned int arg2) : m_arg1(arg1), m_arg2(arg2) {}

     mod* operator()(const char* name, size_t)

     {

          return new mod(name, m_arg1, m_arg2);

     }

};

 

So, where is the corresponding delete operator ?

You mention using the default destructor (I believe something like : ~<class_name>(){} )

but that that will not work -- the delet operator has to be used explicitly.

Please look up some good reference on C++, and then on SystemC.

Share this post


Link to post
Share on other sites

The creator struct and its use looks fine to me.

What's suspicious is indeed the second call to ~mod() from within ~mod() itself.

What types of members do you have in mod?  How do you initialize them?  Do you (ab)use smart-pointers?
What happens, if you add the following line to sc_main?

delete new mod("tmp", args1, args2);

Can you assemble a minimal but compilable example demonstrating the problem?

From your description above, it's more or less just the (relevant parts of the) definition of mod that's missing.

 

@dakupoto: The sc_vector itself will cleanup its allocated elements.  A creator function/class for sc_vector is one of the rare examples, where users must not write their own delete to the new.

 

 

/Philipp

Edited by Philipp A. Hartmann

Share this post


Link to post
Share on other sites

Thank you for your responses dakupoto and Philipp.

 

Philipp - I will post a simple compilable example ASAP.  It may take an hour or so because mod, while simple, is connected to a bunch of other stuff in main.  In the mean time, mod has:

  • 4 private members (3 unsigned ints and 1 static unsigned int)
  • public sc_vector<sc_fifo_in<my_packet_type>>
  • public sc_vector<sc_fifo_out<my_packet_type>>

No pointers or smart pointers.

 

Adding your line to sc_main had no effect (I added it after the call to sc_start, i.e., immediately before the call to return from sc_main).

 

EDIT: Ah, my_packet_type does use a single std::unique_ptr.  I'll wrap up this whole thing into a small compilable example to post here soon.

Share this post


Link to post
Share on other sites

Philipp - I will post a simple compilable example ASAP.  It may take an hour or so because mod, while simple, is connected to a bunch of other stuff in main.

 

For your convenience, I have created a simple example based on your code at EDA playground (which uses SystemC 2.3.0).  Just add/correct the relevant parts and try to reproduce the problem.  If the module has just the members you listed, I don't think the problem is related to mod itself.

 

Adding your line to sc_main had no effect (I added it after the call to sc_start, i.e., immediately before the call to return from sc_main).

 

If you add the line after the call to sc_start, it should lead to an error as you can't instantiate additional modules after the end of the elaboration phase.  If there is no such error, there may be something else going wrong here (memory corruption?).

 

Do you keep seeing the segmentation fault, if you skip the sc_start call?

 

/Philipp

Share this post


Link to post
Share on other sites

There is no error when adding the line after sc_start, so you may be right.  Skipping the sc_start results in no segfault.

 

The module does have only the members I listed.  Like I said, the my_packet_type does have (one) unique_ptr member, but I'm sure it is used appropriately.

 

Moving your line to before the call to sc_start, then debugging, shows something new.  Specifically, inside mod I am trying to wait on a data_written_event to any of the sc_fifo_in contained in sc_vector<sc_fifo_in<my_packet_type>>.  The way I am doing that is with this function:

template <typename T>
static sc_event_or_list multi_data(const sc_vector<sc_fifo_in<T>>& input_ports)
{
       sc_event_or_list my_or_events = input_ports[0].data_written_event() | input_ports[0].data_written_event();
       for(auto& port : input_ports)
       {
           my_or_events |= port.data_written_event();
       }
       return my_or_events;
}

The debugger points to the line in red.

 

When I modify that function as follows:

template <typename T>
static sc_event_or_list multi_data(const sc_vector<sc_fifo_in<T>>& input_ports)
{
       sc_event_or_list my_or_events;
       for(auto& port : input_ports)
       {
           my_or_events |= port.data_written_event();
       }
       return my_or_events;
}

GDB then points to the function in mod that uses this to wait on an event from any of the input ports.

 

The function in mod that tries to use this:

void mod::do_mod()
{
    while(1)
    {
        if(nums_available<my_packet_type>(mod_in) == 0)
        {
            wait(multi_data<my_packet_type>(mod_in));
        }
        else
        {
            for(auto& channel: mod_in)
            {
                my_packet_type d;
                if(channel.num_available())
                {
                    channel.read(d);
                    help_mod(d);
                }
            }
        }
    }
}

Apologies for the delay in putting up a minimal example.  This system is huge and, unfortunately, the mod is at the center of it.  I'm trying to find a way to isolate it and still get something illustrative -- putting up the whole thing is not possible due to an NDA that prevents sharing.

 

Edit: I should probably add, SystemC 2.3.1.

Share this post


Link to post
Share on other sites

I have added to the playground.  Not getting segfault in the simplified model, but getting another unexpected result.  Data seems to be constructed, but I don't generate data anywhere.  I'm obviously overlooking something basic.  The problem seems to be in the type that I'm passing between modules.

Share this post


Link to post
Share on other sites

There is no error when adding the line after sc_start, so you may be right.  Skipping the sc_start results in no segfault.

 Ok, the next step could be to skip simulation and just run the elaboration/initialization via

sc_start( SC_ZERO_TIME );

Secondly, you should break on the destructor of mod in the debugger to check whether you can see any indication why the destructor is called twice for the same object.  If you have a memory corruption, this might be more difficult to track down.

 

Moving your line to before the call to sc_start, then debugging, shows something new.

...

GDB then points to the function in mod that uses this to wait on an event from any of the input ports.

This looks unrelated and is probably caused by accessing unbound ports too early.

 

Apologies for the delay in putting up a minimal example.  This system is huge and, unfortunately, the mod is at the center of it.  I'm trying to find a way to isolate it and still get something illustrative -- putting up the whole thing is not possible due to an NDA that prevents sharing.

 

Edit: I should probably add, SystemC 2.3.1.

 

For now, I think it's more likely that the problem is in your model rather than that there is a bug in SystemC 2.3.1. The sc_vector code didn't change much between 2.3.0 and 2.3.1.

 

I have added to the playground.  Not getting segfault in the simplified model, but getting another unexpected result.  Data seems to be constructed, but I don't generate data anywhere.  I'm obviously overlooking something basic.  The problem seems to be in the type that I'm passing between modules.

 

This also sounds like an unrelated problem.  Good luck in the bug hunting.  Feel free to share/post your simplified code if you have further questions.

 

/Philipp

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×