Add `stopped_with_signal` to the Debugger-agnostic API

pull/2488/head
Matheus Branco Borella 1 year ago committed by Disconnect3d
parent f35e22441a
commit 66d330652c

@ -74,6 +74,15 @@ class module(ModuleType):
""" """
return pwndbg.dbg.selected_inferior().alive() return pwndbg.dbg.selected_inferior().alive()
@property
def stopped_with_signal(self) -> bool:
"""
Returns whether the program has stopped with a signal
Can be used to detect segfaults (but will also detect other signals)
"""
return pwndbg.dbg.selected_inferior().stopped_with_signal()
@property @property
@pwndbg.lib.cache.cache_until("objfile") @pwndbg.lib.cache.cache_until("objfile")
def exe(self) -> str | None: def exe(self) -> str | None:

@ -309,6 +309,12 @@ class Process:
""" """
raise NotImplementedError() raise NotImplementedError()
def stopped_with_signal(self) -> bool:
"""
Returns whether this process was stopped by a signal.
"""
raise NotImplementedError()
def evaluate_expression(self, expression: str) -> Value: def evaluate_expression(self, expression: str) -> Value:
""" """
Evaluate the given expression in the context of the current process, and Evaluate the given expression in the context of the current process, and

@ -349,6 +349,10 @@ class GDBProcess(pwndbg.dbg_mod.Process):
def alive(self) -> bool: def alive(self) -> bool:
return gdb.selected_thread() is not None return gdb.selected_thread() is not None
@override
def stopped_with_signal(self) -> bool:
return "It stopped with signal " in gdb.execute("info program", to_string=True)
@override @override
def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value: def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value:
try: try:

@ -694,6 +694,12 @@ class LLDBProcess(pwndbg.dbg_mod.Process):
and self.process.GetState() != lldb.eStateDetached and self.process.GetState() != lldb.eStateDetached
) )
@override
def stopped_with_signal(self) -> bool:
return self.process.GetState() == lldb.eStateStopped and any(
(thread.GetStopReason() == lldb.eStopReasonSignal for thread in self.process.threads)
)
@override @override
def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value: def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value:
value = self.target.EvaluateExpression(expression) value = self.target.EvaluateExpression(expression)

@ -353,7 +353,7 @@ def run(startup: List[str] | None = None, debug: bool = False) -> None:
# control procedures for us to chew on. Run them now. # control procedures for us to chew on. Run them now.
for process, coroutine in dbg.controllers: for process, coroutine in dbg.controllers:
assert driver.has_process() assert driver.has_process()
assert driver.process == process.process assert driver.process.GetUniqueID() == process.process.GetUniqueID()
driver.run_coroutine(coroutine) driver.run_coroutine(coroutine)

@ -261,7 +261,7 @@ class ProcessDriver:
process in this driver. Returns `True` if the coroutine ran to completion, process in this driver. Returns `True` if the coroutine ran to completion,
and `False` if it was cancelled. and `False` if it was cancelled.
""" """
exception: Exception | None = False exception: Exception | None = None
while True: while True:
try: try:
if exception is None: if exception is None:

Loading…
Cancel
Save