Solving issue #2485 (#2495)

* splitting tests passed and skipped variable into two, solving issue #2485

* Fixing bugs in PR #2495

* jemalloc.py: remove unused Arena class (#2492)

* Fixes canary command when no canaries are there (#2496)

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
```

* Fix gdt command: require address argument (#2497)

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`
```

* Add better handling for exceptions originating in execution controllers under LLDB (#2488)

* Fix try_free command: make addr argument required (#2499)

Fixes the following problem:
```
pwndbg> try_free
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'NoneType'
> /root/pwndbg/pwndbg/commands/heap.py(1195)try_free()
   1194 def try_free(addr: str | int) -> None:
-> 1195     addr = int(addr)
   1196
```

* Fix ctxp command (#2498)

* Fix ctxp and ctxn commands

Before this commit the `ctxp` could fail with:
```
Launching pytest with args: ['/root/pwndbg/tests/gdb-tests/tests/test_commands.py::test_commands[ctxp]', '-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[ctxp] Running command ctxp

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
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/context.py", line 363, in contextprev
    longest_history = max(len(h) for h in context_history.values())
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: max() arg is an empty sequence

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/context.py", line 363, in contextprev
    longest_history = max(len(h) for h in context_history.values())
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: max() arg is an empty sequence
XFAIL (flaky test)
```

* fix

---------

Co-authored-by: Disconnect3d <dominik.b.czarnota@gmail.com>
Co-authored-by: Matt. <dark.ryu.550@gmail.com>
pull/2501/head
Aadish Jain 1 year ago committed by GitHub
parent cf9f3185fc
commit f7bb9b59a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -128,19 +128,15 @@ def run_test(
return (result, test_case)
def run_tests_and_print_stats(
tests_list: List[str],
args: argparse.Namespace,
gdb_binary: str,
gdbinit_path: str,
test_dir_path: str,
ports: List[int] = [],
):
start = time.time()
test_results: List[Tuple[CompletedProcess[str], str]] = []
def handle_parallel_test_result(test_result: Tuple[CompletedProcess[str], str]):
test_results.append(test_result)
class TestStats:
def __init__(self):
self.ftests = 0
self.ptests = 0
self.stests = 0
def handle_test_result(
self, test_result: Tuple[CompletedProcess[str], str], args, test_dir_path
):
(process, _) = test_result
content = process.stdout
@ -151,6 +147,13 @@ def run_tests_and_print_stats(
)[0]
(_, testname) = testname.split("::")
if "FAIL" in result:
self.ftests += 1
elif "PASS" in result:
self.ptests += 1
elif "SKIP" in result:
self.stests += 1
print(f"{testname:<70} {result}")
# Only show the output of failed tests unless the verbose flag was used
@ -158,6 +161,19 @@ def run_tests_and_print_stats(
print("")
print(content)
def run_tests_and_print_stats(
tests_list: List[str],
args: argparse.Namespace,
gdb_binary: str,
gdbinit_path: str,
test_dir_path: str,
ports: List[int] = [],
):
start = time.time()
test_results: List[Tuple[CompletedProcess[str], str]] = []
stats = TestStats()
port_iterator = iter(ports)
if args.serial:
@ -172,22 +188,26 @@ def run_tests_and_print_stats(
for test in tests_list:
executor.submit(
run_test, test, args, gdb_binary, gdbinit_path, next(port_iterator, None)
).add_done_callback(lambda future: handle_parallel_test_result(future.result()))
).add_done_callback(
lambda future: stats.handle_test_result(future.result(), args, test_dir_path)
)
end = time.time()
seconds = int(end - start)
print(f"Tests completed in {seconds} seconds")
failed_tests = [(process, _) for (process, _) in test_results if process.returncode != 0]
num_tests_failed = len(failed_tests)
num_tests_passed_or_skipped = len(tests_list) - num_tests_failed
num_tests_failed = stats.ftests
num_tests_passed = stats.ptests
num_tests_skipped = stats.stests
print("")
print("*********************************")
print("********* TESTS SUMMARY *********")
print("*********************************")
print(f"Tests passed or skipped: {num_tests_passed_or_skipped}")
print(f"Tests failed: {num_tests_failed}")
print(f"Tests Passed: {num_tests_passed}")
print(f"Tests Skipped: {num_tests_skipped}")
print(f"Tests Failed: {num_tests_failed}")
if num_tests_failed != 0:
print("")
@ -261,13 +281,8 @@ if __name__ == "__main__":
gdb_binary = "gdb-multiarch"
test_dir_path = TEST_FOLDER_NAME[args.type]
tests: List[str] = getTestsList(
tests_list = getTestsList(
args.collect_only, args.test_name_filter, gdb_binary, gdbinit_path, test_dir_path
)
ports = []
if args.type == "cross-arch":
ports = open_ports(len(tests))
run_tests_and_print_stats(tests, args, gdb_binary, gdbinit_path, test_dir_path, ports)
ports = open_ports(len(tests_list))
run_tests_and_print_stats(tests_list, args, gdb_binary, gdbinit_path, test_dir_path, ports)

Loading…
Cancel
Save