This is a good illustration of fairly common opaque c++ problems, the most dreadful/terrifying species of developer nightmares.
The error seems to be somewhat consistent but not quite.
Reproducing it in dev enviroment was a first milestone. Adding debug prints proved helpful in this case, but sometimes it would take too long.
In the end, I needed a good hypothesis, before we could set out to verify it.
—
81 bool SwapBustAction::streamInImpl(ETSFlowArchive& ar) 82 { // non-virtual 83 if (exchSliceId.empty()) 84 { 85 ar >> exchSliceId; 86 } 104 } 105 void SwapBustAction::streamOutImpl(ETSFlowArchive& ar) const 106 { // non-virtual 107 if (exchSliceId.size()) 108 { 109 ar << exchSliceId; 110 }
When we save the flow element to file, we write out the exchSliceId field conditionally as on Line 107, but when we restore the same flow element from file, the function looks for this exchSliceId field unconditionally as on Line 85. When the function can’t find this field in the file, it hits BufferUnderflow and aborts the restore of entire flow chain.
The serialization file uses field delimiters between the exchSliceId field and the next field which could be a map. When the exchSliceId field is missing, and the map is present, the runtime would notice an unusable data item. It throws a runtime exception in the form of assertion errors.
The “unconditional” restore of exchSliceId is the bug. We need to check the exchSliceId field is present in the file, before reading it.
In my testing, I only had a test case where exchSliceId was present. Insufficient testing.