Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panoramix fails to work not in main thread (and does not work in Windows) #10

Open
NikZak opened this issue Jun 15, 2021 · 3 comments · May be fixed by #11
Open

Panoramix fails to work not in main thread (and does not work in Windows) #10

NikZak opened this issue Jun 15, 2021 · 3 comments · May be fixed by #11

Comments

@NikZak
Copy link

NikZak commented Jun 15, 2021

ERROR:panoramix.decompiler:Problem with name()
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.9/site-packages/panoramix/decompiler.py", line 177, in _decompile_with_loader
trace = dec()
File "/opt/homebrew/lib/python3.9/site-packages/timeout_decorator/timeout_decorator.py", line 75, in new_function
old = signal.signal(signal.SIGALRM, handler)
File "/opt/homebrew/Cellar/[email protected]/3.9.5/Frameworks/Python.framework/Versions/3.9/lib/python3.9/signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread of the main interpreter

This happens because panoramix in one place uses timeout-decorator library.
Precisely here in panoramix/decompiler.py

def _decompile_with_loader(loader, only_func_name=None) -> Decompilation:
    ...
      @timeout_decorator.timeout(60 * 3, timeout_exception=TimeoutInterrupt)
      def dec():
        trace = VM(loader).run(target, stack=stack, timeout=60)

timeout_decorator project actually describes this problem here:

Multithreading
By default, timeout-decorator uses signals to limit the execution time of the given function. This appoach does not work if your function is executed not in a main thread (for example if it’s a worker thread of the web application). There is alternative timeout strategy for this case - by using multiprocessing. To use it, just pass use_signals=False to the timeout decorator function:

But just adding use_signals=False would not work as the object is sophisticated enough and can not be pickled which is required by the multiprocessing module

So the full solution to this problem is:

  1. pip install wrapt_timeout_decorator

  2. add to panoramix/decompiler.py

from wrapt_timeout_decorator import timeout
  1. replace
def _decompile_with_loader(loader, only_func_name=None) -> Decompilation:
    ...
      @timeout_decorator.timeout(60 * 3, timeout_exception=TimeoutInterrupt)
      def dec():
        trace = VM(loader).run(target, stack=stack, timeout=60)

with

def _decompile_with_loader(loader, only_func_name=None) -> Decompilation:
    ...
      @timeout(60 * 3, timeout_exception=TimeoutInterrupt, use_signals=False)
      def dec():
        trace = VM(loader).run(target, stack=stack, timeout=60)

This solves the failure to work not in main thread problem and should also solve not working in Windows problem (although I can not test the second statement)

I can submit a pull request, just let me know

@FuzzyDev2021
Copy link

Can confirm that editing the code as suggested above fixes it on my Windows machine.

NikZak added a commit to NikZak/panoramix that referenced this issue Jun 17, 2021
@papunku
Copy link

papunku commented Aug 4, 2022

Nice project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants
@NikZak @FuzzyDev2021 @papunku and others