[gdb/testsuite] Add gdb.python/py-commands-breakpoint.exp
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
Commit Message
A recent discussion about what commands are allowed during
gdb.Breakpoint.stop, made me wonder if there would be less restrictions if
we'd do those commands as part of a breakpoint command list instead.
Attribute gdb.Breakpoint.commands is a string with gdb commands, so I
tried implementing a new class PyCommandsBreakpoint, derived from
gdb.Breakpoint, that supports a py_commands method.
My original idea was to forbid setting PyCommandsBreakpoint.commands, and do:
...
def py_commands(self):
print("VAR: %d" % self.var)
self.var += 1
gdb.execute("continue")
...
but as it turns out 'gdb.execute("continue")' does not behave the same way as
continue. I've filed PR python/32454 about this.
So the unsatisfactory solution is to first execute
PyCommandsBreakpoint.py_commands:
...
def py_commands(self):
print("VAR: %d" % self.var)
self.var += 1
...
and then:
...
self.commands = "continue"
...
I was hoping for a better outcome, but having done the work of writing this, I
suppose it has use as a test-case, perhaps also as an example of how to work
around PR python/32454.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32454
---
.../gdb.python/py-commands-breakpoint.c | 31 ++++++++++
.../gdb.python/py-commands-breakpoint.exp | 45 ++++++++++++++
.../gdb.python/py-commands-breakpoint.py | 59 +++++++++++++++++++
3 files changed, 135 insertions(+)
create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.c
create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.exp
create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.py
base-commit: 251abe2e696c2f8cb18791330d3fb917b5e0acbd
Comments
On 12/13/24 11:21, Tom de Vries wrote:
> A recent discussion about what commands are allowed during
> gdb.Breakpoint.stop, made me wonder if there would be less restrictions if
> we'd do those commands as part of a breakpoint command list instead.
>
> Attribute gdb.Breakpoint.commands is a string with gdb commands, so I
> tried implementing a new class PyCommandsBreakpoint, derived from
> gdb.Breakpoint, that supports a py_commands method.
>
> My original idea was to forbid setting PyCommandsBreakpoint.commands, and do:
> ...
> def py_commands(self):
> print("VAR: %d" % self.var)
> self.var += 1
> gdb.execute("continue")
> ...
> but as it turns out 'gdb.execute("continue")' does not behave the same way as
> continue. I've filed PR python/32454 about this.
>
> So the unsatisfactory solution is to first execute
> PyCommandsBreakpoint.py_commands:
> ...
> def py_commands(self):
> print("VAR: %d" % self.var)
> self.var += 1
> ...
> and then:
> ...
> self.commands = "continue"
> ...
>
> I was hoping for a better outcome, but having done the work of writing this, I
> suppose it has use as a test-case, perhaps also as an example of how to work
> around PR python/32454.
>
I've pushed this.
Thanks,
- Tom
> Tested on x86_64-linux.
>
> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32454
> ---
> .../gdb.python/py-commands-breakpoint.c | 31 ++++++++++
> .../gdb.python/py-commands-breakpoint.exp | 45 ++++++++++++++
> .../gdb.python/py-commands-breakpoint.py | 59 +++++++++++++++++++
> 3 files changed, 135 insertions(+)
> create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.c
> create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.exp
> create mode 100644 gdb/testsuite/gdb.python/py-commands-breakpoint.py
>
> diff --git a/gdb/testsuite/gdb.python/py-commands-breakpoint.c b/gdb/testsuite/gdb.python/py-commands-breakpoint.c
> new file mode 100644
> index 00000000000..5a6d6c7afc7
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-commands-breakpoint.c
> @@ -0,0 +1,31 @@
> +/* This testcase is part of GDB, the GNU debugger.
> +
> + Copyright 2024 Free Software Foundation, Inc.
> +
> + This program is free software; you can redistribute it and/or modify
> + it under the terms of the GNU General Public License as published by
> + the Free Software Foundation; either version 3 of the License, or
> + (at your option) any later version.
> +
> + This program is distributed in the hope that it will be useful,
> + but WITHOUT ANY WARRANTY; without even the implied warranty of
> + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + GNU General Public License for more details.
> +
> + You should have received a copy of the GNU General Public License
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
> +
> +static void
> +test (void)
> +{
> +}
> +
> +int
> +main (void)
> +{
> + test ();
> + test ();
> + test ();
> +
> + return 0;
> +}
> diff --git a/gdb/testsuite/gdb.python/py-commands-breakpoint.exp b/gdb/testsuite/gdb.python/py-commands-breakpoint.exp
> new file mode 100644
> index 00000000000..d8dd08d87c3
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-commands-breakpoint.exp
> @@ -0,0 +1,45 @@
> +# Copyright (C) 2024 Free Software Foundation, Inc.
> +#
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# This file is part of the GDB testsuite.
> +
> +load_lib gdb-python.exp
> +
> +require allow_python_tests
> +
> +standard_testfile .c .py
> +
> +if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
> + return -1
> +}
> +
> +if { ![runto_main] } {
> + return 0
> +}
> +
> +set host_python_file \
> + [gdb_remote_download host $srcdir/$subdir/$srcfile2]
> +
> +gdb_test_no_output "source $host_python_file" \
> + "source python file"
> +
> +gdb_test "python TestBreakpoint()" \
> + "Breakpoint $decimal .*"
> +
> +gdb_test "continue" \
> + [multi_line \
> + "VAR: 1" \
> + "VAR: 2" \
> + "VAR: 3"]
> diff --git a/gdb/testsuite/gdb.python/py-commands-breakpoint.py b/gdb/testsuite/gdb.python/py-commands-breakpoint.py
> new file mode 100644
> index 00000000000..e09a255114c
> --- /dev/null
> +++ b/gdb/testsuite/gdb.python/py-commands-breakpoint.py
> @@ -0,0 +1,59 @@
> +# Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +# This program is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see <http://www.gnu.org/licenses/>.
> +
> +# This file is part of the GDB testsuite.
> +
> +import gdb
> +
> +
> +class PyCommandsBreakpoint(gdb.Breakpoint):
> + bp_dict = dict()
> +
> + def __init__(self, *args, **kwargs):
> + gdb.Breakpoint.__init__(self, *args, **kwargs)
> + PyCommandsBreakpoint.bp_dict[self.number] = self
> + self.commands = ""
> +
> + @staticmethod
> + def run_py_commands(num):
> + bp = PyCommandsBreakpoint.bp_dict[num]
> + if hasattr(bp, "py_commands"):
> + bp.py_commands()
> +
> + def __setattr__(self, name, value):
> + if name == "commands":
> + l = ["python PyCommandsBreakpoint.run_py_commands(%d)" % self.number]
> + if value != "":
> + l.append(value)
> + value = "\n".join(l)
> +
> + super().__setattr__(name, value)
> +
> +
> +class TestBreakpoint(PyCommandsBreakpoint):
> + def __init__(self):
> + PyCommandsBreakpoint.__init__(self, spec="test")
> + self.var = 1
> + self.commands = "continue"
> + self.silent = True
> +
> + def stop(self):
> + if self.var == 3:
> + self.commands = ""
> + return True
> +
> + def py_commands(self):
> + print("VAR: %d" % self.var)
> + self.var += 1
>
> base-commit: 251abe2e696c2f8cb18791330d3fb917b5e0acbd
new file mode 100644
@@ -0,0 +1,31 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+ Copyright 2024 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+static void
+test (void)
+{
+}
+
+int
+main (void)
+{
+ test ();
+ test ();
+ test ();
+
+ return 0;
+}
new file mode 100644
@@ -0,0 +1,45 @@
+# Copyright (C) 2024 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.
+
+load_lib gdb-python.exp
+
+require allow_python_tests
+
+standard_testfile .c .py
+
+if { [prepare_for_testing "failed to prepare" $testfile $srcfile] } {
+ return -1
+}
+
+if { ![runto_main] } {
+ return 0
+}
+
+set host_python_file \
+ [gdb_remote_download host $srcdir/$subdir/$srcfile2]
+
+gdb_test_no_output "source $host_python_file" \
+ "source python file"
+
+gdb_test "python TestBreakpoint()" \
+ "Breakpoint $decimal .*"
+
+gdb_test "continue" \
+ [multi_line \
+ "VAR: 1" \
+ "VAR: 2" \
+ "VAR: 3"]
new file mode 100644
@@ -0,0 +1,59 @@
+# Copyright (C) 2024 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.
+
+import gdb
+
+
+class PyCommandsBreakpoint(gdb.Breakpoint):
+ bp_dict = dict()
+
+ def __init__(self, *args, **kwargs):
+ gdb.Breakpoint.__init__(self, *args, **kwargs)
+ PyCommandsBreakpoint.bp_dict[self.number] = self
+ self.commands = ""
+
+ @staticmethod
+ def run_py_commands(num):
+ bp = PyCommandsBreakpoint.bp_dict[num]
+ if hasattr(bp, "py_commands"):
+ bp.py_commands()
+
+ def __setattr__(self, name, value):
+ if name == "commands":
+ l = ["python PyCommandsBreakpoint.run_py_commands(%d)" % self.number]
+ if value != "":
+ l.append(value)
+ value = "\n".join(l)
+
+ super().__setattr__(name, value)
+
+
+class TestBreakpoint(PyCommandsBreakpoint):
+ def __init__(self):
+ PyCommandsBreakpoint.__init__(self, spec="test")
+ self.var = 1
+ self.commands = "continue"
+ self.silent = True
+
+ def stop(self):
+ if self.var == 3:
+ self.commands = ""
+ return True
+
+ def py_commands(self):
+ print("VAR: %d" % self.var)
+ self.var += 1