sola-st / DynaPyt

Dynamic analysis framework for Python
MIT License
55 stars 14 forks source link

Instrumenting super calls as part of binary operations causes RuntimeError #72

Closed nimamg closed 1 week ago

nimamg commented 1 month ago

Description

When instrumenting binary operations that include a super() call in at least one of the operators, the instrumented code puts the super() call into a lambda function, causing it to be invoked later on, and leading to a RuntimeError as the super() function is called outside of its intended scope. This bypasses the only_post workaround that works in other cases.

Original Code

class A:
    def __init__(self):
        self.a = 1

    def f(self):
        return self.a

class B(A):
    def __init__(self):
        super().__init__()
        self.b = 2

    def f(self):
        return super().f() + self.b

b = B()
b.f()

Instrumented Code

I am just including the body of the f function from the B class to be concise. This code was instrumented and ran using the included TraceAll analysis

return _rt._return_(
    _dynapyt_ast_, 21, 14, "f",
    return_val=_rt._binary_op_(_dynapyt_ast_, 20,
                               lambda: _rt._call_(_dynapyt_ast_, 17,
                                                  _rt._attr_(_dynapyt_ast_, 16,
                                                             _rt._call_(_dynapyt_ast_, 15, super(), True,
                                                                        None, None),
                                                             "f"
                                                             ), False, [], {}
                                                  ),
                               0,
                               lambda: _rt._attr_(_dynapyt_ast_, 19,
                                                  _rt._read_(_dynapyt_ast_, 18, lambda: self), "b")
                               )
)

Traceback

Traceback (most recent call last):
  File "/Users/nima/codes/DynaPyt/venv/lib/python3.10/site-packages/dynapyt/run_analysis.py", line 139, in <module>
    run_analysis(
  File "/Users/nima/codes/DynaPyt/venv/lib/python3.10/site-packages/dynapyt/run_analysis.py", line 107, in run_analysis
    exec(open(entry_full_path).read(), globals_dict)
  File "<string>", line 37, in <module>
  File "/Users/nima/codes/DynaPyt/venv/lib/python3.10/site-packages/dynapyt/runtime.py", line 616, in _catch_
    raise exception
  File "<string>", line 35, in <module>
  File "/Users/nima/codes/DynaPyt/venv/lib/python3.10/site-packages/dynapyt/runtime.py", line 409, in _call_
    result = call(*pos_args, **kw_args)
  File "<string>", line 30, in f
  File "/Users/nima/codes/DynaPyt/venv/lib/python3.10/site-packages/dynapyt/runtime.py", line 242, in _binary_op_
    left = left()
  File "<string>", line 30, in <lambda>
RuntimeError: super(): no arguments
AryazE commented 1 month ago

Nice catch! Thanks for reporting this. Coincidentally, I also had a similar issue with super calls when using filters a few days ago. I need to think about how to resolve this. I am also open to any suggestions.

AryazE commented 4 weeks ago

Should be fixed by 0885eb1.