gpt4 book ai didi

What cool hacks can be done using sys.settrace?(使用sys.settrace可以完成哪些很酷的黑客攻击?)

翻译 作者:bug小助手 更新时间:2023-10-26 22:33:53 29 4
gpt4 key购买 nike



I love being able to modify the arguments the get sent to a function, using settrace, like :

我喜欢能够修改发送给函数的参数,使用settrace,比如:



import sys

def trace_func(frame,event,arg):
value = frame.f_locals["a"]
if value % 2 == 0:
value += 1
frame.f_locals["a"] = value

def f(a):
print a

if __name__ == "__main__":
sys.settrace(trace_func)
for i in range(0,5):
f(i)


And this will print:

这将打印出来:



1
1
3
3
5


What other cool stuff can you do using settrace?

使用settrace还可以做什么其他很酷的事情?


更多回答
优秀答案推荐

I would strongly recommend against abusing settrace. I'm assuming you understand this stuff, but others coming along later may not. There are a few reasons:

我强烈建议不要滥用settrace。我假设你理解这些东西,但其他后来出现的人可能不会。原因有几个:




  1. Settrace is a very blunt tool. The OP's example is a simple one, but there's practically no way to extend it for use in a real system.


  2. It's mysterious. Anyone coming to look at your code would be completely stumped why it was doing what it was doing.


  3. It's slow. Invoking a Python function for every line of Python executed is going to slow down your program by many multiples.


  4. It's usually unnecessary. The original example here could have been accomplished in a few other ways (modify the function, wrap the function in a decorator, call it via another function, etc), any of which would have been better than settrace.


  5. It's hard to get right. In the original example, if you had not called f directly, but instead called g which called f, your trace function wouldn't have done its job, because you returned None from the trace function, so it's only invoked once and then forgotten.


  6. It will keep other tools from working. This program will not be debuggable (because debuggers use settrace), it will not be traceable, it will not be possible to measure its code coverage, etc. Part of this is due to lack of foresight on the part of the Python implementors: they gave us settrace but no gettrace, so it's difficult to have two trace functions that work together.




Trace functions make for cool hacks. It's fun to be able to abuse it, but please don't use it for real stuff. If I sound hectoring, I apologize, but this has been done in real code, and it's a pain. For example, DecoratorTools uses a trace function to perform the magic feat of making this syntax work in Python 2.3:

跟踪函数有助于进行很酷的黑客攻击。能够滥用它是很有趣的,但请不要把它用于真正的东西。如果我听起来很威吓,我很抱歉,但这是用真正的代码完成的,这是一种痛苦。例如,DecoratorTools使用跟踪函数来执行在Python2.3中使用此语法的神奇壮举:



# Method decorator example
from peak.util.decorators import decorate

class Demo1(object):
decorate(classmethod) # equivalent to @classmethod
def example(cls):
print "hello from", cls


A neat hack, but unfortunately, it meant that any code that used DecoratorTools wouldn't work with coverage.py (or debuggers, I guess). Not a good tradeoff if you ask me. I changed coverage.py to provide a mode that lets it work with DecoratorTools, but I wish I hadn't had to.

这是一个巧妙的破解,但不幸的是,这意味着任何使用DecoratorTool的代码都不能与overage.py(我猜是调试器)一起工作。如果你问我,这可不是一个好的权衡。我更改了overage.py以提供一种模式,使其可以与DecoratorTool一起工作,但我希望我不必这样做。



Even code in the standard library sometimes gets this stuff wrong. Pyexpat decided to be different than every other extension module, and invoke the trace function as if it were Python code. Too bad they did a bad job of it.

即使是标准库中的代码有时也会出错。Pyexpat决定与其他所有扩展模块不同,并像调用Python代码一样调用跟踪函数。太糟糕了,他们做得不好。



</rant>



I made a module called pycallgraph which generates call graphs using sys.settrace().

我制作了一个名为pyallgraph的模块,它使用sys.settrace()生成调用图。





Of course, code coverage is accomplished with the trace function. One cool thing we haven't had before is branch coverage measurement, and that's coming along nicely, about to be released in an alpha version of coverage.py.

当然,代码覆盖是通过跟踪函数完成的。我们以前没有过的一件很酷的事情是分支覆盖率测量,它进展得很好,即将在Coverage.py的Alpha版本中发布。



So for example, consider this function:

因此,例如,请考虑以下函数:



def foo(x):
if x:
y = 10
return y


if you test it with this call:

如果你用这个调用测试它:



assert foo(1) == 10


then statement coverage will tell you that all the lines of the function were executed. But of course, there's a simple problem in that function: calling it with 0 raises a UnboundLocalError.

然后,语句覆盖率将告诉您函数的所有行都已执行。但当然,该函数中有一个简单的问题:用0调用它会引发UnundLocalError。



Branch measurement would tell you that there's a branch in the code that isn't fully exercised, because only one leg of the branch is ever taken.

分支测量将告诉您,代码中有一个分支没有完全执行,因为只有一个分支被占用。



For example, get the memory consumption of Python code line-by-line: http://pypi.python.org/pypi/memory_profiler

例如,逐行获取PYTHON代码的内存消耗:http://pypi.python.org/pypi/memory_profiler



One latest project that uses settrace heavily is PySnooper

PySnooper是最新的一个大量使用settrace的项目



It helps new programmers to trace/log/monitor their program output. Cheers!

它帮助新程序员跟踪/记录/监控他们的程序输出。干杯!



I don't have an exhaustively comprehensive answer but one thing I did with it, with the help of another user on SO, was create a program that generates the trace tables of other Python programs.

我没有一个详尽而全面的答案,但在SO上的另一个用户的帮助下,我用它做了一件事,就是创建了一个程序来生成其他Python程序的跟踪表。



The python debugger Pdb uses sys.settrace to analyse lines to debug.

Python调试器PDB使用sys.settrace来分析要调试的行。



Here's an c optimization/extension for pdb that also uses sys.settrace

下面是同样使用sys.settrace的pdb的c优化/扩展



https://bitbucket.org/jagguli/cpdb

Https://bitbucket.org/jagguli/cpdb



A really cool project using settrace adds the defer statement from go to the language in a cool way. It allows code like this:

一个使用settrace的很酷的项目以一种很酷的方式将go中的defer语句添加到语言中。它允许这样的代码:


def foo():
print(", world!") in defer
print("Hello", end="")
# do something that might fail...
assert 1 + 1 == 3

This will output:

这将输出:


$ python foo.py
Hello, World!
Traceback (most recent call last):
File "foo.py", line 7, in <module>
assert 1 + 1 == 3
AssertionError

https://github.com/yasyf/python-defer

Https://github.com/yasyf/python-defer


更多回答

sys.gettrace exists since Python 2.6 (docs.python.org/library/sys.html#sys.gettrace), but because of the way settrace is designed, with the handler returning a new handler function on each call, it doesn't really help. I completely agree with your main points -- settrace is unusable for anything other than (slow) debugging.

(docs.python.org/library/sys.html#sys.gettrace),是从Python2.6settrace开始存在的,但是由于settrace的设计方式,处理程序在每次调用时都返回一个新的处理程序函数,所以它并没有真正的帮助。我完全同意您的主要观点--除了(缓慢的)调试之外,settrace不能用于任何事情。

This answer was written in 2009 and I should say that not all of the points raised by the author apply anymore. sys.settrace() and other debuggers can coexist depending on the implementation (such as ipdb.set_trace()). Also there is gettrace() function implemented...Also depending on the implementation, your code doesn't necessarily have to run "slow by many multiples". It will be never be faster, yes, but that's still a gross overgeneralization.

这个答案是在2009年写的,我应该说,作者提出的所有观点并不都适用。根据实现的不同,sys.settrace()和其他调试器可以共存(例如ipdb.set_trace())。此外,还实现了gettrace()函数……根据实现方式的不同,您的代码不必“慢许多倍”地运行。是的,它永远不会更快,但这仍然是一个严重的过度概括。

@aarslan that is not an overgeneralization: adding code is always slower. Moreover, debugging tools are not made for performance, but for debugging. Finally, using debugging tools as functional code is one of the worst practices I've ever met.

@aarslan,这不是一个过度泛化:添加代码总是更慢。此外,调试工具不是为了性能,而是为了调试。最后,使用调试工具作为功能代码是我见过的最糟糕的实践之一。

@Tim I clearly said the code will run slower but not necessarily "slow by many multiples". Moreover, I was criticising the absolute statement that settrace is unusable for anything other than slow debugging. There are certainly practices where it is useful besides that, and they don't have to have anything to do with debugging. It's simply a tool to keep a track of function calls and files. I've seen it used an automatic archival tool to pair a rapidly changing codebase containing an analysis pipeline with its output, in order to ensure easy and accurate reproduction of the same output.

@Tim我清楚地说过,代码的运行速度会更慢,但不一定会“慢很多倍”。此外,我批评的是绝对的声明,即settrace除了用于缓慢的调试外,不能用于任何其他用途。除此之外,当然还有一些实践是有用的,而且它们不必与调试有任何关系。它只是一个跟踪函数调用和文件的工具。我见过它使用自动存档工具将包含分析管道的快速变化的代码库与其输出配对,以确保轻松而准确地复制相同的输出。

@aarslan, well, if your point is sys.settrace() can be used for code coverage tools or testing, I do agree, but you're not saying it explicitly. My point is always use sys.settrace() for meta- programming, not for programming, and so is @Ned's.

@aarslan,好吧,如果您的观点是sys.settrace()可以用于代码覆盖工具或测试,我确实同意,但您没有明确表示出来。我的观点是始终将sys.settrace()用于元编程,而不是用于编程,@Ned也是如此。

I can't see the added value compared to gprof2dot which produces exactly the same graphs for years (since 2007-03-30 exactly see the GitHub project), except that it adds timing info about each called function (self time, total time, number of calls). Nice work though.

我看不出与gpro2dot相比有什么额外的价值,后者多年来生成完全相同的图表(因为2007-03-30完全参见GitHub项目),除了它添加了关于每个被调用函数的计时信息(自身时间、总时间、调用次数)。不过,干得不错。

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com