Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DF][RDatasetSpec] Minimal set of initial functionality #3

Closed

Conversation

ikabadzhov
Copy link

@ikabadzhov ikabadzhov commented May 6, 2022

  • Entry range: if Start > End, logical error is thrown.
  • Entry range: if Start == End, no work done
  • Handle friends

@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch 2 times, most recently from 88f698f to ca0c2bc Compare May 13, 2022 15:40
If Start > End, logical error is thrown.
If Start == End, empty range is always taken.
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from ca0c2bc to 966f873 Compare May 16, 2022 07:28
The RDatasetSpec constructor is no longer interacting with the
RLoopManager's fDefaultColumns. Now, all columns are always taken.
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from b9361c3 to 4b066cc Compare May 16, 2022 07:54
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from 74dfd55 to 2629171 Compare May 16, 2022 12:47
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch 2 times, most recently from 6bffeda to 67c21a6 Compare May 17, 2022 07:50
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch 2 times, most recently from 828b25b to 82a3a0d Compare May 17, 2022 15:45
@ikabadzhov ikabadzhov changed the title [DF] Add RDatasetSpec unit tests [DF][RDatasetSpec] Minimal set of initial functionality May 18, 2022
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from 82a3a0d to 6a21138 Compare May 19, 2022 12:43
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch 3 times, most recently from 70878e9 to f67e9f7 Compare June 3, 2022 06:59
@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from f67e9f7 to 78ede9f Compare June 3, 2022 07:04
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RDatasetSpec.hxx Outdated Show resolved Hide resolved
tree/dataframe/inc/ROOT/RDF/RLoopManager.hxx Outdated Show resolved Hide resolved
tree/dataframe/src/RLoopManager.cxx Outdated Show resolved Hide resolved
tree/dataframe/src/RLoopManager.cxx Show resolved Hide resolved
r.SetEntriesRange(fStartEntry, fEndEntry);
}
if (r.SetEntriesRange(fStartEntry, fEndEntry)) // returning > 0 indicates invalid fStartEntry
throw std::runtime_error("RLoopManager: fStartEntry cannot be larger than the number of entries.");
Copy link
Owner

Choose a reason for hiding this comment

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

Are we sure this is the only case of invalid start entry for TTreeReader?

Copy link
Author

Choose a reason for hiding this comment

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

afaik yes. Because in case fStartEntry > fEndEntry I would have errored out in ctor. Moreover, if the range is fStartEntry < "actual last entry" < fEndEntry then SetEntriesRange returns 0 and will output the entries starting from the fStartEntry up to the the actual last entry.

Copy link
Author

Choose a reason for hiding this comment

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

doublechecking https://github.com/root-project/root/blob/a402af862ace9573193500bcccaa8b4d56cc6632/tree/treeplayer/src/TTreeReader.cxx#L411 this looks like the only invalid thing that can go wrong at this stage.

@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from c44eb5b to 38d6874 Compare June 7, 2022 10:34
gSystem->Exec("rm file0.root file1.root file2.root");
}

TEST(RDatasetSpecTest, Friends)
Copy link
Owner

Choose a reason for hiding this comment

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

Nice that you added these tests with friend trees, but I think it's a bit too convoluted for a single test. Maybe you can have a smaller example before this one and add a table representation of the dataset as a comment in this long one

@ikabadzhov ikabadzhov force-pushed the test_rdatasetspec branch from 76e2a2e to ff9c615 Compare June 8, 2022 13:49
@ikabadzhov
Copy link
Author

Discussion is moved to the newer PR (directly to master)!

@ikabadzhov ikabadzhov closed this Jun 9, 2022
vepadulano pushed a commit that referenced this pull request Jun 1, 2023
Do not use `ActOnReturnStmt()`, given that the scope returned by
`m_Sema->getCurScope()` might be == m_Sema->TUScope which obviously is
not a function scope.

This fixes the following crash:
```
1:  #3 0x0000556b6a50389e clang::Sema::ActOnReturnStmt(clang::SourceLocation, clang::Expr*, clang::Scope*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0x225389e)
1:  root-project#4 0x0000556b69215c56 cling::DeclExtractor::EnforceInitOrder(llvm::SmallVector<clang::Stmt*>&) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf65c56)
1:  root-project#5 0x0000556b69216788 cling::DeclExtractor::ExtractDecl(clang::FunctionDecl*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf66788)
1:  root-project#6 0x0000556b69216a75 cling::DeclExtractor::Transform(clang::Decl*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf66a75)
```
vepadulano pushed a commit that referenced this pull request Jun 26, 2023
Do not use `ActOnReturnStmt()`, given that the scope returned by
`m_Sema->getCurScope()` might be == m_Sema->TUScope which obviously is
not a function scope.

This fixes the following crash:
```
1:  #3 0x0000556b6a50389e clang::Sema::ActOnReturnStmt(clang::SourceLocation, clang::Expr*, clang::Scope*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0x225389e)
1:  root-project#4 0x0000556b69215c56 cling::DeclExtractor::EnforceInitOrder(llvm::SmallVector<clang::Stmt*>&) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf65c56)
1:  root-project#5 0x0000556b69216788 cling::DeclExtractor::ExtractDecl(clang::FunctionDecl*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf66788)
1:  root-project#6 0x0000556b69216a75 cling::DeclExtractor::Transform(clang::Decl*) (/home/jalopezg/CERN/repos/root/_build/interpreter/llvm/src/bin/cling+0xf66a75)
```
vepadulano added a commit that referenced this pull request Jun 11, 2024
```
480: ==2560128==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000011648 at pc 0x7fb9d1ae089e bp 0x7ffd8e35b0a0 sp 0x7ffd8e35b098
480: READ of size 8 at 0x617000011648 thread T0
480:     #0 0x7fb9d1ae089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
480:     #1 0x7fb9d1ae089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
480:     #2 0x7fb9d1ae089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
480:     #3 0x433968 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:104
480:     root-project#4 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4
70bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#5 0x45a5f3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiSillyStruct+0x45a5f3) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#6 0x45a969 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45a969) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#7 0x45ab10 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiSillyStruct+0x45ab10) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#8 0x4675be in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4675be) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#9 0x45af6c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45af6c) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#10 0x425456 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
SillyStruct+0x425456) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#11 0x7fb9cd446149 in __libc_start_call_main (/lib64/libc.so.6+0x28149) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#12 0x7fb9cd44620a in __libc_start_main_impl (/lib64/libc.so.6+0x2820a) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#13 0x4257b4 in _start (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkA
piSillyStruct+0x4257b4) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: 0x617000011648 is located 328 bytes inside of 712-byte region [0x617000011500,0x6170000117c8)
480: freed by thread T0 here:
480:     #0 0x7fb9d1eda878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdfb4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
480:     #2 0x7fb9cdfe8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
480:     #3 0x7fb9cdfc53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
480:     root-project#4 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
480:     root-project#5 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
480:     root-project#6 0x7fb9ce9468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
480:     root-project#7 0x7fb9ce9481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
480:     root-project#8 0x7fb9ce948fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
480:     root-project#9 0x4338cd in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:103
480:     root-project#10 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: previously allocated by thread T0 here:
480:     #0 0x7fb9d1ed9e38 in operator new(unsigned long) (/lib64/libasan.so.8+0xd9e38) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdebbfd0 in TStorage::ObjectAlloc(unsigned long) /home/vpadulan/Programs/rootproject/rootsrc/core/base/src/TStorage.cxx:293
480:     #2 0x7fb9d12cc209 in TObject::operator new(unsigned long) /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/include/TObject.h:181
480:     #3 0x7fb9d12cc209 in new_TTree /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/G__Tree
.cxx:4363
480:     root-project#4 0x7fb9ce10a49c in TClass::NewObject(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx
:5003
480:     root-project#5 0x7fb9ce113c7d in TClass::New(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx:4980
480:     root-project#6 0x7fb9ce9cda38 in TKey::ReadObjectAny(TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TKey.cxx:1086
480:     root-project#7 0x7fb9ce8d10a7 in TDirectoryFile::GetObjectChecked(char const*, TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/T
DirectoryFile.cxx:1111
480:     root-project#8 0x7fb9d1ade1d1 in void TDirectory::GetObject<TTree>(char const*, TTree*&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TD
irectory.h:214
480:     root-project#9 0x7fb9d1ade1d1 in TTreeReader::TTreeReader(char const*, TDirectory*, TEntryList*) /home/vpadulan/Programs/rootproject/rootsrc/tree/tre
eplayer/src/TTreeReader.cxx:232
480:     root-project#10 0x433332 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bu$
kApiSillyStruct.cxx:87
480:     root-project#11 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:
480: SUMMARY: AddressSanitizer: heap-use-after-free /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503 in TTree::GetNotify() co
nst
```
vepadulano added a commit that referenced this pull request Jun 11, 2024
```
479: ==2573107==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000051b48 at pc 0x7f0fcf4e089e bp 0x7fff6e7e1fe0 sp 0x7fff6e7e1fd8
479: READ of size 8 at 0x617000051b48 thread T0
479:     #0 0x7f0fcf4e089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
479:     #1 0x7f0fcf4e089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
479:     #2 0x7f0fcf4e089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
479:     #3 0x4321ca in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:135
479:     root-project#4 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x470
c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#5 0x45a6d3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiVarLength+0x45a6d3) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#6 0x45aa49 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45aa49) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#7 0x45abf0 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiVarLength+0x45abf0) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#8 0x46769e in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiVarLength+0x46769e) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#9 0x45b04c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45b04c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#10 0x424606 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
VarLength+0x424606) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479: 0x617000051b48 is located 328 bytes inside of 712-byte region [0x617000051a00,0x617000051cc8)

479: freed by thread T0 here:
479:     #0 0x7f0fcf8da878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
479:     #1 0x7f0fcb9b4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
479:     #2 0x7f0fcb9e8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
479:     #3 0x7f0fcb9c53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
479:     root-project#4 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
479:     root-project#5 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
479:     root-project#6 0x7f0fcc3468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
479:     root-project#7 0x7f0fcc3481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
479:     root-project#8 0x7f0fcc348fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
479:     root-project#9 0x432ebf in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:130
479:     root-project#10 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x47
0c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
```
vepadulano added a commit that referenced this pull request Jun 12, 2024
The destructor of TTreeReader was making use of the TFile after its destruction.

```
480: ==2560128==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000011648 at pc 0x7fb9d1ae089e bp 0x7ffd8e35b0a0 sp 0x7ffd8e35b098
480: READ of size 8 at 0x617000011648 thread T0
480:     #0 0x7fb9d1ae089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
480:     #1 0x7fb9d1ae089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
480:     #2 0x7fb9d1ae089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
480:     #3 0x433968 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:104
480:     root-project#4 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4
70bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#5 0x45a5f3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiSillyStruct+0x45a5f3) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#6 0x45a969 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45a969) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#7 0x45ab10 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiSillyStruct+0x45ab10) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#8 0x4675be in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4675be) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#9 0x45af6c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45af6c) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#10 0x425456 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
SillyStruct+0x425456) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#11 0x7fb9cd446149 in __libc_start_call_main (/lib64/libc.so.6+0x28149) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#12 0x7fb9cd44620a in __libc_start_main_impl (/lib64/libc.so.6+0x2820a) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#13 0x4257b4 in _start (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkA
piSillyStruct+0x4257b4) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: 0x617000011648 is located 328 bytes inside of 712-byte region [0x617000011500,0x6170000117c8)
480: freed by thread T0 here:
480:     #0 0x7fb9d1eda878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdfb4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
480:     #2 0x7fb9cdfe8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
480:     #3 0x7fb9cdfc53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
480:     root-project#4 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
480:     root-project#5 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
480:     root-project#6 0x7fb9ce9468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
480:     root-project#7 0x7fb9ce9481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
480:     root-project#8 0x7fb9ce948fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
480:     root-project#9 0x4338cd in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:103
480:     root-project#10 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: previously allocated by thread T0 here:
480:     #0 0x7fb9d1ed9e38 in operator new(unsigned long) (/lib64/libasan.so.8+0xd9e38) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdebbfd0 in TStorage::ObjectAlloc(unsigned long) /home/vpadulan/Programs/rootproject/rootsrc/core/base/src/TStorage.cxx:293
480:     #2 0x7fb9d12cc209 in TObject::operator new(unsigned long) /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/include/TObject.h:181
480:     #3 0x7fb9d12cc209 in new_TTree /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/G__Tree
.cxx:4363
480:     root-project#4 0x7fb9ce10a49c in TClass::NewObject(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx
:5003
480:     root-project#5 0x7fb9ce113c7d in TClass::New(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx:4980
480:     root-project#6 0x7fb9ce9cda38 in TKey::ReadObjectAny(TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TKey.cxx:1086
480:     root-project#7 0x7fb9ce8d10a7 in TDirectoryFile::GetObjectChecked(char const*, TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/T
DirectoryFile.cxx:1111
480:     root-project#8 0x7fb9d1ade1d1 in void TDirectory::GetObject<TTree>(char const*, TTree*&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TD
irectory.h:214
480:     root-project#9 0x7fb9d1ade1d1 in TTreeReader::TTreeReader(char const*, TDirectory*, TEntryList*) /home/vpadulan/Programs/rootproject/rootsrc/tree/tre
eplayer/src/TTreeReader.cxx:232
480:     root-project#10 0x433332 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bu$
kApiSillyStruct.cxx:87
480:     root-project#11 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:
480: SUMMARY: AddressSanitizer: heap-use-after-free /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503 in TTree::GetNotify() co
nst
```
vepadulano added a commit that referenced this pull request Jun 12, 2024
Ensure proper TFile memory management and avoid TTreeReader accessing the TFile after its destruction.

```
479: ==2573107==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000051b48 at pc 0x7f0fcf4e089e bp 0x7fff6e7e1fe0 sp 0x7fff6e7e1fd8
479: READ of size 8 at 0x617000051b48 thread T0
479:     #0 0x7f0fcf4e089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
479:     #1 0x7f0fcf4e089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
479:     #2 0x7f0fcf4e089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
479:     #3 0x4321ca in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:135
479:     root-project#4 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x470
c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#5 0x45a6d3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiVarLength+0x45a6d3) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#6 0x45aa49 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45aa49) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#7 0x45abf0 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiVarLength+0x45abf0) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#8 0x46769e in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiVarLength+0x46769e) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#9 0x45b04c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45b04c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#10 0x424606 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
VarLength+0x424606) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479: 0x617000051b48 is located 328 bytes inside of 712-byte region [0x617000051a00,0x617000051cc8)

479: freed by thread T0 here:
479:     #0 0x7f0fcf8da878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
479:     #1 0x7f0fcb9b4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
479:     #2 0x7f0fcb9e8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
479:     #3 0x7f0fcb9c53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
479:     root-project#4 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
479:     root-project#5 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
479:     root-project#6 0x7f0fcc3468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
479:     root-project#7 0x7f0fcc3481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
479:     root-project#8 0x7f0fcc348fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
479:     root-project#9 0x432ebf in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:130
479:     root-project#10 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x47
0c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
```
vepadulano added a commit that referenced this pull request Jun 12, 2024
The destructor of TTreeReader was making use of the TFile after its destruction.

```
480: ==2560128==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000011648 at pc 0x7fb9d1ae089e bp 0x7ffd8e35b0a0 sp 0x7ffd8e35b098
480: READ of size 8 at 0x617000011648 thread T0
480:     #0 0x7fb9d1ae089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
480:     #1 0x7fb9d1ae089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
480:     #2 0x7fb9d1ae089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
480:     #3 0x433968 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:104
480:     root-project#4 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4
70bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#5 0x45a5f3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiSillyStruct+0x45a5f3) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#6 0x45a969 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45a969) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#7 0x45ab10 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiSillyStruct+0x45ab10) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#8 0x4675be in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4675be) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#9 0x45af6c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45af6c) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#10 0x425456 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
SillyStruct+0x425456) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#11 0x7fb9cd446149 in __libc_start_call_main (/lib64/libc.so.6+0x28149) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#12 0x7fb9cd44620a in __libc_start_main_impl (/lib64/libc.so.6+0x2820a) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#13 0x4257b4 in _start (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkA
piSillyStruct+0x4257b4) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: 0x617000011648 is located 328 bytes inside of 712-byte region [0x617000011500,0x6170000117c8)
480: freed by thread T0 here:
480:     #0 0x7fb9d1eda878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdfb4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
480:     #2 0x7fb9cdfe8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
480:     #3 0x7fb9cdfc53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
480:     root-project#4 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
480:     root-project#5 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
480:     root-project#6 0x7fb9ce9468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
480:     root-project#7 0x7fb9ce9481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
480:     root-project#8 0x7fb9ce948fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
480:     root-project#9 0x4338cd in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:103
480:     root-project#10 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: previously allocated by thread T0 here:
480:     #0 0x7fb9d1ed9e38 in operator new(unsigned long) (/lib64/libasan.so.8+0xd9e38) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdebbfd0 in TStorage::ObjectAlloc(unsigned long) /home/vpadulan/Programs/rootproject/rootsrc/core/base/src/TStorage.cxx:293
480:     #2 0x7fb9d12cc209 in TObject::operator new(unsigned long) /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/include/TObject.h:181
480:     #3 0x7fb9d12cc209 in new_TTree /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/G__Tree
.cxx:4363
480:     root-project#4 0x7fb9ce10a49c in TClass::NewObject(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx
:5003
480:     root-project#5 0x7fb9ce113c7d in TClass::New(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx:4980
480:     root-project#6 0x7fb9ce9cda38 in TKey::ReadObjectAny(TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TKey.cxx:1086
480:     root-project#7 0x7fb9ce8d10a7 in TDirectoryFile::GetObjectChecked(char const*, TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/T
DirectoryFile.cxx:1111
480:     root-project#8 0x7fb9d1ade1d1 in void TDirectory::GetObject<TTree>(char const*, TTree*&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TD
irectory.h:214
480:     root-project#9 0x7fb9d1ade1d1 in TTreeReader::TTreeReader(char const*, TDirectory*, TEntryList*) /home/vpadulan/Programs/rootproject/rootsrc/tree/tre
eplayer/src/TTreeReader.cxx:232
480:     root-project#10 0x433332 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bu$
kApiSillyStruct.cxx:87
480:     root-project#11 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:
480: SUMMARY: AddressSanitizer: heap-use-after-free /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503 in TTree::GetNotify() co
nst
```
vepadulano added a commit that referenced this pull request Jun 12, 2024
Ensure proper TFile memory management and avoid TTreeReader accessing the TFile after its destruction.

```
479: ==2573107==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000051b48 at pc 0x7f0fcf4e089e bp 0x7fff6e7e1fe0 sp 0x7fff6e7e1fd8
479: READ of size 8 at 0x617000051b48 thread T0
479:     #0 0x7f0fcf4e089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
479:     #1 0x7f0fcf4e089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
479:     #2 0x7f0fcf4e089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
479:     #3 0x4321ca in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:135
479:     root-project#4 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x470
c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#5 0x45a6d3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiVarLength+0x45a6d3) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#6 0x45aa49 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45aa49) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#7 0x45abf0 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiVarLength+0x45abf0) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#8 0x46769e in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiVarLength+0x46769e) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#9 0x45b04c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45b04c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#10 0x424606 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
VarLength+0x424606) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479: 0x617000051b48 is located 328 bytes inside of 712-byte region [0x617000051a00,0x617000051cc8)

479: freed by thread T0 here:
479:     #0 0x7f0fcf8da878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
479:     #1 0x7f0fcb9b4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
479:     #2 0x7f0fcb9e8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
479:     #3 0x7f0fcb9c53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
479:     root-project#4 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
479:     root-project#5 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
479:     root-project#6 0x7f0fcc3468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
479:     root-project#7 0x7f0fcc3481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
479:     root-project#8 0x7f0fcc348fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
479:     root-project#9 0x432ebf in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:130
479:     root-project#10 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x47
0c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
```
vepadulano added a commit that referenced this pull request Jul 11, 2024
The destructor of TTreeReader was making use of the TFile after its destruction.

```
480: ==2560128==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000011648 at pc 0x7fb9d1ae089e bp 0x7ffd8e35b0a0 sp 0x7ffd8e35b098
480: READ of size 8 at 0x617000011648 thread T0
480:     #0 0x7fb9d1ae089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
480:     #1 0x7fb9d1ae089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
480:     #2 0x7fb9d1ae089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
480:     #3 0x433968 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:104
480:     root-project#4 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4
70bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#5 0x45a5f3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiSillyStruct+0x45a5f3) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#6 0x45a969 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45a969) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#7 0x45ab10 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiSillyStruct+0x45ab10) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#8 0x4675be in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x4675be) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#9 0x45af6c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiSillyStruct+0x45af6c) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#10 0x425456 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
SillyStruct+0x425456) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:     root-project#11 0x7fb9cd446149 in __libc_start_call_main (/lib64/libc.so.6+0x28149) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#12 0x7fb9cd44620a in __libc_start_main_impl (/lib64/libc.so.6+0x2820a) (BuildId: 0d710e9d9dc10c500b8119c85da75004183618e2)
480:     root-project#13 0x4257b4 in _start (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkA
piSillyStruct+0x4257b4) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: 0x617000011648 is located 328 bytes inside of 712-byte region [0x617000011500,0x6170000117c8)
480: freed by thread T0 here:
480:     #0 0x7fb9d1eda878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdfb4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
480:     #2 0x7fb9cdfe8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
480:     #3 0x7fb9cdfc53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
480:     root-project#4 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
480:     root-project#5 0x7fb9ce8d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
480:     root-project#6 0x7fb9ce9468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
480:     root-project#7 0x7fb9ce9481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
480:     root-project#8 0x7fb9ce948fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
480:     root-project#9 0x4338cd in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bulk
ApiSillyStruct.cxx:103
480:     root-project#10 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)

480: previously allocated by thread T0 here:
480:     #0 0x7fb9d1ed9e38 in operator new(unsigned long) (/lib64/libasan.so.8+0xd9e38) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
480:     #1 0x7fb9cdebbfd0 in TStorage::ObjectAlloc(unsigned long) /home/vpadulan/Programs/rootproject/rootsrc/core/base/src/TStorage.cxx:293
480:     #2 0x7fb9d12cc209 in TObject::operator new(unsigned long) /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/include/TObject.h:181
480:     #3 0x7fb9d12cc209 in new_TTree /home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/G__Tree
.cxx:4363
480:     root-project#4 0x7fb9ce10a49c in TClass::NewObject(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx
:5003
480:     root-project#5 0x7fb9ce113c7d in TClass::New(TClass::ENewType, bool) const /home/vpadulan/Programs/rootproject/rootsrc/core/meta/src/TClass.cxx:4980
480:     root-project#6 0x7fb9ce9cda38 in TKey::ReadObjectAny(TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TKey.cxx:1086
480:     root-project#7 0x7fb9ce8d10a7 in TDirectoryFile::GetObjectChecked(char const*, TClass const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/T
DirectoryFile.cxx:1111
480:     root-project#8 0x7fb9d1ade1d1 in void TDirectory::GetObject<TTree>(char const*, TTree*&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TD
irectory.h:214
480:     root-project#9 0x7fb9d1ade1d1 in TTreeReader::TTreeReader(char const*, TDirectory*, TEntryList*) /home/vpadulan/Programs/rootproject/rootsrc/tree/tre
eplayer/src/TTreeReader.cxx:232
480:     root-project#10 0x433332 in BulkApiSillyStructTest_stdReadSplitBranch_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/Bu$
kApiSillyStruct.cxx:87
480:     root-project#11 0x470bac in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiSillyStruct+0x
470bac) (BuildId: 45d8d15c24ba2aae252398ec00943aba7665b034)
480:
480: SUMMARY: AddressSanitizer: heap-use-after-free /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503 in TTree::GetNotify() co
nst
```
vepadulano added a commit that referenced this pull request Jul 11, 2024
Ensure proper TFile memory management and avoid TTreeReader accessing the TFile after its destruction.

```
479: ==2573107==ERROR: AddressSanitizer: heap-use-after-free on address 0x617000051b48 at pc 0x7f0fcf4e089e bp 0x7fff6e7e1fe0 sp 0x7fff6e7e1fd8
479: READ of size 8 at 0x617000051b48 thread T0
479:     #0 0x7f0fcf4e089d in TTree::GetNotify() const /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/inc/TTree.h:503
479:     #1 0x7f0fcf4e089d in void TNotifyLinkBase::RemoveLink<TTree>(TTree&) /home/vpadulan/Programs/rootproject/rootsrc/core/base/inc/TNotifyLin
k.h:104
479:     #2 0x7f0fcf4e089d in TTreeReader::~TTreeReader() /home/vpadulan/Programs/rootproject/rootsrc/tree/treeplayer/src/TTreeReader.cxx:252
479:     #3 0x4321ca in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:135
479:     root-project#4 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)()
, char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x470
c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#5 0x45a6d3 in testing::Test::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-
asan/tree/tree/test/testBulkApiVarLength+0x45a6d3) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#6 0x45aa49 in testing::TestInfo::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45aa49) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#7 0x45abf0 in testing::TestSuite::Run() [clone .part.0] (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-tes
ting-asan/tree/tree/test/testBulkApiVarLength+0x45abf0) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#8 0x46769e in testing::internal::UnitTestImpl::RunAllTests() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-fre
e-testing-asan/tree/tree/test/testBulkApiVarLength+0x46769e) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#9 0x45b04c in testing::UnitTest::Run() (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tr
ee/test/testBulkApiVarLength+0x45b04c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479:     root-project#10 0x424606 in main (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApi
VarLength+0x424606) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
479: 0x617000051b48 is located 328 bytes inside of 712-byte region [0x617000051a00,0x617000051cc8)

479: freed by thread T0 here:
479:     #0 0x7f0fcf8da878 in operator delete(void*) (/lib64/libasan.so.8+0xda878) (BuildId: 2e1c50524ff1a2e7e73c4565b46f3f51892353ea)
479:     #1 0x7f0fcb9b4f25 in TCollection::GarbageCollect(TObject*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TCollection.cxx:736
479:     #2 0x7f0fcb9e8a27 in TList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/TList.cxx:535
479:     #3 0x7f0fcb9c53d7 in THashList::Delete(char const*) /home/vpadulan/Programs/rootproject/rootsrc/core/cont/src/THashList.cxx:215
479:     root-project#4 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:585
479:     root-project#5 0x7f0fcc2d285d in TDirectoryFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TDirectoryFile.cxx:561
479:     root-project#6 0x7f0fcc3468e4 in TFile::Close(char const*) /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:989
479:     root-project#7 0x7f0fcc3481fd in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:566
479:     root-project#8 0x7f0fcc348fd0 in TFile::~TFile() /home/vpadulan/Programs/rootproject/rootsrc/io/io/src/TFile.cxx:603
479:     root-project#9 0x432ebf in BulkApiVariableTest_stdRead_Test::TestBody() /home/vpadulan/Programs/rootproject/rootsrc/tree/tree/test/BulkApiVarLength.c
xx:130
479:     root-project#10 0x470c8c in void testing::internal::HandleExceptionsInMethodIfSupported<testing::Test, void>(testing::Test*, void (testing::Test::*)(
), char const*) (/home/vpadulan/Programs/rootproject/rootbuild/bulksilly-heap-use-after-free-testing-asan/tree/tree/test/testBulkApiVarLength+0x47
0c8c) (BuildId: aac947b72f02e5567382f0dadfefd1e97d058a56)
```
vepadulano added a commit that referenced this pull request Sep 22, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 22, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 23, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 23, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 23, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 24, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
vepadulano added a commit that referenced this pull request Sep 25, 2024
The test was dynamically allocating the array data members of the `Data` struct, but never deallocating them. This commit polishes the `Data` struct definition and ensures proper management of the data members.

The previous way of writing data to the TTree was leading to a bad memory access in the ReadBasicPointer inlined function in TStreamerInfoReadBuffer.cxx while reading the `double*` array. In particular, the issue arises when accessing and then deallocating the array at the current index provided by the `TCompInfo` object.

```
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf140 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb)
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf184 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(TBuffer&, char** const&, TStreamerInfo::TCompInfo* const*, int, int, int, int, int) [inlined] TBuffer::BufferSize(this=0x000060e00010ef00) const at TBuffer.h:98:41 [opt]
   95  	   TObject *GetParent()  const;
   96  	   char    *Buffer()     const { return fBuffer; }
   97  	   char    *GetCurrent() const { return fBufCur; }
-> 98  	   Int_t    BufferSize() const { return fBufSize; }
   99  	   void     DetachBuffer() { fBuffer = nullptr; }
   100 	   Int_t    Length()     const { return (Int_t)(fBufCur - fBuffer); }
   101 	   void     Expand(Int_t newsize, Bool_t copy = kTRUE);  // expand buffer to newsize
Target 0: (repro.out) stopped.
(lldb) p fBufSize
(Int_t) 32008
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = step in
    frame #0: 0x00000001044cf194 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
   920 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong:   ReadBasicPointer(Long_t);  continue;
   921 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kLong64: ReadBasicPointer(Long64_t);  continue;
   922 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kFloat:  ReadBasicPointer(Float_t);  continue;
-> 923 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kDouble: ReadBasicPointer(Double_t);  continue;
   924 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUChar:  ReadBasicPointer(UChar_t);  continue;
   925 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUShort: ReadBasicPointer(UShort_t);  continue;
   926 	         case TStreamerInfo::kOffsetP + TStreamerInfo::kUInt:   ReadBasicPointer(UInt_t);  continue;
Target 0: (repro.out) stopped.
(lldb) s
Process 13498 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
    frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate:
->  0x107bac674 <+76>: casalb w8, w9, [x22]
    0x107bac678 <+80>: cmp    w8, #0x2
    0x107bac67c <+84>: b.ne   0x107bac6f4    ; <+204>
    0x107bac680 <+88>: mov    x8, #-0x100000000 ; =-4294967296
Target 0: (repro.out) stopped.
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbebebebebebebeae)
  * frame #0: 0x0000000107bac674 libclang_rt.asan_osx_dynamic.dylib`__asan::Allocator::Deallocate(void*, unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) + 76
    frame #1: 0x0000000107c0c444 libclang_rt.asan_osx_dynamic.dylib`wrap__ZdaPv + 232
    frame #2: 0x00000001044d4a60 libRIO.so`int TStreamerInfo::ReadBuffer<char**>(this=<unavailable>, b=<unavailable>, arr=<unavailable>, compinfo=<unavailable>, first=<unavailable>, last=<unavailable>, narr=<unavailable>, eoffset=<unavailable>, arrayMode=0) at TStreamerInfoReadBuffer.cxx:923:65 [opt]
    frame #3: 0x0000000103ffc888 libRIO.so`TStreamerInfoActions::GenericReadAction(buf=0x000060e00010ef00, addr=0x0000602000056bd0, config=0x0000604000149910) at TStreamerInfoActions.cxx:195:45
    frame root-project#4: 0x0000000103caa5ec libRIO.so`TStreamerInfoActions::TConfiguredAction::operator()(this=0x00006030001693f0, buffer=0x000060e00010ef00, object=0x0000602000056bd0) const at TStreamerInfoActions.h:123:17
    frame root-project#5: 0x0000000103ca9ef8 libRIO.so`TBufferFile::ApplySequence(this=0x000060e00010ef00, sequence=0x000060600011ac20, obj=0x0000602000056bd0) at TBufferFile.cxx:3702:10
    frame root-project#6: 0x00000001064bc570 libTree.so`TBranchElement::ReadLeavesMemberBranchCount(this=0x0000619000566380, b=0x000060e00010ef00) at TBranchElement.cxx:4603:6
    frame root-project#7: 0x0000000106455ce4 libTree.so`TBranch::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranch.cxx:1753:4
    frame root-project#8: 0x00000001064a1764 libTree.so`TBranchElement::GetEntry(this=0x0000619000566380, entry=0, getall=0) at TBranchElement.cxx:2783:27
    frame root-project#9: 0x000000010739915c libTreePlayer.so`ROOT::Detail::TBranchProxy::Read(this=0x00006110000c9580) at TBranchProxy.h:163:42
    frame root-project#10: 0x0000000107649ba8 libTreePlayer.so`(anonymous namespace)::TObjectArrayReader::At(this=0x0000603000169900, proxy=0x00006110000c9580, idx=1) at TTreeReaderArray.cxx:176:22
    frame root-project#11: 0x000000010000c2e4 repro.out`ROOT::Internal::TTreeReaderArrayBase::UntypedAt(this=0x000000016fdfe740, idx=1) const at TTreeReaderArray.h:41:62
    frame root-project#12: 0x000000010000c200 repro.out`TTreeReaderArray<double>::At(this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:205:54
    frame root-project#13: 0x00000001000065e0 repro.out`TTreeReaderArray<double>::operator[](this=0x000000016fdfe740, idx=1) at TTreeReaderArray.h:207:44
    frame root-project#14: 0x0000000100007b48 repro.out`simpleTest() at repro.cpp:123:26
    frame root-project#15: 0x0000000100007e10 repro.out`main at repro.cpp:128:5
    frame root-project#16: 0x000000018c718274 dyld`start + 2840
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants