Age | Commit message (Collapse) | Author | Files | Lines |
|
Remove the macro, replace all uses by calls to type::target_type.
Change-Id: Ie51d3e1e22f94130176d6abd723255282bb6d1ed
|
|
When an objfile is destroyed, types that are still in use and
allocated on that objfile are copied. A temporary hash map is created
during this process, and it is allocated on the destroyed objfile's
obstack -- which normally is fine, as that is going to be destroyed
shortly anyway.
However, this approach requires that the objfile be passed to registry
destruction, and this won't be possible in the rewritten registry.
This patch changes the copied type hash table to simply use the heap
instead. It also removes the 'objfile' parameter from
copy_type_recursive, to make this all more clear.
This patch also fixes an apparent bug in copy_type_recursive.
Previously it was copying the dynamic property list to the dying
objfile's obstack:
- = copy_dynamic_prop_list (&objfile->objfile_obstack,
However I think this is incorrect -- that obstack is about to be
destroyed.
|
|
Varobj object contains references to types, variables (i.e. struct
variable) and expression. All of those can reference data on an
objfile's obstack. It is possible for this objfile to be deleted (and
the obstack to be feed), while the varobj remains valid. Later, if the
user uses the varobj, this will result in a use-after-free error. With
address sanitizer build, this leads to a plain error. For non address
sanitizer build we might see undefined behaviour, which manifest
themself as assertion failures when accessing data backed by feed
memory.
This can be observed if we create a varobj that refers to ta symbol in a
shared library, after either the objfile gets reloaded (using the `file`
command) or after the shared library is unloaded (with a call to dlclose
for example).
This patch fixes those issues by:
- Adding cleanup procedure to the free_objfile observable. When
activated this observer clears expressions referencing the objfile
being freed, and removes references to blocks belonging to this
objfile.
- Adding varobj support in the `preserve_values` (gdb.value.c). This
ensures that before the objfile is unloaded, any type owned by the
objfile referenced by the varobj is replaced by an equivalent type
not owned by the objfile. This process is done here instead of in the
free_objfile observer in order to reuse the type hash table already
used for similar purpose when replacing types of values kept in the
value history.
This patch also makes sure to keep a reference to the expression's
gdbarch and language_defn members when the varobj->root->exp is
initialized. Those structures outlive the objfile, so this is safe.
This is done because those references might be used initialize a python
context even after exp is invalidated. Another approach could have been
to initialize the python context with default gdbarch and language_defn
(i.e. nullptr) if expr is NULL, but since we might still try to display
the value which was obtained by evaluating exp when it was still valid,
keeping track of the context which was used at this time seems
reasonable.
Tested on x86_64-Linux.
Co-Authored-By: Pedro Alves <pedro@palves.net>
|
|
Building GDB currently fails to build with libc++, because libc++ is
stricter about which headers "leak" entities they're not guaranteed
to support. The following headers have been added:
* `<iterator>`, to support `std::back_inserter`
* `<utility>`, to support `std::move` and `std::swap`
* `<vector>`, to support `std::vector`
Change-Id: Iaeb15057c5fbb43217df77ce34d4e54446dbcf3d
|
|
Replace with equivalent method.
Change-Id: I0e033095e7358799930775e61028b48246971a7d
|
|
Remove all macros related to getting and setting some symbol value:
#define SYMBOL_VALUE(symbol) (symbol)->value.ivalue
#define SYMBOL_VALUE_ADDRESS(symbol) \
#define SET_SYMBOL_VALUE_ADDRESS(symbol, new_value) \
#define SYMBOL_VALUE_BYTES(symbol) (symbol)->value.bytes
#define SYMBOL_VALUE_COMMON_BLOCK(symbol) (symbol)->value.common_block
#define SYMBOL_BLOCK_VALUE(symbol) (symbol)->value.block
#define SYMBOL_VALUE_CHAIN(symbol) (symbol)->value.chain
#define MSYMBOL_VALUE(symbol) (symbol)->value.ivalue
#define MSYMBOL_VALUE_RAW_ADDRESS(symbol) ((symbol)->value.address + 0)
#define MSYMBOL_VALUE_ADDRESS(objfile, symbol) \
#define BMSYMBOL_VALUE_ADDRESS(symbol) \
#define SET_MSYMBOL_VALUE_ADDRESS(symbol, new_value) \
#define MSYMBOL_VALUE_BYTES(symbol) (symbol)->value.bytes
#define MSYMBOL_BLOCK_VALUE(symbol) (symbol)->value.block
Replace them with equivalent methods on the appropriate objects.
Change-Id: Iafdab3b8eefc6dc2fd895aa955bf64fafc59ed50
|
|
Bug 28980 shows that trying to value_copy an entirely optimized out
value causes an internal error. The original bug report involves MI and
some Python pretty printer, and is quite difficult to reproduce, but
another easy way to reproduce (that is believed to be equivalent) was
proposed:
$ ./gdb -q -nx --data-directory=data-directory -ex "py print(gdb.Value(gdb.Value(5).type.optimized_out()))"
/home/smarchi/src/binutils-gdb/gdb/value.c:1731: internal-error: value_copy: Assertion `arg->contents != nullptr' failed.
This is caused by 5f8ab46bc691 ("gdb: constify parameter of
value_copy"). It added an assertion that the contents buffer is
allocated if the value is not lazy:
if (!value_lazy (val))
{
gdb_assert (arg->contents != nullptr);
This was based on the comment on value::contents, which suggest that
this is the case:
/* Actual contents of the value. Target byte-order. NULL or not
valid if lazy is nonzero. */
gdb::unique_xmalloc_ptr<gdb_byte> contents;
However, it turns out that it can also be nullptr also if the value is
entirely optimized out, for example on exit of
allocate_optimized_out_value. That function creates a lazy value, marks
the entire value as optimized out, and then clears the lazy flag. But
contents remains nullptr.
This wasn't a problem for value_copy before, because it was calling
value_contents_all_raw on the input value, which caused contents to be
allocated before doing the copy. This means that the input value to
value_copy did not have its contents allocated on entry, but had it
allocated on exit. The result value had it allocated on exit. And that
we copied bytes for an entirely optimized out value (i.e. meaningless
bytes).
From here I see two choices:
1. respect the documented invariant that contents is nullptr only and
only if the value is lazy, which means making
allocate_optimized_out_value allocate contents
2. extend the cases where contents can be nullptr to also include
values that are entirely optimized out (note that you could still
have some entirely optimized out values that do have contents
allocated, it depends on how they were created) and adjust
value_copy accordingly
Choice #1 is safe, but less efficient: it's not very useful to allocate
a buffer for an entirely optimized out value. It's even a bit less
efficient than what we had initially, because values coming out of
allocate_optimized_out_value would now always get their contents
allocated.
Choice #2 would be more efficient than what we had before: giving an
optimized out value without allocated contents to value_copy would
result in an optimized out value without allocated contents (and the
input value would still be without allocated contents on exit). But
it's more risky, since it's difficult to ensure that all users of the
contents (through the various_contents* accessors) are all fine with
that new invariant.
In this patch, I opt for choice #2, since I think it is a better
direction than choice #1. #1 would be a pessimization, and if we go
this way, I doubt that it will ever be revisited, it will just stay that
way forever.
Add a selftest to test this. I initially started to write it as a
Python test (since the reproducer is in Python), but a selftest is more
straightforward.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28980
Change-Id: I6e2f5c0ea804fafa041fcc4345d47064b5900ed7
|
|
Now that filtered and unfiltered output can be treated identically, we
can unify the printf family of functions. This is done under the name
"gdb_printf". Most of this patch was written by script.
|
|
In a following patch, I have a const value I want to copy using a
value_copy. However, value_copy takes a non-const source value, at the
moment. Change the paramter to be const,
If the source value is not lazy, we currently call
value_contents_all_raw, which calls allocate_value_contents, to get a
view on the contents. They both take a non-const value, that's a
problem. My first attempt at solving it was to add a const version of
value_contents_all_raw, make allocate_value_contents take a const value,
and either:
- make value::contents mutable
- make allocate_value_contents cast away the const
The idea being that allocating the value contents buffer does modify the
value at the bit level, but logically that doesn't change its state.
That was getting a bit complicated, so what I ended up doing is make
value_copy not call value_contents_all_raw. We know at this point that
the value is not lazy, so value::contents must have been allocate
already.
Change-Id: I3741ab362bce14315f712ec24064ccc17e3578d4
|
|
No kind of internal var uses it remove it. This makes the transition to
using a variant easier, since we don't need to think about where this
should be called (in a destructor or not), if it can throw, etc.
Change-Id: Iebbc867d1ce6716480450d9790410d6684cbe4dd
|
|
This adds initializers to bound_minimal_symbol, allowing for the
removal of some calls to memset.
|
|
Add a new function gdb.history_count to the Python api, this function
returns an integer, the number of items in GDB's value history.
This is useful if you want to pull items from the history by their
absolute number, for example, if you wanted to show a complete history
list. Previously we could figure out how many items are in the
history list by trying to fetch the items, and then catching the
exception when the item is not available, but having this function
seems nicer.
|
|
Many otherwise ordinary commands choose to use unfiltered output
rather than filtered. I don't think there's any reason for this, so
this changes many such commands to use filtered output instead.
Note that complete_command is not touched due to a comment there
explaining why unfiltered output is believed to be used.
|
|
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.
|
|
Change a few relatively obvious spots using value contents to propagate
the use array_view a bit more.
Change-Id: I5338a60986f06d5969fec803d04f8423c9288a15
|
|
An assertion was recently added to array_view::operator[] to ensure we
don't do out of bounds accesses. However, when the array_view is copied
to or from using memcpy, it bypasses that safety.
To address this, add a `copy` free function that copies data from an
array view to another, ensuring that the destination and source array
views have the same size. When copying to or from parts of an
array_view, we are expected to use gdb::array_view::slice, which does
its own bounds check. With all that, any copy operation that goes out
of bounds should be caught by an assertion at runtime.
copy is implemented using std::copy and std::copy_backward, which, at
least on libstdc++, appears to pick memmove when copying trivial data.
So in the end there shouldn't be much difference vs using a bare memcpy,
as we do right now. When copying non-trivial data, std::copy and
std::copy_backward assigns each element in a loop.
To properly support overlapping ranges, we must use std::copy or
std::copy_backward, depending on whether the destination is before the
source or vice-versa. std::copy and std::copy_backward don't support
copying exactly overlapping ranges (where the source range is equal to
the destination range). But in this case, no copy is needed anyway, so
we do nothing.
The order of parameters of the new copy function is based on std::copy
and std::copy_backward, where the source comes before the destination.
Change a few randomly selected spots to use the new function, to show
how it can be used.
Add a test for the new function, testing both with arrays of a trivial
type (int) and of a non-trivial type (foo). Test non-overlapping
ranges as well as three kinds of overlapping ranges: source before dest,
dest before source, and dest == source.
Change-Id: Ibeaca04e0028410fd44ce82f72e60058d6230a03
|
|
In commit 50888e42dcd3 ("gdb: change functions returning value contents
to use gdb::array_view"), I believe I made a mistake with the length of
the array views returned by some functions. All functions return a view
of `TYPE_LENGTH (value_type (type))` length. This is not correct when
the value's enclosing type is larger than the value's type. In that
case, the value's contents buffer is of the size of the enclosing type,
and the value's actual contents is a slice of that (as returned by
value_contents). So, functions value_contents_all_raw,
value_contents_for_printing and value_contents_for_printing_const are
not correct. Since they are meant to return the value's contents buffer
as a whole, they should have the size of the enclosing type.
There is nothing that uses the returned array view size at the moment,
so this didn't cause a problem. But it became apparent when trying to
adjust some callers.
Change-Id: Ib4e8837e1069111d2b2784d3253d5f3002419e68
|
|
While reviewing this patch:
https://sourceware.org/pipermail/gdb-patches/2021-November/183227.html
I spotted that the patch could be improved if we threw
OPTIMIZED_OUT_ERROR rather than GENERIC_ERROR in a few places.
This commit updates error_value_optimized_out and
require_not_optimized_out to throw OPTIMIZED_OUT_ERROR.
I ran the testsuite and saw no regressions. This doesn't really
surprise me, we don't usually write code like:
catch (const gdb_exception_error &ex)
{
(if ex.error == GENERIC_ERROR)
...
else
...
}
There are a three places where we write something like:
catch (const gdb_exception_error &ex)
{
(if ex.error == OPTIMIZED_OUT_ERROR)
...
}
In frame.c:unwind_pc, stack.c:info_frame_command_core, and
value.c:value_optimized_out, but if we are hitting these cases then
it's not significantly changing GDB's behaviour.
|
|
Remove TYPE_FIELD_STATIC_PHYSADDR replace with type::field +
field::loc_physaddr.
Change-Id: Ica9bc4a48f34750ec82ec86c298d3ecece81bcbd
|
|
Remove TYPE_FIELD_STATIC_PHYSNAME, replace with type::field +
field::loc_physname.
Change-Id: Ie35d446b67dd1d02f39998b406001bdb7e6d5abb
|
|
Remove TYPE_FIELD_BITPOS, replace its uses with type::field +
field::loc_bitpos.
Change-Id: Iccd8d5a77e5352843a837babaa6bd284162e0320
|
|
Remove TYPE_FIELD_LOC_KIND, replace its uses with type::field +
field::loc_kind.
Change-Id: Ib124a26365df82ac1d23df7962d954192913bd90
|
|
When building on ARM (32-bits), we errors like this:
/home/smarchi/src/binutils-gdb/gdb/value.c: In function 'gdb::array_view<const unsigned char> value_contents_for_printing(value*)':
/home/smarchi/src/binutils-gdb/gdb/value.c:1252:35: error: narrowing conversion of 'length' from 'ULONGEST' {aka 'long long unsigned int'} to 'size_t' {aka 'unsigned int'} [-Werror=narrowing]
1252 | return {value->contents.get (), length};
| ^~~~~~
Fix that by using gdb::make_array_view, which does the appropriate
conversion.
Change-Id: I7d6f2e75d7440d248b8fb18f8272ee92954b404d
|
|
The bug fixed by this [1] patch was caused by an out-of-bounds access to
a value's content. The code gets the value's content (just a pointer)
and then indexes it with a non-sensical index.
This made me think of changing functions that return value contents to
return array_views instead of a plain pointer. This has the advantage
that when GDB is built with _GLIBCXX_DEBUG, accesses to the array_view
are checked, making bugs more apparent / easier to find.
This patch changes the return types of these functions, and updates
callers to call .data() on the result, meaning it's not changing
anything in practice. Additional work will be needed (which can be done
little by little) to make callers propagate the use of array_view and
reap the benefits.
[1] https://sourceware.org/pipermail/gdb-patches/2021-September/182306.html
Change-Id: I5151f888f169e1c36abe2cbc57620110673816f3
|
|
This makes the Ada-specific "varsize-limit" a synonym for
"max-value-size", and removes the Ada-specific checks of the limit.
I am not certain of the history here, but it seems to me that this
code is fully obsolete now. And, removing this makes it possible to
index large Ada arrays without triggering an error. A new test case
is included to demonstrate this.
|
|
This changes value_zero to create a lazy value. In many cases,
value_zero is called in expression evaluation to wrap a type in a
non-eval context. It seems senseless to allocate a buffer in these
cases.
A new 'is_zero' flag is added so we can preserve the existing
assertions in value_fetch_lazy.
A subsequent patch will add a test where creating a zero value would
fail, due to the variable size check. However, the contents of this
value are never needed, and so creating a lazy value avoids the error
case.
|
|
This adds an is_optimized_out function pointer to lval_funcs, and
changes value_optimized_out to call it. This new function lets gdb
determine if a value is optimized out without necessarily fetching the
value. This is needed for a subsequent patch, where an attempt to
access a lazy value would fail due to the value size limit -- however,
the access was only needed to determine the optimized-out state.
|
|
Remove the `TYPE_FIELD_NAME` and `FIELD_NAME` macros, changing all the
call sites to use field::name directly.
Change-Id: I6900ae4e1ffab1396e24fb3298e94bf123826ca6
|
|
I noticed that pointer_type is declared in language.h and defined in
language.c. However, it really has to do with types, so it should
have been in gdbtypes.h all along.
This patch changes it to be a method on struct type. And, I went
through uses of TYPE_IS_REFERENCE and updated many spots to use the
new method as well. (I didn't update ones that were in arch-specific
code, as I couldn't readily test that.)
|
|
Fixing a bug where the value_copy function did not copy the stack data
and initialized members of the struct value. This is needed for the
next patch where the DWARF expression evaluator is changed to return a
single struct value object.
* value.c (value_copy): Change to also copy the stack data
and initialized members.
|
|
This commit was originally part of this patch series:
(v1): https://sourceware.org/pipermail/gdb-patches/2021-May/179357.html
(v2): https://sourceware.org/pipermail/gdb-patches/2021-June/180208.html
(v3): https://sourceware.org/pipermail/gdb-patches/2021-July/181028.html
However, that series is being held up in review, so I wanted to break
out some of the non-related fixes in order to get these merged.
This commit addresses two semi-related issues, both of which are
problems exposed by using 'set debug frame on'.
The first issue is in frame.c in get_prev_frame_always_1, and was
introduced by this commit:
commit a05a883fbaba69d0f80806e46a9457727fcbe74c
Date: Tue Jun 29 12:03:50 2021 -0400
gdb: introduce frame_debug_printf
This commit replaced fprint_frame with frame_info::to_string.
However, the former could handle taking a nullptr while the later, a
member function, obviously requires a non-nullptr in order to make the
function call. In one place we are not-guaranteed to have a
non-nullptr, and so, there is the possibility of triggering undefined
behaviour.
The second issue addressed in this commit has existed for a while in
GDB, and would cause this assertion:
gdb/frame.c:622: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed.
We attempt to get the frame_id for a frame while we are computing the
frame_id for that same frame.
What happens is that when GDB stops we create a frame_info object for
the sentinel frame (frame #-1) and then we attempt to unwind this
frame to create a frame_info object for frame #0.
In the test case used here to expose the issue we have created a
Python frame unwinder. In the Python unwinder we attemt to read the
program counter register.
Reading this register will initially create a lazy register value.
The frame-id stored in the lazy register value will be for the
sentinel frame (lazy register values hold the frame-id for the frame
from which the register will be unwound).
However, the Python unwinder does actually want to examine the value
of the program counter, and so the lazy register value is resolved
into a non-lazy value. This sends GDB into value_fetch_lazy_register
in value.c.
Now, inside this function, if 'set debug frame on' is in effect, then
we want to print something like:
frame=%d, regnum=%d(%s), ....
Where 'frame=%d' will be the relative frame level of the frame for
which the register is being fetched, so, in this case we would expect
to see 'frame=0', i.e. we are reading a register as it would be in
frame #0. But, remember, the lazy register value actually holds the
frame-id for frame #-1 (the sentinel frame).
So, to get the frame_info for frame #0 we used to call:
frame = frame_find_by_id (VALUE_FRAME_ID (val));
Where VALUE_FRAME_ID is:
#define VALUE_FRAME_ID(val) (get_prev_frame_id_by_id (VALUE_NEXT_FRAME_ID (val)))
That is, we start with the frame-id for the next frame as obtained by
VALUE_NEXT_FRAME_ID, then call get_prev_frame_id_by_id to get the
frame-id of the previous frame.
The get_prev_frame_id_by_id function finds the frame_info for the
given frame-id (in this case frame #-1), calls get_prev_frame to get
the previous frame, and then calls get_frame_id.
The problem here is that calling get_frame_id requires that we know
the frame unwinder, so then have to try each frame unwinder in turn,
which would include the Python unwinder.... which is where we started,
and thus we have a loop!
To prevent this loop GDB has an assertion in place, which is what
actually triggers.
Solving the assertion failure is pretty easy, if we consider the code
in value_fetch_lazy_register and get_prev_frame_id_by_id then what we
do is:
1. Start with a frame_id taken from a value,
2. Lookup the corresponding frame,
3. Find the previous frame,
4. Get the frame_id for that frame, and
5. Lookup the corresponding frame
6. Print the frame's level
Notice that steps 3 and 5 give us the exact same result, step 4 is
just wasted effort. We could shorten this process such that we drop
steps 4 and 5, thus:
1. Start with a frame_id taken from a value,
2. Lookup the corresponding frame,
3. Find the previous frame,
6. Print the frame's level
This will give the exact same frame as a result, and this is what I
have done in this patch by removing the use of VALUE_FRAME_ID from
value_fetch_lazy_register.
Out of curiosity I looked to see how widely VALUE_FRAME_ID was used,
and saw it was only used in one other place in valops.c:value_assign,
where, once again, we take the result of VALUE_FRAME_ID and pass it to
frame_find_by_id, thus introducing a redundant frame_id lookup.
I don't think the value_assign case risks triggering the assertion
though, as we are unlikely to call value_assign while computing the
frame_id for a frame, however, we could make value_assign slightly
more efficient, with no real additional complexity, by removing the
use of VALUE_FRAME_ID.
So, in this commit, I completely remove VALUE_FRAME_ID, and replace it
with a use of VALUE_NEXT_FRAME_ID, followed by a direct call to
get_prev_frame_always, this should make no difference in either case,
and resolves the assertion issue from value.c.
As I said, this patch was originally part of another series, the
original test relied on the fixes in that original series. However, I
was able to create an alternative test for this issue by enabling
frame debug within an existing test script.
This commit probably fixes bug PR gdb/27938, though the bug doesn't
have a reproducer attached so it is not possible to know for sure.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27938
|
|
Introduce frame_debug_printf, to convert the "frame" debug messages to
the new system. Replace fprint_frame with a frame_info::to_string
method that returns a string, like what was done with
frame_id::to_string. This makes it easier to use with
frame_debug_printf.
gdb/ChangeLog:
* frame.h (frame_debug_printf): New.
* frame.c: Use frame_debug_printf throughout when printing frame
debug messages.
* amd64-windows-tdep.c: Likewise.
* value.c: Likewise.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-reg-undefined.exp: Update regexp.
Change-Id: I3c230b0814ea81c23af3e1aca1aac8d4ba91d726
|
|
Same idea as previous patch, but for add_alias_cmd. Remove the overload
that accepts the target command as a string (the target command name),
leaving only the one that takes the cmd_list_element.
gdb/ChangeLog:
* command.h (add_alias_cmd): Accept target as
cmd_list_element. Update callers.
Change-Id: I546311f411e9e7da9302322d6ffad4e6c56df266
|
|
Previously, the prefixname field of struct cmd_list_element was manually
set for prefix commands. This seems verbose and error prone as it
required every single call to functions adding prefix commands to
specify the prefix name while the same information can be easily
generated.
Historically, this was not possible as the prefix field was null for
many commands, but this was fixed in commit
3f4d92ebdf7f848b5ccc9e8d8e8514c64fde1183 by Philippe Waroquiers, so
we can rely on the prefix field being set when generating the prefix
name.
This commit also fixes a use after free in this scenario:
* A command gets created via Python (using the gdb.Command class).
The prefix name member is dynamically allocated.
* An alias to the new command is created. The alias's prefixname is set
to point to the prefixname for the original command with a direct
assignment.
* A new command with the same name as the Python command is created.
* The object for the original Python command gets freed and its
prefixname gets freed as well.
* The alias is updated to point to the new command, but its prefixname
is not updated so it keeps pointing to the freed one.
gdb/ChangeLog:
* command.h (add_prefix_cmd): Remove the prefixname argument as
it can now be generated automatically. Update all callers.
(add_basic_prefix_cmd): Ditto.
(add_show_prefix_cmd): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_abbrev_prefix_cmd): Ditto.
* cli/cli-decode.c (add_prefix_cmd): Ditto.
(add_basic_prefix_cmd): Ditto.
(add_show_prefix_cmd): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_prefix_cmd_suppress_notification): Ditto.
(add_abbrev_prefix_cmd): Ditto.
* cli/cli-decode.h (struct cmd_list_element): Replace the
prefixname member variable with a method which generates the
prefix name at runtime. Update all code reading the prefix
name to use the method, and remove all code setting it.
* python/py-cmd.c (cmdpy_destroyer): Remove code to free the
prefixname member as it's now a method.
(cmdpy_function): Determine if the command is a prefix by
looking at prefixlist, not prefixname.
|
|
The current_top_target function is a hidden dependency on the current
inferior. Since I'd like to slowly move towards reducing our dependency
on the global current state, remove this function and make callers use
current_inferior ()->top_target ()
There is no expected change in behavior, but this one step towards
making those callers use the inferior from their context, rather than
refer to the global current inferior.
gdb/ChangeLog:
* target.h (current_top_target): Remove, make callers use the
current inferior instead.
* target.c (current_top_target): Remove.
Change-Id: Iccd457036f84466cdaa3865aa3f9339a24ea001d
|
|
When not parsing for completion, parse_expression ensures that the
resulting expression has operations. This patch removes a couple of
unnecessary checks for this situation.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* printcmd.c (set_command): Remove null check.
* value.c (init_if_undefined_command): Remove null check.
|
|
This removes union exp_element functions that either create such
elements or walk them. struct expression no longer holds
exp_elements. A couple of language_defn methods are also removed, as
they are obsolete.
Note that this patch also removes the print_expression code. The only
in-tree caller of this was from dump_prefix_expression, which is only
called when expression debugging is enabled. Implementing this would
involve a fair amount of code, and it seems to me that prefix dumping
is preferable anyway, as it is unambiguous. So, I have not
reimplemented this feature.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* value.h (evaluate_subexp_with_coercion): Don't declare.
* parse.c (exp_descriptor_standard): Remove.
(expr_builder::expr_builder, expr_builder::release): Update.
(expression::expression): Remove size_t parameter.
(expression::~expression): Simplify.
(expression::resize): Remove.
(write_exp_elt, write_exp_elt_opcode, write_exp_elt_sym)
(write_exp_elt_msym, write_exp_elt_block, write_exp_elt_objfile)
(write_exp_elt_longcst, write_exp_elt_floatcst)
(write_exp_elt_type, write_exp_elt_intern, write_exp_string)
(write_exp_string_vector, write_exp_bitstring): Remove.
* p-lang.h (class pascal_language) <opcode_print_table,
op_print_tab>: Remove.
* p-lang.c (pascal_language::op_print_tab): Remove.
* opencl-lang.c (class opencl_language) <opcode_print_table>:
Remove.
* objc-lang.c (objc_op_print_tab): Remove.
(class objc_language) <opcode_print_table>: Remove.
* m2-lang.h (class m2_language) <opcode_print_table,
op_print_tab>: Remove.
* m2-lang.c (m2_language::op_print_tab): Remove.
* language.h (struct language_defn) <post_parser, expression_ops,
opcode_print_table>: Remove.
* language.c (language_defn::expression_ops)
(auto_or_unknown_language::opcode_print_table): Remove.
* go-lang.h (class go_language) <opcode_print_table,
op_print_tab>: Remove.
* go-lang.c (go_language::op_print_tab): Remove.
* f-lang.h (class f_language) <opcode_print_table>: Remove
<op_print_tab>: Remove.
* f-lang.c (f_language::op_print_tab): Remove.
* expression.h (union exp_element): Remove.
(struct expression): Remove size_t parameter from constructor.
<resize>: Remove.
<first_opcode>: Update.
<nelts, elts>: Remove.
(EXP_ELEM_TO_BYTES, BYTES_TO_EXP_ELEM): Remove.
(evaluate_subexp_standard, print_expression, op_string)
(dump_raw_expression): Don't declare.
* expprint.c (print_expression, print_subexp)
(print_subexp_funcall, print_subexp_standard, op_string)
(dump_raw_expression, dump_subexp, dump_subexp_body)
(dump_subexp_body_funcall, dump_subexp_body_standard): Remove.
(dump_prefix_expression): Update.
* eval.c (evaluate_subexp): Remove.
(evaluate_expression, evaluate_type): Update.
(evaluate_subexpression_type): Remove.
(fetch_subexp_value): Remove "pc" parameter. Update.
(extract_field_op, evaluate_struct_tuple, evaluate_funcall)
(evaluate_subexp_standard, evaluate_subexp_for_address)
(evaluate_subexp_with_coercion, evaluate_subexp_for_sizeof)
(evaluate_subexp_for_cast): Remove.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* d-lang.c (d_op_print_tab): Remove.
(class d_language) <opcode_print_table>: Remove.
* c-lang.h (c_op_print_tab): Don't declare.
* c-lang.c (c_op_print_tab): Remove.
(class c_language, class cplus_language, class asm_language, class
minimal_language) <opcode_print_table>: Remove.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.h (union exp_element): Don't declare.
* ax-gdb.c (const_var_ref, const_expr, maybe_const_expr)
(gen_repeat, gen_sizeof, gen_expr_for_cast, gen_expr)
(gen_expr_binop_rest): Remove.
(gen_trace_for_expr, gen_eval_for_expr, gen_printf): Update.
* ada-lang.c (ada_op_print_tab): Remove.
(class ada_language) <post_parser, opcode_print_table>: Remove.
|
|
This adds an expr::operation_up to struct expression, and then
modifies various parts of GDB to use this member when it is non-null.
The list of such spots was a bit surprising to me, and found only
after writing most of the code and then noticing what no longer
compiled.
In a few spots, new accessor methods are added to operation
subclasses, so that code that dissects an expression will work with
the new scheme.
After this change, code that constructs an expression can be switched
to the new form without breaking.
gdb/ChangeLog
2021-03-08 Tom Tromey <tom@tromey.com>
* ada-exp.h (class ada_var_value_operation) <get_symbol>: Remove;
now in superclass.
* value.h (fetch_subexp_value): Add "op" parameter.
* value.c (init_if_undefined_command): Update.
* tracepoint.c (validate_actionline, encode_actions_1): Update.
* stap-probe.c (stap_probe::compile_to_ax): Update.
* printcmd.c (set_command): Update.
* ppc-linux-nat.c (ppc_linux_nat_target::check_condition):
Update.
* parser-defs.h (struct expr_builder) <set_operation>: New
method.
* parse.c (parse_exp_in_context, exp_uses_objfile): Update.
* expression.h (struct expression) <first_opcode>: Update.
<op>: New member.
* expprint.c (dump_raw_expression, dump_prefix_expression):
Update.
* expop.h (class var_value_operation) <get_symbol>: New method.
(class register_operation) <get_name>: New method.
(class equal_operation): No longer a typedef, now a subclass.
(class unop_memval_operation) <get_type>: New method.
(class assign_operation) <get_lhs>: New method.
(class unop_cast_operation) <get_type>: New method.
* eval.c (evaluate_expression, evaluate_type)
(evaluate_subexpression_type): Update.
(fetch_subexp_value): Add "op" parameter.
(parse_and_eval_type): Update.
* dtrace-probe.c (dtrace_probe::compile_to_ax): Update.
* breakpoint.c (update_watchpoint, watchpoint_check)
(watchpoint_exp_is_const, watch_command_1): Update.
* ax-gdb.c (gen_trace_for_expr, gen_eval_for_expr, gen_printf):
Update.
|
|
With a certain Ada program, ada-lang.c:coerce_unspec_val_to_type can
cause a crash. This function may copy a value, and in the particular
case in the crash, the new value's type is smaller than the original
type. This causes coerce_unspec_val_to_type to create a lazy value --
but the original value is also not_lval, so later, when the value is
un-lazied, gdb asserts.
As with the previous patch, we believe there is a compiler bug here,
but it is difficult to reproduce, so we're not completely certain.
In the particular case we saw, the original value has record type, and
the record holds some variable-length arrays. This leads to the
type's length being 0. At the same time, the value is optimized out.
This patch changes coerce_unspec_val_to_type to handle an
optimized-out value correctly.
It also slightly restructures this code to avoid a crash should a
not_lval value wind up here. This is a purely defensive change.
This change also made it clear that value_contents_copy_raw can now be
made static, so that is also done.
gdb/ChangeLog
2021-02-09 Tom Tromey <tromey@adacore.com>
* ada-lang.c (coerce_unspec_val_to_type): Avoid making lazy
not_lval value.
* value.c (value_contents_copy_raw): Now static.
* value.h (value_contents_copy_raw): Don't declare.
|
|
... and update all users.
gdb/ChangeLog:
* gdbtypes.h (get_type_arch): Rename to...
(struct type) <arch>: ... this, update all users.
Change-Id: I0e3ef938a0afe798ac0da74a9976bbd1d082fc6f
|
|
I think this makes the names of the methods clearer, especially for the
arch. The type::arch method (which gets the arch owner, or NULL if the
type is not arch owned) is easily confused with the get_type_arch method
(which returns an arch no matter what). The name "arch_owner" will make
it intuitive that the method returns NULL if the type is not arch-owned.
Also, this frees the type::arch name, so we will be able to morph the
get_type_arch function into the type::arch method.
gdb/ChangeLog:
* gdbtypes.h (struct type) <arch>: Rename to...
<arch_owner>: ... this, update all users.
<objfile>: Rename to...
<objfile_owner>: ... this, update all users.
Change-Id: Ie7c28684c7b565adec05a7619c418c69429bd8c0
|
|
Change all users to use the type::objfile method instead.
gdb/ChangeLog:
* gdbtypes.h (TYPE_OBJFILE): Remove, change all users to use the
type::objfile method instead.
Change-Id: I6b3f580913fb1fb0cf986b176dba8db68e1fabf9
|
|
Consider this Fortran type:
type :: some_type
integer, allocatable :: array_one (:,:)
integer :: a_field
integer, allocatable :: array_two (:,:)
end type some_type
And a variable declared:
type(some_type) :: some_var
Now within GDB we try this:
(gdb) set $a = some_var
(gdb) p $a
$1 = ( array_one =
../../src/gdb/value.c:3968: internal-error: Unexpected lazy value type.
Normally, when an internalvar ($a in this case) is created, it is
non-lazy, the value is immediately copied out of the inferior into
GDB's memory.
When printing the internalvar ($a) GDB will extract each field in
turn, so in this case `array_one`. As the original internalvar is
non-lazy then the extracted field will also be non-lazy, with its
contents immediately copied from the parent internalvar.
However, when the field has a dynamic type this is not the case, in
value_primitive_field we see that any field with dynamic type is
always created lazy. Further, the content of this field will usually
not have been captured in the contents buffer of the original value, a
field with dynamic location is effectively a pointer value contained
within the parent value, with rules in the DWARF for how to
dereference the pointer.
So, we end up with a lazy lval_internalvar_component representing a
field within an lval_internalvar. This eventually ends up in
value_fetch_lazy, which currently does not support
lval_internalvar_component, and we see the error above.
My original plan for how to handle this involved extending
value_fetch_lazy to handle lval_internalvar_component. However, when
I did this I ran into another error:
(gdb) set $a = some_var
(gdb) p $a
$1 = ( array_one = ((1, 1) (1, 1) (1, 1)), a_field = 5, array_two = ((0, 0, 0) (0, 0, 0)) )
(gdb) p $a%array_one
$2 = ((1, 1) (1, 1) (1, 1))
(gdb) p $a%array_one(1,1)
../../src/gdb/value.c:1547: internal-error: void set_value_address(value*, CORE_ADDR): Assertion `value->lval == lval_memory' failed.
The problem now is inside set_value_component_location, where we
attempt to set the address for a component if the original parent
value has a dynamic location. GDB does not expect to ever set the
address on anything other than an lval_memory value (which seems
reasonable).
In order to resolve this issue I initially thought about how an
internalvar should "capture" the value of a program variable at the
moment the var is created. In an ideal world (I think) GDB would be
able to do this even for values with dynamic type. So in our above
example doing `set $a = some_var` would capture the content of
'some_var', but also the content of 'array_one', and also 'array_two',
even though these content regions are not contained within the region
of 'some_var'.
Supporting this would require GDB values to be able to carry around
multiple non-contiguous regions of memory as content in some way,
which sounds like a pretty huge change to a core part of GDB.
So, I wondered if there was some other solution that wouldn't require
such a huge change.
What if values with a dynamic location were though of like points with
automatic dereferencing? Given this C structure:
struct foo_t {
int *val;
}
struct foo_t my_foo;
Then in GDB:
(gdb) $a = my_foo
We would expect GDB to capture the pointer value in '$a', but not the
value pointed at by the pointer. So maybe it's not that unreasonable
to think that given a dynamically typed field GDB will capture the
address of the content, but not the actual content itself.
That's what this patch does.
The approach is to catch this case in set_value_component_location.
When we create a component location (of an lval_internalvar) that has
a dynamic data location, the lval_internalvar_component is changed
into an lval_memory. After this, both of the above issues are
resolved. In the first case, the lval_memory is still lazy, but
value_fetch_lazy knows how to handle that. In the second case, when
we access an element of the array we are now accessing an element of
an lval_memory, not an lval_internalvar_component, and calling
set_value_address on an lval_memory is fine.
gdb/ChangeLog:
* value.c (set_value_component_location): Adjust the VALUE_LVAL
for internalvar components that have a dynamic location.
gdb/testsuite/ChangeLog:
* gdb.fortran/intvar-dynamic-types.exp: New file.
* gdb.fortran/intvar-dynamic-types.f90: New file.
|
|
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.
|
|
This adds a new helper method, expression::first_opcode, that extracts
the outermost opcode of an expression. This simplifies some patches
in the expression rewrite series.
Note that this patch requires the earlier patch to avoid manual
dissection of OP_TYPE operations.
2020-12-15 Tom Tromey <tom@tromey.com>
* varobj.c (varobj_create): Use first_opcode.
* value.c (init_if_undefined_command): Use first_opcode.
* typeprint.c (whatis_exp): Use first_opcode.
* tracepoint.c (validate_actionline): Use first_opcode.
(encode_actions_1): Use first_opcode.
* stack.c (return_command): Use first_opcode.
* expression.h (struct expression) <first_opcode>: New method.
* eval.c (parse_and_eval_type): Use first_opcode.
* dtrace-probe.c (dtrace_process_dof_probe): Use first_opcode.
|
|
I noticed that value_internal_function_name should have a const return
type. This patch makes this change.
gdb/ChangeLog
2020-12-04 Tom Tromey <tromey@adacore.com>
* value.c (value_internal_function_name): Make return type const.
* value.h (value_internal_function_name): Make return type const.
|
|
This logically connects this function to the object it inspects.
gdb/ChangeLog:
* gdbtypes.h (struct type) <fixed_point_scaling_factor>: New method,
replacing fixed_point_scaling_factor. All callers updated
throughout this project.
(fixed_point_scaling_factor): Delete declaration.
* gdbtypes.c (type::fixed_point_scaling_factor): Replaces
fixed_point_scaling_factor. Adjust implementation accordingly.
|
|
As suggested by Simon, to logically connect this function to
the object it inspects.
Note that, logically, this method should be "const". Unfortunately,
the implementation iterates on struct type objects starting with "this",
and thus trying to declare the method "const" triggers a compilation
error.
gdb/ChangeLog:
* gdbtypes.h (struct type) <fixed_point_type_base_type> New method,
replacing the fixed_point_type_base_type function. All callers
updated throughout this project.
(fixed_point_type_base_type): Remove declaration.
* gdbtypes.c (type::fixed_point_type_base_type): Replaces
fixed_point_type_base_type. Adjust implementation accordingly.
|
|
This commit changes the interfaces of some of the methods declared
in gmp-utils to take a gdb::array_view of gdb_byte instead of a
(gdb_byte *, size) couple.
This makes these methods' API probably more C++-idiomatic.
* gmp-utils.h (gdb_mpz::read): Change buf and len parameters
into one single gdb::array_view parameter.
(gdb_mpz::write): Likewise.
(gdb_mpq::read_fixed_point, gdb_mpq::write_fixed_point): Likewise.
* gmp-utils.c (gdb_mpz::read): Change buf and len parameters
into one single gdb::array_view parameter.
Adjust implementation accordingly.
(gdb_mpz::write): Likewise.
(gdb_mpq::read_fixed_point, gdb_mpq::write_fixed_point): Likewise.
* unittests/gmp-utils-selftests.c: Adapt following changes above.
* valarith.c, valops.c, valprint.c, value.c: Likewise.
|
|
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.
|