Sync gdbtest.py with latest upstream

Signed-off-by: Cleber Rosa <crosa@redhat.com>
This commit is contained in:
Cleber Rosa 2022-05-24 17:22:36 -04:00
commit 75651003a5
No known key found for this signature in database
GPG key ID: 657E8D33A5F209F3

View file

@ -1,14 +1,7 @@
#!/usr/bin/env python
import os
from six.moves import xrange as range
from avocado import Test
from avocado import main
from avocado.utils import gdb
from avocado.utils import genio
from avocado.utils import process
from avocado.utils import gdb, genio, process
class GdbTest(Test):
@ -32,17 +25,22 @@ class GdbTest(Test):
"-auto-debug-it"]
def setUp(self):
return99_source_path = os.path.join(self.datadir, 'return99.c')
segfault_source_path = os.path.join(self.datadir, 'segfault.c')
self.return99_binary_path = os.path.join(self.outputdir, 'return99')
process.system('gcc -O0 -g %s -o %s' % (return99_source_path,
self.return99_binary_path))
self.segfault_binary_path = os.path.join(self.outputdir, 'segfault')
process.system('gcc -O0 -g %s -o %s' % (segfault_source_path,
self.segfault_binary_path))
self.return99_binary_path = os.path.join(self.teststmpdir, 'return99')
if not os.path.exists(self.return99_binary_path):
return99_source_path = self.get_data('return99.c')
if return99_source_path is None:
self.cancel('Test is missing data file "return99.c"')
process.system(f'gcc -O0 -g {return99_source_path} -o {self.return99_binary_path}')
self.segfault_binary_path = os.path.join(self.teststmpdir, 'segfault')
if not os.path.exists(self.segfault_binary_path):
segfault_source_path = self.get_data('segfault.c')
if segfault_source_path is None:
self.cancel('Test is missing data file "segfault.c"')
process.system(f'gcc -O0 -g {segfault_source_path} -o {self.segfault_binary_path}')
@staticmethod
def is_process_alive(process):
def is_process_alive(process): # pylint: disable=W0621
"""
Checks if a process is still alive
@ -73,14 +71,14 @@ class GdbTest(Test):
g = gdb.GDB()
self.log.info("Testing existing (valid) GDB commands using raw commands")
for cmd in self.VALID_CMDS:
info_cmd = "-info-gdb-mi-command %s" % cmd[1:]
info_cmd = f"-info-gdb-mi-command {cmd[1:]}"
r = g.cmd(info_cmd)
self.assertEqual(r.result.result.command.exists, 'true')
self.log.info("Testing non-existing (invalid) GDB commands using raw "
"commands")
for cmd in self.INVALID_CMDS:
info_cmd = "-info-gdb-mi-command %s" % cmd[1:]
info_cmd = f"-info-gdb-mi-command {cmd[1:]}"
r = g.cmd(info_cmd)
self.assertEqual(r.result.result.command.exists, 'false')
@ -105,7 +103,7 @@ class GdbTest(Test):
self.log.info("Testing that GDB loads a file and sets a breakpoint")
g = gdb.GDB()
file_cmd = "-file-exec-and-symbols %s" % self.return99_binary_path
file_cmd = f"-file-exec-and-symbols {self.return99_binary_path}"
r = g.cmd(file_cmd)
self.assertEqual(r.result.class_, 'done')
@ -145,7 +143,7 @@ class GdbTest(Test):
self.log.info("Testing that a core dump will be generated")
g = gdb.GDB()
file_cmd = "-file-exec-and-symbols %s" % self.segfault_binary_path
file_cmd = f"-file-exec-and-symbols {self.segfault_binary_path}"
r = g.cmd(file_cmd)
self.assertEqual(r.result.class_, 'done')
@ -156,12 +154,12 @@ class GdbTest(Test):
other_messages = g.read_until_break()
core_path = None
for msg in other_messages:
parsed_msg = gdb.parse_mi(msg)
parsed_msg = gdb.parse_mi(msg.decode())
if (hasattr(parsed_msg, 'class_') and
(parsed_msg.class_ == 'stopped') and
(parsed_msg.result.signal_name == 'SIGSEGV')):
core_path = "%s.core" % self.segfault_binary_path
gcore_cmd = 'gcore %s' % core_path
core_path = f"{self.segfault_binary_path}.core"
gcore_cmd = f'gcore {core_path}'
gcore_cmd = gdb.encode_mi_cli(gcore_cmd)
r = g.cmd(gcore_cmd)
self.assertEqual(r.result.class_, 'done')
@ -191,14 +189,14 @@ class GdbTest(Test):
# Do 100 cycle of target (kind of connects) and disconnects
for _ in range(0, 100):
cmd = '-target-select extended-remote :%s' % s.port
cmd = f'-target-select extended-remote :{s.port}'
r = g.cmd(cmd)
self.assertEqual(r.result.class_, 'connected')
r = g.cmd('-target-disconnect')
self.assertEqual(r.result.class_, 'done')
# manual server shutdown
cmd = '-target-select extended-remote :%s' % s.port
cmd = f'-target-select extended-remote :{s.port}'
r = g.cmd(cmd)
self.assertEqual(r.result.class_, 'connected')
r = g.cli_cmd('monitor exit')
@ -234,15 +232,15 @@ class GdbTest(Test):
s = gdb.GDBServer()
g = gdb.GDB()
cmd = '-file-exec-and-symbols %s' % self.return99_binary_path
cmd = f'-file-exec-and-symbols {self.return99_binary_path}'
r = g.cmd(cmd)
self.assertEqual(r.result.class_, 'done')
cmd = 'set remote exec-file %s' % self.return99_binary_path
cmd = f'set remote exec-file {self.return99_binary_path}'
r = g.cmd(cmd)
self.assertEqual(r.result.class_, 'done')
cmd = "-break-insert %s" % 'main'
cmd = f"-break-insert {'main'}"
r = g.cmd(cmd)
self.assertEqual(r.result.class_, 'done')
@ -250,7 +248,7 @@ class GdbTest(Test):
other_messages = g.read_until_break()
for msg in other_messages:
parsed_msg = gdb.parse_mi(msg)
parsed_msg = gdb.parse_mi(msg.decode())
if (hasattr(parsed_msg, 'class_') and
parsed_msg.class_ == 'stopped' and
parsed_msg.result.reason == 'breakpoint-hit'):
@ -278,7 +276,8 @@ class GdbTest(Test):
c1 = gdb.GDB()
c1.connect(s.port)
c2 = gdb.GDB()
self.assertRaises(ValueError, c2.connect, s.port)
with self.assertRaises(gdb.UnexpectedResponseError):
c2.connect(s.port)
s.exit()
def test_server_exit(self):
@ -310,43 +309,6 @@ class GdbTest(Test):
server_instances[i].exit()
self.assertFalse(self.is_process_alive(server_instances[i].process))
def test_interactive(self):
"""
Tests avocado's GDB plugin features
If GDB command line options are given, `--gdb-run-bin=return99` for
this particular test, the test will stop at binary main() function.
"""
self.log.info('Testing GDB interactivity')
process.run(self.return99_binary_path, ignore_status=True)
def test_interactive_args(self):
"""
Tests avocado's GDB plugin features with an executable and args
If GDB command line options are given, `--gdb-run-bin=return99` for
this particular test, the test will stop at binary main() function.
This test uses `process.run()` without an `ignore_status` parameter
"""
self.log.info('Testing GDB interactivity with arguments')
result = process.run("%s 0" % self.return99_binary_path)
self.assertEqual(result.exit_status, 0)
def test_exit_status(self):
"""
Tests avocado's GDB plugin features
If GDB command line options are given, `--gdb-run-bin=return99` for
this particular test, the test will stop at binary main() function.
"""
self.log.info('Testing process exit statuses')
for arg, exp in [(-1, 255), (8, 8)]:
self.log.info('Expecting exit status "%s"', exp)
cmd = "%s %s" % (self.return99_binary_path, arg)
result = process.run(cmd, ignore_status=True)
self.assertEqual(result.exit_status, exp)
def test_server_stderr(self):
self.log.info('Testing server stderr collection')
s = gdb.GDBServer()
@ -354,7 +316,7 @@ class GdbTest(Test):
self.assertTrue(os.path.exists(s.stderr_path))
stderr_lines = genio.read_all_lines(s.stderr_path)
listening_line = "Listening on port %s" % s.port
listening_line = f"Listening on port {s.port}"
self.assertIn(listening_line, stderr_lines)
def test_server_stdout(self):
@ -372,28 +334,14 @@ class GdbTest(Test):
stdout_lines = genio.read_all_lines(s.stdout_path)
self.assertIn("return 99", stdout_lines)
def test_interactive_stdout(self):
"""
Tests avocado's GDB plugin features
If GDB command line options are given, `--gdb-run-bin=return99` for
this particular test, the test will stop at binary main() function.
"""
self.log.info('Testing GDB interactivity')
result = process.run(self.return99_binary_path, ignore_status=True)
self.assertIn("return 99\n", result.stdout)
def test_remote(self):
@staticmethod
def test_remote():
"""
Tests GDBRemote interaction with a GDBServer
"""
s = gdb.GDBServer()
r = gdb.GDBRemote('127.0.0.1', s.port)
r.connect()
r.cmd("qSupported")
r.cmd("qfThreadInfo")
r.cmd(b"qSupported")
r.cmd(b"qfThreadInfo")
s.exit()
if __name__ == '__main__':
main()