Jump to content
Ness

sc_trace for sc_bigint<W> when W=1024

Recommended Posts

Hi,
When I try to trace sc_signal<sc_bigint<W> >  when W=1024 the following program doesn't finish.
However when I try W=1023 and W=1025 the program works as expected.
Could you please help me to debug the case?

Thank you in advance,
Ness

Quote

#include "systemc.h"
#include <iostream>
#include <fstream>

int sc_main ( int argc, char **argv ) {

    sc_signal<sc_bigint<1023> > signal_to_trace;

    sc_start(1, SC_NS);

    sc_trace_file *Tf = sc_create_vcd_trace_file("waves");

    sc_trace(Tf, signal_to_trace, "signal_to_trace");

    sc_start(1, SC_NS);

    sc_close_vcd_trace_file(Tf);
    
    return 0 ;
}

 

Share this post


Link to post
Share on other sites

I'm running the code in Visual Studio 2015 on a Windows 10 64-bit platform.
SystemC compiler is "SystemC 2.3.3 (Includes TLM)" from Accellera website.

I can do a workaround in my code if this is a problem in my side.

Thanks for the quick response!
Ness

Share this post


Link to post
Share on other sites

Thanks for reporting this. I've reproduced the issue. On my side (VS 2017) it crashes with heap corruption, instead of hanging. But I think this is the same issue.

I will debug on this evening. 

Share this post


Link to post
Share on other sites

There is a buffer overflow bug in vcd_sc_signed_trace::write,  someone forgot to reserve a space for null terminator in null-terminated string.

void
vcd_sc_signed_trace::write(FILE* f)
{
    static std::vector<char> compdata(1024), rawdata(1024);
    typedef std::vector<char>::size_type size_t;

    if ( compdata.size() < static_cast<size_t>(object.length()) ) {
        size_t sz = ( static_cast<size_t>(object.length()) + 4096 ) & (~static_cast<size_t>(4096-1));
        std::vector<char>( sz ).swap( compdata ); // resize without copying values
        std::vector<char>( sz ).swap( rawdata );
    }
    char *rawdata_ptr  = &rawdata[0];

    for (int bitindex = object.length() - 1; bitindex >= 0; --bitindex) {
        *rawdata_ptr++ = "01"[object[bitindex].to_bool()];
    }
    *rawdata_ptr = '\0';
    compose_data_line(&rawdata[0], &compdata[0]);

    std::fputs(&compdata[0], f);
    old_value = object;
}
When you have sc_bigint<1024> , 1024 chars in compdata and rawdata are not enough to store 1024 symbols, 
because 1 symbol is required for null terminator assigned here:
*rawdata_ptr = '\0';

It will also fail with sc_bigint<4096>

Can you add + 1 to size of buffer everywhere , rebuild SystemC and rerun your test? :

void
vcd_sc_signed_trace::write(FILE* f)
{
    static std::vector<char> compdata(1024 + 1), rawdata(1024 + 1);
    typedef std::vector<char>::size_type size_t;

    if ( compdata.size() < static_cast<size_t>(object.length()) ) {
        size_t sz = ( static_cast<size_t>(object.length()) + 4096 ) & (~static_cast<size_t>(4096-1));
        sz ++;
...

Same problem also with sc_biguint<1024>.

Thanks for finding this bug! 

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

×