fix: segfault when moving scoped_ostream_redirect#6033
Open
kounelisagis wants to merge 2 commits intopybind:masterfrom
Open
fix: segfault when moving scoped_ostream_redirect#6033kounelisagis wants to merge 2 commits intopybind:masterfrom
scoped_ostream_redirect#6033kounelisagis wants to merge 2 commits intopybind:masterfrom
Conversation
The default move constructor left the stream (`std::cout`) pointing at the moved-from `pythonbuf`, whose internal buffer and streambuf pointers were nulled by the move. Any subsequent write through the stream dereferenced null, causing a segfault. Replace `= default` with an explicit move constructor that re-points the stream to the new buffer and disarms the moved-from destructor.
2b243d9 to
156332c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The default move constructor of
scoped_ostream_redirectcaused a segfault when the moved-to object (or the original stream) was subsequently used.The root cause:
= defaultmoved the internalpythonbuf(transferring itsd_buffer,pywrite,pyflushand nulling the streambuf base pointers), but left the stream (e.g.std::cout) still pointing at the moved-from buffer. Any subsequent write through the stream calledoverflow()on the zombiepythonbuf, which dereferencedpptr()(now null) — immediate segfault.Reproducer
Fix
Replace
= defaultwith an explicit move constructor that:costream.rdbuf(&buffer))other.old = nullptrto disarm the moved-from destructorThe destructor is guarded with
if (old)so the moved-from object skips restoring the stream.Suggested changelog entry:
scoped_ostream_redirect: the default move constructor left the stream pointing at a moved-frompythonbufwith null internal pointers, causing a null dereference on the next write.