[gdb/testsuite] Add gdb.python/py-commands-breakpoint.exp

Message ID 20241213102157.14172-1-tdevries@suse.de
State Committed
Headers
Series [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

Tom de Vries Dec. 13, 2024, 10:21 a.m. UTC
  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

Tom de Vries Jan. 4, 2025, 11:11 a.m. UTC | #1
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
  

Patch

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