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

PyROOT] Fix infinite loop in TMemoryRegulator::ClearProxiedObjects() #15106

Merged
merged 2 commits into from Apr 3, 2024

Conversation

guitargeek
Copy link
Contributor

@guitargeek guitargeek commented Apr 2, 2024

There is an infinite loop in
PyROOT::TMemoryRegulator::ClearProxiedObjects():

   while (!fObjectMap.empty()) {
      auto elem = fObjectMap.begin();
      auto cppobj = elem->first;
      auto klassid = elem->second;
      auto pyclass = CreateScopeProxy(klassid);
      auto pyobj = (CPPInstance *)MemoryRegulator::RetrievePyObject(cppobj, pyclass);

      if (pyobj && (pyobj->fFlags & CPPInstance::kIsOwner)) {
         ...
      } else {
         // Non-owning proxy, just unregister to clean tables.
         // The proxy deletion by Python will have no effect on C++, so all good
         MemoryRegulator::UnregisterPyObject(pyobj, pyclass);
      }
   }

In the second code branch, the object is not removed from the fObjMap,
if UnregisterPyObject doesn't call the unregister hook because it
quits early. This can happen if there is not C++ object corresponding to
the regulated python object, causing an infinite loop because
fObjectMap never gets empty.

Although this seems like an obvious logic error, this was only noticed
after the cppyy upgrade. Probably the code path was not hit before.

Addresses
#15085 (comment).

This PR also includes a second refactoring commit to reduce the amount of C++ code in PyROOT.

This could maybe also fix the problem with the distributed RDataFrame test timeouts!

@phsft-bot
Copy link
Collaborator

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@guitargeek guitargeek changed the title Infinite loop PyROOT] Fix infinite loop in TMemoryRegulator::ClearProxiedObjects() Apr 2, 2024
Copy link

github-actions bot commented Apr 2, 2024

Test Results

    12 files      12 suites   1d 23h 1m 18s ⏱️
 2 605 tests  2 605 ✅ 0 💤 0 ❌
29 280 runs  29 280 ✅ 0 💤 0 ❌

Results for commit e1bdab8.

♻️ This comment has been updated with latest results.

@phsft-bot
Copy link
Collaborator

Build failed on ROOT-ubuntu2204/nortcxxmod.
Running on root-ubuntu-2204-3.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Failing tests:

There is an infinite loop in
`PyROOT::TMemoryRegulator::ClearProxiedObjects()`:

```C++
   while (!fObjectMap.empty()) {
      auto elem = fObjectMap.begin();
      auto cppobj = elem->first;
      auto klassid = elem->second;
      auto pyclass = CreateScopeProxy(klassid);
      auto pyobj = (CPPInstance *)MemoryRegulator::RetrievePyObject(cppobj, pyclass);

      if (pyobj && (pyobj->fFlags & CPPInstance::kIsOwner)) {
         ...
      } else {
         // Non-owning proxy, just unregister to clean tables.
         // The proxy deletion by Python will have no effect on C++, so all good
         MemoryRegulator::UnregisterPyObject(pyobj, pyclass);
      }
   }
```

In the second code branch, the object is not removed from the `fObjMap`,
if `UnregisterPyObject` doesn't call the unregister hook because it
quits early. This can happen if there is not C++ object corresponding to
the regulated python object, causing an infinite loop because
`fObjectMap` never gets empty.

Although this seems like an obvious logic error, this was only noticed
after the cppyy upgrade. Probably the code path was not hit before.

Addresses
root-project#15085 (comment).
Most of these helpers were single-use, so it's better to inline them in
the implementations.
@phsft-bot
Copy link
Collaborator

Starting build on ROOT-performance-centos8-multicore/soversion, ROOT-ubuntu2204/nortcxxmod, ROOT-ubuntu2004/python3, mac12arm/cxx20, windows10/default
How to customize builds

@dpiparo
Copy link
Member

dpiparo commented Apr 2, 2024

I restarted the jobs to make sure the failure on Windows was a glitch. A test timedout for a reason which was not clear to me.

Copy link
Member

@dpiparo dpiparo left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for debugging this!

@guitargeek guitargeek merged commit bea7e2d into root-project:master Apr 3, 2024
15 of 17 checks passed
@guitargeek guitargeek deleted the infinite_loop branch April 3, 2024 07:48
@phsft-bot
Copy link
Collaborator

Build failed on ROOT-ubuntu2004/python3.
Running on root-ubuntu-2004-1.cern.ch:/home/sftnight/build/workspace/root-pullrequests-build
See console output.

Errors:

  • [2024-04-03T09:35:21.618Z] CMake Error at /home/sftnight/build/workspace/root-pullrequests-build/rootspi/jenkins/root-build.cmake:1132 (message):

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

Successfully merging this pull request may close these issues.

None yet

3 participants