Skip to content

Conversation

pablogsal
Copy link
Member

@pablogsal pablogsal commented Aug 10, 2024

It's possible that pystack analyses a core file or a program at a
specific moment where the bottom of the stack has a shim frame but a
normal frame has not been pushed yet or the last normal frame has been
removed because the evaluation loop is returning.

In this case, we were not resolving the code object, but we are not
skipping the frame either because it's the first frame. This was causing
the code object pointer in the frame to be NULL but we are not checking
for that condition when unwinding.

Closes: #199

@pablogsal
Copy link
Member Author

@godlygeek we still have a problem with shim frames and native frames in general because it's possible that we are in one of these two situations (we are just returning or we are just entering) and therefore we won't identify the entry frame properly as in 3.12+ entry frames are frames preceded by shim frames but out shim frame it's at the bottom of the stack and this prevents us from merging the native stack properly

@pablogsal
Copy link
Member Author

For instance, this generates such a situation:

import asyncio
import _asyncio
import gc
import time


class MyFuture(asyncio.Future):
    def __del__(self):
        time.sleep(1000)


async def main():
    it = iter(MyFuture())

asyncio.run(main())

@pablogsal pablogsal force-pushed the shims branch 12 times, most recently from 9722e2a to 66c772f Compare August 13, 2024 14:40
@pablogsal pablogsal requested a review from godlygeek August 13, 2024 15:50
@pablogsal
Copy link
Member Author

I decided to fix the shim problem by always capturing shim frames and filter them out properly in the traceback formatter, which is slightly less efficient because we are not skipping them but thanks to the cache the overhead is minimal because the code object is always the same.

Copy link
Contributor

@godlygeek godlygeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small requests

@pablogsal
Copy link
Member Author

I have amended the last commit with your requests, please take another look

It's possible that pystack analyses a core file or a program at a
specific moment where the bottom of the stack has a shim frame but a
normal frame has not been pushed yet or the last normal frame has been
removed because the evaluation loop is returning.

In this case, we were not resolving the code object, but we are not
skipping the frame either because it's the first frame. This was causing
the code object pointer in the frame to be NULL but we are not checking
for that condition when unwinding.

Signed-off-by: Pablo Galindo <pablogsal@gmail.com>
@godlygeek
Copy link
Contributor

LGTM, though I made two more tweaks to the tests:

  1. changed all_pythons_since to take major/minor as two args rather than a 2-tuple, to make it easier to call
  2. updated the indentation of the f-string in generate_core_after_crash to prevent the end triple quotes from being less indented than the start triple quotes (and dropped the \ after the start triple quotes; gdb doesn't mind the leading blank line)

@godlygeek godlygeek enabled auto-merge (rebase) August 23, 2024 21:32
@godlygeek godlygeek merged commit c718d17 into bloomberg:main Aug 23, 2024
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CPython assertion failures cause odd behavior
2 participants