Commit graph

20 commits

Author SHA1 Message Date
Simon Marchi
be40200bc9 gdb/testsuite: update field names in gdb-gdb.py.in
Patches that renamed the type::length and type::target_type fields
didn't update gdb-gdb.py.in accordingly, do that.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=29599
Change-Id: I0f3f37a94d43497789156b0ded4d2f2dd5b89496
2022-09-26 17:28:21 -04:00
Joel Brobecker
4a94e36819 Automatic Copyright Year update after running gdb/copyright.py
This commit brings all the changes made by running gdb/copyright.py
as per GDB's Start of New Year Procedure.

For the avoidance of doubt, all changes in this commits were
performed by the script.
2022-01-01 19:13:23 +04:00
Simon Marchi
a547eaf18c gdb: re-format with black 21.9b0
Run black 21.9b0 on gdb/ (this is the version currently mentioned on the
wiki [1], the subsequent commit will bump that version).

[1] https://sourceware.org/gdb/wiki/Internals%20GDB-Python-Coding-Standards

Change-Id: I5ceaab42c42428e053e2572df172aa42a88f0f86
2021-12-15 20:30:45 -05:00
Andrew Burgess
7eb1526a80 gdb: update gdb-gdb.py.in for latest changes to struct field
This commit updates uses of 'loc' and 'loc_kind' to 'm_loc' and
'm_loc_kind' respectively, in gdb-gdb.py.in, which is required after
this commit:

  commit cd3f655cc7
  Date:   Thu Sep 30 22:38:29 2021 -0400

      gdb: add accessors for field (and call site) location

I have also incorporated this change:

  https://sourceware.org/pipermail/gdb-patches/2021-September/182171.html

Which means we print 'm_name' instead of 'name' when displaying the
'm_name' member variable.

Finally, I have also added support for the new TYPE_SPECIFIC_INT
fields, which were added with this commit:

  commit 20a5fcbd5b
  Date:   Wed Sep 23 09:39:24 2020 -0600

      Handle bit offset and bit size in base types

I updated the gdb.gdb/python-helper.exp test to cover all of these
changes.
2021-12-13 11:37:02 +00:00
Pedro Alves
bf80931081 gdb: introduce intrusive_list, make thread_info use it
GDB currently has several objects that are put in a singly linked list,
by having the object's type have a "next" pointer directly.  For
example, struct thread_info and struct inferior.  Because these are
simply-linked lists, and we don't keep track of a "tail" pointer, when
we want to append a new element on the list, we need to walk the whole
list to find the current tail.  It would be nice to get rid of that
walk.  Removing elements from such lists also requires a walk, to find
the "previous" position relative to the element being removed.  To
eliminate the need for that walk, we could make those lists
doubly-linked, by adding a "prev" pointer alongside "next".  It would be
nice to avoid the boilerplate associated with maintaining such a list
manually, though.  That is what the new intrusive_list type addresses.

With an intrusive list, it's also possible to move items out of the
list without destroying them, which is interesting in our case for
example for threads, when we exit them, but can't destroy them
immediately.  We currently keep exited threads on the thread list, but
we could change that which would simplify some things.

Note that with std::list, element removal is O(N).  I.e., with
std::list, we need to walk the list to find the iterator pointing to
the position to remove.  However, we could store a list iterator
inside the object as soon as we put the object in the list, to address
it, because std::list iterators are not invalidated when other
elements are added/removed.  However, if you need to put the same
object in more than one list, then std::list<object> doesn't work.
You need to instead use std::list<object *>, which is less efficient
for requiring extra memory allocations.  For an example of an object
in multiple lists, see the step_over_next/step_over_prev fields in
thread_info:

  /* Step-over chain.  A thread is in the step-over queue if these are
     non-NULL.  If only a single thread is in the chain, then these
     fields point to self.  */
  struct thread_info *step_over_prev = NULL;
  struct thread_info *step_over_next = NULL;

The new intrusive_list type gives us the advantages of an intrusive
linked list, while avoiding the boilerplate associated with manually
maintaining it.

intrusive_list's API follows the standard container interface, and thus
std::list's interface.  It is based the API of Boost's intrusive list,
here:

 https://www.boost.org/doc/libs/1_73_0/doc/html/boost/intrusive/list.html

Our implementation is relatively simple, while Boost's is complicated
and intertwined due to a lot of customization options, which our version
doesn't have.

The easiest way to use an intrusive_list is to make the list's element
type inherit from intrusive_node.  This adds a prev/next pointers to
the element type.  However, to support putting the same object in more
than one list, intrusive_list supports putting the "node" info as a
field member, so you can have more than one such nodes, one per list.

As a first guinea pig, this patch makes the per-inferior thread list use
intrusive_list using the base class method.

Unlike Boost's implementation, ours is not a circular list.  An earlier
version of the patch was circular: the intrusive_list type included an
intrusive_list_node "head".  In this design, a node contained pointers
to the previous and next nodes, not the previous and next elements.
This wasn't great for when debugging GDB with GDB, as it was difficult
to get from a pointer to the node to a pointer to the element.  With the
design proposed in this patch, nodes contain pointers to the previous
and next elements, making it easy to traverse the list by hand and
inspect each element.

The intrusive_list object contains pointers to the first and last
elements of the list.  They are nullptr if the list is empty.
Each element's node contains a pointer to the previous and next
elements.  The first element's previous pointer is nullptr and the last
element's next pointer is nullptr.  Therefore, if there's a single
element in the list, both its previous and next pointers are nullptr.
To differentiate such an element from an element that is not linked into
a list, the previous and next pointers contain a special value (-1) when
the node is not linked.  This is necessary to be able to reliably tell
if a given node is currently linked or not.

A begin() iterator points to the first item in the list.  An end()
iterator contains nullptr.  This makes iteration until end naturally
work, as advancing past the last element will make the iterator contain
nullptr, making it equal to the end iterator.  If the list is empty,
a begin() iterator will contain nullptr from the start, and therefore be
immediately equal to the end.

Iterating on an intrusive_list yields references to objects (e.g.
`thread_info&`).  The rest of GDB currently expects iterators and ranges
to yield pointers (e.g. `thread_info*`).  To bridge the gap, add the
reference_to_pointer_iterator type.  It is used to define
inf_threads_iterator.

Add a Python pretty-printer, to help inspecting intrusive lists when
debugging GDB with GDB.  Here's an example of the output:

    (top-gdb) p current_inferior_.m_obj.thread_list
    $1 = intrusive list of thread_info = {0x61700002c000, 0x617000069080, 0x617000069400, 0x61700006d680, 0x61700006eb80}

It's not possible with current master, but with this patch [1] that I
hope will be merged eventually, it's possible to index the list and
access the pretty-printed value's children:

    (top-gdb) p current_inferior_.m_obj.thread_list[1]
    $2 = (thread_info *) 0x617000069080
    (top-gdb) p current_inferior_.m_obj.thread_list[1].ptid
    $3 = {
      m_pid = 406499,
      m_lwp = 406503,
      m_tid = 0
    }

Even though iterating the list in C++ yields references, the Python
pretty-printer yields pointers.  The reason for this is that the output
of printing the thread list above would be unreadable, IMO, if each
thread_info object was printed in-line, since they contain so much
information.  I think it's more useful to print pointers, and let the
user drill down as needed.

[1] https://sourceware.org/pipermail/gdb-patches/2021-April/178050.html

Co-Authored-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: I3412a14dc77f25876d742dab8f44e0ba7c7586c0
2021-07-12 20:46:52 -04:00
Simon Marchi
91e159e93b gdb: add pyproject.toml
When running black to format Python files, files with extension .py.in
are ignored, because they don't end in .py.  Add a pyproject.toml file
to instruct black to pick up these files too.

gdb/ChangeLog:

	* py-project.toml: New.
	* gdb-gdb.py.in: Re-format.

gdb/testsuite/ChangeLog:

	* gdb.python/py-framefilter-gdb.py.in: Re-format.
	* gdb.python/py-framefilter-invalidarg-gdb.py.in: Re-format.

Change-Id: I9b88faec3360ea24788f44c8b89fe0b2a5f4eb97
2021-05-17 14:31:00 -04:00
Andrew Burgess
fbb1aaceba gdb: fix field names of GDB's type main_type structure
In commit:

  commit 5b7d941b90
  Date:   Fri Jan 22 12:21:09 2021 -0500

      gdb: add owner-related methods to struct type

two fields of struct maint_type were renamed.  'flag_objfile_owned'
became 'm_flag_objfile_owned' and 'owner' became 'm_owner'.  Update
our python helper script to take this into account.

I've added a basic test that uses the self-test framework to load the
pretty printers, and print a type.

The test relies on stopping in GDB's `value_print` function.

gdb/ChangeLog:

	* gdb-gdb.py.in (StructMainTypePrettyPrinter) <owner_to_string>:
	Updated fields names flag_objfile_owned to m_flag_objfile_owned,
	and owner to m_owner.

gdb/testsuite/ChangeLog:

	* gdb.gdb/python-helper.exp: New file.
2021-03-09 11:03:26 +00:00
Hannes Domani
b66b4e658f Fix pretty printer of main_type.flds_bnds.bounds
In struct dynamic_prop the members kind and data were renamed to m_kind and
m_data.

And flag_upper_bound_is_count is actually in bounds directly, not in its
high member.

gdb/ChangeLog:

2021-01-02  Hannes Domani  <ssbssa@yahoo.de>

	* gdb-gdb.py.in: Fix main_type.flds_bnds.bounds pretty printer.
2021-01-02 19:47:53 +01:00
Joel Brobecker
3666a04883 Update copyright year range in all GDB files
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...

gdb/ChangeLog

        Update copyright year range in copyright header of all GDB files.
2021-01-01 12:12:21 +04:00
Hannes Domani
e51765f932 Fix name of main_type field type in pretty printer
It was renamed from type to m_type.

gdb/ChangeLog:

2020-12-18  Hannes Domani  <ssbssa@yahoo.de>

	* gdb-gdb.py.in: Fix main_type field name.
2020-12-18 22:06:01 +01:00
Joel Brobecker
0958441403 Add support for printing value of DWARF-based fixed-point type objects
This commit introduces a new kind of type, meant to describe
fixed-point types, using a new code added specifically for
this purpose (TYPE_CODE_FIXED_POINT).

It then adds handling of fixed-point base types in the DWARF reader.

And finally, as a first step, this commit adds support for printing
the value of fixed-point type objects.

Note that this commit has a known issue: Trying to print the value
of a fixed-point object with a format letter (e.g. "print /x NAME")
causes the wrong value to be printed because the scaling factor
is not applied. Since the fix for this issue is isolated, and
this is not a regression, the fix will be made in a pach of its own.
This is meant to simplify review and archeology.

Also, other functionalities related to fixed-point type handling
(ptype, arithmetics, etc), will be added piecemeal as well, for
the same reasons (faciliate reviews and archeology). Related to this,
the testcase gdb.ada/fixed_cmp.exp is adjusted to compile the test
program with -fgnat-encodings=all, so as to force the use of GNAT
encodings, rather than rely on the compiler's default to use them.
The intent is to enhance this testcase to also test the pure DWARF
approach using -fgnat-encodings=minimal as soon as the corresponding
suport gets added in. Thus, the modification to the testcase is made
in a way that it prepares this testcase to be tested in both modes.

gdb/ChangeLog:

        * ada-valprint.c (ada_value_print_1): Add fixed-point type handling.
        * dwarf2/read.c (get_dwarf2_rational_constant)
        (get_dwarf2_unsigned_rational_constant, finish_fixed_point_type)
        (has_zero_over_zero_small_attribute): New functions.
        read_base_type, set_die_type): Add fixed-point type handling.
        * gdb-gdb.py.in: Add fixed-point type handling.
        * gdbtypes.c: #include "gmp-utils.h".
        (create_range_type, set_type_code): Add fixed-point type handling.
        (init_fixed_point_type): New function.
        (is_integral_type, is_scalar_type): Add fixed-point type handling.
        (print_fixed_point_type_info): New function.
        (recursive_dump_type, copy_type_recursive): Add fixed-point type
        handling.
        (fixed_point_type_storage): New typedef.
        (fixed_point_objfile_key): New static global.
        (allocate_fixed_point_type_info, is_fixed_point_type): New functions.
        (fixed_point_type_base_type, fixed_point_scaling_factor): New
        functions.
        * gdbtypes.h: #include "gmp-utils.h".
        (enum type_code) <TYPE_SPECIFIC_FIXED_POINT>: New enum.
        (union type_specific) <fixed_point_info>: New field.
        (struct fixed_point_type_info): New struct.
        (INIT_FIXED_POINT_SPECIFIC, TYPE_FIXED_POINT_INFO): New macros.
        (init_fixed_point_type, is_fixed_point_type)
        (fixed_point_type_base_type, fixed_point_scaling_factor)
        (allocate_fixed_point_type_info): Add declarations.
        * valprint.c (generic_val_print_fixed_point): New function.
        (generic_value_print): Add fixed-point type handling.
        * value.c (value_as_address, unpack_long): Add fixed-point type
        handling.

gdb/testsuite/ChangeLog:

        * gdb.ada/fixed_cmp.exp: Force compilation to use -fgnat-encodings=all.
        * gdb.ada/fixed_points.exp: Add fixed-point variables printing tests.
        * gdb.ada/fixed_points/pck.ads, gdb.ada/fixed_points/pck.adb:
        New files.
        * gdb.ada/fixed_points/fixed_points.adb: Add use of package Pck.

        * gdb.dwarf2/dw2-fixed-point.c, gdb.dwarf2/dw2-fixed-point.exp:
        New files.
2020-11-15 03:12:52 -05:00
Simon Marchi
4d0bcfcf62 gdb: update instance_flags field name in gdb-gdb.py.in
Commit 314ad88df6 ("Use type_instance_flags more throughout") changed
the name of field type::instance_flags to type::m_instance_flags.  It
however missed changing it in the gdb-gdb.py.in file, which results in
this when trying to use the pretty-printer:

    (top-gdb) p *val.type
    Traceback (most recent call last):
      File "/home/smarchi/build/binutils-gdb/gdb/gdb-gdb.py", line 116, in to_string
        % TypeFlagsPrinter(self.val['instance_flags']))
      File "/home/smarchi/build/binutils-gdb/gdb/gdb-gdb.py", line 76, in __str__
        flag_list = [flag.short_name for flag in TYPE_FLAGS
      File "/home/smarchi/build/binutils-gdb/gdb/gdb-gdb.py", line 77, in <listcomp>
        if self.val & flag.value]
    gdb.error: Argument to arithmetic operation not a number or boolean.
    $7 =

This patch fixes it.

gdb/ChangeLog:

	* gdb-gdb.py.in (class StructTypePrettyPrinter) <to_string>:
	Change instance_flags to m_instance_flags.

Change-Id: Ib5e03c08fe41ca11cd71998f2b1c58052879ce95
2020-09-16 16:43:39 -04:00
Joel Brobecker
b811d2c292 Update copyright year range in all GDB files.
gdb/ChangeLog:

        Update copyright year range in all GDB files.
2020-01-01 10:20:53 +04:00
Joel Brobecker
7f5331a885 gdb-gdb.py.in: Fix error when printing range type
I noticed that trying to print the contents of a struct main_type
would fail when the type was a TYPE_CODE_RANGE:

    (gdb) p *type.main_type
    $1 = Python Exception <class 'gdb.error'> There is no member named low_undefined.:

And indeed, Python is right, fields "low_undefined" has been removed
from struct range_bounds back in ... 2014! It was done when we introduced
dynamic bounds handling. This patch fixes gdb-gdb.py.in according to
the new structure.

gdb/ChangeLog:

	* gdb-gdb.py.in (StructMainTypePrettyPrinter.bound_img): New method.
	(StructMainTypePrettyPrinter.bounds_img): Use new "bound_img"
	method to compute the bounds of range types. Also print "[evaluated]"
	if the bounds' values come from a dynamic evaluation.
2019-03-26 18:30:21 -04:00
Joel Brobecker
42a4f53d2b Update copyright year range in all GDB files.
This commit applies all changes made after running the gdb/copyright.py
script.

Note that one file was flagged by the script, due to an invalid
copyright header
(gdb/unittests/basic_string_view/element_access/char/empty.cc).
As the file was copied from GCC's libstdc++-v3 testsuite, this commit
leaves this file untouched for the time being; a patch to fix the header
was sent to gcc-patches first.

gdb/ChangeLog:

	Update copyright year range in all GDB files.
2019-01-01 10:01:51 +04:00
Simon Marchi
e76f78a052 Format gdb-gdb.py.in with autopep8
Format using "autopep8 -i".

gdb/ChangeLog:

	* gdb-gdb.py.in: Format using autopep8.
2018-06-27 15:31:05 -04:00
Simon Marchi
9a14af7b1a Add pretty-printer for CORE_ADDR
Add a pretty-printer that prints CORE_ADDR values in hex.

gdb/ChangeLog:

	* gdb-gdb.py.in (CoreAddrPrettyPrinter): New class.
	(type_lookup_function): Recognize CORE_ADDR values.
2018-06-27 15:21:47 -04:00
Simon Marchi
189366cd86 gdb-gdb.py.in: Don't print value's tag_name
This has been removed recently.

gdb/ChangeLog:

	* gdb-gdb.py.in (StructMainTypePrettyPrinter) <to_string>: Don't
	print tag_name.
2018-06-27 14:32:08 -04:00
Simon Marchi
68ad5fb9aa gdb-gdb.py.in: Fix ordering of TypeFlags objects with Python 3
Python 3 doesn't use __cmp__ to order objects, it uses __lt__.  Because
of this, we get this exception when trying to pretty-print "type"
objects:

I tested it with Python 2.7 as well.

gdb/ChangeLog:

	* gdb-gdb.py.in (TypeFlag) <__cmp__>: Remove.
	<__lt__>: Add.
2018-06-27 14:32:05 -04:00
Simon Marchi
141ec9f67f Copy gdb-gdb.py to build dir
I have thought for a long time how nice it would be to have cool pretty
printers for GDB's internal types.  Well, turns out there are few
already in gdb-gdb.py!  Unfortunately, if you build GDB outside of the
source directory, that file never gets loaded.  top-gdb will look for a
file called

  ../path/to/build/gdb/gdb-gdb.py

but that file is in the source directory at

  ../path/to/src/gdb/gdb-gdb.py

This patch makes it so we copy it to the build directory, just like we
do for gdb-gdb.gdb.  With this, I can at least see the file getting
automatically loaded:

(top-gdb) info pretty-printer
global pretty-printers:
  builtin
    mpx_bound128
  objfile /home/emaisin/build/binutils-gdb/gdb/gdb pretty-printers:
  type_lookup_function

I noticed that running "make" didn't re-generate gdb-gdb.py from
gdb-gdb.py.in.  That's because it's copied when running the configure
script and that's it.  I added a rule in the Makefile for that (and for
gdb-gdb.gdb too) and added them as a dependency to the "all" target.

gdb/ChangeLog:

	* gdb-gdb.py: Move to...
	* gdb-gdb.py.in: ... here.
	* configure.ac (AC_CONFIG_FILES): Add gdb-gdb.py.
	* Makefile.in (all): Add gdb-gdb.gdb and gdb-gdb.py as
	dependencies.
	(distclean): Remove gdb-gdb.py when cleaning.
	(gdb-gdb.py, gdb-gdb.gdb): New rules.
	* configure: Re-generate.
2018-06-27 14:32:02 -04:00
Renamed from gdb/gdb-gdb.py (Browse further)