Skip to content

renderdem segfault when using --decimation > 1 (out-of-bounds write in point_io.cpp) #2

@JinyuJia-bot

Description

@JinyuJia-bot

Description

renderdem consistently crashes with a Segmentation fault (core dumped) when using --decimation > 1 with LAZ point cloud inputs. The crash does NOT occur when --decimation=1.

Reproduction

  1. Run renderdem with --decimation > 1 on a large LAZ file (164M points):
    ./renderdem "/datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz" \
      --outdir "/datasets/PhaseOne_cut/odm_dem" \
      --output-type max \
      --radiuses 0.11,0.15556349186104046,0.22 \
      --resolution 20 \
      --decimation 50 \
      --classification -1 \
      --force
  2. Observe immediate segfault;
  3. Run the same command with --decimation=1 → no crash, DEM generates successfully.

Terminal Output (Fault Case)

Decimation set to 50
Reading points from /datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz
Number of points: 164352797
Classification dimension: Classification
Segmentation fault (core dumped)

Terminal Output (Working Case, --decimation=1)

Reading points from /datasets/PhaseOne_cut/odm_georeferencing/odm_georeferenced_model.laz
Number of points: 164352797
Classification dimension: Classification
Point cloud bounds are [minx: 600123.28, maxx: 603468.245, miny: 3601441.208, maxy: 3604695.694]
DEM resolution is (168, 163), max tile size is 4096, will split DEM generation into 1 tiles
r0.11_x0_y0.tif
r0.155563_x0_y0.tif
r0.22_x0_y0.tif
...

Root Cause

The decimation logic is inverted in point_io.cpp, leading to an out-of-bounds memory write:

  1. Memory is pre-allocated for count / decimation points (expected to keep 1/N points):
    r->resize(count / decimation); // Allocates space for 1/50 of points 
  2. The loop skips points incorrectly (keeps 49/50 points instead of 1/50):
    if (decimate && idx % decimation == 0) continue; // Skips Nth point (wrong)
  3. This mismatch causes the program to write past the allocated memory buffer → segfault.

Proposed Fix

Correct the decimation condition to keep every Nth point (consistent with the CLI help text: "Read every Nth point"):

// Replace this (wrong):
...
r->resize(count / decimation); 
...
if (decimate && idx % decimation == 0) continue;

// With this (correct):
...
r->resize((count + decimation - 1) / decimation); // ceil(count/decimation)
...
if (decimate && (idx % decimation) != 0) continue;

Apply this fix to both:

  • pdalReadPointSet()
  • fastPlyReadPointSet() (ASCII and binary)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions