Before this commit, the `gdt` command incorrectly did not require the `address` argument, while it was required.
Because of that, the command crashed like this:
```
pwndbg> gdt
'gdt': Decode X86-64 GDT entries at address
See also:
* https://wiki.osdev.org/Global_Descriptor_Table
* https://wiki.osdev.org/GDT_Tutorial
Note:
In 64-bit mode, the Base and Limit values are ignored, each descriptor covers the entire linear address space regardless of what they are set to.
Exception occurred: gdt: int() argument must be a string, a bytes-like object or a real number, not 'NoneType' (<class 'TypeError'>)
For more info invoke `set exception-verbose on` and rerun the command
or debug it by yourself with `set exception-debugger on`
```
Fixes the following bug uncovered by our test_commands[canary] test suite:
```
(.venv) root@pwndbg:~/pwndbg# RUN_FLAKY=1 ./tests.sh 'test_commands' --pdb
Will run tests in serial and with Python debugger
ZIGPATH set to /root/pwndbg/.zig
make: Nothing to be done for 'all'.
pwndbg: loaded 173 pwndbg commands and 47 shell commands. Type pwndbg [--shell | --all] [filter] for a list.
pwndbg: created $rebase, $base, $bn_sym, $bn_var, $bn_eval, $ida GDB functions (can be used with print/break)
Launching pytest with args: ['/root/pwndbg/tests/gdb-tests/tests/test_commands.py::test_commands[canary]', '-vvv', '-s', '--showlocals', '--color=yes', '--pdb']
======================================================================== test session starts ========================================================================
platform linux -- Python 3.11.6, pytest-8.0.2, pluggy-1.5.0 -- /usr/bin/python
cachedir: .pytest_cache
rootdir: /root/pwndbg/tests
plugins: cov-4.1.0
collected 1 item
gdb-tests/tests/test_commands.py::test_commands[canary] Running command canary
This GDB supports auto-downloading debuginfo from the following URLs:
<https://debuginfod.ubuntu.com>
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
Program stopped.
0x00007ffff7fe4b40 in _start () from /lib64/ld-linux-x86-64.so.2
AT_RANDOM = 0x7fffffffe3d9 # points to (not masked) global canary value
Canary = 0x37492280ae2b3000 (may be incorrect on != glibc)
No canaries found.
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/__init__.py", line 378, in _OnlyWhenRunning
return function(*a, **kw)
^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/canary.py", line 91, in canary
if some_canaries_not_shown is True:
^^^^^^^^^^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'some_canaries_not_shown' where it is not associated with a value
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/root/pwndbg/pwndbg/dbg/gdb.py", line 871, in invoke
self.handler(self.debugger, args, from_tty)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 105, in _handler
self.invoke(arguments, is_interactive)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 153, in invoke
self(*args, **kwargs)
File "/root/pwndbg/pwndbg/commands/__init__.py", line 192, in __call__
pwndbg.exception.handle(self.function.__name__)
File "/root/pwndbg/pwndbg/exception.py", line 106, in handle
raise e
File "/root/pwndbg/pwndbg/commands/__init__.py", line 187, in __call__
return self.function(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/__init__.py", line 378, in _OnlyWhenRunning
return function(*a, **kw)
^^^^^^^^^^^^^^^^^^
File "/root/pwndbg/pwndbg/commands/canary.py", line 91, in canary
if some_canaries_not_shown is True:
^^^^^^^^^^^^^^^^^^^^^^^
UnboundLocalError: cannot access local variable 'some_canaries_not_shown' where it is not associated with a value
```
* Don't ignore set safe-linking settings
The previous code was testing the existance of the safe_lnk option
object, which always exists, and therefore was ignoring the actual
value of the option. Change the test to safe_lnk.value.
* Update pwndbg/glibc.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
GDB wraps stdout and doesn't proxy some functions through to the underlying TextIOWrapper. This causes pwnlib to error out when trying to detect terminal support.
By monkey patching the functions back onto the _GdbOutputFile object, we can use `pwnlib.term.text.red("hi")` to print colored text.
* Fix ansi color truncation in TUI windows
All remaining ansi escape codes after the substring of real characters weren't printed.
This caused some colors to linger over to the next line.
* Add two default TUI layouts
One including the sourcecode section and one without.
The allows to try the TUI quickly by selecting one of the layouts: `layout pwndbg` or `layout pwndbg_code`.
* Don't use \t tabs in context threads section
Horizontal scroll in TUI mode would jump around causing visual glitches. Use spaces instead.
* Add warning when section is in TUI layout but not in 'context-sections'
The section won't be updated automatically on stop.
* Update FEATURES docs including screenshot
* Don't create TUI windows when GDB is compiled without it
Don't stop pwndbg from loading on gdb without tui integration.
* Fix redraw of all windows after toggling TUI mode
When switching back to TUI mode, the contextoutput would be sent before a TUI window's `render` function was called. This caused some sections to be printed normally in the cmd window instead of being sent to their TUI window.
Keep a list of all open context TUI windows and redirect contextoutput for all of them once the first window is rerendered instead of waiting for them to be rendered too.
Also fix the _static_enabled class variable usage.
gdb doesn't allow debugging itself:
```
attachp some-nonexistent-process-name
Attaching to 361478
Error: I refuse to debug myself!
```
This fixes the test_attachp_command_nonexistent_procname test for me.
* 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
* Add history of context output
Every context section is cached individually to allow to display older output again. You can scroll through the old context output using `contextprev` and `contextnext`.
This allows to "scroll" in TUI mode.
* Add button TUI window to control context history
* Simplify history status output generation
termios.tcgetwinsize and termios.tcsetwinsize were added in Python 3.11, which caused undefined-attr typing errors when linting on python 3.10.
mypy doesn't support the Python version indirection of a global constant, so move the condition into the if statement.
The __doc__ is read in the gdb.Function constructor, so copy it from the function to the class in the decorator before calling the parent constructor.
`apropos` displays the first line of the docstring only, so move it up in the `bn_*` commands.
* Fix attachp tests when ptrace_scope is missing
Assume we can attach to any process when ptrace_scope is not available. This is the case in WSL2.
* Update tests/gdb-tests/tests/test_attachp.py
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
* Remove SIGWINCH signal handler
gdb updates `height` and `width` automatically since 2015,
so this code seems to be obsolete.
Installing our own signal handler replaced gdb's one and prevented it from reacting to SIGWINCH signals.
* Add context sections TUI windows
This adds `pwndbg_[section]` tui windows to be used in a layout.
You can arrange `pwndbg_regs` or `pwndbg_disasm` as you wish.
The horizontal scrolling and truncation has to consider ANSI escape codes and makes sure to include all of them while scrolling through to properly keep the colors.
Since there is no event fired when TUI mode is enabled/disabled, we have to check `.is_valid()` whenever context data is available or the TUI is rendered to redirect context output appropriately again.
* Make last-signal context section selectable
There exists a context section to display the reason for the last stop, but it wasn't registered anywhere.
Add it to the list of available sections to choose from.
* Fix default context sections "heap-tracker"
The section name is derived from the function name.
The function is called `context_heap_tracker` so `heap-tracker` wouldn't work:
```
pwndbg> set context-sections heap-tracker
Invalid section: heap-tracker, valid values: args, regs, disasm, stack, backtrace, code, expressions, ghidra, heap_tracker, threads
```
The validator doesn't appear to run for the default value :D
* Update help text to include all available context sections
* gdblib & aglib proc now returns executed filename
+ executed filename received through "info proc exe"
+ previous the local filename was returned, which could be different from remote
+ this also fixes#2430
+ fixed softlock if `set integration-provider binja`
* Update pwndbg/aglib/proc.py
* Update pwndbg/gdblib/proc.py
* Update pwndbg/gdblib/proc.py
* fixed binja integration issues
+ ensure current process is alive, for needed events
+ handle ConnectionErrors correctly
* fixed binja integration issues
+ ensure current process is alive, for needed events
+ handle ConnectionErrors correctly
---------
Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>