diff --git a/lint.sh b/lint.sh index 0840d6251..f1ce9f2b5 100755 --- a/lint.sh +++ b/lint.sh @@ -8,4 +8,4 @@ black --diff --check pwndbg tests flake8 --show-source pwndbg tests # Indents are four spaces, binary ops can start a line, and indent switch cases -shfmt -i 4 -bn -ci -d . \ No newline at end of file +shfmt -i 4 -bn -ci -d . diff --git a/pwndbg/commands/misc.py b/pwndbg/commands/misc.py index 5223202d3..9935c0dab 100644 --- a/pwndbg/commands/misc.py +++ b/pwndbg/commands/misc.py @@ -35,10 +35,24 @@ def errno_(err): err = int(gdb.parse_and_eval("errno")) except gdb.error: try: - err = int(gdb.parse_and_eval("*((int *(*) (void)) __errno_location) ()")) + # We can't simply call __errno_location because its .plt.got entry may be uninitialized + # (e.g. if the binary was just started with `starti` command) + # So we have to check the got.plt entry first before calling it + errno_loc_gotplt = pwndbg.symbol.address("__errno_location@got.plt") + + # If the got.plt entry is not there (is None), it means the symbol is not used by the binary + if errno_loc_gotplt is None or pwndbg.vmmap.find( + pwndbg.memory.pvoid(errno_loc_gotplt) + ): + err = int(gdb.parse_and_eval("*((int *(*) (void)) __errno_location) ()")) + else: + print( + "Could not determine error code automatically: the __errno_location@got.plt has no valid address yet (perhaps libc.so hasn't been loaded yet?)" + ) + return except gdb.error: print( - "Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (was libc.so loaded already?)" + "Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (perhaps libc.so hasn't been not loaded yet?)" ) return diff --git a/pwndbg/lib/tips.py b/pwndbg/lib/tips.py index 8b9a4c80a..c235e7f92 100644 --- a/pwndbg/lib/tips.py +++ b/pwndbg/lib/tips.py @@ -21,6 +21,7 @@ TIPS = [ "Use the `procinfo` command for better process introspection (than the GDB's `info proc` command)", "Want to display each context panel in a separate tmux window? See https://github.com/pwndbg/pwndbg/blob/dev/FEATURES.md#splitting--layouting-context", "The $heap_base GDB variable can be used to refer to the starting address of the heap after running the `heap` command", + "Use the `errno` (or `errno `) command to see the name of the last or provided (libc) error", ] diff --git a/tests/test_command_errno.py b/tests/test_command_errno.py index 83da35042..00a3247a2 100644 --- a/tests/test_command_errno.py +++ b/tests/test_command_errno.py @@ -21,7 +21,7 @@ def test_command_errno(start_binary): result = "".join(gdb.execute("errno", to_string=True).splitlines()) assert ( result - == "Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (was libc.so loaded already?)" + == "Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (perhaps libc.so hasn't been not loaded yet?)" ) gdb.execute("break main")