From 3db6ba4eed90abe12d75a31d7612bc20986f6f9e Mon Sep 17 00:00:00 2001 From: "Matt." Date: Tue, 3 Sep 2024 12:48:38 -0300 Subject: [PATCH] Add GDB scheduler-locking control to the Debugger-agnostic API (#2409) * Add GDB scheduler-locking control to the Debugger-agnostic API * Add back uses of scheduler-locking where they'd been removed --- pwndbg/aglib/tls.py | 6 +++++- pwndbg/dbg/__init__.py | 9 ++++++++- pwndbg/dbg/gdb.py | 9 ++++++--- pwndbg/dbg/lldb/__init__.py | 4 +++- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/pwndbg/aglib/tls.py b/pwndbg/aglib/tls.py index 6a8311327..4ac60ad5f 100644 --- a/pwndbg/aglib/tls.py +++ b/pwndbg/aglib/tls.py @@ -16,7 +16,11 @@ def __call_pthread_self() -> int: if pwndbg.dbg.selected_inferior().symbol_address_from_name("pthread_self") is None: return 0 try: - return int(pwndbg.dbg.selected_frame().evaluate_expression("(void *)pthread_self()")) + return int( + pwndbg.dbg.selected_frame().evaluate_expression( + "(void *)pthread_self()", lock_scheduler=True + ) + ) except pwndbg.dbg_mod.Error: return 0 diff --git a/pwndbg/dbg/__init__.py b/pwndbg/dbg/__init__.py index e5c79d8bf..2edf2c917 100644 --- a/pwndbg/dbg/__init__.py +++ b/pwndbg/dbg/__init__.py @@ -154,10 +154,17 @@ class Registers: class Frame: - def evaluate_expression(self, expression: str) -> Value: + def evaluate_expression(self, expression: str, lock_scheduler: bool = False) -> Value: """ Evaluate the given expression in the context of this frame, and return a `Value`. + + # `lock_scheduler` + Additionally, callers of this function might specify that they want to + enable scheduler locking during the evaluation of this expression. This + is a GDB-only option, and is intended for cases in which the result + would be incorrect without it enabled, when running in GDB. Other + debuggers should ignore this parameter. """ raise NotImplementedError() diff --git a/pwndbg/dbg/gdb.py b/pwndbg/dbg/gdb.py index 8a9a648d7..eb5fc14a2 100644 --- a/pwndbg/dbg/gdb.py +++ b/pwndbg/dbg/gdb.py @@ -2,6 +2,7 @@ from __future__ import annotations import re import signal +from contextlib import nullcontext from typing import Any from typing import Generator from typing import List @@ -86,10 +87,12 @@ class GDBFrame(pwndbg.dbg_mod.Frame): self.inner = inner @override - def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value: - from pwndbg.gdblib.scheduler import lock_scheduler + def evaluate_expression( + self, expression: str, lock_scheduler: bool = False + ) -> pwndbg.dbg_mod.Value: + from pwndbg.gdblib.scheduler import lock_scheduler as do_lock_scheduler - with lock_scheduler(): + with do_lock_scheduler() if lock_scheduler else nullcontext(): with selection(self.inner, lambda: gdb.selected_frame(), lambda f: f.select()): try: value = parse_and_eval(expression, global_context=False) diff --git a/pwndbg/dbg/lldb/__init__.py b/pwndbg/dbg/lldb/__init__.py index 8836e5fc6..2132149ad 100644 --- a/pwndbg/dbg/lldb/__init__.py +++ b/pwndbg/dbg/lldb/__init__.py @@ -97,7 +97,9 @@ class LLDBFrame(pwndbg.dbg_mod.Frame): self.proc = proc @override - def evaluate_expression(self, expression: str) -> pwndbg.dbg_mod.Value: + def evaluate_expression( + self, expression: str, lock_scheduler: bool = False + ) -> pwndbg.dbg_mod.Value: value = self.inner.EvaluateExpression(expression) opt_out = _is_optimized_out(value)