diff --git a/etheno/manticoreclient.py b/etheno/manticoreclient.py index bb0138d..cea87e8 100644 --- a/etheno/manticoreclient.py +++ b/etheno/manticoreclient.py @@ -1,6 +1,34 @@ import logging import time +import builtins +import sys + +# ####BEGIN#### +# Horrible hack to workaround Manticore's global logging system. +# This can be removed after https://github.com/trailofbits/manticore/issues/1369 +# is resolved. +from . import manticorelogger + +oldimport = builtins.__import__ +def manticoreimport(name, *args, **kwargs): + if name == 'manticore.utils.log': + manticorelogger.__name__ = 'manticore.utils.log' + sys.modules[name] = manticorelogger + return manticorelogger + else: + return oldimport(name, *args, **kwargs) + +builtins.__import__ = manticoreimport +try: + import manticore.utils.log + import manticore.utils +finally: + builtins.__import__ = oldimport + +manticore.utils.log = manticorelogger +# ####END#### + from manticore.ethereum import ManticoreEVM import manticore @@ -57,13 +85,21 @@ def create_account(self, balance, address): def reassign_manticore_loggers(self): # Manticore uses a global to track its loggers: - for name in manticore.utils.log.all_loggers: - if not name.startswith('manticore'): - continue - manticore_logger = logging.getLogger(name) - for handler in list(manticore_logger.handlers): - manticore_logger.removeHandler(handler) - logger.EthenoLogger(name, parent=self.logger, cleanup_empty=True) + manticore.utils.log.ETHENO_LOGGER = self.logger + manticore_loggers = (name for name in logging.root.manager.loggerDict if name.startswith('manticore')) + logger_parents = {} + for name in sorted(manticore_loggers): + sep = name.rfind('.') + if sep > 0: + path = name[:sep] + parent = logger_parents[path] + displayname = name[len(path)+1:] + else: + parent = self.logger + displayname = name + m_logger = logger.EthenoLogger(name, parent=parent, cleanup_empty=True, displayname=displayname) + m_logger.propagate = False + logger_parents[name] = m_logger @jsonrpc(from_addr = QUANTITY, to = QUANTITY, gas = QUANTITY, gasPrice = QUANTITY, value = QUANTITY, data = DATA, nonce = QUANTITY, RETURN = DATA) def eth_sendTransaction(self, from_addr, to = None, gas = 90000, gasPrice = None, value = 0, data = None, nonce = None, rpc_client_result = None): diff --git a/etheno/manticorelogger.py b/etheno/manticorelogger.py new file mode 100644 index 0000000..2245223 --- /dev/null +++ b/etheno/manticorelogger.py @@ -0,0 +1,26 @@ +# This is a horrible hack that is used to replace manticore.utils.log +# Remove this once https://github.com/trailofbits/manticore/issues/1369 +# is resolved. + +ETHENO_LOGGER = None + +@property +def manticore_verbosity(): + return ETHENO_LOGGER.log_level + +@property +def DEFAULT_LOG_LEVEL(): + return ETHENO_LOGGER.log_level + +def set_verbosity(setting): + pass + #global manticore_verbosity + #manticore_verbosity = min(max(setting, 0), len(get_levels()) - 1) + #for logger_name in all_loggers: + # logger = logging.getLogger(logger_name) + # # min because more verbosity == lower numbers + # # This means if you explicitly call setLevel somewhere else in the source, and it's *more* + # # verbose, it'll stay that way even if manticore_verbosity is 0. + # logger.setLevel(min(get_verbosity(logger_name), logger.getEffectiveLevel())) + +all_loggers = set()