From f95968a3725309433e1dfed1ecfe1b5b32c44d74 Mon Sep 17 00:00:00 2001 From: krrish175-byte Date: Thu, 26 Feb 2026 23:56:38 +0530 Subject: [PATCH] gpl: fix segfault when selecting instance in debug mode Fix three issues that caused segmentation faults in GPL debug mode: 1. In debugForNesterovPlace(), the nbVec_ search for the selected instance was outside the 'if (inst)' guard, causing cell_handle->contains(nullptr) to be called when no debug instance was specified. 2. In drawNesterov(), accessing nbVec_[nb_index] for gradient drawing without checking that nb_index is within bounds of nbVec_. 3. In reportSelected(), same missing bounds check on nbVec_[nb_index]. Fixes #9017 Signed-off-by: Krrish Biswas Signed-off-by: krrish175-byte --- src/gpl/src/graphicsImpl.cpp | 60 ++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 19 deletions(-) diff --git a/src/gpl/src/graphicsImpl.cpp b/src/gpl/src/graphicsImpl.cpp index 6bd04b3ca1..79b9b90c9f 100644 --- a/src/gpl/src/graphicsImpl.cpp +++ b/src/gpl/src/graphicsImpl.cpp @@ -27,6 +27,30 @@ namespace gpl { +namespace { + +std::optional getSelectedNesterovBaseIndex( + size_t nb_selected_index, + const std::vector>& nbVec, + utl::Logger* logger, + int msg_id) +{ + size_t nb_index = 0; + if (nb_selected_index != std::numeric_limits::max()) { + nb_index = nb_selected_index; + } else if (!nbVec.empty()) { + logger->warn( + utl::GPL, msg_id, "Selected instance not found in any NesterovBase"); + } + + if (nb_index >= nbVec.size()) { + return std::nullopt; + } + return nb_index; +} + +} // namespace + GraphicsImpl::GraphicsImpl(utl::Logger* logger) : HeatMapDataSource(logger, "gpl", "gpl"), logger_(logger), mode_(Mbff) { @@ -119,14 +143,14 @@ void GraphicsImpl::debugForNesterovPlace( break; } } - } - for (const auto& nb : nbVec_) { - for (size_t idx = 0; idx < nb->getGCells().size(); ++idx) { - GCellHandle cell_handle = nb->getGCells()[idx]; - if (cell_handle->contains(inst)) { - nb_selected_index_ = &nb - nbVec_.data(); - break; + for (const auto& nb : nbVec_) { + for (size_t idx = 0; idx < nb->getGCells().size(); ++idx) { + GCellHandle cell_handle = nb->getGCells()[idx]; + if (cell_handle->contains(inst)) { + nb_selected_index_ = &nb - nbVec_.data(); + break; + } } } } @@ -393,13 +417,12 @@ void GraphicsImpl::drawNesterov(gui::Painter& painter) const GCell* gcell = nbc_->getGCellByIndex(selected_); auto wlCoeffX = np_->getWireLengthCoefX(); auto wlCoeffY = np_->getWireLengthCoefY(); - size_t nb_index = 0; - if (nb_selected_index_ != kInvalidIndex) { - nb_index = nb_selected_index_; - } else { - logger_->warn( - utl::GPL, 317, "Selected instance not found in any NesterovBase"); + auto opt_nb_index = getSelectedNesterovBaseIndex( + nb_selected_index_, nbVec_, logger_, 317); + if (!opt_nb_index) { + return; } + size_t nb_index = *opt_nb_index; FloatPoint densityGrad = nbVec_[nb_index]->getDensityGradient(gcell); FloatPoint wlGrad = nbc_->getWireLengthGradientWA(gcell, wlCoeffX, wlCoeffY); @@ -524,13 +547,12 @@ void GraphicsImpl::reportSelected() = nbc_->getWireLengthGradientWA(gcell, wlCoeffX, wlCoeffY); logger_->report(" sum wl ({: .2e}, {: .2e})", wlGrad.x, wlGrad.y); - size_t nb_index = 0; - if (nb_selected_index_ != kInvalidIndex) { - nb_index = nb_selected_index_; - } else { - logger_->warn( - utl::GPL, 318, "Selected instance not found in any NesterovBase"); + auto opt_nb_index = getSelectedNesterovBaseIndex( + nb_selected_index_, nbVec_, logger_, 318); + if (!opt_nb_index) { + return; } + size_t nb_index = *opt_nb_index; FloatPoint densityGrad = nbVec_[nb_index]->getDensityGradient(gcell); float densityPenalty = nbVec_[nb_index]->getDensityPenalty(); logger_->report(" density ({: .2e}, {: .2e}) (penalty: {})",