Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Crash after unpickling hard switched tasklet #61

Closed

Description

Originally reported by: Anselm Kruis (Bitbucket: akruis, GitHub: akruis)


Hi,

a few weeks ago I observed crashes during the development of pyheapdump. Now I had some time to track them down and to write a small example.

The attached script first pickles a single frame and unpickles the frame. Then it accesses frame.f_locals. Python crashes in function map_to_dict() from frameobject.c. This function is invoked from PyFrame_FastToLocals().

Obviously we have two bugs:

  1. Upon unpickling python fails to set up frame->f_localsplus correctly (== as expected by PyFrame_FastToLocals) in function frame_setstate from prickelpit.c. The localsplus array must start with frame->f_code->co_nlocals local variables, followed by len(frame->f_code->co_cellvars) + len(frame->f_code->co_freevars) cell objects.

  2. Upon pickling python creates an inconsistent object state for the frame in function frameobject_reduce from prickelpit.c. If the frame has no stacktop, python omits the localsplus array from the pickle. This would be correct, if the only valid use case for pickling frames was pickling, unpickling and resuming of tasklets. But is is also possible to pickle/unpickle a tasklet with the sole intent to inspect it using a debugger.

Plan

I'll add test cases for the two bugs and prepare pull requests with fixes.

Here is the code:

#!python
import pickle
import stackless


def pickle_current_frame():
    result = []

    def func(current):
        result.append(pickle.dumps(current.frame, -1))
    stackless.tasklet().bind(func, (stackless.current,)).run()
    return result[0]


soft = stackless.enable_softswitch(False)  # no crash, if soft switching
try:
    p = pickle_current_frame()
finally:
    stackless.enable_softswitch(soft)
frame = pickle.loads(p)
frame.f_locals  # this line crashes Stackless
print("No Crash, OK")

f_locals_crash.py.zip


Activity

  1. ghost added on Sep 24, 2017
  2. ghost closed this as completedon Sep 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions