Skip to content

CCDB: read std::array objects written by libstdc++ on libc++ builds - #16072

Merged
ktf merged 1 commit into
AliceO2Group:devfrom
ktf:pr16072
Nov 8, 2026
Merged

ktf merged 1 commit into
AliceO2Group:devfrom
ktf:pr16072

Conversation

@ktf

@ktf ktf commented Nov 7, 2026 •

Copy link
Copy Markdown
Member

This allows reading on macOS some of the TRD CCDB objects which are stored as std::array and get serialised differently on macOS wrt Linux. I think we already complained about this in ROOT ages ago. Given we are now entering a new era, maybe they will find a solution for it with some helps from friends.

The only member of std::array<T,N> is T _M_elems[N] in libstdc++ and
T _elems[N] in libc++, so the StreamerInfo of an array written on Linux
has a checksum (0x9189320d for array<int,540>) that the macOS class does
not have (0x919bc501). When the file is opened, TStreamerInfo::BuildCheck
(ROOT 6.40.04, "perfect alias" block, since 2014) drops the on-file
StreamerInfo as an alias of the in-memory one, and the read then fails:

Error in TBufferFile::ReadVersion: Could not find the StreamerInfo with
a checksum of 0x9189320d for the class "array<int,540>" in name.
Error in TBufferFile::CheckByteCount: object of class array<int,540>
read too few bytes: 6 instead of 2166

leaving the array zero-filled. TRD/Calib/DCSDPsFedChamberStatus is such an
object: every chamber looks off, the TRD digitizer writes 0 digits, and on
macOS the full system test has no TRD and no CTF. If the in-memory
StreamerInfo already exists when the file is opened, ROOT registers the
on-file one but cannot map _M_elems, and reads zeros without any error.

Before reading an array<...> object, DataRefUtils::registerLibstdcxxStdArray
registers the on-file layout as a class version of its own, with its member
renamed to the in-memory name, so ROOT finds it by checksum and reads the
T[N] payload, identical in both libraries, as usual. It is called from both
copies of extractFromTFile: CcdbApi (CcdbApi/BasicCCDBManager, DPL CCDB
fetcher) and DataRefUtils (DPL condition inputs).

Everything is inside #if defined(_LIBCPP_VERSION): libstdc++ builds (EPN,
Grid, CI) compile exactly the same code as before.

Verified on macOS 27.2, ROOT 6.40.04-alice:

  • BasicCCDBManager read of DCSDPsFedChamberStatus at 1550600800000:
    540 zeros before, 521x3 + 19x0 after, the same as decoding the payload
    by hand; at 1720000000000: 431x3, 89x4, 2x5, 18x0.
  • array<string,540> (TRD/Calib/DCSDPsFedCFGtag): 540 empty strings before,
    the real tags after.
  • TRD-only o2-sim-digitizer-workflow on the 10-event PbPb FST sample:
    0 digits before, 126921 after.
    Plain-ROOT reproducer for the ROOT team: ~/src/data/ccdb-stdarray-libcxx-repro.

Needs review.

The only member of std::array<T,N> is T _M_elems[N] in libstdc++ and
T __elems_[N] in libc++, so the StreamerInfo of an array written on Linux
has a checksum (0x9189320d for array<int,540>) that the macOS class does
not have (0x919bc501). When the file is opened, TStreamerInfo::BuildCheck
(ROOT 6.40.04, "perfect alias" block, since 2014) drops the on-file
StreamerInfo as an alias of the in-memory one, and the read then fails:

  Error in <TBufferFile::ReadVersion>: Could not find the StreamerInfo with
  a checksum of 0x9189320d for the class "array<int,540>" in name.
  Error in <TBufferFile::CheckByteCount>: object of class array<int,540>
  read too few bytes: 6 instead of 2166

leaving the array zero-filled. TRD/Calib/DCSDPsFedChamberStatus is such an
object: every chamber looks off, the TRD digitizer writes 0 digits, and on
macOS the full system test has no TRD and no CTF. If the in-memory
StreamerInfo already exists when the file is opened, ROOT registers the
on-file one but cannot map _M_elems, and reads zeros without any error.

Before reading an array<...> object, DataRefUtils::registerLibstdcxxStdArray
registers the on-file layout as a class version of its own, with its member
renamed to the in-memory name, so ROOT finds it by checksum and reads the
T[N] payload, identical in both libraries, as usual. It is called from both
copies of extractFromTFile: CcdbApi (CcdbApi/BasicCCDBManager, DPL CCDB
fetcher) and DataRefUtils (DPL condition inputs).

Everything is inside #if defined(_LIBCPP_VERSION): libstdc++ builds (EPN,
Grid, CI) compile exactly the same code as before.

Verified on macOS 27.2, ROOT 6.40.04-alice:
- BasicCCDBManager read of DCSDPsFedChamberStatus at 1550600800000:
  540 zeros before, 521x3 + 19x0 after, the same as decoding the payload
  by hand; at 1720000000000: 431x3, 89x4, 2x5, 18x0.
- array<string,540> (TRD/Calib/DCSDPsFedCFGtag): 540 empty strings before,
  the real tags after.
- TRD-only o2-sim-digitizer-workflow on the 10-event PbPb FST sample:
  0 digits before, 126921 after.
Plain-ROOT reproducer for the ROOT team: ~/src/data/ccdb-stdarray-libcxx-repro.
@ktf

ktf commented Nov 7, 2026

Copy link
Copy Markdown
Member Author

See also root-project/root#17216

@ktf

ktf commented Nov 8, 2026

Copy link
Copy Markdown
Member Author

code only relevant when building with libc++. Works on mac. merging.

@ktf
ktf merged commit d273816 into AliceO2Group:dev Nov 8, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant