Age | Commit message (Collapse) | Author | Files | Lines |
|
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
|
|
The top comment in gdb.python/py-source-styling.exp was completely
wrong, clearly a cut&paste job from elsewhere. Write a comment that
actually reflects what the test does.
I've also moved the allow_python_tests check earlier in the file.
And I changed some 'return -1' into just 'return'. I'm not aware that
the '-1' adds any value.
I also folded a 'pass $gdb_test_name' into the preceding gdb_assert,
which I think is neater.
There is no change in what is actually being tested after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
The current py-symbol.exp test makes an assumption about which symbol
will be returned first. I don't think gdb should really make promises
about the order in which the symbols are listed, though, and a series
I am working on changes this behavior. This patch changes the test to
merely ensure that both symbols are returned.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
|
|
The procedures set_sanitizer_1, set_sanitizer and set_sanitizer_default
are used for the configuration of ASAN specific environment variables.
However, they are actually generic. Rename them to append_environment*
so that their purpose is more clear.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
This commit adds a new method to Python architecture objects that
returns a void type for that architecture.
This will be useful later to create types for function symbols created
using Python extension code.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
This commit adds new propery "subblocks" to gdb.Block objects. This
allows Python to traverse block tree starting with global block.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
With test-case gdb.python/py-mi-notify.exp and python 3.4, I occasionally run
into:
...
python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })
&"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n"
=-test-notification,data2="2",data1="1"
^done
(gdb)
FAIL: $exp: python notification, with additional data (unexpected output)
...
In contrast, a passing version looks like:
...
python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })
&"python gdb.notify_mi('-test-notification', { 'data1' : 1 , 'data2' : 2 })\n"
=-test-notification,data1="1",data2="2"
^done
(gdb)
PASS: gdb.python/py-mi-notify.exp: python notification, with additional data
...
The python method "gdb.notify_mi(name, data)" has parameter data which is a
dictionary, and it iterates over that dictionary.
The problem is that dictionaries are only guaranteed to be iterating in
insertion order starting python 3.7 (though cpython does this starting python
3.6).
Fix this in the same way as in commit 362a867f2ac ("[gdb/testsuite] Handle
unordered dict in gdb.python/py-mi-cmd.exp"): by allowing the alternative
order.
Tested on x86_64-linux.
|
|
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.
|
|
This removes the "then" keyword from the test suite. Andrew did this
once before, but some new ones crept in.
This also adds braces to the "if" conditions and normalizes the
failures to just use "return".
|
|
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
|
|
This changes gdbpy_lookup_static_symbols to pass the 'flags' parameter
to expand_symtabs_matching. This should refine the search somewhat.
Note this is "just" a performance improvement, as the loop over
symtabs already checks 'flags'.
v2 also removes 'SEARCH_GLOBAL_BLOCK' and updates py-symbol.exp to
verify that this works properly. Thanks to Tom for this insight.
Co-Authored-By: Tom de Vries <tdevries@suse.de>
|
|
Since commit e69d35f45e0 ("Use ui-out table in "maint print reggroups""),
test-case gdb.python/py-arch-reg-groups.exp fails with check-read1:
...
FAIL: $exp: Same number of registers groups found
FAIL: $exp: all register groups match
...
Fix this by adding a gdb_test_multiple clause that matches the command.
Tested on x86_64-linux.
|
|
gdbpy_create_lazy_string_object will throw an exception if you pass it
a NULL pointer without also setting length=0 -- the default,
length==-1, will fail. This seems bizarre. Furthermore, it doesn't
make sense to do this check for array types, as an array can have a
zero length. This patch cleans up the check and makes it specific to
TYPE_CODE_PTR.
|
|
Currently, gdb.Value.lazy_string will allow the conversion of any
object to a "lazy string". However, this was never the intent and is
weird besides. This patch changes this code to correctly throw an
exception in the non-matching cases.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=20769
|
|
While testing DAP, we found a situation where a compiler-generated
variable caused the "variables" request to fail -- the variable in
question being an apparent 67-megabyte string.
It seems to me that artificial variables like this aren't interesting
to DAP users, and the gdb CLI omits these as well.
This patch changes DAP to omit these variables, adding a new
gdb.Symbol.is_artificial attribute to make this possible.
|
|
In commit 922ab963e1c ("[gdb/python] Handle empty PYTHONDONTWRITEBYTECODE") I
added a test in gdb.python/py-startup-opt.exp that checks the
"show python dont-write-bytecode" output.
Then in commit 348290c7ef4 ("[gdb/python] Warn and ignore ineffective python
settings") I changed the output of "show python dont-write-bytecode" after
python initialization.
I tested these changes individually, and found no problems but after
committing both the test started failing, which the Linaro CI reported.
Fix this by updating the expected output.
While we're at it, make the test a bit more generic by testing
"show python $setting" in all cases.
Tested on x86_64-linux, using:
- PYTHONDONTWRITEBYTECODE=
- PYTHONDONTWRITEBYTECODE=1
- unset PYTHONDONTWRITEBYTECODE
|
|
This changes the "maint print reggroups" command to use a ui-out table
rather than printf.
It also fixes a typo I noticed in a related test case name; and lets
us finally remove the leading \s from the regexp in completion.exp.
Reviewed-by: Christina Schimpe <christina.schimpe@intel.com>
Approved-By: Andrew Burgess <aburgess@redhat.com>
|
|
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
|
|
PYTHONDONTWRITEBYTECODE
When running test-case gdb.python/py-startup-opt.exp with empty
PYTHONDONTWRITEBYTECODE:
...
$ cd build/gdb/testsuite
$ PYTHONDONTWRITEBYTECODE= make check \
RUNTESTFLAGS=gdb.python/py-startup-opt.exp
...
I get:
...
end^M
dont_write_bytecode is off^M
(gdb) FAIL: $exp: attr=dont_write_bytecode: testname: input 6: end
...
The problem is that the test-case expects dont_write_bytecode to be
on, which is incorrect because PYTHONDONTWRITEBYTECODE only has effect if set
to a non-empty string [1].
Fix this by correctly setting expectations in the test-case.
Tested on x86_64-linux, with:
- PYTHONDONTWRITEBYTECODE=
- PYTHONDONTWRITEBYTECODE=1
- unset PYTHONDONTWRITEBYTECODE
Approved-By: Tom Tromey <tom@tromey.com>
[1] https://docs.python.org/3/using/cmdline.html#envvar-PYTHONDONTWRITEBYTECODE
|
|
When building gdb with --disable-tui, we run into:
...
(gdb) python print(type(gdb.TuiWindow))^M
Python Exception <class 'AttributeError'>: \
module 'gdb' has no attribute 'TuiWindow'^M
Error occurred in Python: module 'gdb' has no attribute 'TuiWindow'^M
(gdb) FAIL: gdb.python/python.exp: gdb.TuiWindow is registered
...
Fix this by skipping the test for --disable-tui.
Tested on x86_64-linux.
|
|
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>
|
|
As with the previous two commits, this commit fixes a location where
we called PyObject_IsTrue without including an error check, this time
in bppy_init.
The 'qualified' argument is supposed to be a bool, the docs say:
The optional QUALIFIED argument is a boolean that allows
interpreting the function passed in 'spec' as a fully-qualified
name. It is equivalent to 'break''s '-qualified' flag (*note
Linespec Locations:: and *note Explicit Locations::).
It's not totally clear that the only valid values are True or False,
but I'm choosing to interpret the docs that way, and so I've added a
PyBool_Type check during argument parsing. Now, if a non-bool is
passed the user will get a TypeError during argument parsing. I've
added a test to cover this case.
This is a potentially breaking change to the Python API, but hopefully
this will not impact too many people. I've added a NEWS entry to
highlight this change.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Like the previous commit, I discovered that in micmdpy_set_installed
we were calling PyObject_IsTrue, but not checking for a possible error
value being returned.
The micmdpy_set_installed function implements the
gdb.MICommand.installed attribute, and the documentation indicates that
this attribute should only be assigned a bool:
This attribute is read-write, setting this attribute to 'False'
will uninstall the command, removing it from the set of available
commands. Setting this attribute to 'True' will install the
command for use.
So I propose that instead of using PyObject_IsTrue we use
PyBool_Check, and if the new value fails this check we raise an
error. We can then compare the new value to Py_True directly instead
of calling PyObject_IsTrue.
This is a potentially breaking change to the Python API, but hopefully
this will not impact too many people, and the fix is pretty
easy (switch to using a bool). I've added a NEWS entry to draw
attention to this change.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
Building on the previous two commits, I was auditing our uses of
PyObject_IsTrue looking for places where we were missing an error
check.
The gdb.Architecture.integer_type() function takes a 'signed' argument
which should be a 'bool', and the docs do say:
If SIGNED is not specified, it defaults to 'True'. If SIGNED is
'False', the returned type will be unsigned.
Currently we use PyObject_IsTrue, but we are missing an error check.
To fix this I've tightened the code to enforce the bool requirement at
the point that the arguments are parsed. With that done I can remove
the call to PyObject_IsTrue and instead compare to Py_True directly,
the object in question will always be a PyBool_Type.
However, we were testing that passing a non-bool argument for 'signed'
is treated as Py_False, this was added with this commit:
commit 90fe61ced1c9aa4afb263326e336330d15603fbf
Date: Mon Nov 29 13:53:06 2021 +0000
gdb/python: don't use the 'p' format for parsing args
which is when the PyObject_IsTrue call was added. Given that the docs
do seem pretty clear that only True or False are suitable argument
values, my proposal is that we just remove these tests and instead
test that any non-bool argument value for 'signed' gives a TypeError.
This is a breaking change to the Python API, however, my hope is that
this is such a edge case that it will not cause too many problem.
I've added a NEWS entry to highlight this change though.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
|
|
After the previous commit I audited all our uses of PyObject_IsTrue
looking for places where we were missing an error check. I did find
some that are missing error checks in places where we really should
have error checks, and I'll fix those in later commits.
This commit however, focuses on those locations where PyObject_IsTrue
is called, there is no error check, and the error check isn't really
necessary because we already know that the object we are dealing with
is of type PyBool_Type.
Inline with the previous commit, in these cases I have removed the
PyObject_IsTrue call, and replaced it with a comparison against
Py_True. In one location where it is not obvious that the object we
have is PyBool_Type I've added an assert, but in the other cases the
comparison to Py_True immediately follows a PyBool_Check call, so an
assert would be redundant.
I've added a test for the gdb.Value.format_string styling argument
being passed a non-bool value as this wasn't previously being tested,
though this new test will pass before and after this commit.
There should be no functional change after this commit.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
I noticed that in commit:
commit 5cabc8098e65ac22d4245232ad20b19fa4729802
Date: Wed Jul 31 15:55:57 2024 +0100
gdb/python: implement Python find_exec_by_build_id hook
I managed to typo 'unsupported' as 'unsupport'. If you run the test
on a target that doesn't support core file creation then you'll get a
TCL error.
Fixed in this commit.
|
|
pre-commit pointed out that one file needed a change to satisfy isort.
This patch is the result.
|
|
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>
|
|
This adds a new event source so that Python scripts can track whether
or not the TUI is presently enabled.
v2 of the patch renames "status" -> "enabled".
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32162
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Reviewed-by: Keith Seitz <keiths@redhat.com>
|
|
I ran the testsuite in an environment simulating a stressed system in
combination with check-read1. This exposes a few more FAILs.
Fix some by using gdb_test_lines, as well as related gdb_get_lines.
Tested on x86_64-linux.
|
|
Hannes pointed out that gdb.execute_mi() will crash.
This patch fixes the bug.
Reviewed-By: Guinevere Larsen <guinevere@redhat.com>
|
|
With a gdb build with -fsanitize=thread, and test-case
gdb.python/py-inferior.exp I run into:
...
(gdb) python gdb.selected_inferior().read_memory (0, 0xffffffffffffffff)^M
ERROR: ThreadSanitizer: requested allocation size 0xffffffffffffffff exceeds \
maximum supported size of 0x10000000000^M
...
There's already a workaround for this using ASAN_OPTIONS, and apparently the
same is needed for TSAN_OPTIONS.
Add the allocator_may_return_null=1 workaround also in TSAN_OPTIONS.
Likewise in gdb.dap/memory.exp.
Tested on x86_64-linux.
|
|
Fix the following common misspellings:
...
accidently -> accidentally
additonal -> additional
addresing -> addressing
adress -> address
agaisnt -> against
albiet -> albeit
arbitary -> arbitrary
artifical -> artificial
auxillary -> auxiliary
auxilliary -> auxiliary
bcak -> back
begining -> beginning
cannonical -> canonical
compatiblity -> compatibility
completetion -> completion
diferent -> different
emited -> emitted
emiting -> emitting
emmitted -> emitted
everytime -> every time
excercise -> exercise
existance -> existence
fucntion -> function
funtion -> function
guarentee -> guarantee
htis -> this
immediatly -> immediately
layed -> laid
noone -> no one
occurances -> occurrences
occured -> occurred
originaly -> originally
preceeded -> preceded
preceeds -> precedes
propogate -> propagate
publically -> publicly
refering -> referring
substract -> subtract
substracting -> subtracting
substraction -> subtraction
taht -> that
targetting -> targeting
teh -> the
thier -> their
thru -> through
transfered -> transferred
transfering -> transferring
upto -> up to
vincinity -> vicinity
whcih -> which
whereever -> wherever
wierd -> weird
withing -> within
writen -> written
wtih -> with
doesnt -> doesn't
...
Tested on x86_64-linux.
|
|
Re-running 'isort' (via pre-commit) showed that the file
py-read-memory-leak.py (from the gdb test suite) needed a small patch.
|
|
For a long time Fedora GDB has carried an out of tree patch which
checks for memory leaks in gdb.Inferior.read_memory(). At one point
in the distant past GDB did have a memory leak in this code, but this
was first fixed in commit:
commit 655e820cf9a039ee55325d9e1f8423796d592b4b
Date: Wed Mar 28 17:38:07 2012 +0000
* python/py-inferior.c (infpy_read_memory): Remove cleanups and
explicitly free 'buffer' on exit paths. Decref 'membuf_object'
before returning.
And the code has changed a lot since then, but the leak is still
fixed. Unfortunately, this commit didn't have any associated tests.
The original Fedora test wasn't really suitable for upstream, it was
reading /proc/PID/... to figure out if there was a leak or not.
However, we already have gdb.python/py-inferior-leak.exp in upstream
GDB, which makes use of the Python tracemalloc module to check for
memory leaks in a corner of the Python API, so I figured it wouldn't
hurt to rewrite the test in the same style.
And so here is a test for a bug which was closed 12 years ago. This
detects if the gdb.Inferior.read_memory() call leaks any memory.
I've tested this by hacking gdbpy_buffer_to_membuf, replacing the last
line which currently looks like this:
return PyMemoryView_FromObject ((PyObject *) membuf_obj.get ());
and instead doing:
return PyMemoryView_FromObject ((PyObject *) membuf_obj.release ());
The use of "release" here will mean we no longer decrement the
reference count on membuf_obj before returning from the function. As
a consequence the membuf_obj will not be garbage collected. With this
hack in place the new test will fail.
The Python script in the new test is mostly a copy&paste from
py-inferior-leak.py with the core changed to do a memory read instead
of inferior creation. I did consider rewriting both tests into a
single file, maybe, py-memory-leak.py, which would make it easier to
add additional similar tests in the future. For now I've held off
doing that, but if this gets merged then I _might_ revisit this idea.
If folk feel that this new test should only be accepted if I do this
rewrite then let me know and I can get that done.
On copyright date ranges: The .exp and .py scripts are new enough for
this commit that I've dated them 2024. The .c source script is lifted
directly from the old Fedora patch, so I've retained the original 2014
start date for that file only.
Approved-By: Tom Tromey <tom@tromey.com>
|
|
With gdb 15.1, python sys.exit no longer makes gdb exit:
...
$ gdb -q -batch -ex "python sys.exit(2)" -ex "print 123"; echo $?
Python Exception <class 'SystemExit'>: 2
Error occurred in Python: 2
$1 = 123
0
...
This is a change in behaviour since commit a207f6b3a38 ("Rewrite "python"
command exception handling"), first available in gdb 15.1.
This patch reverts to the old behaviour by handling PyExc_SystemExit in
gdbpy_handle_exception, such what we have instead:
...
$ gdb -q -batch -ex "python sys.exit(2)" -ex "print 123"; echo $?
2
...
Tested on x86_64-linux, with python 3.6 and 3.13.
Tested-By: Guinevere Larsen <blarsen@redhat.com>
Approved-By: Tom Tromey <tom@tromey.com>
PR python/31946
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31946
|
|
Format with black.
Change-Id: I28e79e9da07ea29391ad1942047633960fa72ed2
|
|
GDB deprecated the commands "show/set mpx bound" in GDB 15.1, as Intel
listed Intel(R) Memory Protection Extensions (MPX) as removed in 2019.
MPX is also deprecated in gcc (since v9.1), the linux kernel (since v5.6)
and glibc (since v2.35). Let's now remove MPX support in GDB completely.
This includes the removal of:
- MPX functionality including register support
- deprecated mpx commands
- i386 and amd64 implementation of the hooks report_signal_info and
get_siginfo_type
- tests
- and pretty printer.
We keep MPX register numbers to not break compatibility with old gdbservers.
Approved-By: Felix Willgerodt <felix.willgerodt@intel.com>
|
|
Removing the pretty printer (bound_registers.py) in the next commit
leads to failures due to a missing import of 'gdb.printing':
"AttributeError: module 'gdb' has no attribute 'printing'".
Add this import to each file requiring it, as it's not imported by the
pretty-printer anymore.
Approved-By: Andrew Burgess <aburgess@redhat.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 typo in a test name in py-arch.exp.
|
|
gdb.python/py-missing-debug.exp"
This reverts commit 29c70787112e01cd52b53bf14bdcacb0a11e0725.
After the previous commit 29c70787112e01cd52 should no longer be
needed as the curses dependency has been removed.
|
|
On a system with python 3.6, module gdb.missing_debug imports module curses,
so when running test-case gdb.python/py-missing-debug.exp on a system without
that module installed, we run into:
...
(gdb) source py-missing-debug.py^M
Python Exception <class 'ImportError'>: Module 'curses' is not installed.^M
Use:^M
sudo zypper install python36-curses^M
to install it.^M
Error occurred in Python: Module 'curses' is not installed.^M
Use:^M
sudo zypper install python36-curses^M
to install it.^M
(gdb) FAIL: gdb.python/py-missing-debug.exp: source python script
...
Fix this by issuing UNSUPPORTED instead, and bailing out.
Tested on x86_64-linux.
Approved-by: Kevin Buettner <kevinb@redhat.com>
PR testsuite/31576
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31576
|
|
When debugging ROCm code, you might have something like this:
__global__ void kernel ()
{
...
// break here
...
}
int main ()
{
// Code to call `kernel`
}
... where kernel is a function compiled to execute on the GPU. It does
not exist in the host x86-64 program that runs the main function, and
GDB doesn't know about that function until it is called, at which point
the runtime loads the corresponding code object and GDB learns about the
code of the "kernel" function. Before the GPU code object is loaded,
from the point of view of GDB, you might as well have blank lines
instead of the "kernel" function. The DWARF in the host program doesn't
describe anything at these lines.
So, a common problem that users face is:
- Start GDB with the host binary
- Place a breakpoint by line number at the "break here" line
- At this point, GDB only knows about the host code, the lines of the
`kernel` function are a big void.
- GDB finds no code mapped to the "break here" line and searches for
the first following line that has code mapped to it.
- GDB finds that the line with the opening bracket of the `main`
function (or around there) has code mapped to it, places breakpoint
there.
- User runs the program.
- The programs hits the breakpoint at the start of main.
- User is confused, because they didn't ask for a breakpoint in main.
If they continue, the code object eventually gets loaded, GDB reads the
debug info from it, re-evaluates the breakpoint locations, and at this
point the breakpoint is placed at the expected location.
The goal of this patch is to get rid of this annoyance.
A case similar to the one shown above can actually be simulated without
GPU-specific code: using a single source file to generate a library and
an executable loading that library (see the new test
gdb.linespec/line-breakpoint-outside-function.c for an example). Before
the library is loaded, trying to place a breakpoint in the library code
results in the breakpoint "drifting" down to the main function.
To address this problem, make it so that when a user requests a
breakpoint outside a function, GDB makes a pending breakpoint, rather
than placing a breakpoint at the next line with code, which happens to
be in the next function. When the GPU kernel or shared library gets
loaded, the breakpoint resolves to a location in the kernel or library.
Note that we still want breakpoints placed inside a function to
"drift" down to the next line with code. For example, here:
9
10 void foo()
11 {
12 int x;
13
14 x++;
There is probably no code associated to lines 10, 12 and 13, but the
user can still reasonably expect to be able to put a breakpoint there.
In my experience, GCC maps the function prologue to the line with the
opening curly bracket, so the user will be able to place a breakpoint
there anyway (line 11 in the example). But I don't really see a use
case to put a breakpoint above line 10 and expect to get a breakpoint in
foo. So I think that is a reasonable behavior change for GDB.
This is implemented using the following heuristic:
- If a breakpoint is requested at line L but there is no code mapped to
L, search for a following line with associated code (this already
exists today).
- However, if:
1. the found location falls in a function symbol's block
2. the found location's address is equal the entry PC of that
function
3. the found location's line is greater that the requested line
... then we don't place a breakpoint at the found location, we will
end up with a pending breakpoint.
Change the message "No line X in file..." to "No compiled code for line
X in file...". There is clearly a line 9 in the example above, so it
would be weird to say "No line 9 in file...". What we mean is that
there is no code associated to line 9.
All the regressions that I found this patch to cause were:
1. tests specifically this behavior where placing a breakpoint before
a function results in a breakpoint on that function, in which case I
removed the tests or changed them to expect a pending breakpoint
2. linespec tests expecting things like "break -line N garbage" to
error out because of the following garbage, but we now got a
different error because line N now doesn't resolve to something
anymore. For example, before:
(gdb) break -line 3 if foofoofoo == 1
No symbol "foofoofoo" in current context.
became
(gdb) break -line 3 if foofoofoo == 1
No line 3 in the current file.
These tests were modified to refer to a valid line with code, so
that we can still test what we intended to test.
Notes:
- The CUDA compiler "solves" this problem by adding dummy function
symbols between functions, that are never called. So when you try to
insert a breakpoint in the not-yet-loaded kernel, the breakpoint
still drifts, but is placed on some dummy symbol. For reasons that
would be too long to explain here, the ROCm compiler does not do
that, and it is not a desirable option.
- You can have constructs like this:
void host_function()
{
struct foo
{
static void __global__ kernel ()
{
// Place breakpoint here
}
};
// Host code that calls `kernel`
}
The heuristic won't work then, as the breakpoint will drift somewhere
inside the enclosing function, but won't be at the start of that
function. So a bogus breakpoint location will be created on the host
side. I don't think that people are going to use this kind of
construct often though, so we can probably ignore it (or at least it
shouldn't prevent making the more common case better).
ROCm doesn't support passing a lambda kernel function to
hipLaunchKernelGGL (the function used to launch kernels on the
device), but if it eventually does, there will be the same
problem.
I think that to properly support this, we will need some DWARF
improvements to be able to say "there is really nothing at these
lines" in the line table.
Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I3cc12cfa823dc7d8e24dd4d35bced8e8baf7f9b6
|
|
When running test-case gdb.python/py-mi-cmd.exp with python 3.13, I run into:
...
Expecting: ^(-pycmd exp[^M
]+)?(.*&"Traceback \(most recent call last\):.."^M
&"[^^M
]+py-mi-cmd.py[^^M
]+"^M
&"[^^M
]+raise gdb.GdbError\(\).."^M
&"gdb.GdbError.."^M
\^error,msg="Error occurred in Python\."[^M
]+[(]gdb[)] ^M
[ ]*)
-pycmd exp^M
&"Traceback (most recent call last):\n"^M
&" File \"py-mi-cmd.py\", line 76, in invoke\n raise gdb.GdbError()\n"^M
&"gdb.GdbError\n"^M
^error,msg="Error occurred in Python."^M
(gdb) ^M
FAIL: gdb.python/py-mi-cmd.exp: -pycmd exp (unexpected output)
...
In contrast, with python 3.12 I have:
...
Expecting: ^(-pycmd exp[^M
]+)?(.*&"Traceback \(most recent call last\):.."^M
&"[^^M
]+py-mi-cmd.py[^^M
]+"^M
&"[^^M
]+raise gdb.GdbError\(\).."^M
&"gdb.GdbError.."^M
\^error,msg="Error occurred in Python\."[^M
]+[(]gdb[)] ^M
[ ]*)
-pycmd exp^M
&"Traceback (most recent call last):\n"^M
&" File \"py-mi-cmd.py\", line 76, in invoke\n"^M
&" raise gdb.GdbError()\n"^M
&"gdb.GdbError\n"^M
^error,msg="Error occurred in Python."^M
(gdb) ^M
PASS: gdb.python/py-mi-cmd.exp: -pycmd exp
...
To make it easier to understand what we're looking at, let's take this out of
the mi interpreter context and use the cli interpreter:
...
$ gdb -q -batch -ex "set trace-commands on" -x gdb.in
+set python print-stack full
+source py-mi-cmd.py
+python pycmd1('-pycmd')
+python pycmd1.invoke (pycmd1, ["exp"])
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "py-mi-cmd.py", line 76, in invoke
raise gdb.GdbError()
gdb.GdbError
gdb.in:4: Error in sourced command file:
Error occurred in Python.
...
Interestingly, this is what we're seeing with both python 3.12 and 3.13.
The difference between the python versions is that:
- with python 3.12 each line is printed by itself, and
- with python 3.13 two particular lines are printed toghether.
With the cli interpreter, that makes no difference, because the '\n' is
interpreted.
But with the mi interpreter, that causes a difference in output because the
'\n' is not interpreted, but rather printed literally.
Fix this by accepting the new output in addition to the old one.
Tested on aarch64-linux.
Reviewed-by: Thiago Jung Bauermann <thiago.bauermann@linaro.org>
PR testsuite/31913
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31913
|
|
Usually with test-case gdb.python/py-progspace-events.exp I get:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 4116] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 4116))]^M
28 { /* Nothing. */ }^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
step^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabf4f850>^M
do_parent_stuff () at py-progspace-events.c:41^M
41 ++global_var;^M
(gdb) PASS: gdb.python/py-progspace-events.exp: step
...
But occasionally I run into the following FAIL:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
(gdb) FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
FAIL: gdb.python/py-progspace-events.exp: inferior 1 (timeout)
...
This is caused by a race between the handling of an event, and the
"inferior 1" command.
In the passing case, the event is handled first. During which prune_inferiors
is called, but it can't remove inferior 2, because it's still the current one.
In the failing case, the "inferior 1" command is handled first. Then during
handling of the event, prune_inferiors is called, and it can remove inferior 2
because it's no longer the current one.
This looks like a test-case issue to me, but ISTM that we can do better: by
calling prune_inferiors asap, at the end of the "inferior 1" command, we
stabilize the moment when the inferior is removed:
...
(gdb) inferior 1^M
[Switching to inferior 1 [process 5199] (py-progspace-events)]^M
[Switching to thread 1.1 (Thread 0xf77d0ce0 (LWP 5199))]^M
28 { /* Nothing. */ }^M
FreeProgspaceEvent: <gdb.Progspace object at 0xabaf03a0>^M
(gdb) PASS: gdb.python/py-progspace-events.exp: inferior 1
...
This also allows us to simplify the test-case by removing the step command,
which is no longer required to trigger the pruning of the inferior.
Tested on x86_64-linux.
Approved-by: Kevin Buettner <kevinb@redhat.com>
PR gdb/31440
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=31440
|
|
My previous patch
commit 8958aefd34200c8d2cd6e81bba32198468789c62 (HEAD)
Author: Felix Willgerodt <felix.willgerodt@intel.com>
Date: Mon Feb 25 15:30:29 2019 +0100
python: Add clear() to gdb.Record.
exposed a clear function for btrace data in python and added some tests
for it. That caused a regression (PR 32086) when recording with bts.
This is reproducible even without my patch, when adding
"maintenance btrace clear" to the test.
When comparing the instructions that get recorded in both cases, the traces
are almost identical, just that the first 3 instructions are missing.
Before clear:
(gdb) record instruction-history 1,100
1 0x0000555555555163 <main+12>: movl $0x0,-0x4(%rbp)
2 0x000055555555516a <main+19>: movl $0x0,-0x8(%rbp)
3 0x0000555555555171 <main+26>: jmp 0x555555555184 <main+45>
4 0x0000555555555184 <main+45>: cmpl $0x63,-0x4(%rbp)
5 0x0000555555555188 <main+49>: jle 0x555555555173 <main+28>
6 0x0000555555555173 <main+28>: mov -0x8(%rbp),%eax
7 0x0000555555555176 <main+31>: mov %eax,%edi
...
After clear:
(gdb) record instruction-history 1,100
1 0x0000555555555184 <main+45>: cmpl $0x63,-0x4(%rbp)
2 0x0000555555555188 <main+49>: jle 0x555555555173 <main+28>
3 0x0000555555555173 <main+28>: mov -0x8(%rbp),%eax
4 0x0000555555555176 <main+31>: mov %eax,%edi
...
The GDB manual describes this behaviour already:
maint btrace clear
Discard the branch trace data. The data will be fetched anew and
the branch trace will be recomputed when needed.
This implicitly truncates the branch trace to a single branch trace
buffer. When updating branch trace incrementally, the branch trace
available to GDB may be bigger than a single branch trace buffer.
The test with BTS is updating the recorded trace incrementally. After the
clear, the buffer of raw trace data available is not enough to recompute the
whole trace as it was before the clear(), and the first 3 instructions are
missing.
As increasing the buffer size for BTS didn't help, I propose to fix the test
by moving the testing of clear to the end of the test.
Approved-By: Tom de Vries <tdevries@suse.de>
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32086
|
|
This function allows to clear the trace data from python, forcing to
re-decode the trace for successive commands.
This will be used in future ptwrite patches, to trigger re-decoding when
the ptwrite filter changes.
Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Markus Metzger <markus.t.metzger@intel.com>
|