Uninitialized Print::m_origin and Print::m_isBBLPrinter cause undefined behavior in non-GUI builds #139

Open
opened 2026-04-05 16:18:36 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @taylormadearmy on 3/26/2026

Bug Description

Two member variables in Print (Print.hpp) have no default initializers, causing undefined behavior in release builds on platforms where the GUI does not call their setters:

1. Print::m_origin (Vec3d) — no initializer

// Print.hpp — current
Vec3d   m_origin;

set_plate_origin() is only called from PartPlate.cpp (desktop GUI). Any non-GUI consumer of Print (CLI tools, embedded/mobile builds) will read uninitialized memory. In release builds with optimizations, this can contain arbitrary values including -inf, which propagates through WipeTowerIntegration::append_tcr2()plate_origin_2d → every wipe tower travel move, producing impossible coordinates in the G-code output.

2. Print::m_isBBLPrinter (bool) — no initializer

// Print.hpp — current
bool m_isBBLPrinter;

When this reads true from garbage memory, the wrong wipe tower implementation (WipeTower instead of WipeTower2) is selected for non-BBL printers.

Fix

One-line default initializers:

Vec3d   m_origin = Vec3d::Zero();
bool    m_isBBLPrinter = false;

How we found this

We're building an Android wrapper around OrcaSlicer (via Snapmaker Orca 2.2.4) and hit intermittent post-install slicing failures on release builds. After extensive investigation (native backtrace capture, TCR checksum/canary system, per-call state logging), we traced the bad G-code coordinates to plate_origin_y: -inf in the WipeTowerIntegration constructor, which reads from Print::get_plate_origin(). The value was uninitialized because set_plate_origin() is never called outside the desktop GUI.

Debug builds mask the issue because most toolchains zero-fill memory in debug mode.

Impact

  • Any non-GUI use of Print::process() + Print::export_gcode() is affected
  • Desktop OrcaSlicer is not affected because PartPlate always calls set_plate_origin() before slicing
  • The bug manifests as intermittent impossible coordinates in G-code output (sentinel values, infinity, large random numbers)
  • Both variables exist in the upstream OrcaSlicer codebase

Environment

  • Based on Snapmaker Orca 2.2.4 / OrcaSlicer fork
  • ARM64 (Android NDK clang, RelWithDebInfo)
  • Reproduced on Pixel 6, Pixel 8a, Pixel 9a
*Originally created by @taylormadearmy on 3/26/2026* ## Bug Description Two member variables in `Print` (Print.hpp) have no default initializers, causing undefined behavior in release builds on platforms where the GUI does not call their setters: ### 1. `Print::m_origin` (Vec3d) — no initializer ```cpp // Print.hpp — current Vec3d m_origin; ``` `set_plate_origin()` is only called from `PartPlate.cpp` (desktop GUI). Any non-GUI consumer of `Print` (CLI tools, embedded/mobile builds) will read uninitialized memory. In release builds with optimizations, this can contain arbitrary values including `-inf`, which propagates through `WipeTowerIntegration::append_tcr2()` → `plate_origin_2d` → every wipe tower travel move, producing impossible coordinates in the G-code output. ### 2. `Print::m_isBBLPrinter` (bool) — no initializer ```cpp // Print.hpp — current bool m_isBBLPrinter; ``` When this reads `true` from garbage memory, the wrong wipe tower implementation (`WipeTower` instead of `WipeTower2`) is selected for non-BBL printers. ## Fix One-line default initializers: ```cpp Vec3d m_origin = Vec3d::Zero(); bool m_isBBLPrinter = false; ``` ## How we found this We're building an Android wrapper around OrcaSlicer (via Snapmaker Orca 2.2.4) and hit intermittent post-install slicing failures on release builds. After extensive investigation (native backtrace capture, TCR checksum/canary system, per-call state logging), we traced the bad G-code coordinates to `plate_origin_y: -inf` in the `WipeTowerIntegration` constructor, which reads from `Print::get_plate_origin()`. The value was uninitialized because `set_plate_origin()` is never called outside the desktop GUI. Debug builds mask the issue because most toolchains zero-fill memory in debug mode. ## Impact - Any non-GUI use of `Print::process()` + `Print::export_gcode()` is affected - Desktop OrcaSlicer is not affected because `PartPlate` always calls `set_plate_origin()` before slicing - The bug manifests as intermittent impossible coordinates in G-code output (sentinel values, infinity, large random numbers) - Both variables exist in the upstream OrcaSlicer codebase ## Environment - Based on Snapmaker Orca 2.2.4 / OrcaSlicer fork - ARM64 (Android NDK clang, RelWithDebInfo) - Reproduced on Pixel 6, Pixel 8a, Pixel 9a
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/OrcaSlicer#139