Fix crash when getting the free interval around a TrackSegment.

* Bug: In TrackSegment::getFreeInterval(), if, for whatever reason,
    a discrepency happens between the TrackSegment and the Track,
    that is the _track fields point to a *wrong* Track. Then the
    index lookup will fail (Track::npos), so return an all-span
    interval instead of trying to expand it and crash (out of
    bound).
This commit is contained in:
Jean-Paul Chaput 2021-04-18 20:36:20 +02:00
parent 444cc777e5
commit 2019fa25d7
2 changed files with 23 additions and 1 deletions

View File

@ -382,6 +382,8 @@ namespace Katana {
void Track::getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const void Track::getBeginIndex ( DbU::Unit position, size_t& begin, uint32_t& state ) const
{ {
cdebug_log(155,0) << "Track::getBeginIndex(): @" << DbU::getValueString(position)
<< "begin=" << begin << endl;
if (_segments.empty()) { if (_segments.empty()) {
state = EmptyTrack; state = EmptyTrack;
begin = 0; begin = 0;
@ -424,10 +426,18 @@ namespace Katana {
if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) { if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) {
state = BeforeFirstElement; state = BeforeFirstElement;
} else { } else {
cdebug_log(155,0) << " Expanding from begin=" << begin << endl;
if (begin and not sameNetDelta) begin -= 1; if (begin and not sameNetDelta) begin -= 1;
size_t usedBegin = begin; size_t usedBegin = begin;
Interval usedInterval = getOccupiedInterval( usedBegin ); Interval usedInterval = getOccupiedInterval( usedBegin );
cdebug_log(155,0) << " Used interval " << usedInterval << endl;
if (usedInterval.isEmpty()) {
for ( size_t j=0 ; j<_segments.size() ; ++j ) {
cerr << j << ":" << _segments[j] << endl;
}
}
if (position < usedInterval.getVMax()) if (position < usedInterval.getVMax())
state = InsideElement; state = InsideElement;
@ -621,7 +631,8 @@ namespace Katana {
{ {
cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end cdebug_log(155,1) << "Track::expandFreeInterval() begin:" << begin << " end:" << end
<< " state:" << state << " " << net << endl; << " state:" << state << " " << net << endl;
cdebug_log(155,0) << _segments[begin] << endl; if (begin != Track::npos)
cdebug_log(155,0) << _segments[begin] << endl;
DbU::Unit minFree = _min; DbU::Unit minFree = _min;
cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl; cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " (track min)" << endl;
@ -870,6 +881,7 @@ namespace Katana {
Interval Track::getOccupiedInterval ( size_t& begin ) const Interval Track::getOccupiedInterval ( size_t& begin ) const
{ {
cdebug_log(155,0) << "Track::getOccupiedInterval() begin=" << begin << endl;
if (begin == npos) return Interval(); if (begin == npos) return Interval();
size_t seed = begin; size_t seed = begin;

View File

@ -276,6 +276,16 @@ namespace Katana {
size_t begin = _track->find( this ); size_t begin = _track->find( this );
size_t end = begin; size_t end = begin;
if (begin == Track::npos) {
cerr << Error( "TrackSegment::getFreeInterval(): Segment not found in it's assigned track.\n"
" * %s\n"
" * %s\n"
, getString(_track).c_str()
, getString(this).c_str()
) << endl;
return Interval(false);
}
return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() ); return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() );
} }