mirror of https://github.com/pwndbg/pwndbg.git
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
3.6 KiB
Python
101 lines
3.6 KiB
Python
from __future__ import annotations
|
|
|
|
import gdb
|
|
import pytest
|
|
|
|
import pwndbg.gdblib.config
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"params",
|
|
(
|
|
("int", 123, "123", {}),
|
|
("bool", True, "on", {}),
|
|
("bool", False, "off", {}),
|
|
("string", "some-string-val", "some-string-val", {}),
|
|
("auto-bool", None, "auto", {"param_class": gdb.PARAM_AUTO_BOOLEAN}),
|
|
("unlimited-uint", 0, "unlimited", {"param_class": gdb.PARAM_UINTEGER}),
|
|
("unlimited-int", 0, "unlimited", {"param_class": gdb.PARAM_INTEGER}),
|
|
(
|
|
"enum",
|
|
"enum1",
|
|
"enum1",
|
|
{"param_class": gdb.PARAM_ENUM, "enum_sequence": ["enum1", "enum2", "enum3"]},
|
|
),
|
|
# Note: GDB < 9 does not support PARAM_ZUINTEGER*, so we implement it by ourselves for consistency
|
|
(
|
|
"zuint",
|
|
0,
|
|
"0",
|
|
{
|
|
"param_class": (
|
|
gdb.PARAM_ZUINTEGER if hasattr(gdb, "PARAM_ZUINTEGER") else "PARAM_ZUINTEGER"
|
|
)
|
|
},
|
|
),
|
|
(
|
|
"unlimited-zuint",
|
|
-1,
|
|
"unlimited",
|
|
{
|
|
"param_class": (
|
|
gdb.PARAM_ZUINTEGER_UNLIMITED
|
|
if hasattr(gdb, "PARAM_ZUINTEGER_UNLIMITED")
|
|
else "PARAM_ZUINTEGER_UNLIMITED"
|
|
)
|
|
},
|
|
),
|
|
),
|
|
)
|
|
def test_gdb_parameter_default_value_works(start_binary, params):
|
|
if not params:
|
|
pytest.skip("Current GDB version does not support this testcase")
|
|
|
|
name_suffix, default_value, displayed_value, optional_kwargs = params
|
|
|
|
param_name = f"test-param-{name_suffix}"
|
|
help_docstring = f"Help docstring for {param_name}"
|
|
|
|
set_show_doc = "the value of the foo"
|
|
|
|
param = pwndbg.gdblib.config.add_param(
|
|
param_name,
|
|
default_value,
|
|
set_show_doc,
|
|
help_docstring=help_docstring,
|
|
**optional_kwargs,
|
|
)
|
|
|
|
# Initialize and register param in GDB as if it would be done by gdblib.config.init_params
|
|
pwndbg.gdblib.config_mod.Parameter(param)
|
|
|
|
out = gdb.execute(f"show {param_name}", to_string=True)
|
|
assert (
|
|
out
|
|
== f"{set_show_doc.capitalize()} is {displayed_value!r}. See `help set {param_name}` for more information.\n"
|
|
)
|
|
if (
|
|
optional_kwargs.get("param_class") in (gdb.PARAM_UINTEGER, gdb.PARAM_INTEGER)
|
|
and default_value == 0
|
|
):
|
|
# Note: This is really weird, according to GDB docs, 0 should mean "unlimited" for gdb.PARAM_UINTEGER and gdb.PARAM_INTEGER, but somehow GDB sets the value to `None` actually :/
|
|
# And hilarious thing is that GDB won't let you set the default value to `None` when you construct the `gdb.Parameter` object with `gdb.PARAM_UINTEGER` or `gdb.PARAM_INTEGER` lol
|
|
# Maybe it's a bug of GDB?
|
|
# Anyway, to avoid some unexpected behaviors, we still set pwndbg's Parameter object's value to 0 in `get_set_string()` and `__init__()`
|
|
assert gdb.parameter(param_name) is None
|
|
else:
|
|
assert gdb.parameter(param_name) == default_value
|
|
assert param.value == default_value
|
|
|
|
out = gdb.execute(f"help show {param_name}", to_string=True)
|
|
assert out == f"Show {set_show_doc}.\n{help_docstring}\n"
|
|
assert (
|
|
gdb.execute(f"help set {param_name}", to_string=True)
|
|
== f"Set {set_show_doc}.\n{help_docstring}\n"
|
|
)
|
|
|
|
# TODO/FIXME: Is there a way to unregister a GDB parameter defined in Python?
|
|
# Probably no? If the fact that we register params above ever causes issues,
|
|
# then we should just not test it via gdb.* APIs and only check if the added param
|
|
# has proper/expected fields set?
|