diff --git a/hilda/hilda_client.py b/hilda/hilda_client.py index 48e060f..5a03705 100644 --- a/hilda/hilda_client.py +++ b/hilda/hilda_client.py @@ -58,7 +58,8 @@ Hilda has been successfully loaded! 😎 Usage: p Global to access all features. - F1 UI Show. + F1 Show UI. + F2 Toggle enabling of stdout & stderr. F7 Step Into. F8 Step Over. F9 Continue. @@ -92,6 +93,8 @@ class Configs: 'doc': 'Whether to exclude NSObject during evaluation - reduce ipython autocomplete results.'}) objc_verbose_monitor: bool = field(default=False, metadata={ 'doc': 'When set to True, using monitor() will automatically print objc methods arguments.'}) + enable_stdout_stderr: bool = field(default=True, metadata={ + 'doc': 'When set to True, will enable process stdout and stderr.'}) def __repr__(self): return self.__str__() @@ -1089,6 +1092,10 @@ def interact(self, additional_namespace: Optional[typing.Mapping] = None, sys.argv = ['a'] IPython.start_ipython(config=ipython_config, user_ns=namespace) + def toggle_enable_stdout_stderr(self, *args) -> None: + self.configs.enable_stdout_stderr = not self.configs.enable_stdout_stderr + self.logger.info(f'Changed stdout and stderr status to: {self.configs.enable_stdout_stderr}') + def __enter__(self) -> 'HildaClient': return self diff --git a/hilda/ipython_extensions/keybindings.py b/hilda/ipython_extensions/keybindings.py index a7c3c90..ce58fcb 100644 --- a/hilda/ipython_extensions/keybindings.py +++ b/hilda/ipython_extensions/keybindings.py @@ -7,6 +7,7 @@ def load_ipython_extension(ipython): def register_keybindings(): hilda = ipython.user_ns['p'] keys_mapping = {Keys.F1: hilda.ui_manager.show, + Keys.F2: hilda.toggle_enable_stdout_stderr, Keys.F7: hilda.step_into, Keys.F8: hilda.step_over, Keys.F9: lambda _: (hilda.log_info('Sending continue'), hilda.cont()), diff --git a/hilda/launch_lldb.py b/hilda/launch_lldb.py index 753ecb7..2b2f859 100644 --- a/hilda/launch_lldb.py +++ b/hilda/launch_lldb.py @@ -1,5 +1,6 @@ import logging import os +import sys from abc import ABC, abstractmethod from threading import Thread from typing import List, Optional @@ -46,6 +47,20 @@ def _check_success(self) -> None: return raise LLDBError(self.error.description) + def _process_stdout(self) -> None: + stdout = self.process.GetSTDOUT(1024) + while stdout: + if lldb.hilda_client is not None and lldb.hilda_client.configs.enable_stdout_stderr: + sys.stdout.write(stdout) + stdout = self.process.GetSTDOUT(1024) + + def _process_stderr(self) -> None: + stderr = self.process.GetSTDERR(1024) + while stderr: + if lldb.hilda_client is not None and lldb.hilda_client.configs.enable_stdout_stderr: + sys.stderr.write(stderr) + stderr = self.process.GetSTDERR(1024) + def run(self): event = lldb.SBEvent() last_state = lldb.eStateStopped @@ -54,6 +69,13 @@ def run(self): continue if not lldb.SBProcess.EventIsProcessEvent(event): continue + + event_type = event.GetType() + if event_type & lldb.SBProcess.eBroadcastBitSTDOUT: + self._process_stdout() + if event_type & lldb.SBProcess.eBroadcastBitSTDERR: + self._process_stderr() + state = self.process.GetStateFromEvent(event) if state == lldb.eStateDetached: logger.debug('Process Detached')