Skip to content

Segfault on most of Boost.GIL's headers #1270

Description

@sdebionne

While converting Boost.GIL documentation to AsciiDoc + Antora + MrDocs toolchain (in boostorg/gil#797), I hit a serious blocker while validating the MrDocs piece.

Summary

Running MrDocs 0.8.0 (Linux release binary, MrDocs-0.8.0-Linux.tar.xz) against boostorg/gil's headers segfaults on 38 of the 49 headers pulled in by the library's umbrella header (boost/gil.hpp), each reproducing in complete isolation (a single #include in an otherwise empty translation unit). The headers that crash are exactly the ones built around GIL's CRTP proxy-reference pattern: pixel.hpp, image.hpp, image_view.hpp, locator.hpp, algorithm.hpp, pixel_iterator*.hpp, rgb.hpp, step_iterator.hpp, and everything under image_processing/. Headers without that pattern (channel.hpp, point.hpp, color_base.hpp, concepts.hpp, utilities.hpp, gray.hpp, dynamic_step.hpp, promote_integral.hpp, rasterization/*.hpp) extract cleanly.

This effectively blocks generating a MrDocs/Antora reference for GIL today, since the crashing headers are exactly the ones declaring GIL's most-used public types.

Environment

  • MrDocs 0.8.0 (MrDocs version 0.8.0, Built with LLVM 22.0.0git,
    Build SHA 33d985ccf31e2e3208f317bb5e6e9b91be4400f5, x86_64-unknown-linux-gnu)
  • Ubuntu (linux-64), boostorg/gil develop branch as of 2026-09-01
    (commit 9bb53c581)

Reproduction

git clone https://github.com/boostorg/gil.git
git clone --depth 1 https://github.com/boostorg/stl_interfaces.git   # gil's iterator base
git clone --depth 1 https://github.com/boostorg/boost.git boost-root # for cross-lib headers, OR use a full boost checkout with headers staged under `boost/`

mkdir -p smoketest/src
cat > smoketest/src/all.cpp <<'EOF'
#include <boost/gil/pixel.hpp>
EOF

cat > smoketest/compile_commands.json <<EOF
[
  {
    "directory": "$(pwd)/smoketest/src",
    "command": "c++ -std=c++17 -I$(pwd)/gil/include -I<boost-root> -I$(pwd)/stl_interfaces/include -c all.cpp",
    "file": "all.cpp"
  }
]
EOF

cat > smoketest/mrdocs.yml <<'EOF'
source-root: gil
input:
  - gil/include/boost/gil
file-patterns:
  - '*.hpp'
include-symbols:
  - 'boost::gil::**'
generator: adoc
multipage: true
EOF

mrdocs --config=smoketest/mrdocs.yml \
       --compilation-database=smoketest/compile_commands.json \
       --output=smoketest/out

Result: segmentation fault, exit code 139. Stack dump has no symbols (no llvm-symbolizer on PATH in this environment), but is a deep, repeating frame pattern (255+ frames before truncation) consistent with unbounded recursion during AST visitation, not a simple null-pointer crash. Immediately before the crash, MrDocs prints:

Extracting declarations
<eof> parser at end of file

which looks like it's coming from the comment-doc lexer/parser hitting EOF unexpectedly, though I haven't traced further without symbols.

Per-header result (isolated, #include <boost/gil/X.hpp> alone)

Header Result
channel.hpp OK (225 pages)
color_base.hpp OK
color_base_algorithm.hpp OK
concepts.hpp OK
dynamic_step.hpp OK
gray.hpp OK
point.hpp OK
promote_integral.hpp OK
utilities.hpp OK
extension/rasterization/{circle,ellipse,line}.hpp OK
algorithm.hpp segfault
bit_aligned_pixel_iterator.hpp segfault
bit_aligned_pixel_reference.hpp segfault
channel_algorithm.hpp segfault
cmyk.hpp segfault
color_convert.hpp segfault
device_n.hpp segfault
histogram.hpp segfault
image.hpp segfault
image_view.hpp segfault
image_view_factory.hpp segfault
iterator_from_2d.hpp segfault
locator.hpp segfault
metafunctions.hpp segfault
packed_pixel.hpp segfault
pixel.hpp segfault
pixel_iterator.hpp segfault
pixel_iterator_adaptor.hpp segfault
planar_pixel_iterator.hpp segfault
planar_pixel_reference.hpp segfault
position_iterator.hpp segfault
premultiply.hpp segfault
rgb.hpp segfault
rgba.hpp segfault
step_iterator.hpp segfault
typedefs.hpp segfault
virtual_locator.hpp segfault
image_processing/*.hpp (all 8 files) segfault

Expected behavior

MrDocs should either successfully extract declarations from these headers, or fail gracefully with a diagnostic pointing at the offending construct (as it already does for e.g. --ignore-failures-recoverable warnings), rather than segfaulting.

Possibly related

GIL's pixel/iterator/locator classes are heavy users of exactly these patterns (CRTP proxy references, nested const_t/value_type type aliases, iterator adaptors built via template-template parameters), so this may be a recurrence or an unfixed corner of one of those.

Notes

  • algorithm.hpp and pixel.hpp alone (no other GIL headers) are probably the smallest starting points to bisect from, since they crash in total isolation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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