From df405cd61df7c9edf776f8c30cb18e6cbc717a09 Mon Sep 17 00:00:00 2001 From: Serapheim Dimitropoulos Date: Wed, 3 Feb 2021 13:56:57 -0800 Subject: [PATCH] Fix regressions introduced by drgn's updated type equality drgn recently dropped all semantics of == for drgn.Type objects in the following commit as there are multiple reasonable ways to define type equality depending on the use case: https://github.com/osandov/drgn/commit/7d7aa7bf7b070a3270bb99cae7827bb20e37629f We already have our own definition within SDB were we pretty much match types by name [see comment sdb.target.type_equals()]. This commit updates leftover instances of == for types within SDB. --- sdb/pipeline.py | 3 ++- sdb/target.py | 2 +- tests/unit/__init__.py | 2 +- tests/unit/commands/test_address.py | 20 ++++++++-------- tests/unit/commands/test_cast.py | 10 ++++---- tests/unit/commands/test_echo.py | 36 ++++++++++++++--------------- tests/unit/commands/test_filter.py | 4 ++-- 7 files changed, 39 insertions(+), 38 deletions(-) diff --git a/sdb/pipeline.py b/sdb/pipeline.py index 6ccba8e4..35b39fe9 100644 --- a/sdb/pipeline.py +++ b/sdb/pipeline.py @@ -59,7 +59,8 @@ def massage_input_and_call( return # If we are passed a foo_t when we expect a foo_t*, use its address. - if target.get_pointer_type(first_obj_type) == expected_type: + if target.type_equals(target.get_pointer_type(first_obj_type), + expected_type): yield from execute_pipeline(objs, [Address(), cmd]) return diff --git a/sdb/target.py b/sdb/target.py index b20cc13e..64db9b39 100644 --- a/sdb/target.py +++ b/sdb/target.py @@ -150,7 +150,7 @@ def type_equals(a: drgn.Type, b: drgn.Type) -> bool: same because we usually just need to know, "is this a foo_t*", without regard for which source .c file defined the foo_t. - Note that the drgn type equality operator (==) attempts to evalue deep + Note that the drgn type equality operator (==) attempts to evaluate deep type equality and therefore doesn't complete in a reasonable amount of time. "Deep type equality" means that two "struct foo"s that each contain a "struct bar *member" are not necessarily equal, because we must recursively diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index e0a7d153..ac05c52e 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -44,7 +44,7 @@ def create_struct_type(prog: drgn.Program, name: str, member_names: List[str], struct_size, bit_offset = 0, 0 member_list = [] for member_name, type_ in zip(member_names, member_types): - member_type = drgn.TypeMember(type_, member_name, bit_offset, 0) + member_type = drgn.TypeMember(type_, member_name, bit_offset) member_list.append(member_type) if type_.kind == drgn.TypeKind.ARRAY: bit_offset += 8 * type_.length * type_.type.size diff --git a/tests/unit/commands/test_address.py b/tests/unit/commands/test_address.py index 1e320641..6945a6c0 100644 --- a/tests/unit/commands/test_address.py +++ b/tests/unit/commands/test_address.py @@ -37,7 +37,7 @@ def test_single_object() -> None: assert len(ret) == 1 assert ret[0].value_() == 0xffffffffc0000000 - assert ret[0].type_ == MOCK_PROGRAM.type('int *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('int *')) def test_plain_address() -> None: @@ -47,7 +47,7 @@ def test_plain_address() -> None: assert len(ret) == 1 assert ret[0].value_() == 0xffffffffc084eee0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) def test_multiple_object() -> None: @@ -57,11 +57,11 @@ def test_multiple_object() -> None: assert len(ret) == 3 assert ret[0].value_() == 0xffffffffc0000000 - assert ret[0].type_ == MOCK_PROGRAM.type('int *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('int *')) assert ret[1].value_() == 0xffffffffc084eee0 - assert ret[1].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('void *')) assert ret[2].value_() == 0xffff88d26353c108 - assert ret[2].type_ == MOCK_PROGRAM.type('void **') + assert sdb.type_equals(ret[2].type_, MOCK_PROGRAM.type('void **')) def test_piped_invocations() -> None: @@ -71,11 +71,11 @@ def test_piped_invocations() -> None: assert len(ret) == 3 assert ret[0].value_() == 0xffffffffc0000000 - assert ret[0].type_ == MOCK_PROGRAM.type('int *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('int *')) assert ret[1].value_() == 0xffffffffc084eee0 - assert ret[1].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('void *')) assert ret[2].value_() == 0xffff88d26353c108 - assert ret[2].type_ == MOCK_PROGRAM.type('void **') + assert sdb.type_equals(ret[2].type_, MOCK_PROGRAM.type('void **')) def test_echo_pipe() -> None: @@ -85,9 +85,9 @@ def test_echo_pipe() -> None: assert len(ret) == 2 assert ret[0].value_() == 0xffffffffc084eee0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 0xffff88d26353c108 - assert ret[1].type_ == MOCK_PROGRAM.type('void **') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('void **')) def test_global_not_found() -> None: diff --git a/tests/unit/commands/test_cast.py b/tests/unit/commands/test_cast.py index 2ed43b14..e943d28a 100644 --- a/tests/unit/commands/test_cast.py +++ b/tests/unit/commands/test_cast.py @@ -53,7 +53,7 @@ def test_invoke_pipe_input() -> None: ret = invoke(MOCK_PROGRAM, objs, line) assert len(ret) == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[0].value_() == 0x01020304 @@ -63,7 +63,7 @@ def test_str_pipe_input() -> None: ret = invoke(MOCK_PROGRAM, [], line) assert len(ret) == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[0].value_() == 0xffffffffc0000000 @@ -73,7 +73,7 @@ def test_pipe_input_pointer_to_int() -> None: ret = invoke(MOCK_PROGRAM, [], line) assert len(ret) == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('unsigned int') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('unsigned int')) assert ret[0].value_() == 0xc0000000 @@ -92,7 +92,7 @@ def test_double_cast() -> None: ret = invoke(MOCK_PROGRAM, [], line) assert len(ret) == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('char *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('char *')) assert ret[0].value_() == 0xc0000000 @@ -102,4 +102,4 @@ def test_pointer_to_struct() -> None: with pytest.raises(sdb.CommandError) as err: invoke(MOCK_PROGRAM, [], line) - assert "cannot convert 'int *' to 'struct test_struct'" in str(err.value) + assert "cannot cast to 'struct test_struct'" in str(err.value) diff --git a/tests/unit/commands/test_echo.py b/tests/unit/commands/test_echo.py index b90a5084..2c3d6dfc 100644 --- a/tests/unit/commands/test_echo.py +++ b/tests/unit/commands/test_echo.py @@ -39,7 +39,7 @@ def test_piped_input() -> None: assert len(ret) == 1 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) def test_single_arg_hex() -> None: @@ -49,7 +49,7 @@ def test_single_arg_hex() -> None: assert len(ret) == 1 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) def test_single_arg_decimal() -> None: @@ -59,7 +59,7 @@ def test_single_arg_decimal() -> None: assert len(ret) == 1 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) def test_bogus_arg() -> None: @@ -79,7 +79,7 @@ def test_test_piped_int() -> None: assert len(ret) == 1 assert ret[0].value_() == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('int') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('int')) def test_single_arg() -> None: @@ -89,7 +89,7 @@ def test_single_arg() -> None: assert len(ret) == 1 assert ret[0].value_() == 1 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) def test_multiple_piped() -> None: @@ -103,9 +103,9 @@ def test_multiple_piped() -> None: assert len(ret) == 2 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 1 - assert ret[1].type_ == MOCK_PROGRAM.type('int') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('int')) def test_multiple_args() -> None: @@ -115,9 +115,9 @@ def test_multiple_args() -> None: assert len(ret) == 2 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 1 - assert ret[1].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('void *')) def test_piped_and_args_combo() -> None: @@ -131,13 +131,13 @@ def test_piped_and_args_combo() -> None: assert len(ret) == 4 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 1 - assert ret[1].type_ == MOCK_PROGRAM.type('int') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('int')) assert ret[2].value_() == 0 - assert ret[2].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[2].type_, MOCK_PROGRAM.type('void *')) assert ret[3].value_() == 1 - assert ret[3].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[3].type_, MOCK_PROGRAM.type('void *')) def test_multi_echo_combo() -> None: @@ -151,12 +151,12 @@ def test_multi_echo_combo() -> None: assert len(ret) == 5 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 1 - assert ret[1].type_ == MOCK_PROGRAM.type('int') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('int')) assert ret[2].value_() == 2 - assert ret[2].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[2].type_, MOCK_PROGRAM.type('void *')) assert ret[3].value_() == 3 - assert ret[3].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[3].type_, MOCK_PROGRAM.type('void *')) assert ret[4].value_() == 4 - assert ret[4].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[4].type_, MOCK_PROGRAM.type('void *')) diff --git a/tests/unit/commands/test_filter.py b/tests/unit/commands/test_filter.py index 86ec86be..2de128cd 100644 --- a/tests/unit/commands/test_filter.py +++ b/tests/unit/commands/test_filter.py @@ -85,9 +85,9 @@ def test_multi_void_ptr_input_value_match_ne() -> None: assert len(ret) == 2 assert ret[0].value_() == 0 - assert ret[0].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[0].type_, MOCK_PROGRAM.type('void *')) assert ret[1].value_() == 2 - assert ret[1].type_ == MOCK_PROGRAM.type('void *') + assert sdb.type_equals(ret[1].type_, MOCK_PROGRAM.type('void *')) def test_char_array_input_object_match() -> None: