| 1 | """Test GDB's follow-fork-mode child. |
| 2 | |
| 3 | SPDX-License-Identifier: GPL-2.0-or-later |
| 4 | """ |
| 5 | from test_gdbstub import main, report |
| 6 | |
| 7 | |
| 8 | def run_test(): |
| 9 | """Run through the tests one by one""" |
| 10 | gdb.execute("set follow-fork-mode child") |
| 11 | # Check that the parent breakpoints are unset. |
| 12 | gdb.execute("break break_after_fork") |
| 13 | # Check that the parent syscall catchpoints are unset. |
| 14 | # Skip this check on the architectures that don't have them. |
| 15 | have_fork_syscall = False |
| 16 | for fork_syscall in ("fork", "clone", "clone2", "clone3"): |
| 17 | try: |
| 18 | gdb.execute("catch syscall {}".format(fork_syscall)) |
| 19 | except gdb.error: |
| 20 | pass |
| 21 | else: |
| 22 | have_fork_syscall = True |
| 23 | gdb.execute("continue") |
| 24 | for i in range(42): |
| 25 | if have_fork_syscall: |
| 26 | # syscall entry. |
| 27 | if i % 2 == 0: |
| 28 | # Check that the parent single-stepping is turned off. |
| 29 | gdb.execute("si") |
| 30 | else: |
| 31 | gdb.execute("continue") |
| 32 | # syscall exit. |
| 33 | gdb.execute("continue") |
| 34 | # break_after_fork() |
| 35 | gdb.execute("continue") |
| 36 | exitcode = int(gdb.parse_and_eval("$_exitcode")) |
| 37 | report(exitcode == 42, "{} == 42".format(exitcode)) |
| 38 | |
| 39 | |
| 40 | main(run_test) |