mirror of https://github.com/pwndbg/pwndbg
fix errno command (#1112)
* fix errno command * fix isort * try to fix CI * Update test_command_errno.py
This commit is contained in:
parent
9755a40d7b
commit
42f32d7cc7
|
@ -339,7 +339,7 @@ class _ArgparsedCommand(Command):
|
|||
class ArgparsedCommand:
|
||||
"""Adds documentation and offloads parsing for a Command via argparse"""
|
||||
|
||||
def __init__(self, parser_or_desc, aliases=[]):
|
||||
def __init__(self, parser_or_desc, aliases=[], command_name=None):
|
||||
"""
|
||||
:param parser_or_desc: `argparse.ArgumentParser` instance or `str`
|
||||
"""
|
||||
|
@ -348,6 +348,8 @@ class ArgparsedCommand:
|
|||
else:
|
||||
self.parser = parser_or_desc
|
||||
self.aliases = aliases
|
||||
self._command_name = command_name
|
||||
|
||||
# We want to run all integer and otherwise-unspecified arguments
|
||||
# through fix() so that GDB parses it.
|
||||
for action in self.parser._actions:
|
||||
|
@ -360,8 +362,8 @@ class ArgparsedCommand:
|
|||
|
||||
def __call__(self, function):
|
||||
for alias in self.aliases:
|
||||
_ArgparsedCommand(self.parser, function, alias)
|
||||
return _ArgparsedCommand(self.parser, function)
|
||||
_ArgparsedCommand(self.parser, function, command_name=alias)
|
||||
return _ArgparsedCommand(self.parser, function, command_name=self._command_name)
|
||||
|
||||
|
||||
# We use a 64-bit max value literal here instead of pwndbg.arch.current
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import argparse
|
||||
import errno as _errno
|
||||
import errno
|
||||
|
||||
import gdb
|
||||
|
||||
import pwndbg as _pwndbg
|
||||
import pwndbg.arch as _arch
|
||||
import pwndbg.auxv
|
||||
import pwndbg.commands
|
||||
import pwndbg.regs
|
||||
import pwndbg.symbol
|
||||
|
||||
_errno.errorcode[0] = "OK"
|
||||
errno.errorcode[0] = "OK"
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="""
|
||||
|
@ -24,24 +24,25 @@ parser.add_argument(
|
|||
)
|
||||
|
||||
|
||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
||||
@pwndbg.commands.ArgparsedCommand(parser, command_name="errno")
|
||||
@pwndbg.commands.OnlyWhenRunning
|
||||
def errno(err):
|
||||
def errno_(err):
|
||||
if err is None:
|
||||
# Dont ask.
|
||||
errno_location = pwndbg.symbol.get("__errno_location")
|
||||
err = pwndbg.memory.int(errno_location)
|
||||
# err = int(gdb.parse_and_eval('*((int *(*) (void)) __errno_location) ()'))
|
||||
# Try to get the `errno` variable value
|
||||
# if it does not exist, get the errno variable from its location
|
||||
try:
|
||||
err = int(gdb.parse_and_eval("errno"))
|
||||
except gdb.error:
|
||||
try:
|
||||
err = int(gdb.parse_and_eval("*((int *(*) (void)) __errno_location) ()"))
|
||||
except gdb.error:
|
||||
print(
|
||||
"Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (was libc.so loaded already?)"
|
||||
)
|
||||
return
|
||||
|
||||
err = abs(int(err))
|
||||
|
||||
if err >> 63:
|
||||
err -= 1 << 64
|
||||
elif err >> 31:
|
||||
err -= 1 << 32
|
||||
|
||||
msg = _errno.errorcode.get(int(err), "Unknown error code")
|
||||
print("Errno %i: %s" % (err, msg))
|
||||
msg = errno.errorcode.get(int(err), "Unknown error code")
|
||||
print("Errno %s: %s" % (err, msg))
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
|
@ -58,8 +59,8 @@ parser.add_argument(
|
|||
)
|
||||
|
||||
|
||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
||||
def pwndbg(filter_pattern):
|
||||
@pwndbg.commands.ArgparsedCommand(parser, command_name="pwndbg")
|
||||
def pwndbg_(filter_pattern):
|
||||
for name, docs in list_and_filter_commands(filter_pattern):
|
||||
print("%-20s %s" % (name, docs))
|
||||
|
||||
|
@ -69,19 +70,19 @@ parser.add_argument("a", type=int, help="The first address.")
|
|||
parser.add_argument("b", type=int, help="The second address.")
|
||||
|
||||
|
||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
||||
@pwndbg.commands.ArgparsedCommand(parser)
|
||||
def distance(a, b):
|
||||
"""Print the distance between the two arguments"""
|
||||
a = int(a) & _arch.ptrmask
|
||||
b = int(b) & _arch.ptrmask
|
||||
a = int(a) & pwndbg.arch.ptrmask
|
||||
b = int(b) & pwndbg.arch.ptrmask
|
||||
|
||||
distance = b - a
|
||||
|
||||
print("%#x->%#x is %#x bytes (%#x words)" % (a, b, distance, distance // _arch.ptrsize))
|
||||
print("%#x->%#x is %#x bytes (%#x words)" % (a, b, distance, distance // pwndbg.arch.ptrsize))
|
||||
|
||||
|
||||
def list_and_filter_commands(filter_str):
|
||||
sorted_commands = list(_pwndbg.commands.commands)
|
||||
sorted_commands = list(pwndbg.commands.commands)
|
||||
sorted_commands.sort(key=lambda x: x.__name__)
|
||||
|
||||
if filter_str:
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
import gdb
|
||||
|
||||
import pwndbg
|
||||
import pwndbg.memory
|
||||
import pwndbg.regs
|
||||
import tests
|
||||
|
||||
# We use the heap_vis binary as it enforces pthreads and so will have TLS on all distros
|
||||
REFERENCE_BINARY = tests.binaries.get("heap_vis.out")
|
||||
|
||||
|
||||
def test_command_errno(start_binary):
|
||||
"""
|
||||
Tests the errno command display
|
||||
"""
|
||||
start_binary(REFERENCE_BINARY)
|
||||
|
||||
# Since start_binary does 'starti' which stops on the very first instruction
|
||||
# the errno is not yet an available symbol, because the libc library it is
|
||||
# defined in is not yet loaded
|
||||
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?)"
|
||||
)
|
||||
|
||||
gdb.execute("break main")
|
||||
gdb.execute("continue")
|
||||
|
||||
result = gdb.execute("errno", to_string=True)
|
||||
assert result == "Errno 0: OK\n"
|
||||
|
||||
gdb.execute("set *(int*)&errno=11")
|
||||
result = gdb.execute("errno", to_string=True)
|
||||
assert result == "Errno 11: EAGAIN\n"
|
||||
|
||||
gdb.execute("set *(int*)&errno=111")
|
||||
result = gdb.execute("errno", to_string=True)
|
||||
assert result == "Errno 111: ECONNREFUSED\n"
|
||||
|
||||
result = gdb.execute("errno 8", to_string=True)
|
||||
assert result == "Errno 8: ENOEXEC\n"
|
||||
|
||||
result = gdb.execute("errno 123", to_string=True)
|
||||
assert result == "Errno 123: ENOMEDIUM\n"
|
||||
|
||||
result = gdb.execute("errno 250", to_string=True)
|
||||
assert result == "Errno 250: Unknown error code\n"
|
Loading…
Reference in New Issue