Skip to content

Commit

Permalink
hilda_client: seperate configurable values into their own namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
netanelc305 committed May 23, 2024
1 parent fc54eca commit 24fc03a
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 40 deletions.
68 changes: 30 additions & 38 deletions hilda/hilda_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,33 @@ def fbp(line, local_ns=None):
SerializableSymbol = namedtuple('SerializableSymbol', 'address type_ filename')


@dataclass
class Configs:
""" Configuration settings for evaluation and monitoring. """
evaluation_unwind_on_error: bool = field(default=False,
metadata={'doc': 'Whether to unwind on error during evaluation.'})
evaluation_ignore_breakpoints: bool = field(default=False,
metadata={'doc': 'Whether to ignore breakpoints during evaluation.'})
nsobject_exclusion: bool = field(default=False, metadata={
'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.'})

def __repr__(self):
return self.__str__()

def __str__(self):
config_str = 'Configuration settings:\n'
max_len = max(len(field_name) for field_name in self.__dataclass_fields__) + 2

for field_name, field_info in self.__dataclass_fields__.items():
value = getattr(self, field_name)
doc = field_info.metadata.get('doc', 'No docstring available')
config_str += f'\t{field_name.ljust(max_len)}: {str(value).ljust(5)} | {doc}\n'

return config_str


class HildaClient:
Breakpoint = namedtuple('Breakpoint', 'address options forced callback')

Expand All @@ -108,13 +135,7 @@ def __init__(self, debugger: lldb.SBDebugger):
self.registers = Registers(self)
self.arch = self.target.GetTriple().split('-')[0]
self.ui_manager = UiManager(self)
# should unwind the stack on errors. change this to False in order to debug self-made calls
# within hilda
self._evaluation_unwind_on_error = True

# should ignore breakpoints while evaluation
self._evaluation_ignore_breakpoints = True

self.configs = Configs()
self._dynamic_env_loaded = False
self._symbols_loaded = False

Expand Down Expand Up @@ -821,9 +842,9 @@ def evaluate_expression(self, expression) -> Symbol:
formatted_expression = str(expression)

options = lldb.SBExpressionOptions()
options.SetIgnoreBreakpoints(self._evaluation_ignore_breakpoints)
options.SetIgnoreBreakpoints(self.configs.evaluation_ignore_breakpoints)
options.SetTryAllThreads(True)
options.SetUnwindOnError(self._evaluation_unwind_on_error)
options.SetUnwindOnError(self.configs.evaluation_unwind_on_error)

e = self.frame.EvaluateExpression(formatted_expression, options)

Expand All @@ -847,35 +868,6 @@ def import_module(self, filename: str, name: Optional[str] = None) -> Any:
spec.loader.exec_module(m)
return m

def set_evaluation_unwind(self, value: bool):
"""
Set whether LLDB will attempt to unwind the stack whenever an expression evaluation error occurs.
Use unwind() to restore when an error is raised in this case.
"""
self._evaluation_unwind_on_error = value

def get_evaluation_unwind(self) -> bool:
"""
Get evaluation unwind state.
When this value is True, LLDB will attempt unwinding the stack on evaluation errors.
Otherwise, the stack frame will remain the same on errors to help you investigate the error.
"""
return self._evaluation_unwind_on_error

def set_evaluation_ignore_breakpoints(self, value: bool):
"""
Set whether to ignore breakpoints while evaluating expressions
"""
self._evaluation_ignore_breakpoints = value

def get_evaluation_ignore_breakpoints(self) -> bool:
"""
Get evaluation "ignore-breakpoints" state.
"""
return self._evaluation_ignore_breakpoints

def unwind(self) -> bool:
""" Unwind the stack (useful when get_evaluation_unwind() == False) """
return self.thread.UnwindInnermostExpression().Success()
Expand Down
2 changes: 2 additions & 0 deletions hilda/objective_c_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,8 @@ def __dir__(self):
result.add(method.name.replace(':', '_'))

for sup in self.iter_supers():
if self._client.configs.nsobject_exclusion and sup.name == 'NSObject':
continue
for method in sup.methods:
if method.is_class:
result.add(method.name.replace(':', '_'))
Expand Down
2 changes: 2 additions & 0 deletions hilda/objective_c_symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ def __dir__(self):
result.add(method.name.replace(':', '_'))

for sup in self.class_.iter_supers():
if self._client.configs.nsobject_exclusion and sup.name == 'NSObject':
continue
for method in sup.methods:
result.add(method.name.replace(':', '_'))

Expand Down
9 changes: 7 additions & 2 deletions hilda/symbols_jar.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,15 @@ def monitor(self, **args):
:param args: given arguments for monitor command
"""
for name, address in self.items():
args_c = args.copy()
if name == '_client':
continue
name = args.get('name', name)
address.monitor(name=name, **args)
if self.__dict__['_client'].configs.objc_verbose_monitor:
arg_count = name.count(':')
if arg_count > 0:
args_c['regs'] = {f'x{i + 2}': 'po' for i in range(arg_count)}
name = args_c.get('name', name)
address.monitor(name=name, **args_c)

def startswith(self, exp, case_sensitive=True):
"""
Expand Down

0 comments on commit 24fc03a

Please sign in to comment.