获取C python exec参数字符串或访问评估堆栈 [英] getting the C python exec argument string or accessing the evaluation stack

查看:112
本文介绍了获取C python exec参数字符串或访问评估堆栈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的 python调试器中,我有一种将字符串重新映射到文件名的方法,这样当您正在调试器中逐步执行一个exec函数,您可以列出经过pygmentized的行,或者通过 realgud .

In my python debugger I have a way of remapping a string to a filename so that when you are stepping through an exec'd function inside the debugger you can list lines pygmentized, or view them along inside an editor like Emacs via realgud.

因此,我希望能够在CPython停止对其进行评估时在exec语句中提取字符串.

So I'd like to be able to extract the string in an exec statement when CPython is stopped inside evaluating that.

我已经有了一种可以在调用框架中进行回顾的机制,以查看

I already have a mechanism that can look back in the call frame to see if the caller was an EXEC_STMT and I can look back one instruction to see if the previous instruction was say DUP_TOP. So I'd be home free if I could just figure out a way to read the stack entry at the time of the call and that gives the string evaluated. There is probably a way to drop into C to get this, but my knowledge of CPython internals lacking, and would prefer not to do this. If there's a package out there, maybe I could include that optionally.

CPython已经提供了对函数参数和局部变量的访问,但是当然,由于这是一个内置函数,因此不会记录为函数参数.

CPython already provides access to function arguments, and local variables but of course since this is a built-in function this isn't recorded as a function parameter.

如果对如何做同样的事情还有其他想法,那也没关系.我觉得不太好的解决方案是尝试以某种方式重载或替换exec,因为调试器可以在游戏后期引入.

If there are other thoughts at how to do the same thing, that'd be okay too. I feel a less good solution would be to somehow try to overload or replace exec since debuggers can be brought in late in the game.

我知道CPython2和CPython3在这里可能有些不同,但是从两者开始都是可以的.

I understand that CPython2 and CPython3 may be a little bit different here, but to start off either would do.

推荐答案

我想我已经找到了一种方法.

I think I've now found a way.

在调试器中,我将调用堆栈上移至exec语句.然后,我可以使用 uncompyle6 来获取源代码的语法树代码. (可能需要在uncompyle6中进行更改以使其变得更容易.)

Inside the debugger I go up the call stack one level to get to the exec statement. Then I can use uncompyle6 to get a syntax tree of the source code. (A change may be needed in uncompyle6 to make this easier.)

调用点处的树将具有类似exec_stmt -> expr ...的内容.该表达式将具有该表达式的 text ,不一定是该表达式的值.该表达式可以是一个常量字符串值,但也可以像"foo" + var1这样复杂.

The tree at the point of call will have something like exec_stmt -> expr .... That expression will have the text of the expression which is not necessarily the value of the expression. The expression could be a constant string value, but it could be something complex like "foo" + var1.

因此调试器可以在调试器的上下文中求值该字符串,该调试器知道如何在调用堆栈中求值表达式.

So then the debugger can evaluate that string in the context of the debugger which knows how to evaluate expressions up the call stack.

这仍然存在重新评估表达式可能有副作用的问题.但这是不好的编程习惯,对吗? ;-)

This still has a problem of the reevaluating the expression may have side effects. But that's bad programming practice, right? ;-)

因此,如果源不存在,我要做的就是从字节码中反编译代码.这样做的缺点是字节码中提到的行号并不总是与字节码中的行号对齐.为此,重新创建上面的字符串的方法更好.

So instead what I do is just decompile the code from the bytecode if the source isn't there. This has a disadvantage in that the line numbers mentioned in the bytecode don't always line up with those in the bytecode. For that the method of recreating the string above is better.

最后,我希望给出一个想法,为什么编写一个真正好的调试器很困难,为什么大量的调试器甚至在一些简单的事情上都有很多限制,例如在当前停止的地方获取源文本.

In closing, I hope to give some idea why writing a really good debugger is hard and why the vast number of debuggers have a number of limitations on even simple things like getting the source text at the point you are currently stopped.

一种完全不同的方法是尽早停止并切换到 byterun (或某些经过适当修改的Python C模块),这些模块可以访问堆栈.

A totally different approach would be to stop early and switch to an sub-interpreter like byterun (or some suitably modified Python C module) which would have access to a stack.

这篇关于获取C python exec参数字符串或访问评估堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆