mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
Fix some hanging issues with the repl
This commit is contained in:
@@ -49,7 +49,7 @@ def await_enter(reactor):
|
||||
pass
|
||||
|
||||
class ConsoleApplication(object):
|
||||
def __init__(self, run_until_return=await_enter):
|
||||
def __init__(self, run_until_return=await_enter, on_stop=None):
|
||||
colorama.init()
|
||||
|
||||
parser = OptionParser(usage=self._usage(), version=frida.__version__)
|
||||
@@ -87,7 +87,7 @@ class ConsoleApplication(object):
|
||||
self._schedule_on_session_detached = lambda: self._reactor.schedule(self._on_session_detached)
|
||||
self._started = False
|
||||
self._resumed = False
|
||||
self._reactor = Reactor(run_until_return)
|
||||
self._reactor = Reactor(run_until_return, on_stop)
|
||||
self._exit_status = None
|
||||
self._status_updated = False
|
||||
|
||||
@@ -250,9 +250,10 @@ def expand_target(target):
|
||||
|
||||
|
||||
class Reactor(object):
|
||||
def __init__(self, run_until_return):
|
||||
def __init__(self, run_until_return, on_stop):
|
||||
self._running = False
|
||||
self._run_until_return = run_until_return
|
||||
self._on_stop = on_stop
|
||||
self._pending = collections.deque([])
|
||||
self._lock = threading.Lock()
|
||||
self._cond = threading.Condition(self._lock)
|
||||
@@ -290,6 +291,9 @@ class Reactor(object):
|
||||
self._cond.wait(timeout)
|
||||
running = self._running
|
||||
|
||||
if self._on_stop:
|
||||
self._on_stop()
|
||||
|
||||
def stop(self):
|
||||
with self._lock:
|
||||
self._running = False
|
||||
|
||||
+37
-4
@@ -8,9 +8,10 @@ def main():
|
||||
import sys
|
||||
import threading
|
||||
import os
|
||||
from prompt_toolkit.shortcuts import get_input
|
||||
from prompt_toolkit.shortcuts import create_default_application, create_default_output, create_eventloop
|
||||
from prompt_toolkit.history import FileHistory
|
||||
from prompt_toolkit.completion import Completion, Completer
|
||||
from prompt_toolkit.interface import CommandLineInterface
|
||||
from pygments.lexers import JavascriptLexer
|
||||
from pygments.token import Token
|
||||
|
||||
@@ -24,8 +25,9 @@ def main():
|
||||
self._completor_locals = []
|
||||
self._history = FileHistory(os.path.join(os.path.expanduser('~'), '.frida_history'))
|
||||
self._completer = FridaCompleter(self)
|
||||
self._cli = None
|
||||
|
||||
super(REPLApplication, self).__init__(self._process_input)
|
||||
super(REPLApplication, self).__init__(self._process_input, self._on_stop)
|
||||
|
||||
def _add_options(self, parser):
|
||||
parser.add_option("-l", "--load", help="load SCRIPT", metavar="SCRIPT",
|
||||
@@ -54,6 +56,15 @@ def main():
|
||||
sys.stdout.write("\033[A")
|
||||
self._ready.set()
|
||||
|
||||
def _on_stop(self):
|
||||
def set_return():
|
||||
raise EOFError()
|
||||
|
||||
try:
|
||||
self._cli.eventloop.call_from_executor(set_return)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _stop(self):
|
||||
self._unload_script()
|
||||
|
||||
@@ -78,15 +89,37 @@ def main():
|
||||
|
||||
def _process_input(self, reactor):
|
||||
self._print_startup_message()
|
||||
self._ready.wait()
|
||||
while self._ready.wait(0.5) != True:
|
||||
if not reactor._running:
|
||||
return
|
||||
|
||||
while True:
|
||||
expression = ""
|
||||
line = ""
|
||||
while len(expression) == 0 or line.endswith("\\"):
|
||||
if not reactor._running:
|
||||
return
|
||||
try:
|
||||
prompt = "[%s]" % self._prompt_string + "-> " if len(expression) == 0 else "... "
|
||||
line = get_input(prompt, history=self._history, lexer=JavascriptLexer, completer=self._completer)
|
||||
|
||||
# We create the prompt manually instead of using get_input,
|
||||
# so we can use the cli in the _on_stop method
|
||||
eventloop = create_eventloop()
|
||||
|
||||
self._cli = CommandLineInterface(
|
||||
application=create_default_application(prompt, history=self._history, completer=self._completer, lexer=JavascriptLexer),
|
||||
eventloop=eventloop,
|
||||
output=create_default_output())
|
||||
|
||||
try:
|
||||
line = None
|
||||
|
||||
document = self._cli.run()
|
||||
|
||||
if document:
|
||||
line = document.text
|
||||
finally:
|
||||
eventloop.close()
|
||||
except EOFError:
|
||||
# An extra newline after EOF to exit the REPL cleanly
|
||||
print("\nThank you for using Frida!")
|
||||
|
||||
Reference in New Issue
Block a user