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
Comments
Original Redmine Comment Here it is again with better formatting... SymptomsSeveral of our tests fail using the verilated component when writing out data to the trace file:
DiagnosisInvestigating this with valgrind suggests the verilator is writing past the end of its tracing output buffer m_wrBufP. There are several messages like this:
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. WorkaroundIf 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):
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. |
Original Redmine Comment Please add to verilated_vcd_c.cpp around line 452:
And check that it prints a message in your case. Assuming so I will change the code to dynamically resize the insert. |
Original Redmine Comment Dynamic sizing pushed to git towards 3.865. |
Original Redmine Comment In 3.866. |
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 161024; }
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.
The text was updated successfully, but these errors were encountered: