diff --git a/DEVELOPING.md b/DEVELOPING.md index 20eac671d..2cd085535 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -51,19 +51,6 @@ We have four types of tests: `gdb-tests`,`qemu-tests`, `unit-tests`, and Linux k To run these tests, run [`./tests.sh`](./tests.sh). You can filter the tests to run by providing an argument to the script, such as `./tests.sh heap`, which will only run tests that contain "heap" in the name. You can also drop into the PDB debugger when a test fails with `./tests.sh --pdb`. -Some of the tests rely on output that depends on a certain width/height of the terminal, so you will likely see many test failures when simply running `./tests.sh`. To run the tests in the expected environment, you can use: - -```sh -docker compose run --build -T ubuntu24.04 ./tests.sh -# The `-T` disables the use of a pseudo-TTY -``` - -If you want rapidly iterate on tests (waiting for the container to rebuild and all the test source code files to compile can take a while), you can pipe `cat` on both ends to disable the PTY and get the correct terminal width/height for the tests. - -```sh -cat | ./tests.sh | cat -``` - To invoke cross-architecture tests, use `./qemu-tests.sh`, and to run unit tests, use `./unit-tests.sh` ## Writing Tests diff --git a/pwndbg/dbg/gdb.py b/pwndbg/dbg/gdb.py index 3cc144048..dc74e52e4 100644 --- a/pwndbg/dbg/gdb.py +++ b/pwndbg/dbg/gdb.py @@ -6,6 +6,7 @@ from typing import Any from typing import Generator from typing import List from typing import Literal +from typing import Optional from typing import Sequence from typing import Tuple from typing import TypeVar @@ -1254,38 +1255,22 @@ class GDB(pwndbg.dbg_mod.Debugger): return f"%#{2 * pwndbg.gdblib.arch.ptrsize}x" % address @override - def get_cmd_window_size(self) -> Tuple[int, int]: - """Get the size of the command window in TUI mode which could be different than the terminal window width \ - with horizontal split "tui new-layout hsrc { -horizontal src 1 cmd 1 } 1". + def get_cmd_window_size(self) -> Tuple[Optional[int], Optional[int]]: + """Get the size of the command window. - Possible output of "info win" in TUI mode: - (gdb) info win - Name Lines Columns Focus - src 77 104 (has focus) - cmd 77 105 + GDB keeps these parameters up to date with the actual window size + of the command output. This is the full terminal size in CLI mode + or the size of the cmd window in TUI mode. - Output of "info win" in non-TUI mode: - (gdb) info win - The TUI is not active.""" - try: - info_out = gdb.execute("info win", to_string=True).split() - except gdb.error: - # Return None if the command is not compiled into GDB - # (gdb.error: Undefined info command: "win". Try "help info") - return None, None - if "cmd" not in info_out: - # if TUI is not enabled, info win will output "The TUI is not active." - return None, None - # parse cmd window size from the output of "info win" - cmd_win_index = info_out.index("cmd") - if len(info_out) <= cmd_win_index + 2: - return None, None - elif ( - not info_out[cmd_win_index + 1].isdigit() and not info_out[cmd_win_index + 2].isdigit() - ): - return None, None - else: - return int(info_out[cmd_win_index + 1]), int(info_out[cmd_win_index + 2]) + When the window size is set to be unlimited (0), the parameter + is None. + """ + width = gdb.parameter("width") + height = gdb.parameter("height") + return ( + height if height is None else int(height), + width if width is None else int(width), + ) @override def set_python_diagnostics(self, enabled: bool) -> None: diff --git a/pwndbg/ui.py b/pwndbg/ui.py index b82028dc0..8fdecc0bc 100644 --- a/pwndbg/ui.py +++ b/pwndbg/ui.py @@ -73,6 +73,8 @@ def get_window_size(target=sys.stdin): rows, cols = get_cmd_window_size() if rows is not None and cols is not None: return rows, cols + elif os.environ.get("PWNDBG_IN_TEST") is not None: + return fallback try: # get terminal size and force ret buffer len of 4 bytes for safe unpacking by passing equally long arg rows, cols = struct.unpack("hh", fcntl.ioctl(target.fileno(), termios.TIOCGWINSZ, b"1234")) diff --git a/tests/gdb-tests/conftest.py b/tests/gdb-tests/conftest.py index 341a26538..a946075e8 100644 --- a/tests/gdb-tests/conftest.py +++ b/tests/gdb-tests/conftest.py @@ -4,6 +4,8 @@ This file should consist of global test fixtures. from __future__ import annotations +import os + import gdb import pytest @@ -17,8 +19,11 @@ def start_binary(): """ def _start_binary(path, *args): + os.environ["PWNDBG_IN_TEST"] = "1" gdb.execute("file " + path) gdb.execute("set exception-verbose on") + gdb.execute("set width 80") + os.environ["COLUMNS"] = "80" gdb.execute("starti " + " ".join(args)) global _start_binary_called