使用sys.settrace可以完成哪些很酷的黑客攻击?

时间:2009-11-07 12:25:47

标签: python

我喜欢能够使用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)

这将打印出来:

1
1
3
3
5

使用settrace可以做些什么很酷的事情?

7 个答案:

答案 0 :(得分:24)

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

  1. Settrace是一个非常生硬的工具。 OP的示例很简单,但实际上没有办法扩展它以用于实际系统。

  2. 这很神秘。任何来看你的代码的人都会完全不知道为什么它正在做它正在做的事情。

  3. 这很慢。为执行的每一行Python调用Python函数会使程序减慢许多倍。

  4. 通常没必要。这里的原始示例可以通过其他几种方式完成(修改函数,在装饰器中包装函数,通过另一个函数调用它等),其中任何一个都比settrace更好。

  5. 很难做对。在原始示例中,如果您没有直接调用f,而是调用名为f的g,则跟踪函数将无法完成其工作,因为您从跟踪函数返回None,因此它只被调用一次然后被遗忘。

  6. 这将使其他工具无法正常工作。这个程序不可调试(因为调试器使用settrace),它不可追溯,无法测量其代码覆盖率等。部分原因是由于Python实现者缺乏远见:它们给了我们settrace但没有gettrace,所以很难有两个跟踪函数一起工作。

  7. 跟踪功能可以实现酷炫的黑客攻击。能够滥用它很有趣,但请不要将它用于真实的东西。如果我听起来很糟糕,我道歉,但这是在真实的代码中完成的,这很痛苦。例如,DecoratorTools使用跟踪函数来执行使这种语法在Python 2.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
    

    一个整洁的黑客,但不幸的是,这意味着任何使用DecoratorTools的代码都无法使用coverage.py(或者我认为是调试器)。如果你问我,不是一个很好的权衡。我更改了coverage.py以提供一种模式,让它可以与DecoratorTools一起使用,但我希望我不必这样做。

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

    < /咆哮>

答案 1 :(得分:18)

我创建了一个名为pycallgraph的模块,它使用sys.settrace()生成调用图。

答案 2 :(得分:10)

当然,代码覆盖是通过跟踪功能完成的。我们之前从未有过的一个很酷的事情是分支覆盖率测量,并且即将发布,即将在coverage.py的alpha版本中发布。

例如,考虑这个函数:

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

如果您使用此次通话进行测试:

assert foo(1) == 10

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

分支测量会告诉您代码中有一个未完全运用的分支,因为分支中只有一个分支。

答案 3 :(得分:3)

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

答案 4 :(得分:1)

我没有详尽全面的答案,但在SO上的另一位用户的帮助下,我做了一件事,create a program that generates the trace tables of other Python programs

答案 5 :(得分:1)

python调试器Pdb使用sys.settrace来分析要调试的行。

这是pdb的c优化/扩展,它也使用sys.settrace

https://bitbucket.org/jagguli/cpdb

答案 6 :(得分:1)

PySnooper

大量使用settrace的最新项目

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