Age | Commit message (Collapse) | Author | Files | Lines |
|
Currently, gdb.execute emits styled output when the command is sending
its output to GDB's stdout, and produces unstyled output when the
output is going to a string.
But it is not unreasonable that a user might wish to capture styled
output from a gdb.execute call, for example, the user might want to
display the styled output are part of some larger UI output block.
At the same time, I don't think it makes sense to always produce
styled output when capturing the output in a string; if what the user
wants is to parse the output, then the style escape sequences make
this far harder.
I propose that gdb.execute gain a new argument 'styling'. When False
we would always produce unstyled output, and when True we would
produce styled output if styling is not disabled by some other means.
For example, if GDB's 'set style enabled' is off, then I think
gdb.execute() should respect that. My assumption here is that
gdb.execute() might be executed by some extension. If the extension
thinks "styled output world work here", but the user hates styled
output, and has turned it off, then the extension should not be
forcing styled output on the user.
I chose 'styling' instead of 'styled' as the Python argument name
because we already use 'styling' in gdb.Value.format_string, and we
don't use 'styled' anywhere else. This is only a little bit of
consistency, but I still think it's a good thing.
The default for 'styling' will change depending on where the output is
going. When gdb.execute is sending the output to GDB's stdout then
the default for 'styling' is True. When the output is going to a
string, then the default for 'styling' will be False. Not only does
this match the existing behaviour, but I think this makes sense. By
default we assume that output captured in a string is going to be
parsed, and therefore styling markup is unhelpful, while output going
to stdout should receive styling.
This fixes part of the problem described in PR gdb/32676. That bug
tries to capture styled source listing in a string, which wasn't
previously possible.
There are some additional issues with capturing source code; GDB
caches the source code in the source code cache. However, GDB doesn't
check if the cached content is styled or not. As a consequence, if
the first time the source of a file is shown it is unstyled, then the
cached will hold the unstyled source code, and future requests will
return that unstyled source. I'll address this issue in a separate
patch.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32676
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I noticed that it was not possible to return a string containing non
utf-8 characters using gdb.execute(). For example, using the binary
from the gdb.python/py-source-styling.exp test:
(gdb) file ./gdb/testsuite/outputs/gdb.python/py-source-styling/py-source-styling
Reading symbols from ./gdb/testsuite/outputs/gdb.python/py-source-styling/py-source-styling...
(gdb) set style enabled off
(gdb) list 26
21 int some_variable = 1234;
22
23 /* The following line contains a character that is non-utf-8. This is a
24 critical part of the test as Python 3 can't convert this into a string
25 using its default mechanism. */
26 char c[] = "�"; /* List this line. */
27
28 return 0;
29 }
(gdb) python print(gdb.execute('list 26', to_string=True))
Python Exception <class 'UnicodeDecodeError'>: 'utf-8' codec can't decode byte 0xc0 in position 250: invalid start byte
Error occurred in Python: 'utf-8' codec can't decode byte 0xc0 in position 250: invalid start byte
It is necessary to disable styling before the initial 'list 26',
otherwise the source will be passed through GNU source highlight, and
GNU source highlight seems to be smart enough to figure out the
character encoding, and convert it to UTF-8. This conversion is then
cached in the source cache, and the later Python gdb.execute call will
get back a pure UTF-8 string.
If source styling is disabled, then GDB caches the string without the
conversion to UTF-8, now the gdb.execute call gets back the string
with a non-UTF-8 character within it, and Python throws an error
during its attempt to create a string object.
I'm not, at this point, proposing a solution that tries to guess the
source file encoding, though I guess such a thing could be done.
Instead, I think we should make use of the host_charset(), as set by
the user with 'set host-charset ....' during the creation of the
Python string.
To do this, in execute_gdb_command, we should switch from
PyUnicode_FromString, which requires the input be a UTF-8 string, to
using PyUnicode_Decode, which allows GDB to specify the string
encoding. We will use host_charset().
With this done, it is now possible to list the file contents using
gdb.execute(), with the contents passing through a string:
(gdb) set host-charset ISO-8859-1
(gdb) python print(gdb.execute('list 26', to_string=True), end='')
21 int some_variable = 1234;
22
23 /* The following line contains a character that is non-utf-8. This is a
24 critical part of the test as Python 3 can't convert this into a string
25 using its default mechanism. */
26 char c[] = "À"; /* List this line. */
27
28 return 0;
29 }
(gdb)
There are already plenty of other places in GDB's Python code where we
use PyUnicode_Decode to create a string from something that might
contain user generated content, so I believe this is the correct
approach.
|
|
I noticed a
// namespace selftests
comment, which doesn't follow our comment formatting convention. I did
a find & replace to fix all the offenders.
Change-Id: Idf8fe9833caf1c3d99e15330db000e4bab4ec66c
|
|
In AIX a recent commit caused a build break with the error as shown below.
In file included from python/py-color.h:23,
from python/python.c:39:
python/python-internal.h:86:10: fatal error: Python.h: No such file or directory
86 | #include <Python.h>
In AIX, we run builds with and without python for our internal CI's.
A feature development made by the recent commit https://sourceware.org/git/?p=binutils-gdb.git;a=commitdiff;h=6447969d0ac774b6dec0f95a0d3d27c27d158690
missed to guard Python.h in HAVE_PYTHON macro.
This commit is a fix for the same.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Colors can be specified as "none" for terminal's default color, as a name of
one of the eight standard colors of ISO/IEC 6429 "black", "red", "green", etc.,
as an RGB hexadecimal tripplet #RRGGBB for 24-bit TrueColor, or as an
integer from 0 to 255. Integers 0 to 7 are the synonyms for the standard
colors. Integers 8-15 are used for the so-called bright colors from the
aixterm extended 16-color palette. Integers 16-255 are the indexes into xterm
extended 256-color palette (usually 6x6x6 cube plus gray ramp). In
general, 256-color palette is terminal dependent and sometimes can be
changed with OSC 4 sequences, e.g. "\033]4;1;rgb:00/FF/00\033\\".
It is the responsibility of the user to verify that the terminal supports
the specified colors.
PATCH v5 changes: documentation fixed.
PATCH v6 changes: documentation fixed.
PATCH v7 changes: rebase onto master and fixes after review.
PATCH v8 changes: fixes after review.
|
|
A common problem is that python may fail to initialize if PYTHONHOME is
set incorrectly, or points to incompatible default libraries.
Likewise if PYTHONPATH points to incompatible modules.
For instance, say PYTHONHOME is foo, then we get:
...
$ gdb -q
Python path configuration:
PYTHONHOME = 'foo'
PYTHONPATH = (not set)
program name = '/usr/bin/python'
isolated = 0
environment = 1
user site = 1
safe_path = 0
import site = 1
is in build tree = 0
stdlib dir = 'foo/lib64/python3.12'
sys._base_executable = '/usr/bin/python'
sys.base_prefix = 'foo'
sys.base_exec_prefix = 'foo'
sys.platlibdir = 'lib64'
sys.executable = '/usr/bin/python'
sys.prefix = 'foo'
sys.exec_prefix = 'foo'
sys.path = [
'foo/lib64/python312.zip',
'foo/lib64/python3.12',
'foo/lib64/python3.12/lib-dynload',
]
Python Exception <class 'ModuleNotFoundError'>: No module named 'encodings'
Python not initialized
$
...
In this case, it might be easy to figure out what went wrong because of the
obviously incorrect pathnames, but that might not be the case if PYTHONHOME
points to an incompatible python installation.
Fix this by adding a warning with a description of the possible cause and what
to do about it:
...
Python initialization failed: \
failed to get the Python codec of the filesystem encoding
gdb: warning: Python failed to initialize with PYTHONHOME set. Maybe because \
it is set incorrectly? Maybe because it points to incompatible standard \
libraries? Consider changing or unsetting it, or ignoring it using "set \
python ignore-environment on" at early initialization.
...
Likewise for PYTHONPATH:
...
Python initialization failed: \
failed to get the Python codec of the filesystem encoding
gdb: warning: Python failed to initialize with PYTHONPATH set. Maybe because \
it points to incompatible modules? Consider changing or unsetting it, or \
ignoring it using "set python ignore-environment on" at early \
initialization.
...
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR python/32379
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32379
|
|
When using PYTHONDONTWRITEBYTECODE with an empty string we get:
...
$ PYTHONDONTWRITEBYTECODE= gdb -q -batch -ex "show python dont-write-bytecode"
Python's dont-write-bytecode setting is auto (currently on).
...
This is incorrect, it should be off.
The actual setting is correct, that was already fixed in commit 24d2cbc42cc
("set/show python dont-write-bytecode fixes"), in function
python_write_bytecode.
Fix this by:
- factoring out new function env_python_dont_write_bytecode out of
python_write_bytecode, and
- using it in show_python_dont_write_bytecode.
Tested on x86_64-linux, using test-case gdb.python/py-startup-opt.exp and:
- PYTHONDONTWRITEBYTECODE=
- PYTHONDONTWRITEBYTECODE=1
- unset PYTHONDONTWRITEBYTECODE
Approved-By: Tom Tromey <tom@tromey.com>
PR python/32389
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32389
|
|
Configuration flags "python dont-write-bytecode" and
"python ignore-environment" have effect only at Python initialization.
For instance, setting "python dont-write-bytecode" here has no effect:
...
$ gdb -q
(gdb) show python dont-write-bytecode
Python's dont-write-bytecode setting is auto (currently off).
(gdb) python import sys
(gdb) python print (sys.dont_write_bytecode)
False
(gdb) set python dont-write-bytecode on
(gdb) python print (sys.dont_write_bytecode)
False
...
This is not clear in the code: we set Py_DontWriteBytecodeFlag and
Py_IgnoreEnvironmentFlag in set_python_ignore_environment and
set_python_dont_write_bytecode. Fix this by moving the setting of those
variables to py_initialization.
Furthermore, this is not clear to the user: after Python initialization, the
user can still modify the configuration flags, and observe the changed setting:
...
$ gdb -q
(gdb) show python ignore-environment
Python's ignore-environment setting is off.
(gdb) set python ignore-environment on
(gdb) show python ignore-environment
Python's ignore-environment setting is on.
(gdb)
...
Fix this by emitting a warning when trying to set these configuration flags
after Python initialization:
...
$ gdb -q
(gdb) set python ignore-environment on
warning: Setting python ignore-environment after Python initialization has \
no effect, try setting this during early initialization
(gdb) set python dont-write-bytecode on
warning: Setting python dont-write-bytecode after Python initialization has \
no effect, try setting this during early initialization, or try setting \
sys.dont_write_bytecode
...
and by keeping the values constant after Python initialization.
Since the auto setting for python dont-write-bytecode depends on the current
value of environment variable PYTHONDONTWRITEBYTECODE, we simply avoid it
after Python initialization:
...
$ gdb -q -batch \
-eiex "show python dont-write-bytecode" \
-iex "show python dont-write-bytecode"
Python's dont-write-bytecode setting is auto (currently off).
Python's dont-write-bytecode setting is off.
...
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR python/32388
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32388
|
|
I added ATTRIBUTE_UNUSED to py_initialize_catch_abort as a quick fix to deal
with it being unused for PY_VERSION_HEX >= 0x030a0000, but forgot to fix this
before committing.
Fix this now, by removing the attribute and using
'#if PY_VERSION_HEX < 0x030a0000' instead.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Function do_start_initialization has a large part dedicated to initializing
the python interpreter, as opposed to the rest of the function where
gdb-specific python support is initialized.
Factor out this part, as new function py_initialize, and rename the existing
py_initialize to py_initialize_catch_abort.
Refactor the new function py_initialize by getting rid of the nested:
...
#ifdef WITH_PYTHON_PATH
#if PY_VERSION_HEX < 0x030a0000
#else
#endif
#else
#endif
...
In particular, this changes behaviour for the "!defined (WITH_PYTHON_PATH)"
case.
For the "defined (WITH_PYTHON_PATH)" case, we've started using
Py_InitializeFromConfig () for PY_VERSION_HEX >= 0x030a0000 to deal with the
deprecation of Py_SetProgramName in 3.11.
For the "!defined (WITH_PYTHON_PATH)" case, we don't use Py_SetProgramName so
we stuck with Py_Initialize ().
However, in 3.12 Py_DontWriteBytecodeFlag and Py_IgnoreEnvironmentFlag got
deprecated and also here we need Py_InitializeFromConfig () to deal with this,
but the "!defined (WITH_PYTHON_PATH)" case didn't get updated.
This should be taken care of, now that we have this behavior:
- for PY_VERSION_HEX < 0x030a0000 we use Py_Initialize
- for PY_VERSION_HEX >= 0x030a0000 we use Py_InitializeFromConfig
I'm not sure how to test the "!defined (WITH_PYTHON_PATH)" though.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I tried out making python initialization fail by passing an incorrect
PYTHONHOME, and got:
...
$ PYTHONHOME=foo ./gdb.sh -q
Python path configuration:
PYTHONHOME = 'foo'
...
Python initialization failed: \
failed to get the Python codec of the filesystem encoding
Python not initialized
$
...
The relevant part of the code is:
...
static void
gdbpy_initialize (const struct extension_language_defn *extlang)
{
if (!do_start_initialization () && py_isinitialized && PyErr_Occurred ())
gdbpy_print_stack ();
gdbpy_enter enter_py;
...
What happens is:
- gdbpy_enter::gdbpy_enter () is called, where we run into:
'if (!gdb_python_initialized) error (_("Python not initialized"));'
- the error propagates to gdb's toplevel
- gdb print the error and exits.
It seems unnecesssary that we exit gdb. We could continue the
session without python support.
Fix this by:
- bailing out of gdbpy_initialize if !do_start_initialization
- bailing out of finalize_python if !gdb_python_initialized
This gets us instead:
...
$ PYTHONHOME=foo gdb -q
Python path configuration:
PYTHONHOME = 'foo'
...
Python initialization failed: \
failed to get the Python codec of the filesystem encoding
(gdb) python print (1)
Python not initialized
(gdb)
...
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I tried out making python initialization fail by passing an incorrect
PYTHONHOME with python 3.6, and got:
...
$ PYTHONHOME=foo gdb -q
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x0000ffff89269c80 (most recent call first):
Fatal signal: Aborted
...
Aborted (core dumped)
$
...
This is as per spec: when Py_Initialize () fails, a fatal error is raised
using Py_FatalError.
This can be worked around using:
...
$ PYTHONHOME=foo gdb -q -eiex "set python ignore-environment on"
(gdb)
...
but it would be better if gdb didn't abort.
I found an article [1] describing two solutions:
- try out Py_Initialize in a separate process, and
- catch the abort using a signal handler.
This patch implements the latter solution.
Obviously we cannot call into python anymore after the abort, so we avoid
calling Py_IsInitialized (), and instead use a new variable py_isinitialized.
This gets us instead:
...
$ PYTHONHOME=foo gdb -q
Fatal Python error: Py_Initialize: Unable to get the locale encoding
ModuleNotFoundError: No module named 'encodings'
Current thread 0x0000fffecfd49c80 (most recent call first):
Python not initialized
$
...
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR python/32379
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32379
[1] https://stackoverflow.com/questions/7688374/how-to-i-catch-and-handle-a-fatal-error-when-py-initialize-fails
|
|
I tried out making python initialization fail by passing an incorrect
PYTHONHOME, and got:
...
$ PYTHONHOME=foo gdb -q
Python path configuration:
PYTHONHOME = 'foo'
...
Python Exception <class 'ModuleNotFoundError'>: No module named 'encodings'
Python not initialized
$
...
The relevant part of the code is:
...
static void
gdbpy_initialize (const struct extension_language_defn *extlang)
{
if (!do_start_initialization () && PyErr_Occurred ())
gdbpy_print_stack ();
gdbpy_enter enter_py;
...
What happens is that:
- do_start_initialization returns false because Py_InitializeFromConfig fails,
leaving us in the !Py_IsInitialized () state
- PyErr_Occurred () returns true
- gdbpy_print_stack is called, which prints
"Python Exception <class 'ModuleNotFoundError'>: No module named 'encodings"
The problem is that in the Py_IsInitialized () == false state, very few
functions can be called, and PyErr_Occurred is not one of them [1], and
likewise functions in gdbpy_print_stack.
Fix this by:
- guarding the PyErr_Occurred / gdbpy_print_stack part with Py_IsInitialized ().
- handling the !Py_IsInitialized () case by printing the failure PyStatus
in do_start_initialization
This gets us instead:
...
$ PYTHONHOME=foo ./gdb.sh -q
Python path configuration:
PYTHONHOME = 'foo'
...
Python initialization failed: failed to get the Python codec of the filesystem encoding
Python not initialized
$
...
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
[1] https://docs.python.org/3/c-api/init.html#before-python-initialization
|
|
I noticed in do_start_initialization:
...
std::string oldloc = setlocale (LC_ALL, NULL);
setlocale (LC_ALL, "");
...
if (count == (size_t) -1)
{
fprintf (stderr, "Could not convert python path to string\n");
return false;
}
setlocale (LC_ALL, oldloc.c_str ());
...
that the old locale is not restored if the "return false" is triggered.
Fix this by using SCOPE_EXIT.
Tested on aarch64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
In this review:
https://inbox.sourceware.org/gdb-patches/87wmirfzih.fsf@tromey.com
Tom pointed out that using PyObject_IsTrue as I was doing, though
technically fine, at least appears to be missing an error check, and
that it would be better to compare to Py_True directly. I made that
change in the patch Tom was commenting on, but I'd actually copied
that code from elsewhere in python/python.c, so this commit updates
the original code inline with Tom's review feedback.
There should be no functional change after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Implement extension_language_ops::find_objfile_from_buildid within
GDB's Python API. Doing this allows users to write Python extensions
that can help locate missing objfiles when GDB opens a core file. A
handler might perform some project- or site-specific actions to find a
missing objfile. Or might provide some project- or site-specific
advice to the user on how they can obtain the missing objfile.
The implementation is very similar to the approach taken in:
commit 8f6c452b5a4e50fbb55ff1d13328b392ad1fd416
Date: Sun Oct 15 22:48:42 2023 +0100
gdb: implement missing debug handler hook for Python
The following new commands are added as commands implemented in
Python, this is similar to how the Python missing debug and unwinder
commands are implemented:
info missing-objfile-handlers
enable missing-objfile-handler LOCUS HANDLER
disable missing-objfile-handler LOCUS HANDLER
To make use of this extension hook a user will create missing objfile
handler objects, and registers these handlers with GDB. When GDB
opens a core file and encounters a missing objfile each handler is
called in turn until one is able to help. Here is a minimal handler
that does nothing useful:
import gdb
import gdb.missing_objfile
class MyFirstHandler(gdb.missing_objfile.MissingObjfileHandler):
def __init__(self):
super().__init__("my_first_handler")
def __call__(self, pspace, build_id, filename):
# This handler does nothing useful.
return None
gdb.missing_objfile.register_handler(None, MyFirstHandler())
Returning None from the __call__ method tells GDB that this handler
was unable to find the missing objfile, and GDB should ask any other
registered handlers.
Possible return values from a handler:
- None: This means the handler couldn't help. GDB will call other
registered handlers to see if they can help instead.
- False: The handler has done all it can, but the objfile couldn't
be found. GDB will not call any other handlers, and will
continue without the objfile.
- True: The handler has installed the objfile into a location where
GDB would normally expect to find it. GDB should repeat its
normal lookup process and the objfile should now be found.
- A string: The handler can return a filename, which is the missing
objfile. GDB will load this file.
Handlers can be registered globally, or per program space. GDB checks
the handlers for the current program space first, and then all of the
global handles. The first handler that returns a value that is not
None, has "handled" the missing objfile, at which point GDB continues.
The implementation of this feature is mostly straight forward. I have
reworked some of the missing debug file related code so that it can be
shared with this feature. E.g. gdb/python/lib/gdb/missing_files.py is
mostly content moved from gdb/python/lib/gdb/missing_debug.py, but
updated to be more generic. Now gdb/python/lib/gdb/missing_debug.py
and the new file gdb/python/lib/gdb/missing_objfile.py both call into
the missing_files.py file.
For gdb/python/lib/gdb/command/missing_files.py this is even more
extreme, gdb/python/lib/gdb/command/missing_debug.py is completely
gone now and gdb/python/lib/gdb/command/missing_files.py provides all
of the new commands in a generic way.
I have made one change to the existing Python API, I renamed the
attribute Progspace.missing_debug_handlers to
Progspace.missing_file_handlers. I don't see this as too
problematic. This attribute was only used to implement the missing
debug feature and was never documented beyond the fact that it
existed. There was no reason for users to be touching this attribute.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
In preparation for later commits in this series, rename
ext_lang_missing_debuginfo_result to ext_lang_missing_file_result.
A later commit will add additional Python APIs to handle different
types of missing files beyond just debuginfo.
This is just a rename commit, there should be no functional changes
after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Result of:
...
$ search="GDB_PY_HANDLE_EXCEPTION ("
$ replace="return gdbpy_handle_gdb_exception (nullptr, "
$ sed -i \
"s/$search/$replace/" \
gdb/python/*.c
...
Also remove the now unused GDB_PY_HANDLE_EXCEPTION.
No functional changes.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
PR python/32163 points out that various types provided by gdb are not
added to the gdb module, so they aren't available for interactive
inspection. I think this is just an oversight.
This patch fixes the problem by introducing a new helper function that
both readies the type and then adds it to the appropriate module. The
patch also poisons PyType_Ready, the idea being to avoid this bug in
the future.
v2:
* Fixed a bug in original patch in gdb.Architecture registration
* Added regression test for the types mentioned in the bug
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32163
Reviewed-By: Alexandra Petlanova Hajkova <ahajkova@redhat.com>
|
|
I found a few more places where we can use GDB_PY_HANDLE_EXCEPTION.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
By default GDB will be printing the hex payload of the ptwrite package as
auxiliary information. To customize this, the user can register a ptwrite
filter function in python, that takes the payload and the PC as arguments and
returns a string which will be printed instead. Registering the filter
function is done using a factory pattern to make per-thread filtering easier.
Approved-By: Markus Metzger <markus.t.metzger@intel.com>
|
|
Make the current program space reference bubble up one level.
Change-Id: I6ba6dc4a2cb188720cbb61b84ab5c954aac105c6
Approved-By: Tom Tromey <tom@tromey.com>
Reviewed-By: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
|
|
This patch renames global_symbol_searcher::filenames and makes it
private, adding a new method to append a filename to the vector. This
also cleans up memory management here, removing an alloca from rbreak,
and removing a somewhat ugly SCOPE_EXIT from the Python code, in favor
of having global_symbol_searcher manage the memory itself.
Regression tested on x86-64 Fedora 38.
|
|
Most files including gdbcmd.h currently rely on it to access things
actually declared in cli/cli-cmds.h (setlist, showlist, etc). To make
things easy, replace all includes of gdbcmd.h with includes of
cli/cli-cmds.h. This might lead to some unused includes of
cli/cli-cmds.h, but it's harmless, and much faster than going through
the 170 or so files by hand.
Change-Id: I11f884d4d616c12c05f395c98bbc2892950fb00f
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Change the return type of the check_quit_flag function to bool. Update
a few related spots.
Change-Id: I9d3a15d3f8651efb02c7d211f06222a592bd4184
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Now that defs.h, server.h and common-defs.h are included via the
`-include` option, it is no longer necessary for source files to include
them. Remove all the inclusions of these files I could find. Update
the generation scripts where relevant.
Change-Id: Ia026cff269c1b7ae7386dd3619bc9bb6a5332837
Approved-By: Pedro Alves <pedro@palves.net>
|
|
This patch arranges to set __file__ when source'ing a Python script.
This fixes a problem that was introduced by the "source" rewrite, and
then pointed out by Lancelot Six.
Reviewed-by: Lancelot Six <lancelot.six@amd.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Right now, Python is shut down via a final cleanup. However, it seems
to me that it is better for extension languages to be shut down
explicitly, after all the ordinary final cleanups are run. The main
reason for this is that a subsequent patch adds another case like
finalize_values; and rather than add a series of workarounds for
Python shutdown, it seemed better to let these be done via final
cleanups, and then have Python shutdown itself be the special case.
|
|
This patch rewrites final cleanups to use std::function and otherwise
be more C++-ish.
|
|
The "python" command (and the Python implementation of the gdb
"source" command) does not handle Python exceptions in the same way as
other gdb-facing Python code. In particular, exceptions are turned
into a generic error rather than being routed through
gdbpy_handle_exception, which takes care of converting to 'quit' as
appropriate.
I think this was done this way because PyRun_SimpleFile and friends do
not propagate the Python exception -- they simply indicate that one
occurred.
This patch reimplements these functions to respect the general gdb
convention here. As a bonus, some Windows-specific code can be
removed, as can the _execute_file function.
The bulk of this change is tweaking the test suite to match the new
way that exceptions are displayed. These changes are largely
uninteresting. However, it's worth pointing out the py-error.exp
change. Here, the failure changes because the test changes the host
charset to something that isn't supported by Python. This then
results in a weird error in the new setup.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31354
Acked-By: Tom de Vries <tdevries@suse.de>
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
python.c has a split string that is missing a space. There's also a
stray backslash in this code.
Reviewed-By: Tom de Vries <tdevries@suse.de>
|
|
From the Python API, we can execute GDB commands via gdb.execute. If
the command gives an exception, however, we need to recover the GDB
prompt and enable stdin, because the exception does not reach
top-level GDB or normal_stop. This was done in commit
commit 1ba1ac88011703abcd0271e4f5d00927dc69a09a
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Tue Nov 19 11:17:20 2019 +0000
gdb: Enable stdin on exception in execute_gdb_command
with the following code:
catch (const gdb_exception &except)
{
/* If an exception occurred then we won't hit normal_stop (), or have
an exception reach the top level of the event loop, which are the
two usual places in which stdin would be re-enabled. So, before we
convert the exception and continue back in Python, we should
re-enable stdin here. */
async_enable_stdin ();
GDB_PY_HANDLE_EXCEPTION (except);
}
In this patch, we explain what happens when we run a GDB command in
the context of a synchronous command, e.g. via Python observer
notifications.
As an example, suppose we have the following objfile event listener,
specified in a file named file.py:
~~~
import gdb
class MyListener:
def __init__(self):
gdb.events.new_objfile.connect(self.handle_new_objfile_event)
self.processed_objfile = False
def handle_new_objfile_event(self, event):
if self.processed_objfile:
return
print("loading " + event.new_objfile.filename)
self.processed_objfile = True
gdb.execute('add-inferior -no-connection')
gdb.execute('inferior 2')
gdb.execute('target remote | gdbserver - /tmp/a.out')
gdb.execute('inferior 1')
the_listener = MyListener()
~~~
Using this Python file, we see the behavior below:
$ gdb -q -ex "source file.py" -ex "run" --args a.out
Reading symbols from a.out...
Starting program: /tmp/a.out
loading /lib64/ld-linux-x86-64.so.2
[New inferior 2]
Added inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
stdin/stdout redirected
Process /tmp/a.out created; pid = 3075406
Remote debugging using stdio
Reading /tmp/a.out from remote target...
...
[Switching to inferior 1 [process 3075400] (/tmp/a.out)]
[Switching to thread 1.1 (process 3075400)]
#0 0x00007ffff7fe3290 in ?? () from /lib64/ld-linux-x86-64.so.2
(gdb) [Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Inferior 1 (process 3075400) exited normally]
Note how the GDB prompt comes in-between the debugger output. We have this
obscure behavior, because the executed command, "target remote", triggers
an invocation of `normal_stop` that enables stdin. After that, however,
the Python notification context completes and GDB continues with its normal
flow of executing the 'run' command. This can be seen in the call stack
below:
(top-gdb) bt
#0 async_enable_stdin () at src/gdb/event-top.c:523
#1 0x00005555561c3acd in normal_stop () at src/gdb/infrun.c:9432
#2 0x00005555561b328e in start_remote (from_tty=0) at src/gdb/infrun.c:3801
#3 0x0000555556441224 in remote_target::start_remote_1 (this=0x5555587882e0, from_tty=0, extended_p=0) at src/gdb/remote.c:5225
#4 0x000055555644166c in remote_target::start_remote (this=0x5555587882e0, from_tty=0, extended_p=0) at src/gdb/remote.c:5316
#5 0x00005555564430cf in remote_target::open_1 (name=0x55555878525e "| gdbserver - /tmp/a.out", from_tty=0, extended_p=0) at src/gdb/remote.c:6175
#6 0x0000555556441707 in remote_target::open (name=0x55555878525e "| gdbserver - /tmp/a.out", from_tty=0) at src/gdb/remote.c:5338
#7 0x00005555565ea63f in open_target (args=0x55555878525e "| gdbserver - /tmp/a.out", from_tty=0, command=0x555558589280) at src/gdb/target.c:824
#8 0x0000555555f0d89a in cmd_func (cmd=0x555558589280, args=0x55555878525e "| gdbserver - /tmp/a.out", from_tty=0) at src/gdb/cli/cli-decode.c:2735
#9 0x000055555661fb42 in execute_command (p=0x55555878529e "t", from_tty=0) at src/gdb/top.c:575
#10 0x0000555555f1a506 in execute_control_command_1 (cmd=0x555558756f00, from_tty=0) at src/gdb/cli/cli-script.c:529
#11 0x0000555555f1abea in execute_control_command (cmd=0x555558756f00, from_tty=0) at src/gdb/cli/cli-script.c:701
#12 0x0000555555f19fc7 in execute_control_commands (cmdlines=0x555558756f00, from_tty=0) at src/gdb/cli/cli-script.c:411
#13 0x0000555556400d91 in execute_gdb_command (self=0x7ffff43b5d00, args=0x7ffff440ab60, kw=0x0) at src/gdb/python/python.c:700
#14 0x00007ffff7a96023 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#15 0x00007ffff7a4dadc in _PyObject_MakeTpCall () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#16 0x00007ffff79e9a1c in _PyEval_EvalFrameDefault () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#17 0x00007ffff7b303af in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#18 0x00007ffff7a50358 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#19 0x00007ffff7a4f3f4 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#20 0x00007ffff7a4f883 in PyObject_CallFunctionObjArgs () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#21 0x00005555563a9758 in evpy_emit_event (event=0x7ffff42b5430, registry=0x7ffff42b4690) at src/gdb/python/py-event.c:104
#22 0x00005555563cb874 in emit_new_objfile_event (objfile=0x555558761700) at src/gdb/python/py-newobjfileevent.c:52
#23 0x00005555563b53bc in python_new_objfile (objfile=0x555558761700) at src/gdb/python/py-inferior.c:195
#24 0x0000555555d6dff0 in std::__invoke_impl<void, void (*&)(objfile*), objfile*> (__f=@0x5555585b5860: 0x5555563b5360 <python_new_objfile(objfile*)>) at /usr/include/c++/11/bits/invoke.h:61
#25 0x0000555555d6be18 in std::__invoke_r<void, void (*&)(objfile*), objfile*> (__fn=@0x5555585b5860: 0x5555563b5360 <python_new_objfile(objfile*)>) at /usr/include/c++/11/bits/invoke.h:111
#26 0x0000555555d69661 in std::_Function_handler<void (objfile*), void (*)(objfile*)>::_M_invoke(std::_Any_data const&, objfile*&&) (__functor=..., __args#0=@0x7fffffffd080: 0x555558761700) at /usr/include/c++/11/bits/std_function.h:290
#27 0x0000555556314caf in std::function<void (objfile*)>::operator()(objfile*) const (this=0x5555585b5860, __args#0=0x555558761700) at /usr/include/c++/11/bits/std_function.h:590
#28 0x000055555631444e in gdb::observers::observable<objfile*>::notify (this=0x55555836eea0 <gdb::observers::new_objfile>, args#0=0x555558761700) at src/gdb/../gdbsupport/observable.h:166
#29 0x0000555556599b3f in symbol_file_add_with_addrs (abfd=..., name=0x55555875d310 "/lib64/ld-linux-x86-64.so.2", add_flags=..., addrs=0x7fffffffd2f0, flags=..., parent=0x0) at src/gdb/symfile.c:1125
#30 0x0000555556599ca4 in symbol_file_add_from_bfd (abfd=..., name=0x55555875d310 "/lib64/ld-linux-x86-64.so.2", add_flags=..., addrs=0x7fffffffd2f0, flags=..., parent=0x0) at src/gdb/symfile.c:1160
#31 0x0000555556546371 in solib_read_symbols (so=..., flags=...) at src/gdb/solib.c:692
#32 0x0000555556546f0f in solib_add (pattern=0x0, from_tty=0, readsyms=1) at src/gdb/solib.c:1015
#33 0x0000555556539891 in enable_break (info=0x55555874e180, from_tty=0) at src/gdb/solib-svr4.c:2416
#34 0x000055555653b305 in svr4_solib_create_inferior_hook (from_tty=0) at src/gdb/solib-svr4.c:3058
#35 0x0000555556547cee in solib_create_inferior_hook (from_tty=0) at src/gdb/solib.c:1217
#36 0x0000555556196f6a in post_create_inferior (from_tty=0) at src/gdb/infcmd.c:275
#37 0x0000555556197670 in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at src/gdb/infcmd.c:486
#38 0x000055555619783f in run_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:512
#39 0x0000555555f0798d in do_simple_func (args=0x0, from_tty=1, c=0x555558567510) at src/gdb/cli/cli-decode.c:95
#40 0x0000555555f0d89a in cmd_func (cmd=0x555558567510, args=0x0, from_tty=1) at src/gdb/cli/cli-decode.c:2735
#41 0x000055555661fb42 in execute_command (p=0x7fffffffe2c4 "", from_tty=1) at src/gdb/top.c:575
#42 0x000055555626303b in catch_command_errors (command=0x55555661f4ab <execute_command(char const*, int)>, arg=0x7fffffffe2c1 "run", from_tty=1, do_bp_actions=true) at src/gdb/main.c:513
#43 0x000055555626328a in execute_cmdargs (cmdarg_vec=0x7fffffffdaf0, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffda3c) at src/gdb/main.c:612
#44 0x0000555556264849 in captured_main_1 (context=0x7fffffffdd40) at src/gdb/main.c:1293
#45 0x0000555556264a7f in captured_main (data=0x7fffffffdd40) at src/gdb/main.c:1314
#46 0x0000555556264b2e in gdb_main (args=0x7fffffffdd40) at src/gdb/main.c:1343
#47 0x0000555555ceccab in main (argc=9, argv=0x7fffffffde78) at src/gdb/gdb.c:39
(top-gdb)
The use of the "target remote" command here is just an example. In
principle, we would reproduce the problem with any command that
triggers an invocation of `normal_stop`.
To omit enabling the stdin in `normal_stop`, we would have to check the
context we are in. Since we cannot do that, we add a new field to
`struct ui` to track whether the prompt was already blocked, and set
the tracker flag in the Python context before executing a GDB command.
After applying this patch, the output becomes
...
Reading symbols from a.out...
Starting program: /tmp/a.out
loading /lib64/ld-linux-x86-64.so.2
[New inferior 2]
Added inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
stdin/stdout redirected
Process /tmp/a.out created; pid = 3032261
Remote debugging using stdio
Reading /tmp/a.out from remote target...
...
[Switching to inferior 1 [process 3032255] (/tmp/a.out)]
[Switching to thread 1.1 (process 3032255)]
#0 0x00007ffff7fe3290 in ?? () from /lib64/ld-linux-x86-64.so.2
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[Inferior 1 (process 3032255) exited normally]
(gdb)
Let's now consider a secondary scenario, where the command executed from
the Python raises an error. As an example, suppose we have the Python
file below:
def handle_new_objfile_event(self, event):
...
print("loading " + event.new_objfile.filename)
self.processed_objfile = True
gdb.execute('print a')
The executed command, "print a", gives an error because "a" is not
defined. Without this patch, we see the behavior below, where the
prompt is again placed incorrectly:
...
Reading symbols from /tmp/a.out...
Starting program: /tmp/a.out
loading /lib64/ld-linux-x86-64.so.2
Python Exception <class 'gdb.error'>: No symbol "a" in current context.
(gdb) [Inferior 1 (process 3980401) exited normally]
This time, `async_enable_stdin` is called from the 'catch' block in
`execute_gdb_command`:
(top-gdb) bt
#0 async_enable_stdin () at src/gdb/event-top.c:523
#1 0x0000555556400f0a in execute_gdb_command (self=0x7ffff43b5d00, args=0x7ffff440ab60, kw=0x0) at src/gdb/python/python.c:713
#2 0x00007ffff7a96023 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#3 0x00007ffff7a4dadc in _PyObject_MakeTpCall () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#4 0x00007ffff79e9a1c in _PyEval_EvalFrameDefault () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#5 0x00007ffff7b303af in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#6 0x00007ffff7a50358 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#7 0x00007ffff7a4f3f4 in ?? () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#8 0x00007ffff7a4f883 in PyObject_CallFunctionObjArgs () from /lib/x86_64-linux-gnu/libpython3.10.so.1.0
#9 0x00005555563a9758 in evpy_emit_event (event=0x7ffff42b5430, registry=0x7ffff42b4690) at src/gdb/python/py-event.c:104
#10 0x00005555563cb874 in emit_new_objfile_event (objfile=0x555558761410) at src/gdb/python/py-newobjfileevent.c:52
#11 0x00005555563b53bc in python_new_objfile (objfile=0x555558761410) at src/gdb/python/py-inferior.c:195
#12 0x0000555555d6dff0 in std::__invoke_impl<void, void (*&)(objfile*), objfile*> (__f=@0x5555585b5860: 0x5555563b5360 <python_new_objfile(objfile*)>) at /usr/include/c++/11/bits/invoke.h:61
#13 0x0000555555d6be18 in std::__invoke_r<void, void (*&)(objfile*), objfile*> (__fn=@0x5555585b5860: 0x5555563b5360 <python_new_objfile(objfile*)>) at /usr/include/c++/11/bits/invoke.h:111
#14 0x0000555555d69661 in std::_Function_handler<void (objfile*), void (*)(objfile*)>::_M_invoke(std::_Any_data const&, objfile*&&) (__functor=..., __args#0=@0x7fffffffd080: 0x555558761410) at /usr/include/c++/11/bits/std_function.h:290
#15 0x0000555556314caf in std::function<void (objfile*)>::operator()(objfile*) const (this=0x5555585b5860, __args#0=0x555558761410) at /usr/include/c++/11/bits/std_function.h:590
#16 0x000055555631444e in gdb::observers::observable<objfile*>::notify (this=0x55555836eea0 <gdb::observers::new_objfile>, args#0=0x555558761410) at src/gdb/../gdbsupport/observable.h:166
#17 0x0000555556599b3f in symbol_file_add_with_addrs (abfd=..., name=0x55555875d020 "/lib64/ld-linux-x86-64.so.2", add_flags=..., addrs=0x7fffffffd2f0, flags=..., parent=0x0) at src/gdb/symfile.c:1125
#18 0x0000555556599ca4 in symbol_file_add_from_bfd (abfd=..., name=0x55555875d020 "/lib64/ld-linux-x86-64.so.2", add_flags=..., addrs=0x7fffffffd2f0, flags=..., parent=0x0) at src/gdb/symfile.c:1160
#19 0x0000555556546371 in solib_read_symbols (so=..., flags=...) at src/gdb/solib.c:692
#20 0x0000555556546f0f in solib_add (pattern=0x0, from_tty=0, readsyms=1) at src/gdb/solib.c:1015
#21 0x0000555556539891 in enable_break (info=0x55555874a670, from_tty=0) at src/gdb/solib-svr4.c:2416
#22 0x000055555653b305 in svr4_solib_create_inferior_hook (from_tty=0) at src/gdb/solib-svr4.c:3058
#23 0x0000555556547cee in solib_create_inferior_hook (from_tty=0) at src/gdb/solib.c:1217
#24 0x0000555556196f6a in post_create_inferior (from_tty=0) at src/gdb/infcmd.c:275
#25 0x0000555556197670 in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at src/gdb/infcmd.c:486
#26 0x000055555619783f in run_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:512
#27 0x0000555555f0798d in do_simple_func (args=0x0, from_tty=1, c=0x555558567510) at src/gdb/cli/cli-decode.c:95
#28 0x0000555555f0d89a in cmd_func (cmd=0x555558567510, args=0x0, from_tty=1) at src/gdb/cli/cli-decode.c:2735
#29 0x000055555661fb42 in execute_command (p=0x7fffffffe2c4 "", from_tty=1) at src/gdb/top.c:575
#30 0x000055555626303b in catch_command_errors (command=0x55555661f4ab <execute_command(char const*, int)>, arg=0x7fffffffe2c1 "run", from_tty=1, do_bp_actions=true) at src/gdb/main.c:513
#31 0x000055555626328a in execute_cmdargs (cmdarg_vec=0x7fffffffdaf0, file_type=CMDARG_FILE, cmd_type=CMDARG_COMMAND, ret=0x7fffffffda3c) at src/gdb/main.c:612
#32 0x0000555556264849 in captured_main_1 (context=0x7fffffffdd40) at src/gdb/main.c:1293
#33 0x0000555556264a7f in captured_main (data=0x7fffffffdd40) at src/gdb/main.c:1314
#34 0x0000555556264b2e in gdb_main (args=0x7fffffffdd40) at src/gdb/main.c:1343
#35 0x0000555555ceccab in main (argc=9, argv=0x7fffffffde78) at src/gdb/gdb.c:39
(top-gdb)
Again, after we enable stdin, GDB continues with its normal flow
of the 'run' command and receives the inferior's exit event, where
it would have enabled stdin, if we had not done it prematurely.
(top-gdb) bt
#0 async_enable_stdin () at src/gdb/event-top.c:523
#1 0x00005555561c3acd in normal_stop () at src/gdb/infrun.c:9432
#2 0x00005555561b5bf1 in fetch_inferior_event () at src/gdb/infrun.c:4700
#3 0x000055555618d6a7 in inferior_event_handler (event_type=INF_REG_EVENT) at src/gdb/inf-loop.c:42
#4 0x000055555620ecdb in handle_target_event (error=0, client_data=0x0) at src/gdb/linux-nat.c:4316
#5 0x0000555556f33035 in handle_file_event (file_ptr=0x5555587024e0, ready_mask=1) at src/gdbsupport/event-loop.cc:573
#6 0x0000555556f3362f in gdb_wait_for_event (block=0) at src/gdbsupport/event-loop.cc:694
#7 0x0000555556f322cd in gdb_do_one_event (mstimeout=-1) at src/gdbsupport/event-loop.cc:217
#8 0x0000555556262df8 in start_event_loop () at src/gdb/main.c:407
#9 0x0000555556262f85 in captured_command_loop () at src/gdb/main.c:471
#10 0x0000555556264a84 in captured_main (data=0x7fffffffdd40) at src/gdb/main.c:1324
#11 0x0000555556264b2e in gdb_main (args=0x7fffffffdd40) at src/gdb/main.c:1343
#12 0x0000555555ceccab in main (argc=9, argv=0x7fffffffde78) at src/gdb/gdb.c:39
(top-gdb)
The solution implemented by this patch addresses the problem. After
applying the patch, the output becomes
$ gdb -q -ex "source file.py" -ex "run" --args a.out
Reading symbols from /tmp/a.out...
Starting program: /tmp/a.out
loading /lib64/ld-linux-x86-64.so.2
Python Exception <class 'gdb.error'>: No symbol "a" in current context.
[Inferior 1 (process 3984511) exited normally]
(gdb)
Regression-tested on X86_64 Linux using the default board file (i.e. unix).
Co-Authored-By: Oguzhan Karakaya <oguzhan.karakaya@intel.com>
Reviewed-By: Guinevere Larsen <blarsen@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I noticed that the help text for set/show python ignore-environment
was messed up, some lines had unwanted leading white space, like this:
(gdb) help set python ignore-environment
Set whether the Python interpreter should ignore environment variables.
When enabled GDB's Python interpreter will ignore any Python related
flags in the environment. This is equivalent to passing `-E' to a
python executable.
(gdb)
This has been present since the ignore-environment setting was added
in commit:
commit edeaceda7b2f33b2c3bf78c732e67f3188e7f0b9
Date: Thu Aug 27 16:53:13 2020 +0100
gdb: startup commands to control Python extension language
Fixed in this commit.
|
|
Currently gdb.parameter doesn't raise an exception if an
ambiguous name is used, it instead returns the value of the
last partly matching parameter:
```
(gdb) show print sym
Ambiguous show print command "sym": symbol, symbol-filename, symbol-loading.
(gdb) show print symbol-loading
Printing of symbol loading messages is "full".
(gdb) py print(gdb.parameter("print sym"))
full
```
It's because lookup_cmd_composition_1 tries to detect
ambigous names by checking the return value of find_cmd
for CMD_LIST_AMBIGUOUS, which never happens, since only
lookup_cmd_1 returns CMD_LIST_AMBIGUOUS.
Instead the nfound argument contains the number of found
matches.
By using it instead, and by setting *CMD to the special value
CMD_LIST_AMBIGUOUS in this case, gdbpy_parameter can now show
the appropriate error message:
```
(gdb) py print(gdb.parameter("print sym"))
Traceback (most recent call last):
File "<string>", line 1, in <module>
RuntimeError: Parameter `print sym' is ambiguous.
Error while executing Python code.
(gdb) py print(gdb.parameter("print symbol"))
True
(gdb) py print(gdb.parameter("print symbol-"))
Traceback (most recent call last):
File "<string>", line 1, in <module>
RuntimeError: Parameter `print symbol-' is ambiguous.
Error while executing Python code.
(gdb) py print(gdb.parameter("print symbol-load"))
full
```
Since the document command also uses lookup_cmd_composition, it needed
to check for CMD_LIST_AMBIGUOUS as well, so it now also shows an
"Ambiguous command" error message in this case.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=14639
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This patch changes gdb to replace search_domain with
domain_search_flags everywhere. search_domain is removed.
|
|
This commit is the result of the following actions:
- Running gdb/copyright.py to update all of the copyright headers to
include 2024,
- Manually updating a few files the copyright.py script told me to
update, these files had copyright headers embedded within the
file,
- Regenerating gdbsupport/Makefile.in to refresh it's copyright
date,
- Using grep to find other files that still mentioned 2023. If
these files were updated last year from 2022 to 2023 then I've
updated them this year to 2024.
I'm sure I've probably missed some dates. Feel free to fix them up as
you spot them.
|
|
Move gdbpy_gil class into python-internal.h, the next
commit wants to make use of this class from a file other
than python.c.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
DAP cancellation needs a way to interrupt whatever is happening on
gdb's main thread -- whether that is the inferior, a gdb CLI command,
or Python code.
This patch adds a new gdb.interrupt() function for this purpose. It
simply sets the quit flag and lets gdb do the rest.
No tests in this patch -- instead this is tested via the DAP
cancellation tests.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-By: Kévin Le Gouguec <legouguec@adacore.com>
|
|
Since GDB now requires C++17, we don't need the internally maintained
gdb::optional implementation. This patch does the following replacing:
- gdb::optional -> std::optional
- gdb::in_place -> std::in_place
- #include "gdbsupport/gdb_optional.h" -> #include <optional>
This change has mostly been done automatically. One exception is
gdbsupport/thread-pool.* which did not use the gdb:: prefix as it
already lives in the gdb namespace.
Change-Id: I19a92fa03e89637bab136c72e34fd351524f65e9
Approved-By: Tom Tromey <tom@tromey.com>
Approved-By: Pedro Alves <pedro@palves.net>
|
|
If you run gdb in the build tree without --data-directory, on a
program that does not have debug info, it will crash, because
gdbpy_handle_missing_debuginfo unconditionally uses gdb_python_module.
Other code in gdb using gdb_python_module checks it first and it
seemes harmless to do the same thing here. (gdb_python_initialized
does not cover this case so that python can be partially initialized
and still somewhat work.)
|
|
This commit builds on the previous commit, and implements the
extension_language_ops::handle_missing_debuginfo function for Python.
This hook will give user supplied Python code a chance to help find
missing debug information.
The implementation of the new hook is pretty minimal within GDB's C++
code; most of the work is out-sourced to a Python implementation which
is modelled heavily on how GDB's Python frame unwinders are
implemented.
The following new commands are added as commands implemented in
Python, this is similar to how the Python unwinder commands are
implemented:
info missing-debug-handlers
enable missing-debug-handler LOCUS HANDLER
disable missing-debug-handler LOCUS HANDLER
To make use of this extension hook a user will create missing debug
information handler objects, and registers these handlers with GDB.
When GDB encounters an objfile that is missing debug information, each
handler is called in turn until one is able to help. Here is a
minimal handler that does nothing useful:
import gdb
import gdb.missing_debug
class MyFirstHandler(gdb.missing_debug.MissingDebugHandler):
def __init__(self):
super().__init__("my_first_handler")
def __call__(self, objfile):
# This handler does nothing useful.
return None
gdb.missing_debug.register_handler(None, MyFirstHandler())
Returning None from the __call__ method tells GDB that this handler
was unable to find the missing debug information, and GDB should ask
any other registered handlers.
By extending the __call__ method it is possible for the Python
extension to locate the debug information for objfile and return a
value that tells GDB how to use the information that has been located.
Possible return values from a handler:
- None: This means the handler couldn't help. GDB will call other
registered handlers to see if they can help instead.
- False: The handler has done all it can, but the debug information
for the objfile still couldn't be found. GDB will not call
any other handlers, and will continue without the debug
information for objfile.
- True: The handler has installed the debug information into a
location where GDB would normally expect to find it. GDB
should look again for the debug information.
- A string: The handler can return a filename, which is the file
containing the missing debug information. GDB will load
this file.
When a handler returns True, GDB will look again for the debug
information, but only using the standard built-in build-id and
.gnu_debuglink based lookup strategies. It is not possible for an
extension to trigger another debuginfod lookup; the assumption is that
the debuginfod server is remote, and out of the control of extensions
running within GDB.
Handlers can be registered globally, or per program space. GDB checks
the handlers for the current program space first, and then all of the
global handles. The first handler that returns a value that is not
None, has "handled" the objfile, at which point GDB continues.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I noticed that gdb/python/python.c unconditionally includes
gdbsupport/selftest.h.
Make this conditional on GDB_SELF_TEST.
Tested on x86_64-linux.
|
|
This function is just a wrapper around the current inferior's gdbarch.
I find that having that wrapper just obscures where the arch is coming
from, and that it's often used as "I don't know which arch to use so
I'll use this magical target_gdbarch function that gets me an arch" when
the arch should in fact come from something in the context (a thread,
objfile, symbol, etc). I think that removing it and inlining
`current_inferior ()->arch ()` everywhere will make it a bit clearer
where that arch comes from and will trigger people into reflecting
whether this is the right place to get the arch or not.
Change-Id: I79f14b4e4934c88f91ca3a3155f5fc3ea2fadf6b
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Make the inferior's gdbarch field private, and add getters and setters.
This helped me by allowing putting breakpoints on set_arch to know when
the inferior's arch was set. A subsequent patch in this series also
adds more things in set_arch.
Change-Id: I0005bd1ef4cd6b612af501201cec44e457998eec
Reviewed-By: John Baldwin <jhb@FreeBSD.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
This commit adds a new Python function, gdb.notify_mi, that can be used
to emit custom async notification to MI channel. This can be used, among
other things, to implement notifications about events MI does not support,
such as remote connection closed or register change.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Tom de Vries filed a bug about an intermittent gdb DAP failure -- and
coincidentally, at the same time, Alexandra Hájková sent email about a
somewhat similar failure.
After looking into this for a while (with no results) using ASan and
valgrind, I found that setting PYTHONMALLOC=malloc_debug found the bug
instantly.
The problem is that gdbpy_parse_and_eval releases the GIL while
calling parse_and_eval, but fails to re-acquire it before calling
value_to_value_object. This is easily fixed by introducing a new
scope.
I wonder whether the test suite should unconditionally set
PYTHONMALLOC=malloc_debug.
Tested-by: Tom de Vries <tdevries@suse.de>
Reviewed-By: Tom de Vries <tdevries@suse.de>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30686
|
|
Fix a few typos:
- implemention -> implementation
- convertion(s) -> conversion(s)
- backlashes -> backslashes
- signoring -> ignoring
- (un)ambigious -> (un)ambiguous
- occured -> occurred
- hidding -> hiding
- temporarilly -> temporarily
- immediatelly -> immediately
- sillyness -> silliness
- similiar -> similar
- porkuser -> pokeuser
- thats -> that
- alway -> always
- supercede -> supersede
- accomodate -> accommodate
- aquire -> acquire
- priveleged -> privileged
- priviliged -> privileged
- priviledges -> privileges
- privilige -> privilege
- recieve -> receive
- (p)refered -> (p)referred
- succesfully -> successfully
- successfuly -> successfully
- responsability -> responsibility
- wether -> whether
- wich -> which
- disasbleable -> disableable
- descriminant -> discriminant
- construcstor -> constructor
- underlaying -> underlying
- underyling -> underlying
- structureal -> structural
- appearences -> appearances
- terciarily -> tertiarily
- resgisters -> registers
- reacheable -> reachable
- likelyhood -> likelihood
- intepreter -> interpreter
- disassemly -> disassembly
- covnersion -> conversion
- conviently -> conveniently
- atttribute -> attribute
- struction -> struct
- resonable -> reasonable
- popupated -> populated
- namespaxe -> namespace
- intialize -> initialize
- identifer(s) -> identifier(s)
- expection -> exception
- exectuted -> executed
- dungerous -> dangerous
- dissapear -> disappear
- completly -> completely
- (inter)changable -> (inter)changeable
- beakpoint -> breakpoint
- automativ -> automatic
- alocating -> allocating
- agressive -> aggressive
- writting -> writing
- reguires -> requires
- registed -> registered
- recuding -> reducing
- opeartor -> operator
- ommitted -> omitted
- modifing -> modifying
- intances -> instances
- imbedded -> embedded
- gdbaarch -> gdbarch
- exection -> execution
- direcive -> directive
- demanged -> demangled
- decidely -> decidedly
- argments -> arguments
- agrument -> argument
- amespace -> namespace
- targtet -> target
- supress(ed) -> suppress(ed)
- startum -> stratum
- squence -> sequence
- prompty -> prompt
- overlow -> overflow
- memember -> member
- languge -> language
- geneate -> generate
- funcion -> function
- exising -> existing
- dinking -> syncing
- destroh -> destroy
- clenaed -> cleaned
- changep -> changedp (name of variable)
- arround -> around
- aproach -> approach
- whould -> would
- symobl -> symbol
- recuse -> recurse
- outter -> outer
- freeds -> frees
- contex -> context
Tested on x86_64-linux.
Reviewed-By: Tom Tromey <tom@tromey.com>
|
|
This adds a 'global_context' parse_and_eval to gdb.parse_and_eval.
This lets users request a parse that is done at "global scope".
I considered letting callers pass in a block instead, with None
meaning "global" -- but then there didn't seem to be a clean way to
express the default for this parameter.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
This adds a new Python function, gdb.execute_mi, that can be used to
invoke an MI command but get the output as a Python object, rather
than a string. This is done by implementing a new ui_out subclass
that builds a Python object.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=11688
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
|
|
Currently, when we add a new python sub-system to GDB,
e.g. py-inferior.c, we end up having to create a new function like
gdbpy_initialize_inferior, which then has to be called from the
function do_start_initialization in python.c.
In some cases (py-micmd.c and py-tui.c), we have two functions
gdbpy_initialize_*, and gdbpy_finalize_*, with the second being called
from finalize_python which is also in python.c.
This commit proposes a mechanism to manage these initialization and
finalization calls, this means that adding a new Python subsystem will
no longer require changes to python.c or python-internal.h, instead,
the initialization and finalization functions will be registered
directly from the sub-system file, e.g. py-inferior.c, or py-micmd.c.
The initialization and finalization functions are managed through a
new class gdbpy_initialize_file in python-internal.h. This class
contains a single global vector of all the initialization and
finalization functions.
In each Python sub-system we create a new gdbpy_initialize_file
object, the object constructor takes care of registering the two
callback functions.
Now from python.c we can call static functions on the
gdbpy_initialize_file class which take care of walking the callback
list and invoking each callback in turn.
To slightly simplify the Python sub-system files I added a new macro
GDBPY_INITIALIZE_FILE, which hides the need to create an object. We
can now just do this:
GDBPY_INITIALIZE_FILE (gdbpy_initialize_registers);
One possible problem with this change is that there is now no
guaranteed ordering of how the various sub-systems are initialized (or
finalized). To try and avoid dependencies creeping in I have added a
use of the environment variable GDB_REVERSE_INIT_FUNCTIONS, this is
the same environment variable used in the generated init.c file.
Just like with init.c, when this environment variable is set we
reverse the list of Python initialization (and finalization)
functions. As there is already a test that starts GDB with the
environment variable set then this should offer some level of
protection against dependencies creeping in - though for full
protection I guess we'd need to run all gdb.python/*.exp tests with
the variable set.
I have tested this patch with the environment variable set, and saw no
regressions, so I think we are fine right now.
One other change of note was for gdbpy_initialize_gdb_readline, this
function previously returned void. In order to make this function
have the correct signature I've updated its return type to int, and we
now return 0 to indicate success.
All of the other initialize (and finalize) functions have been made
static within their respective sub-system files.
There should be no user visible changes after this commit.
|