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.

pickling of frames without a tasklet #62

Closed
@ghost

Description

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


Hi,

now that #61 is resolved, I can look after another long standing problem. If Stackless pickles a frame, it does not save or restore the f_back attribute. This is not a problem, if the frame is part of a taklet, because tasklet.setstate() sets f_back. But in every other case, current behaviour violates the premise that the unpickled object has the same internal structure as the original object.

Use Cases

trace backs

The most prominent use case for pickling frames (besides tasklets) are trace-backs. I assume that the internal structure of a trace-back is well known.
If you pickle/unpickle a trace back, the missing f_back has two consequences:

  1. A (post mortem) debugger can't analyse/display the trace-back. This could be fixed by setting the frame.f_back attributes in tb_setstate().
  2. The frame objects above the frame, where the exception was caught, are not available.

pyheapdump

pyheapdump is a library to support post mortem debugging using a dump file. It works similar to the well known UNIX core dumps, but the format of the pyheapdump files is based on pickle. pyheapdump uses an extended pickler (sPickle). For vanilla C-Python a frame gets (un)pickled as a fake-frame that has the same attributes as a frame but is really a plain Python object.

But for Stackless I have a problem. If I pickle frame-objects as a fake frame, I break (un)pickling of tasklets. And if I don't change the pickling of frames, trace-backs a broken.

How to fix this probelm

Obviously a fix needs to meet a few conditions:

  1. It must not break anything, especially a pickle created by a current version of Stackless must stay readable and vice versa.
  2. We must add the f_back frame to the state-part of the result of frameobject_reduce()

For a long time I thought that it would be impossible to meet both conditions. Only recently I discovered a possibility to add f_back so to the frame-state that current versions of Stackless simply ignore this additional information. A fixed version would detect the presence of f_back and use it.

How? The (c)frame-state as returned by frameobject_reduce() or cframe_reduce() always contains a "tuple with nulls" structure which is created by slp_into_tuple_with_nulls() and processed by slp_from_tuple_with_nulls(). Fortunately slp_from_tuple_with_nulls() ignores/skips non integer items in the inner "nulls"-tuple. This is our chance to add additional information to the frame-state without breaking unpickling of the enriched state with the current code-base.

I created a preliminary patch to verify that it is indeed possible to fix this problem. The patch is meant as a starting point for a discussion. I'll create a pull request.


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