Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SIGSEGV writing to VerilatedVcd::m_wrBufp in 3.864 #834

Closed
veripoolbot opened this issue Oct 31, 2014 · 4 comments
Closed

SIGSEGV writing to VerilatedVcd::m_wrBufp in 3.864 #834

veripoolbot opened this issue Oct 31, 2014 · 4 comments
Assignees
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed

Comments

@veripoolbot
Copy link
Contributor


Author Name: Geoff Barrett
Original Redmine Issue: 834 from https://www.veripool.org
Original Date: 2014-10-31
Original Assignee: Wilson Snyder (@wsnyder)


Symptoms

Several of our tests fail using the verilated component when writing out data to the trace file:

==2893== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==2893== General Protection Fault
==2893== at 0x7EB1A7C: Vfpv8_top_m::traceChgThis__204(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace__15.cpp:121)
==2893== by 0x7D5C965: Vfpv8_top_m::traceChgThis(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace.cpp:693)
==2893== by 0x5A3C6A0: VerilatedVcd::dump(unsigned long) (verilated_vcd_c.cpp:581)
...
==2893== by 0x423494: main (run.c:328)

Diagnosis

Investigating this with valgrind suggests the verilator is writing past the end of its tracing output buffer m_wrBufP. There are several messages like this:

==2893== Invalid write of size 1
==2893== at 0x7D5CCD0: VerilatedVcd::fullArray(unsigned int, unsigned int const*, int) (verilated_vcd_c.h:236)
==2893== by 0x7E93E50: Vfpv8_top_m::traceChgThis__202(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace__14.cpp:388)
==2893== by 0x7D5C946: Vfpv8_top_m::traceChgThis(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace.cpp:688)
==2893== by 0x5A3C6A0: VerilatedVcd::dump(unsigned long) (verilated_vcd_c.cpp:581)
...
==2893== by 0x423494: main (run.c:328)

The VerilatedVcd tracing methods all assume that on entry there will be enough space left in the output buffer to write their content. Before returning to their caller, they call bufferCheck() to ensure there is 16K of buffer left for next time (flushing the buffer if there is not).

The problem arises when a method needs to write out more than 16K of data. The VerilatedVcd::fullArray method writes out each of its array elements but doesn't check between elements that there is room enough for the next one, only at the end.

Workaround

If I modify the following methods in include/verilated_vcd_c.h, increasing the insert size and also allowing a larger buffer (but this is less important):

90,91c90,91
< inline static size_t bufferSize() { return 2561024; } // See below for slack calculation
< inline static size_t bufferInsertSize() { return 16
1024; }

inline static size_t bufferSize() { return 1024*1024; }  // See below for slack calculation
inline static size_t bufferInsertSize() { return 160*1024; }

and rebuild the verilated component, the failing cases all pass and the valgrind messages about the trace buffer disappear.

NB: we have some very large packed structures in our design.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Geoff Barrett
Original Date: 2014-10-31T09:41:59Z


Here it is again with better formatting...

Symptoms

Several of our tests fail using the verilated component when writing out data to the trace file:

==2893== Process terminating with default action of signal 11 (SIGSEGV): dumping core ==2893==  General Protection Fault
==2893==    at 0x7EB1A7C: Vfpv8_top_m::traceChgThis__204(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace__15.cpp:121)
==2893==    by 0x7D5C965: Vfpv8_top_m::traceChgThis(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace.cpp:693)
==2893==    by 0x5A3C6A0: VerilatedVcd::dump(unsigned long) (verilated_vcd_c.cpp:581)
...
==2893==    by 0x423494: main (run.c:328)

Diagnosis

Investigating this with valgrind suggests the verilator is writing past the end of its tracing output buffer m_wrBufP. There are several messages like this:

==2893== Invalid write of size 1
==2893==    at 0x7D5CCD0: VerilatedVcd::fullArray(unsigned int, unsigned int const*, int) (verilated_vcd_c.h:236)
==2893==    by 0x7E93E50: Vfpv8_top_m::traceChgThis__202(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace__14.cpp:388)
==2893==    by 0x7D5C946: Vfpv8_top_m::traceChgThis(Vfpv8_top_m__Syms*, VerilatedVcd*, unsigned int) (Vfpv8_top_m__Trace.cpp:688)
==2893==    by 0x5A3C6A0: VerilatedVcd::dump(unsigned long) (verilated_vcd_c.cpp:581)
...
==2893==    by 0x423494: main (run.c:328)

The VerilatedVcd tracing methods all assume that on entry there will be enough space left in the output buffer to write their content. Before returning to their caller, they call bufferCheck() to ensure there is 16K of buffer left for next time (flushing the buffer if there is not).

The problem arises when a method needs to write out more than 16K of data. The VerilatedVcd::fullArray method writes out each of its array elements but doesn't check between elements that there is room enough for the next one, only at the end.

Workaround

If I modify the following methods in include/verilated_vcd_c.h, increasing the insert size and also allowing a larger buffer (but this is less important):

90,91c90,91
<     inline static size_t bufferSize() { return 256*1024; }  // See below for slack calculation
<     inline static size_t bufferInsertSize() { return 16*1024; }
---
>     inline static size_t bufferSize() { return 1024*1024; }  // See below for slack calculation
>     inline static size_t bufferInsertSize() { return 160*1024; }

and rebuild the verilated component, the failing cases all pass and the valgrind messages about the trace buffer disappear.

NB: we have some very large packed structures in our design.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-10-31T21:45:16Z


Please add to verilated_vcd_c.cpp around line 452:

 if (codesNeeded > bufferInsertSize()) {
     printf("FIXME - will OVERRUN %d %d\n", (int)codesNeeded, (int)bufferInsertSize());
 }

And check that it prints a message in your case. Assuming so I will change the code to dynamically resize the insert.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-11-06T03:26:40Z


Dynamic sizing pushed to git towards 3.865.

@veripoolbot
Copy link
Contributor Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2014-11-15T13:46:37Z


In 3.866.

@veripoolbot veripoolbot added area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed labels Dec 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: wrong runtime result Issue involves an incorrect runtine result from Verilated model resolution: fixed Closed; fixed
Projects
None yet
Development

No branches or pull requests

2 participants