[3/3] Add a way to temporarily set a gdb parameter from Python

Message ID 20220105171347.2307106-4-tromey@adacore.com
State New
Headers show
Series
  • Improvements to Python parameters
Related show

Commit Message

Andrew Burgess via Gdb-patches Jan. 5, 2022, 5:13 p.m.
It's sometimes useful to temporarily set some gdb parameter from
Python.  Now that the 'endian' crash is fixed, and now that the
current language is no longer captured by the Python layer, it seems
reasonable to add a helper function for this situation.

This adds a new gdb.set_parameter function.  This creates a context
manager which temporarily sets some parameter to a specified value.
The old value is restored when the context is exited.  This is most
useful with the Python "with" statement:

   with gdb.set_parameter('language', 'ada'):
      ... do Ada stuff

This is PR python/10790.  I think for permanent changes to parameters,
it's fine (IMO anyway) to just rely on gdb.execute, so I plan to close
the PR if this lands.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=10790
---
 gdb/NEWS                                    |  4 ++++
 gdb/doc/python.texi                         | 19 +++++++++++++++++++
 gdb/python/lib/gdb/__init__.py              | 12 ++++++++++++
 gdb/testsuite/gdb.python/py-lookup-type.exp | 12 ++++++++++++
 4 files changed, 47 insertions(+)

-- 
2.31.1

Comments

Andrew Burgess via Gdb-patches Jan. 10, 2022, 3:59 p.m. | #1
* Tom Tromey via Gdb-patches <gdb-patches@sourceware.org> [2022-01-05 10:13:47 -0700]:

> It's sometimes useful to temporarily set some gdb parameter from

> Python.  Now that the 'endian' crash is fixed, and now that the

> current language is no longer captured by the Python layer, it seems

> reasonable to add a helper function for this situation.

> 

> This adds a new gdb.set_parameter function.  This creates a context

> manager which temporarily sets some parameter to a specified value.

> The old value is restored when the context is exited.  This is most

> useful with the Python "with" statement:

> 

>    with gdb.set_parameter('language', 'ada'):

>       ... do Ada stuff


I don't have time to look through this patch right now, but I did have
one question/thought.

Maybe I'm missing something, but, if I wanted to make a permanent
change to a parameter (i.e. one that persists outside the scope of a
call to gdb.set_parameter) do I need to use gdb.execute ("set ....")?

If that's the case, I wonder how you'd feel about having two
functions,

  gdb.set_parameter(PARAM, VALUE)
  gdb.with_parameter(PARAM, VALUE)

The second of these is what you propose adding (but with a new name),
the first make a persistent change to the parameter value?

Thanks,
Andrew


  



> 

> This is PR python/10790.  I think for permanent changes to parameters,

> it's fine (IMO anyway) to just rely on gdb.execute, so I plan to close

> the PR if this lands.

> 

> Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=10790

> ---

>  gdb/NEWS                                    |  4 ++++

>  gdb/doc/python.texi                         | 19 +++++++++++++++++++

>  gdb/python/lib/gdb/__init__.py              | 12 ++++++++++++

>  gdb/testsuite/gdb.python/py-lookup-type.exp | 12 ++++++++++++

>  4 files changed, 47 insertions(+)

> 

> diff --git a/gdb/NEWS b/gdb/NEWS

> index c26e15b530a..e3b4e4da609 100644

> --- a/gdb/NEWS

> +++ b/gdb/NEWS

> @@ -120,6 +120,10 @@ clone-inferior

>       is equivalent to the existing 'maint packet' CLI command; it

>       allows a user specified packet to be sent to the remote target.

>  

> +  ** New gdb.set_parameter(NAME, VALUE).  This returns a context

> +     manager that temporarily sets the gdb parameter NAME to VALUE,

> +     then resets it when the context is exited.

> +

>  * New features in the GDB remote stub, GDBserver

>  

>    ** GDBserver is now supported on OpenRISC GNU/Linux.

> diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi

> index 6bd5f6b90ac..a97d8c2015c 100644

> --- a/gdb/doc/python.texi

> +++ b/gdb/doc/python.texi

> @@ -332,6 +332,25 @@ parameter's value is converted to a Python value of the appropriate

>  type, and returned.

>  @end defun

>  

> +@findex gdb.set_parameter

> +@defun gdb.set_parameter (name, value)

> +Create a Python context manager (for use with the Python

> +@command{with} statement) that temporarily sets the gdb parameter

> +@var{name} to @var{value}.  On exit from the context, the previous

> +value will be restored.

> +

> +This uses @code{gdb.parameter} in its implementation, so it can throw

> +the same exceptions as that function.

> +

> +For example, it's sometimes useful to evaluate some Python code with a

> +particular gdb language:

> +

> +@smallexample

> +with gdb.set_parameter('language', 'pascal'):

> +  ... language-specific operations

> +@end smallexample

> +@end defun

> +

>  @findex gdb.history

>  @defun gdb.history (number)

>  Return a value from @value{GDBN}'s value history (@pxref{Value

> diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py

> index 11a1b444bfd..ea41f405157 100644

> --- a/gdb/python/lib/gdb/__init__.py

> +++ b/gdb/python/lib/gdb/__init__.py

> @@ -17,6 +17,7 @@ import traceback

>  import os

>  import sys

>  import _gdb

> +from contextlib import contextmanager

>  

>  # Python 3 moved "reload"

>  if sys.version_info >= (3, 4):

> @@ -231,6 +232,17 @@ def find_pc_line(pc):

>      return current_progspace().find_pc_line(pc)

>  

>  

> +@contextmanager

> +def set_parameter(name, value):

> +    """Temporarily set the GDB parameter NAME to VALUE.

> +    Note that this is a context manager."""

> +    old_value = parameter(name)

> +    execute('set ' + name + ' ' + str(value))

> +    # Nothing that useful to return.

> +    yield None

> +    execute('set ' + name + ' ' + old_value)

> +

> +

>  try:

>      from pygments import formatters, lexers, highlight

>  

> diff --git a/gdb/testsuite/gdb.python/py-lookup-type.exp b/gdb/testsuite/gdb.python/py-lookup-type.exp

> index 534a5fd418e..8cdbeaeb2a5 100644

> --- a/gdb/testsuite/gdb.python/py-lookup-type.exp

> +++ b/gdb/testsuite/gdb.python/py-lookup-type.exp

> @@ -55,6 +55,18 @@ test_lookup_type "objective-c" "char"

>  

>  test_lookup_type "pascal" "char"

>  

> +gdb_test "show language" \

> +    "The current source language is .pascal.." \

> +    "show language before 'with'"

> +gdb_test_multiline "look up type using set_parameter" \

> +    "python" "" \

> +    "with gdb.set_parameter('language', 'ada'):" "" \

> +    "  print(gdb.lookup_type('character'))" "" \

> +    "end" "character"

> +gdb_test "show language" \

> +    "The current source language is .pascal.." \

> +    "show language after 'with'"

> +

>  # Ensure that the language can be changed from within Python and still

>  # affect the results.

>  gdb_test_multiline "look up ada type from another language" \

> -- 

> 2.31.1

>
Andrew Burgess via Gdb-patches Jan. 10, 2022, 9:16 p.m. | #2
Andrew> Maybe I'm missing something, but, if I wanted to make a permanent
Andrew> change to a parameter (i.e. one that persists outside the scope of a
Andrew> call to gdb.set_parameter) do I need to use gdb.execute ("set ....")?

Yes.

Andrew> If that's the case, I wonder how you'd feel about having two
Andrew> functions,

Andrew>   gdb.set_parameter(PARAM, VALUE)
Andrew>   gdb.with_parameter(PARAM, VALUE)

Andrew> The second of these is what you propose adding (but with a new name),
Andrew> the first make a persistent change to the parameter value?

Sounds good, I'll make this change.

Tom

Patch

diff --git a/gdb/NEWS b/gdb/NEWS
index c26e15b530a..e3b4e4da609 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -120,6 +120,10 @@  clone-inferior
      is equivalent to the existing 'maint packet' CLI command; it
      allows a user specified packet to be sent to the remote target.
 
+  ** New gdb.set_parameter(NAME, VALUE).  This returns a context
+     manager that temporarily sets the gdb parameter NAME to VALUE,
+     then resets it when the context is exited.
+
 * New features in the GDB remote stub, GDBserver
 
   ** GDBserver is now supported on OpenRISC GNU/Linux.
diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
index 6bd5f6b90ac..a97d8c2015c 100644
--- a/gdb/doc/python.texi
+++ b/gdb/doc/python.texi
@@ -332,6 +332,25 @@  parameter's value is converted to a Python value of the appropriate
 type, and returned.
 @end defun
 
+@findex gdb.set_parameter
+@defun gdb.set_parameter (name, value)
+Create a Python context manager (for use with the Python
+@command{with} statement) that temporarily sets the gdb parameter
+@var{name} to @var{value}.  On exit from the context, the previous
+value will be restored.
+
+This uses @code{gdb.parameter} in its implementation, so it can throw
+the same exceptions as that function.
+
+For example, it's sometimes useful to evaluate some Python code with a
+particular gdb language:
+
+@smallexample
+with gdb.set_parameter('language', 'pascal'):
+  ... language-specific operations
+@end smallexample
+@end defun
+
 @findex gdb.history
 @defun gdb.history (number)
 Return a value from @value{GDBN}'s value history (@pxref{Value
diff --git a/gdb/python/lib/gdb/__init__.py b/gdb/python/lib/gdb/__init__.py
index 11a1b444bfd..ea41f405157 100644
--- a/gdb/python/lib/gdb/__init__.py
+++ b/gdb/python/lib/gdb/__init__.py
@@ -17,6 +17,7 @@  import traceback
 import os
 import sys
 import _gdb
+from contextlib import contextmanager
 
 # Python 3 moved "reload"
 if sys.version_info >= (3, 4):
@@ -231,6 +232,17 @@  def find_pc_line(pc):
     return current_progspace().find_pc_line(pc)
 
 
+@contextmanager
+def set_parameter(name, value):
+    """Temporarily set the GDB parameter NAME to VALUE.
+    Note that this is a context manager."""
+    old_value = parameter(name)
+    execute('set ' + name + ' ' + str(value))
+    # Nothing that useful to return.
+    yield None
+    execute('set ' + name + ' ' + old_value)
+
+
 try:
     from pygments import formatters, lexers, highlight
 
diff --git a/gdb/testsuite/gdb.python/py-lookup-type.exp b/gdb/testsuite/gdb.python/py-lookup-type.exp
index 534a5fd418e..8cdbeaeb2a5 100644
--- a/gdb/testsuite/gdb.python/py-lookup-type.exp
+++ b/gdb/testsuite/gdb.python/py-lookup-type.exp
@@ -55,6 +55,18 @@  test_lookup_type "objective-c" "char"
 
 test_lookup_type "pascal" "char"
 
+gdb_test "show language" \
+    "The current source language is .pascal.." \
+    "show language before 'with'"
+gdb_test_multiline "look up type using set_parameter" \
+    "python" "" \
+    "with gdb.set_parameter('language', 'ada'):" "" \
+    "  print(gdb.lookup_type('character'))" "" \
+    "end" "character"
+gdb_test "show language" \
+    "The current source language is .pascal.." \
+    "show language after 'with'"
+
 # Ensure that the language can be changed from within Python and still
 # affect the results.
 gdb_test_multiline "look up ada type from another language" \