mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
Fix race-condition that resulted in the REPL hanging
With two successive requests, for example a completion request and an eval request fired from two different Python threads, the second response could end up overwriting the first one before it got processed. The initial design assumed that only a single Python thread would be making these requests, but that changed when the completion was introduced. We now fix this issue by using a queue and knowing that these requests are processed and replied to in FIFO order.
This commit is contained in:
+6
-5
@@ -3,6 +3,7 @@ from __future__ import unicode_literals, print_function
|
||||
|
||||
def main():
|
||||
import codecs
|
||||
from collections import deque
|
||||
from colorama import Fore, Style
|
||||
import frida
|
||||
from frida.application import ConsoleApplication
|
||||
@@ -24,7 +25,7 @@ def main():
|
||||
self._seqno = 0
|
||||
self._ready = threading.Event()
|
||||
self._response_cond = threading.Condition()
|
||||
self._response_data = None
|
||||
self._response_queue = deque()
|
||||
self._completor_locals = []
|
||||
self._history = FileHistory(os.path.join(os.path.expanduser('~'), '.frida_history'))
|
||||
self._completer = FridaCompleter(self)
|
||||
@@ -313,12 +314,11 @@ def main():
|
||||
def _evaluate(self, text):
|
||||
self._reactor.schedule(lambda: self._script.post_message({'name': '.evaluate', 'payload': {'expression': text}}))
|
||||
with self._response_cond:
|
||||
while self._response_data is None:
|
||||
while len(self._response_queue) == 0:
|
||||
if not self._reactor.is_running():
|
||||
raise frida.InvalidOperationError("Invalid operation while stopping")
|
||||
self._response_cond.wait(0.5)
|
||||
response = self._response_data
|
||||
self._response_data = None
|
||||
response = self._response_queue.popleft()
|
||||
stanza, data = response
|
||||
if data is not None:
|
||||
return ('binary', data)
|
||||
@@ -334,7 +334,8 @@ def main():
|
||||
if message_type == 'send':
|
||||
stanza = message['payload']
|
||||
with self._response_cond:
|
||||
self._response_data = (stanza, data)
|
||||
response = (stanza, data)
|
||||
self._response_queue.append(response)
|
||||
self._response_cond.notify()
|
||||
elif message_type == 'error':
|
||||
text = message.get('stack', message['description'])
|
||||
|
||||
Reference in New Issue
Block a user