mirror of https://github.com/pwndbg/pwndbg
Fix terminal width to 80 columns in tests (#2444)
* Fix terminal width to 80 columns in tests Set a `PWNDBG_IN_TEST`environment variable when running gdb in tests. Use the dimensions in `LINES` and `COLUMNS` when looking up the window size when that envvar is set. This makes context output always be 80 columns wide which allows to compare to hardcoded output. * Use `width` and `height` parameters for cmd window size They are updated to the correct values when switching between tui and cli mode. So it's unnecessary to parse `info win`. * Remove workarounds for terminal size in DEVELOPING * Don't bother updating the env of the debuggee
This commit is contained in:
parent
5553a93a3e
commit
6892a09c5a
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue