Skip to content

Conversation

@gouzil
Copy link
Member

@gouzil gouzil commented Feb 8, 2024

PR types

Bug fixes

PR changes

Others

Description

修复在 #61305 中遇到的问题

过不去 python debug 版本中的 framesize检查

assert((PyObject **)frame + frame->f_code->co_framesize == tstate->datastack_top);

问题一:

原先使用自己malloc创建的shadow没有对tstate进行管理,导致在RETURN_VALUE字节码中_PyEvalFrameClearAndPop的时候不能正常的清理和释放内存。

解决方式:使用 cpython 自己的 Push 方式,这里用的是_PyThreadState_PushFrame

问题二:

没有对frametstate进行同步_PyEvalFrameClearAndPop导致后续tstate->datastack_top异常

d844b773a71bac05a0c2f44a56121ed8

@paddle-bot
Copy link

paddle-bot bot commented Feb 8, 2024

你的PR提交成功,感谢你对开源项目的贡献!
请关注后续CI自动化测试结果,详情请参考Paddle-CI手册
Your PR has been submitted. Thanks for your contribution!
Please wait for the result of CI firstly. See Paddle CI Manual for details.

@paddle-bot paddle-bot bot added the contributor External developers label Feb 8, 2024
@gouzil gouzil changed the title [sot][3.12] Fix that frame in eval custom code was not released in tstate [SOT][3.12] Fix that frame in eval custom code was not released in tstate Feb 8, 2024
@gouzil gouzil requested a review from SigureMo February 8, 2024 08:15
Copy link
Member

@SigureMo SigureMo left a comment

Choose a reason for hiding this comment

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

LGTMeow

Comment on lines +228 to +233
#if PY_VERSION_HEX >= 0x030c0000
Internal_PyEvalFrameClearAndPop(tstate, frame);
#else
Internal_PyFrame_Clear(shadow);
free(shadow);
#endif
Copy link
Member

Choose a reason for hiding this comment

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

之后加一个注释吧,因为两个分支一个清理 frame,一个清理 shadow,不清楚缘由的人很容易当成 bug 的

@SigureMo
Copy link
Member

SigureMo commented Feb 8, 2024

记录:

Python 3.11 和 3.12 的 frame 管理是不同的

Python 3.11 是自己管理,_PyEval_EvalFrameDefault 不负责释放 frame,因此我们需要自己创建孤立的 frame,并在完成后释放

Python 3.12 则是会在 _PyEval_EvalFrameDefault 释放掉传入的 frame(3.12 传入的 frame 不是 entry_frameentry_frame 是一个类似 Sentinel 的 fake 的 frame),因此需要改变以下几部分

  • 初始化使用 shadow PushAndInit,否则在释放时,_PyEval_EvalFrameDefaultRETURN_VALUE 释放的 datastack_top 假设无法满足
  • 不需要清理 shadow frame,因为 _PyEval_EvalFrameDefaultRETURN_VALUE 会做
  • 需要使用 PopAndClear 手动清理原始 frame,因为 3.12 认为 eval 时候就会清理,但我们并没有将该 frame 传入 _PyEval_EvalFrameDefault,因此需要我们来清理

这里的差异导致了 3.11 和 3.12 分别清理了 shadow 和 frame,但其实是正确的

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contributor External developers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants