Skip to content

Positions substring bug#32

Merged
mattcieslak merged 3 commits intomainfrom
windows-mmap-no-huge-pages
Mar 1, 2026
Merged

Positions substring bug#32
mattcieslak merged 3 commits intomainfrom
windows-mmap-no-huge-pages

Conversation

@mattcieslak
Copy link
Collaborator

Root Cause: ext.substr(1, ext.size() - 1) bug in trx-cpp at trx.tpp:362

The crash is caused by a bug in trx-cpp's _create_trx_from_pointer function at trx.tpp:362:

  trx->streamlines->mmap_pos =
      trx::_create_memmap(filename, shape, "r+", ext.substr(1, ext.size() - 1), mem_adress);

_split_ext_with_dimensionality returns ext = "float32" (no leading dot). The ext.substr(1, 6) produces "loat32", which is passed to _create_memmap as the dtype.

In _create_memmap (trx.cpp:751-753), the filesize is calculated as:
filesize = rows * cols * _sizeof_dtype(dtype)

_sizeof_dtype("loat32") matches no known dtype and falls through to the default return of sizeof(uint16_t) = 2 (dtype_helpers.cpp:30). For float32 data it should
return 4.

This means the positions mmap is created at half the required size:

  • 5000 vertices × 3 × 2 = 30,000 bytes mapped
  • 5000 vertices × 3 × 4 = 60,000 bytes needed

The Eigen::Map is then created with shape (5000, 3) over this undersized buffer. When build_streamline_aabbs() iterates all vertices, it reads beyond the mapped memory.

Why Windows crashes but Linux doesn't:

  • Windows: MapViewOfFile provides exactly the requested 30,000 bytes. Accessing byte 30,000+ causes an immediate access violation.
  • Linux: mmap rounds up to page boundaries (30,000 → 32,768 bytes = 8 pages). This provides ~2,730 extra floats of accessible memory. With 5000 vertices the code still reads beyond 32,768 bytes, but Linux may be surviving due to the positions file's pages being in the page cache from the prior zip extraction, making the unmapped region coincidentally accessible (this is undefined behavior).

@mattcieslak mattcieslak added the bug Something isn't working label Mar 1, 2026
@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.81%. Comparing base (3409085) to head (c58ef24).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #32   +/-   ##
=======================================
  Coverage   86.81%   86.81%           
=======================================
  Files          14       14           
  Lines        5869     5872    +3     
  Branches      887      888    +1     
=======================================
+ Hits         5095     5098    +3     
  Misses        774      774           
Flag Coverage Δ
linux 86.75% <100.00%> (+<0.01%) ⬆️
macos 86.73% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mattcieslak mattcieslak merged commit 7f40e25 into main Mar 1, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant