Skip to content

Fix IOBuf memory leak in PythonUserException exception path#9738

Open
banitag1 wants to merge 1 commit intofacebook:masterfrom
banitag1:export-D96219777
Open

Fix IOBuf memory leak in PythonUserException exception path#9738
banitag1 wants to merge 1 commit intofacebook:masterfrom
banitag1:export-D96219777

Conversation

@banitag1
Copy link
Copy Markdown
Contributor

Summary:
CONTEXT: When a thrift-python service handler raises a user-defined exception,
the exception path serializes the response into an IOBuf and wraps it in a
PythonUserException. This IOBuf was being leaked on every exception.

WHAT: Two issues combined to cause the leak:

  1. PythonUserException defines an explicit copy constructor (which clones the
    IOBuf) but no move constructor, suppressing implicit move generation. This
    caused cmove() to fall back to copying, cloning the IOBuf unnecessarily.

  2. The pattern _cpp_obj.release() in serverCallback_coro returned a raw
    pointer that was never deleted. After the copy (not move) into the promise,
    the original object (including its cloned IOBuf) was leaked.

Fix: Add defaulted move constructor/assignment to PythonUserException, and
replace the release() pattern with a cdef helper that moves the unique_ptr
into a local variable whose destructor properly cleans up.

Differential Revision: D96219777

Summary:
CONTEXT: When a thrift-python service handler raises a user-defined exception,
the exception path serializes the response into an IOBuf and wraps it in a
PythonUserException. This IOBuf was being leaked on every exception.

WHAT: Two issues combined to cause the leak:

1. PythonUserException defines an explicit copy constructor (which clones the
   IOBuf) but no move constructor, suppressing implicit move generation. This
   caused cmove() to fall back to copying, cloning the IOBuf unnecessarily.

2. The pattern `_cpp_obj.release()` in serverCallback_coro returned a raw
   pointer that was never deleted. After the copy (not move) into the promise,
   the original object (including its cloned IOBuf) was leaked.

Fix: Add defaulted move constructor/assignment to PythonUserException, and
replace the release() pattern with a cdef helper that moves the unique_ptr
into a local variable whose destructor properly cleans up.

Differential Revision: D96219777
@meta-cla meta-cla bot added the CLA Signed label Mar 18, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync bot commented Mar 18, 2026

@banitag1 has exported this pull request. If you are a Meta employee, you can view the originating Diff in D96219777.

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.

1 participant