From f9e9cff53a8623346cfe0229456899a271ec4fed Mon Sep 17 00:00:00 2001 From: packerlschupfer <83344883+packerlschupfer@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:26:14 +0200 Subject: [PATCH] calib: defensive guards in find_optimal_PA_speed (fix CLI pa-tower SIGSEGV) (#14414) --- src/libslic3r/Config.cpp | 4 +++- src/libslic3r/calib.cpp | 17 ++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/libslic3r/Config.cpp b/src/libslic3r/Config.cpp index 52a46dcacf..c8d816b3a4 100644 --- a/src/libslic3r/Config.cpp +++ b/src/libslic3r/Config.cpp @@ -776,7 +776,9 @@ double ConfigBase::get_abs_value(const t_config_option_key &opt_key, double rati { // Get stored option value. const ConfigOption *raw_opt = this->option(opt_key); - assert(raw_opt != nullptr); + // Mirror the single-arg overload — assert() is a no-op under NDEBUG. + if (raw_opt == nullptr) + throw ConfigurationError("ConfigBase::get_abs_value(): \"" + opt_key + "\" is not defined"); if (raw_opt->type() != coFloatOrPercent) throw ConfigurationError("ConfigBase::get_abs_value(): opt_key is not of coFloatOrPercent"); // Compute absolute value. diff --git a/src/libslic3r/calib.cpp b/src/libslic3r/calib.cpp index 3c2981d822..99625ca196 100644 --- a/src/libslic3r/calib.cpp +++ b/src/libslic3r/calib.cpp @@ -11,12 +11,23 @@ namespace Slic3r { float CalibPressureAdvance::find_optimal_PA_speed(const DynamicPrintConfig &config, double line_width, double layer_height, int extruder_id, int filament_idx) { const double general_suggested_min_speed = 100.0; - double filament_max_volumetric_speed = config.option("filament_max_volumetric_speed")->get_at(filament_idx); + // Read defensively — CLI callers may hand us a config missing optional keys. + auto vector_at = [&config](const char *key, int idx) -> double { + if (const auto *o = config.option(key)) return o->get_at(idx); + const ConfigOptionDef *d = config.def() ? config.def()->get(key) : nullptr; + return (d && d->default_value) ? d->get_default_value()->get_at(idx) : 0.0; + }; + auto nullable_at = [&config](const char *key, int idx) -> double { + if (const auto *o = config.option(key)) return o->get_at(idx); + const ConfigOptionDef *d = config.def() ? config.def()->get(key) : nullptr; + return (d && d->default_value) ? d->get_default_value()->get_at(idx) : 0.0; + }; + double filament_max_volumetric_speed = vector_at("filament_max_volumetric_speed", filament_idx); // todo multi_extruders: - const float nozzle_diameter = config.option("nozzle_diameter")->get_at(extruder_id); + const float nozzle_diameter = vector_at("nozzle_diameter", extruder_id); if (line_width <= 0.) line_width = Flow::auto_extrusion_width(frPerimeter, nozzle_diameter); Flow pattern_line = Flow(line_width, layer_height, nozzle_diameter); - auto pa_speed = std::min(std::max(general_suggested_min_speed, config.option("outer_wall_speed")->get_at(extruder_id)), + auto pa_speed = std::min(std::max(general_suggested_min_speed, nullable_at("outer_wall_speed", extruder_id)), filament_max_volumetric_speed / pattern_line.mm3_per_mm()); return std::floor(pa_speed);