-
-
Notifications
You must be signed in to change notification settings - Fork 30.3k
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
double free in io.TextIOWrapper #72573
Comments
We have found that you can produce a crash when an instance of _io.TextIOWrapper is being deallocated while there's another thread invoking the garbage collector. I've attached a simple script that should reproduce the issue (textiowrapper_crash.py) Looking at the code of the _io module, we found that on the dealloc method of the TextIOWrapper class, it first tries to invoke the close method, then releases its internal members, after that removes itself from the garbage collector tracking and finally frees deallocates the remaining stuff. What happens, is that while releasing it's internal members, it might end up calling code that releases the interpreter lock (because its doing an operating system call), letting other threads execute. If for example the thread that comes in, invokes the garbage collector, on debug will raise an assert on gcmodule.c on line 351, where I understand it is complaining that it is tracking an object with refcount 0. In a release build, I suppose this goes on and will end up releasing the object (given it has a refcount of 0), and when the interrupted dealloc thread continues will end up freeing again itself which at some point produces a crash. Attached is a proposed fix for the issue in textio.c.patch, where the it the call to _PyObject_GC_UNTRACK is now done right after the call to the close method and before release its internal members. As a reference we have been able to reproduce this with Python 2.7.12 on Windows (i386) |
Thank you for your report and patch Sebastian. In Python 3 the solution can be simpler, just move the line "_PyObject_GC_UNTRACK(self);" above the line "textiowrapper_clear(self);". But calling PyObject_ClearWeakRefs() also should be moved up. Otherwise half-destroyed TextIOWrapper instance can be accessed via weak references. Following patches do this (and small refactoring). |
New changeset 91f024fc9b3a by Serhiy Storchaka in branch '2.7': New changeset 89f7386104e2 by Serhiy Storchaka in branch '3.5': New changeset c4319c0d0131 by Serhiy Storchaka in branch '3.6': New changeset 36af3566b67a by Serhiy Storchaka in branch 'default': |
`Nov 30 09:15:44 ob systemd-coredump[1408395]: Process 1407506 (python) of user 1001 dumped core. Stack trace of thread 1407700: Stack trace of thread 1407516: Stack trace of thread 1407605: Stack trace of thread 1407509: Stack trace of thread 1407544: Stack trace of thread 1407536: Stack trace of thread 1407550: Stack trace of thread 1407548: Stack trace of thread 1407551: Stack trace of thread 1407524: Stack trace of thread 1407530: Stack trace of thread 1407552: Stack trace of thread 1407506: Stack trace of thread 1407512: Stack trace of thread 1407507: Stack trace of thread 1407514: Stack trace of thread 1407511: Stack trace of thread 1407519: Stack trace of thread 1407510: Stack trace of thread 1407526: Stack trace of thread 1407508: Stack trace of thread 1407533: Stack trace of thread 1407518: Stack trace of thread 1407515: Stack trace of thread 1407539: Stack trace of thread 1407513: Stack trace of thread 1407521: Stack trace of thread 1407532: Stack trace of thread 1407531: Stack trace of thread 1407517: Stack trace of thread 1407525: Stack trace of thread 1407522: Stack trace of thread 1407523: Stack trace of thread 1407527: Stack trace of thread 1407535: Stack trace of thread 1407534: Stack trace of thread 1407537: Stack trace of thread 1407545: Stack trace of thread 1407540: Stack trace of thread 1407592: Stack trace of thread 1407529: Stack trace of thread 1407520: Stack trace of thread 1407541: Stack trace of thread 1407604: Stack trace of thread 1407538: Stack trace of thread 1407528: Stack trace of thread 1407549: Stack trace of thread 1407542: Stack trace of thread 1407547: Stack trace of thread 1407612: Stack trace of thread 1407623: Stack trace of thread 1407629: Stack trace of thread 1407553: Stack trace of thread 1407589: Stack trace of thread 1407614: Stack trace of thread 1407596: Stack trace of thread 1407630: Stack trace of thread 1407631: Stack trace of thread 1407602: Stack trace of thread 1407615: Stack trace of thread 1407586: Stack trace of thread 1407590: Stack trace of thread 1407613: Stack trace of thread 1407591: Appears I may have just encountered this bug again? Really heavy print I/O with 12 threads. Really hard to debug, core often doesn't get dumped. I'm lucky I got this core dump at all. It randomly succeeded in dumping the core. Runing on python 3.9.9 |
Misc/NEWS
so that it is managed by towncrier #552Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: