Skip to content

Conversation

vepadulano
Copy link
Member

Followup to #19817

In the method we need to check if the current TTree has a TTreeCache associated with the current file. The previous logic was getting the pointer to the current file but calling LoadTree afterwards, which deleted the current file and switched it for a new instance. In turn, this would cause bad reads as highlighted by a run of the associated unit test with the address sanitizer:

==18501==ERROR: AddressSanitizer: heap-use-after-free on address 0x61800004be60 at pc 0x000108735e2c bp 0x00016b501950 sp 0x00016b501948
READ of size 8 at 0x61800004be60 thread T0
    #0 0x000108735e28 in TFile::GetCacheRead(TObject const*) const TFile.cxx:1262
    https://github.com/root-project/root/issues/1 0x00010a6e0758 in TTree::GetReadCache(TFile*) const TTree.cxx:6403
    https://github.com/root-project/root/pull/2 0x00010a6e79c0 in TTree::GetReadCache(TFile*, bool) TTree.cxx:6416
    https://github.com/root-project/root/pull/3 0x00010acd2f58 in TTreeReader::Restart() TTreeReader.cxx:574
    https://github.com/root-project/root/pull/4 0x00010acd2634 in TTreeReader::SetEntriesRange(long long, long long) TTreeReader.cxx:550
    https://github.com/root-project/root/pull/5 0x0001048fd23c in main test_ttreereader_uninitialized_chain.cpp:28
    https://github.com/root-project/root/pull/6 0x000190a96b94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)

0x61800004be60 is located 480 bytes inside of 824-byte region [0x61800004bc80,0x61800004bfb8)
freed by thread T0 here:
    #0 0x00010c757b0c in _ZdlPv+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x4bb0c)
    https://github.com/root-project/root/issues/1 0x000107556f6c in TStorage::ObjectDealloc(void*) TStorage.cxx:325
    https://github.com/root-project/root/pull/2 0x0001074a8a68 in TObject::operator delete(void*) TObject.cxx:1189
    https://github.com/root-project/root/pull/3 0x000108732650 in TFile::~TFile() TFile.cxx:569
    https://github.com/root-project/root/pull/4 0x00010a5c6e04 in TChain::LoadTree(long long) TChain.cxx:1449
    https://github.com/root-project/root/pull/5 0x00010acd2dfc in TTreeReader::Restart() TTreeReader.cxx:571
    https://github.com/root-project/root/pull/6 0x00010acd2634 in TTreeReader::SetEntriesRange(long long, long long) TTreeReader.cxx:550
    https://github.com/root-project/root/pull/7 0x0001048fd23c in main test_ttreereader_uninitialized_chain.cpp:28
    https://github.com/root-project/root/pull/8 0x000190a96b94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)

previously allocated by thread T0 here:
    #0 0x00010c7576e4 in _Znwm+0x74 (libclang_rt.asan_osx_dynamic.dylib:arm64e+0x4b6e4)
    https://github.com/root-project/root/issues/1 0x000107556eec in TStorage::ObjectAlloc(unsigned long) TStorage.cxx:293
    https://github.com/root-project/root/pull/2 0x0001056ee26c in TObject::operator new(unsigned long) TObject.h:187
    https://github.com/root-project/root/pull/3 0x00010875b3c8 in TFile::Open(char const*, char const*, char const*, int, int) TFile.cxx:3956
    https://github.com/root-project/root/pull/4 0x00010a5c71a0 in TChain::LoadTree(long long) TChain.cxx:1481
    https://github.com/root-project/root/pull/5 0x00010a5c0f04 in TChain::GetEntries() const TChain.cxx:910
    https://github.com/root-project/root/pull/6 0x0001048fd224 in main test_ttreereader_uninitialized_chain.cpp:28
    https://github.com/root-project/root/pull/7 0x000190a96b94 in start+0x17b8 (dyld:arm64e+0xfffffffffff3ab94)

Change the logic to instead load the tree beforehand, so the pointer to the file will be the correct one.

Fixes CI failures such as https://github.com/root-project/root/actions/runs/17610706130/job/50031825233?pr=19860#step:6:4762

@vepadulano vepadulano self-assigned this Sep 10, 2025
@vepadulano vepadulano requested a review from pcanal as a code owner September 10, 2025 14:25
if (const auto curFile = fTree->GetCurrentFile()) {
if (!fTree->GetTree()) {
fTree->LoadTree(0);
}
if (fTree->GetTree()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe this if-statement is no longer needed if you have the assert above.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed. Although these changes are causing further side effects in a few tests. We may have to revert everything and go back to the drawing board

Copy link
Collaborator

@ferdymercury ferdymercury Sep 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about:

   if (auto curFile = fTree->GetCurrentFile()) {
      if (!fTree->GetTree()) {
         fTree->LoadTree(0);
         curFile = fTree->GetCurrentFile();
      }
      if (fTree->GetTree()) {

(In case the side-effects appear when curFile is null)

Copy link

github-actions bot commented Sep 10, 2025

Test Results

    19 files      19 suites   3d 10h 12m 28s ⏱️
 3 663 tests  3 660 ✅ 0 💤  3 ❌
68 220 runs  68 194 ✅ 5 💤 21 ❌

For more details on these failures, see this check.

Results for commit afb31f5.

♻️ This comment has been updated with latest results.

The previous code was invalidating the tree after the full search through the list of files to gather the number of entries, but it was not taking care of the last file that had been opened.
@vepadulano vepadulano force-pushed the investigate-ttreeplayer-regressions branch from 67284a6 to afb31f5 Compare September 12, 2025 13:46
@vepadulano vepadulano changed the title Fix logic of TTreeReader::Restart Cleanup also current file in TChain::GetEntries Sep 12, 2025
@vepadulano
Copy link
Member Author

I have updated this PR with a second version of the approach. It now also deals with the root cause which is the side-effect caused by TChain::GetEntries, but in a way that keeps all the side-effects of the method. It becomes another alternative to #19873 . Note that this PR will still fail the same tests as before due to the introduction of yet another side-effect. This is meant for discussion with @pcanal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants