Age | Commit message (Collapse) | Author | Files | Lines |
|
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
|
|
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.
|
|
Add a getter and a setter for a symbol's line. Remove the corresponding macro
and adjust all callers.
Change-Id: I229f2b8fcf938c07975f641361313a8761fad9a5
|
|
This moves the gdb-specific obstack code -- both extensions like
obconcat and obstack_strdup, and things like auto_obstack -- to
gdbsupport.
|
|
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
|
|
I think it would make sense for extract_integer, extract_signed_integer
and extract_unsigned_integer to take an array_view. This way, when we
extract an integer, we can validate that we don't overflow the buffer
passed by the caller (e.g. ask to extract a 4-byte integer but pass a
2-byte buffer).
- Change extract_integer to take an array_view
- Add overloads of extract_signed_integer and extract_unsigned_integer
that take array_views. Keep the existing versions so we don't
need to change all callers, but make them call the array_view
versions.
This shortens some places like:
result = extract_unsigned_integer (value_contents (result_val).data (),
TYPE_LENGTH (value_type (result_val)),
byte_order);
into
result = extract_unsigned_integer (value_contents (result_val), byte_order);
value_contents returns an array view that is of length
`TYPE_LENGTH (value_type (result_val))` already, so the length is
implicitly communicated through the array view.
Change-Id: Ic1c1f98c88d5c17a8486393af316f982604d6c95
|
|
There's a common pattern to call add_basic_prefix_cmd and
add_show_prefix_cmd to add matching set and show commands. Add the
add_setshow_prefix_cmd function to factor that out and use it at a few
places.
Change-Id: I6e9e90a30e9efb7b255bf839cac27b85d7069cfd
|
|
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
|
|
I ran into this assertion while GDB was trying to unwind the stack:
gdb/inline-frame.c:173: internal-error: void inline_frame_this_id(frame_info*, void**, frame_id*): Assertion `frame_id_p (*this_id)' failed.
That is, when building the frame_id for an inline frame, GDB asks for
the frame_id of the previous frame. Unfortunately, no valid frame_id
was returned for the previous frame, and so the assertion triggers.
What is happening is this, I had a stack that looked something like
this (the arrows '->' point from caller to callee):
normal_frame -> inline_frame
However, for whatever reason (e.g. broken debug information, or
corrupted stack contents in the inferior), when GDB tries to unwind
"normal_frame", it ends up getting back effectively the same frame,
thus the call stack looks like this to GDB:
.-> normal_frame -> inline_frame
| |
'-----'
Given such a situation we would expect GDB to terminate the stack with
an error like this:
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
However, the inline_frame causes a problem, and here's why:
When unwinding we start from the sentinel frame and call
get_prev_frame. We eventually end up in get_prev_frame_if_no_cycle,
in here we create a raw frame, and as this is frame #0 we immediately
return.
However, eventually we will try to unwind the stack further. When we
do this we inevitably needing to know the frame_id for frame #0, and
so, eventually, we end up in compute_frame_id.
In compute_frame_id we first find the right unwinder for this frame,
in our case (i.e. for inline_frame) the $pc is within the function
normal_frame, but also within a block associated with the inlined
function inline_frame, as such the inline frame unwinder claims this
frame.
Back in compute_frame_id we next compute the frame_id, for our
inline_frame this means a call to inline_frame_this_id.
The ID of an inline frame is based on the id of the previous frame, so
from inline_frame_this_id we call get_prev_frame_always, this
eventually calls get_prev_frame_if_no_cycle again, which creates
another raw frame and calls compute_frame_id (for frames other than
frame 0 we immediately compute the frame_id).
In compute_frame_id we again identify the correct unwinder for this
frame. Our $pc is unchanged, however, the fact that the next frame is
of type INLINE_FRAME prevents the inline frame unwinder from claiming
this frame again, and so, the standard DWARF frame unwinder claims
normal_frame.
We return to compute_frame_id and call the standard DWARF function to
build the frame_id for normal_frame.
With the frame_id of normal_frame figured out we return to
compute_frame_id, and then to get_prev_frame_if_no_cycle, where we add
the ID for normal_frame into the frame_id cache, and return the frame
back to inline_frame_this_id.
From inline_frame_this_id we build a frame_id for inline_frame and
return to compute_frame_id, and then to get_prev_frame_if_no_cycle,
which adds the frame_id for inline_frame into the frame_id cache.
So far, so good.
However, as we are trying to unwind the complete stack, we eventually
ask for the previous frame of normal_frame, remember, at this point
GDB doesn't know the stack is corrupted (with a cycle), GDB still
needs to figure that out.
So, we eventually end up in get_prev_frame_if_no_cycle where we create
a raw frame and call compute_frame_id, remember, this is for the frame
before normal_frame.
The first task for compute_frame_id is to find the unwinder for this
frame, so all of the frame sniffers are tried in order, this includes
the inline frame sniffer.
The inline frame sniffer asks for the $pc, this request is sent up the
stack to normal_frame, which, due to its cyclic behaviour, tells GDB
that the $pc in the previous frame was the same as the $pc in
normal_frame.
GDB spots that this $pc corresponds to both the function normal_frame
and also the inline function inline_frame. As the next frame is not
an INLINE_FRAME then GDB figures that we have not yet built a frame to
cover inline_frame, and so the inline sniffer claims this new frame.
Our stack is now looking like this:
inline_frame -> normal_frame -> inline_frame
But, we have not yet computed the frame id for the outer most (on the
left) inline_frame. After the frame sniffer has claimed the inline
frame GDB returns to compute_frame_id and calls inline_frame_this_id.
In here GDB calls get_prev_frame_always, which eventually ends up
in get_prev_frame_if_no_cycle again, where we create a raw frame and
call compute_frame_id.
Just like before, compute_frame_id tries to find an unwinder for this
new frame, it sees that the $pc is within both normal_frame and
inline_frame, but the next frame is, again, an INLINE_FRAME, so, just
like before the standard DWARF unwinder claims this frame. Back in
compute_frame_id we again call the standard DWARF function to build
the frame_id for this new copy of normal_frame.
At this point the stack looks like this:
normal_frame -> inline_frame -> normal_frame -> inline_frame
After compute_frame_id we return to get_prev_frame_if_no_cycle, where
we try to add the frame_id for the new normal_frame into the frame_id
cache, however, unlike before, we fail to add this frame_id as it is
a duplicate of the previous normal_frame frame_id. Having found a
duplicate get_prev_frame_if_no_cycle unlinks the new frame from the
stack, and returns nullptr, the stack now looks like this:
inline_frame -> normal_frame -> inline_frame
The nullptr result from get_prev_frame_if_no_cycle is fed back to
inline_frame_this_id, which forwards this to get_frame_id, which
immediately returns null_frame_id. As null_frame_id is not considered
a valid frame_id, this is what triggers the assertion.
In summary then:
- inline_frame_this_id currently assumes that as the inline frame
exists, we will always get a valid frame back from
get_prev_frame_always,
- get_prev_frame_if_no_cycle currently assumes that it is safe to
return nullptr when it sees a cycle.
Notice that in frame.c:compute_frame_id, this code:
fi->this_id.value = outer_frame_id;
fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value);
gdb_assert (frame_id_p (fi->this_id.value));
The assertion makes it clear that the this_id function must always
return a valid frame_id (e.g. null_frame_id is not a valid return
value), and similarly in inline_frame.c:inline_frame_this_id this
code:
*this_id = get_frame_id (get_prev_frame_always (this_frame));
/* snip comment */
gdb_assert (frame_id_p (*this_id));
Makes it clear that every inline frame expects to be able to get a
previous frame, which will have a valid frame_id.
As I have discussed above, these assumptions don't currently hold in
all cases.
One possibility would be to move the call to get_prev_frame_always
forward from inline_frame_this_id to inline_frame_sniffer, however,
this falls foul of (in frame.c:frame_cleanup_after_sniffer) this
assertion:
/* No sniffer should extend the frame chain; sniff based on what is
already certain. */
gdb_assert (!frame->prev_p);
This assert prohibits any sniffer from trying to get the previous
frame, as getting the previous frame is likely to depend on the next
frame, I can understand why this assertion is a good thing, and I'm in
no rush to alter this rule.
The solution proposed here takes onboard feedback from both Pedro, and
Simon (see the links below). The get_prev_frame_if_no_cycle function
is renamed to get_prev_frame_maybe_check_cycle, and will now not do
cycle detection for inline frames, even when we spot a duplicate frame
it is still returned. This is fine, as, if the normal frame has a
duplicate frame-id then the inline frame will also have a duplicate
frame-id. And so, when we reject the inline frame, the duplicate
normal frame, which is previous to the inline frame, will also be
rejected.
In inline-frame.c the call to get_prev_frame_always is no longer
nested inside the call to get_frame_id. There are reasons why
get_prev_frame_always can return nullptr, for example, if there is a
memory error while trying to get the previous frame, if this should
happen then we now give a more informative error message.
Historical Links:
Patch v2: https://sourceware.org/pipermail/gdb-patches/2021-June/180208.html
Feedback: https://sourceware.org/pipermail/gdb-patches/2021-July/180651.html
https://sourceware.org/pipermail/gdb-patches/2021-July/180663.html
Patch v3: https://sourceware.org/pipermail/gdb-patches/2021-July/181029.html
Feedback: https://sourceware.org/pipermail/gdb-patches/2021-July/181035.html
Additional input: https://sourceware.org/pipermail/gdb-patches/2021-September/182040.html
|
|
Rename thread_info::executing to thread_info::m_executing, and make it
private. Add a new get/set member functions, and convert GDB to make
use of these.
The only real change of interest in this patch is in thread.c where I
have deleted the helper function set_executing_thread, and now just
use the new set function thread_info::set_executing. However, the old
helper function set_executing_thread included some code to reset the
thread's stop_pc, so I moved this code into the new function
thread_info::set_executing. However, I don't believe there is
anywhere that this results in a change of behaviour, previously the
executing flag was always set true through a call to
set_executing_thread anyway.
|
|
While working on a stack unwinding issue using 'set debug frame on', I
noticed the frame_info::to_string method could be slightly improved.
Unwinders have been given a name in
a154d838a70e96d888620c072e2d6ea8bdf044ca. Before this patch, frame_info
debug output prints the host address of the used unwinder, which is not
easy to interpret. This patch proposes to use the unwinder name
instead since we now have it.
Before the patch:
{level=1,type=NORMAL_FRAME,unwind=0x2ac1763ec0,pc=0x3ff7fc3460,id={stack=0x3ff7ea79b0,code=0x0000003ff7fc33ac,!special},func=0x3ff7fc33ac}
With the patch:
{level=1,type=NORMAL_FRAME,unwinder="riscv prologue",pc=0x3ff7fc3460,id={stack=0x3ff7ea79b0,code=0x0000003ff7fc33ac,!special},func=0x3ff7fc33ac}
Tested on riscv64-linux-gnu.
|
|
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_SCOPED_DEBUG_ENTER_EXIT and use it to print enter/exit
messages in important frame-related functions. I think this helps
understand which lower-level operations are done as part of which
higher-level operation. And it helps visually skip over a higher-level
operation you are not interested in.
Here's an example, combined with some py-unwind messages:
[frame] frame_unwind_find_by_frame: enter
[frame] frame_unwind_find_by_frame: this_frame=0
[frame] frame_unwind_try_unwinder: trying unwinder "dummy"
[frame] frame_unwind_try_unwinder: no
[frame] frame_unwind_try_unwinder: trying unwinder "dwarf2 tailcall"
[frame] frame_unwind_try_unwinder: no
[frame] frame_unwind_try_unwinder: trying unwinder "inline"
[frame] frame_unwind_try_unwinder: no
[frame] frame_unwind_try_unwinder: trying unwinder "jit"
[frame] frame_unwind_try_unwinder: no
[frame] frame_unwind_try_unwinder: trying unwinder "python"
[py-unwind] pyuw_sniffer: enter
[frame] frame_unwind_register_value: enter
[frame] frame_unwind_register_value: frame=-1, regnum=7(rsp)
[frame] frame_unwind_register_value: -> register=7 bytes=[40ddffffff7f0000]
[frame] frame_unwind_register_value: exit
[py-unwind] pyuw_sniffer: frame=0, sp=0x7fffffffdd40, pc=0x5555555551ec
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_unwind_register_value: enter
[frame] frame_unwind_register_value: frame=-1, regnum=6(rbp)
[frame] frame_unwind_register_value: -> register=6 bytes=[50ddffffff7f0000]
[frame] frame_unwind_register_value: exit
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] get_prev_frame: enter
[frame] get_prev_frame_always_1: enter
[frame] get_prev_frame_always_1: this_frame=-1
[frame] get_prev_frame_always_1: -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d17c0,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
[frame] get_prev_frame_always_1: exit
[frame] get_prev_frame: exit
[frame] value_fetch_lazy_register: (frame=0, regnum=6(rbp), ...) -> register=6 bytes=[50ddffffff7f0000]
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_unwind_register_value: enter
[frame] frame_unwind_register_value: frame=-1, regnum=7(rsp)
[frame] frame_unwind_register_value: -> register=7 bytes=[40ddffffff7f0000]
[frame] frame_unwind_register_value: exit
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] get_prev_frame: enter
[frame] get_prev_frame_always_1: enter
[frame] get_prev_frame_always_1: this_frame=-1
[frame] get_prev_frame_always_1: -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d1824,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
[frame] get_prev_frame_always_1: exit
[frame] get_prev_frame: exit
[frame] value_fetch_lazy_register: (frame=0, regnum=7(rsp), ...) -> register=7 bytes=[40ddffffff7f0000]
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_unwind_register_value: enter
[frame] frame_unwind_register_value: frame=-1, regnum=16(rip)
[frame] frame_unwind_register_value: -> register=16 bytes=[ec51555555550000]
[frame] frame_unwind_register_value: exit
[frame] frame_id_p: l={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] frame_id_eq: l={stack=<sentinel>,!code,special=0x0000000000000000}, r={stack=<sentinel>,!code,special=0x0000000000000000} -> 1
[frame] get_prev_frame: enter
[frame] get_prev_frame_always_1: enter
[frame] get_prev_frame_always_1: this_frame=-1
[frame] get_prev_frame_always_1: -> {level=0,type=NORMAL_FRAME,unwind=0x5588ee3d1888,pc=0x5555555551ec,id=<not computed>,func=<unknown>} // cached
[frame] get_prev_frame_always_1: exit
[frame] get_prev_frame: exit
[frame] value_fetch_lazy_register: (frame=0, regnum=16(rip), ...) -> register=16 bytes=[ec51555555550000]
[py-unwind] pyuw_sniffer: frame claimed by unwinder test unwinder
[py-unwind] pyuw_sniffer: exit
[frame] frame_unwind_try_unwinder: yes
[frame] frame_unwind_find_by_frame: exit
gdb/ChangeLog:
* frame.h (FRAME_SCOPED_DEBUG_ENTER_EXIT): New.
* frame.c (compute_frame_id, get_prev_frame_always_1,
get_prev_frame): Use FRAME_SCOPED_DEBUG_ENTER_EXIT.
* frame-unwind.c (frame_unwind_find_by_frame): Likewise.
(frame_unwind_register_value): Likewise.
Change-Id: I45b69b4ed962e70572bc55b8adfb211483c1eeed
|
|
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
|
|
gdb/ChangeLog:
* frame.h (frame_debug): Change type to bool.
* frame.c (frame_debug): Change type to bool.
(_initialize_frame): Adjust.
Change-Id: I27b5359a25ad53ac42618b5708a025c348a1eeda
|
|
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.
|
|
Replace fprint_frame_id with a member function frame_id::to_string
that returns a std::string. Convert all of the previous users of
fprint_frame_id to use the new member function. This means that
instead of writing things like this:
fprintf_unfiltered (file, " id=");
fprint_frame_id (file, s->id.id);
We can write this:
fprintf_unfiltered (file, " id=%s", s->id.id.to_string ().c_str ());
There should be no user visible changes after this commit.
gdb/ChangeLog:
* dummy-frame.c (fprint_dummy_frames): Convert use of
fprint_frame_id to use frame_id::to_string.
* frame.c (fprint_field): Delete.
(fprint_frame_id): Moved to...
(frame_id::to_string): ...this, rewritten to return a string.
(fprint_frame): Convert use of fprint_frame_id to use
frame_id::to_string.
(compute_frame_id): Likewise.
(frame_id_p): Likewise.
(frame_id_eq): Likewise.
(frame_id_inner): Likewise.
* frame.h (struct frame_id) <to_string>: New member function.
(fprint_frame_id): Delete declaration.
* guile/scm-frame.c (frscm_print_frame_smob): Convert use of
fprint_frame_id to use frame_id::to_string.
* python/py-frame.c (frame_object_to_frame_info): Likewise.
* python/py-unwind.c (unwind_infopy_str): Likewise.
(pyuw_this_id): Likewise.
|
|
Give a name to each observer, this will help produce more meaningful
debug message.
gdbsupport/ChangeLog:
* observable.h (class observable) <struct observer> <observer>:
Add name parameter.
<name>: New field.
<attach>: Add name parameter, update all callers.
Change-Id: Ie0cc4664925215b8d2b09e026011b7803549fba0
|
|
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
|
|
This patch converts the most obvious functions from gdb/frame.h to use
the gdb::array_view abstraction. I've converted the ones that used buffer +
length.
There are others using only the buffer, with an implicit size. I did not
touch those for now. But it would be nice to pass the size for safety.
Tested with --enable-targets=all on Ubuntu 18.04/20.04 aarch64-linux.
gdb/ChangeLog
2021-01-19 Luis Machado <luis.machado@linaro.org>
* frame.h (get_frame_register_bytes): Pass a gdb::array_view instead
of buffer + length.
(put_frame_register_bytes): Likewise.
Adjust documentation.
(get_frame_memory): Pass a gdb::array_view instead of buffer + length.
(safe_frame_unwind_memory): Likewise.
* frame.c (get_frame_register_bytes, put_frame_register_bytes)
(get_frame_memory, safe_frame_unwind_memory): Adjust to use
gdb::array_view.
* amd64-fbsd-tdep.c (amd64fbsd_sigtramp_p): Likewise.
* amd64-linux-tdep.c (amd64_linux_sigtramp_start): Likewise.
* amd64-obsd-tdep.c (amd64obsd_sigtramp_p): Likewise.
* arc-linux-tdep.c (arc_linux_is_sigtramp): Likewise.
* cris-tdep.c (cris_sigtramp_start, cris_rt_sigtramp_start): Likewise.
* dwarf2/loc.c (rw_pieced_value): Likewise.
* hppa-tdep.c (hppa_frame_cache): Likewise.
* i386-fbsd-tdep.c (i386fbsd_sigtramp_p): Likewise.
* i386-gnu-tdep.c (i386_gnu_sigtramp_start): Likewise.
* i386-linux-tdep.c (i386_linux_sigtramp_start)
(i386_linux_rt_sigtramp_start): Likewise.
* i386-obsd-tdep.c (i386obsd_sigtramp_p): Likewise.
* i386-tdep.c (i386_register_to_value): Likewise.
* i387-tdep.c (i387_register_to_value): Likewise.
* ia64-tdep.c (ia64_register_to_value): Likewise.
* m32r-linux-tdep.c (m32r_linux_sigtramp_start)
(m32r_linux_rt_sigtramp_start): Likewise.
* m68k-linux-tdep.c (m68k_linux_pc_in_sigtramp): Likewise.
* m68k-tdep.c (m68k_register_to_value): Likewise.
* mips-tdep.c (mips_register_to_value)
(mips_value_to_register): Likewise.
* ppc-fbsd-tdep.c (ppcfbsd_sigtramp_frame_sniffer)
(ppcfbsd_sigtramp_frame_cache): Likewise.
* ppc-obsd-tdep.c (ppcobsd_sigtramp_frame_sniffer)
(ppcobsd_sigtramp_frame_cache): Likewise.
* rs6000-tdep.c (rs6000_in_function_epilogue_frame_p)
(rs6000_register_to_value): Likewise.
* tilegx-tdep.c (tilegx_analyze_prologue): Likewise.
* tramp-frame.c (tramp_frame_start): Likewise.
* valops.c (value_assign): Likewise.
|
|
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.
|
|
gdb/ChangeLog:
* frame.c: Remove trailing white spaces.
* frame.h: Likewise.
|
|
The recent commit to make scoped_restore_current_thread's cdtors
exception free regressed gdb.base/eh_return.exp:
Breakpoint 1, 0x00000000004012bb in eh2 (gdb/frame.c:641: internal-error: frame_id get_frame_id(frame_info*): Assertion `stashed' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n) FAIL: gdb.base/eh_return.exp: hit breakpoint (GDB internal error)
That testcase uses __builtin_eh_return and, before the regression, the
backtrace at eh2 looked like this:
(gdb) bt
#0 0x00000000004006eb in eh2 (p=0x4006ec <continuation>) at src/gdb/testsuite/gdb.base/eh_return.c:54
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
That "previous frame identical to this frame" is caught by the cycle
detection based on frame id.
The assertion failing is this one:
638 /* Since this is the first frame in the chain, this should
639 always succeed. */
640 bool stashed = frame_stash_add (fi);
641 gdb_assert (stashed);
originally added by
commit f245535cf583ae4ca13b10d47b3c7d3334593ece
Author: Pedro Alves <palves@redhat.com>
AuthorDate: Mon Sep 5 18:41:38 2016 +0100
Fix PR19927: Avoid unwinder recursion if sniffer uses calls parse_and_eval
The assertion is failing because frame #1's frame id was stashed
before the id of frame #0 is stashed. The frame id of frame #1 was
stashed here:
(top-gdb) bt
#0 frame_stash_add (frame=0x1e24c90) at src/gdb/frame.c:276
#1 0x0000000000669c1b in get_prev_frame_if_no_cycle (this_frame=0x19f8370) at src/gdb/frame.c:2120
#2 0x000000000066a339 in get_prev_frame_always_1 (this_frame=0x19f8370) at src/gdb/frame.c:2303
#3 0x000000000066a360 in get_prev_frame_always (this_frame=0x19f8370) at src/gdb/frame.c:2319
#4 0x000000000066b56c in get_frame_unwind_stop_reason (frame=0x19f8370) at src/gdb/frame.c:3028
#5 0x000000000059f929 in dwarf2_frame_cfa (this_frame=0x19f8370) at src/gdb/dwarf2/frame.c:1462
#6 0x00000000005ce434 in dwarf_evaluate_loc_desc::get_frame_cfa (this=0x7fffffffc070) at src/gdb/dwarf2/loc.c:666
#7 0x00000000005989a9 in dwarf_expr_context::execute_stack_op (this=0x7fffffffc070, op_ptr=0x1b2a053 "\364\003", op_end=0x1b2a053 "\364\003") at src/gdb/dwarf2/expr.c:1161
#8 0x0000000000596af6 in dwarf_expr_context::eval (this=0x7fffffffc070, addr=0x1b2a052 "\234\364\003", len=1) at src/gdb/dwarf2/expr.c:303
#9 0x0000000000597b4e in dwarf_expr_context::execute_stack_op (this=0x7fffffffc070, op_ptr=0x1b2a063 "", op_end=0x1b2a063 "") at src/gdb/dwarf2/expr.c:865
#10 0x0000000000596af6 in dwarf_expr_context::eval (this=0x7fffffffc070, addr=0x1b2a061 "\221X", len=2) at src/gdb/dwarf2/expr.c:303
#11 0x00000000005c8b5a in dwarf2_evaluate_loc_desc_full (type=0x1b564d0, frame=0x19f8370, data=0x1b2a061 "\221X", size=2, per_cu=0x1b28760, per_objfile=0x1a84930, subobj_type=0x1b564d0, subobj_byte_offset=0) at src/gdb/dwarf2/loc.c:2260
#12 0x00000000005c9243 in dwarf2_evaluate_loc_desc (type=0x1b564d0, frame=0x19f8370, data=0x1b2a061 "\221X", size=2, per_cu=0x1b28760, per_objfile=0x1a84930) at src/gdb/dwarf2/loc.c:2444
#13 0x00000000005cb769 in locexpr_read_variable (symbol=0x1b59840, frame=0x19f8370) at src/gdb/dwarf2/loc.c:3687
#14 0x0000000000663137 in language_defn::read_var_value (this=0x122ea60 <c_language_defn>, var=0x1b59840, var_block=0x0, frame=0x19f8370) at src/gdb/findvar.c:618
#15 0x0000000000663c3b in read_var_value (var=0x1b59840, var_block=0x0, frame=0x19f8370) at src/gdb/findvar.c:822
#16 0x00000000008c7d9f in read_frame_arg (fp_opts=..., sym=0x1b59840, frame=0x19f8370, argp=0x7fffffffc470, entryargp=0x7fffffffc490) at src/gdb/stack.c:542
#17 0x00000000008c89cd in print_frame_args (fp_opts=..., func=0x1b597c0, frame=0x19f8370, num=-1, stream=0x1aba860) at src/gdb/stack.c:890
#18 0x00000000008c9bf8 in print_frame (fp_opts=..., frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, print_args=1, sal=...) at src/gdb/stack.c:1394
#19 0x00000000008c92b9 in print_frame_info (fp_opts=..., frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at src/gdb/stack.c:1119
#20 0x00000000008c75f0 in print_stack_frame (frame=0x19f8370, print_level=0, print_what=SRC_AND_LOC, set_current_sal=1) at src/gdb/stack.c:366
#21 0x000000000070250b in print_stop_location (ws=0x7fffffffc9e0) at src/gdb/infrun.c:8110
#22 0x0000000000702569 in print_stop_event (uiout=0x1a8b9e0, displays=true) at src/gdb/infrun.c:8126
#23 0x000000000096d04b in tui_on_normal_stop (bs=0x1bcd1c0, print_frame=1) at src/gdb/tui/tui-interp.c:98
...
Before the commit to make scoped_restore_current_thread's cdtors
exception free, scoped_restore_current_thread's dtor would call
get_frame_id on the selected frame, and we use
scoped_restore_current_thread pervasively. That had the side effect
of stashing the frame id of frame #0 before reaching the path shown in
the backtrace. I.e., the frame id of frame #0 happened to be stashed
before the frame id of frame #1. But that was by chance, not by
design.
This commit:
commit 256ae5dbc73d1348850f86ee77a0dc3b04bc7cc0
Author: Kevin Buettner <kevinb@redhat.com>
AuthorDate: Mon Oct 31 12:47:42 2016 -0700
Stash frame id of current frame before stashing frame id for previous frame
Fixed a similar problem, by making sure get_prev_frame computes the
frame id of the current frame before unwinding the previous frame, so
that the cycle detection works properly. That fix misses the scenario
we're now running against, because if you notice, the backtrace above
shows that frame #4 calls get_prev_frame_always, not get_prev_frame.
I.e., nothing is calling get_frame_id on the current frame.
The fix here is to move Kevin's fix down from get_prev_frame to
get_prev_frame_always. Or actually, a bit further down to
get_prev_frame_always_1 -- note that inline_frame_this_id calls
get_prev_frame_always, so we need to be careful to avoid recursion in
that scenario.
gdb/ChangeLog:
* frame.c (get_prev_frame): Move get_frame_id call from here ...
(get_prev_frame_always_1): ... to here.
* inline-frame.c (inline_frame_this_id): Mention
get_prev_frame_always_1 in comment.
Change-Id: Id960c98ab2d072c48a436c3eb160cc4b2a5cfd1d
|
|
Many spots incorrectly use only spaces for indentation (for example,
there are a lot of spots in ada-lang.c). I've always found it awkward
when I needed to edit one of these spots: do I keep the original wrong
indentation, or do I fix it? What if the lines around it are also
wrong, do I fix them too? I probably don't want to fix them in the same
patch, to avoid adding noise to my patch.
So I propose to fix as much as possible once and for all (hopefully).
One typical counter argument for this is that it makes code archeology
more difficult, because git-blame will show this commit as the last
change for these lines. My counter counter argument is: when
git-blaming, you often need to do "blame the file at the parent commit"
anyway, to go past some other refactor that touched the line you are
interested in, but is not the change you are looking for. So you
already need a somewhat efficient way to do this.
Using some interactive tool, rather than plain git-blame, makes this
trivial. For example, I use "tig blame <file>", where going back past
the commit that changed the currently selected line is one keystroke.
It looks like Magit in Emacs does it too (though I've never used it).
Web viewers of Github and Gitlab do it too. My point is that it won't
really make archeology more difficult.
The other typical counter argument is that it will cause conflicts with
existing patches. That's true... but it's a one time cost, and those
are not conflicts that are difficult to resolve. I have also tried "git
rebase --ignore-whitespace", it seems to work well. Although that will
re-introduce the faulty indentation, so one needs to take care of fixing
the indentation in the patch after that (which is easy).
gdb/ChangeLog:
* aarch64-linux-tdep.c: Fix indentation.
* aarch64-ravenscar-thread.c: Fix indentation.
* aarch64-tdep.c: Fix indentation.
* aarch64-tdep.h: Fix indentation.
* ada-lang.c: Fix indentation.
* ada-lang.h: Fix indentation.
* ada-tasks.c: Fix indentation.
* ada-typeprint.c: Fix indentation.
* ada-valprint.c: Fix indentation.
* ada-varobj.c: Fix indentation.
* addrmap.c: Fix indentation.
* addrmap.h: Fix indentation.
* agent.c: Fix indentation.
* aix-thread.c: Fix indentation.
* alpha-bsd-nat.c: Fix indentation.
* alpha-linux-tdep.c: Fix indentation.
* alpha-mdebug-tdep.c: Fix indentation.
* alpha-nbsd-tdep.c: Fix indentation.
* alpha-obsd-tdep.c: Fix indentation.
* alpha-tdep.c: Fix indentation.
* amd64-bsd-nat.c: Fix indentation.
* amd64-darwin-tdep.c: Fix indentation.
* amd64-linux-nat.c: Fix indentation.
* amd64-linux-tdep.c: Fix indentation.
* amd64-nat.c: Fix indentation.
* amd64-obsd-tdep.c: Fix indentation.
* amd64-tdep.c: Fix indentation.
* amd64-windows-tdep.c: Fix indentation.
* annotate.c: Fix indentation.
* arc-tdep.c: Fix indentation.
* arch-utils.c: Fix indentation.
* arch/arm-get-next-pcs.c: Fix indentation.
* arch/arm.c: Fix indentation.
* arm-linux-nat.c: Fix indentation.
* arm-linux-tdep.c: Fix indentation.
* arm-nbsd-tdep.c: Fix indentation.
* arm-pikeos-tdep.c: Fix indentation.
* arm-tdep.c: Fix indentation.
* arm-tdep.h: Fix indentation.
* arm-wince-tdep.c: Fix indentation.
* auto-load.c: Fix indentation.
* auxv.c: Fix indentation.
* avr-tdep.c: Fix indentation.
* ax-gdb.c: Fix indentation.
* ax-general.c: Fix indentation.
* bfin-linux-tdep.c: Fix indentation.
* block.c: Fix indentation.
* block.h: Fix indentation.
* blockframe.c: Fix indentation.
* bpf-tdep.c: Fix indentation.
* break-catch-sig.c: Fix indentation.
* break-catch-syscall.c: Fix indentation.
* break-catch-throw.c: Fix indentation.
* breakpoint.c: Fix indentation.
* breakpoint.h: Fix indentation.
* bsd-uthread.c: Fix indentation.
* btrace.c: Fix indentation.
* build-id.c: Fix indentation.
* buildsym-legacy.h: Fix indentation.
* buildsym.c: Fix indentation.
* c-typeprint.c: Fix indentation.
* c-valprint.c: Fix indentation.
* c-varobj.c: Fix indentation.
* charset.c: Fix indentation.
* cli/cli-cmds.c: Fix indentation.
* cli/cli-decode.c: Fix indentation.
* cli/cli-decode.h: Fix indentation.
* cli/cli-script.c: Fix indentation.
* cli/cli-setshow.c: Fix indentation.
* coff-pe-read.c: Fix indentation.
* coffread.c: Fix indentation.
* compile/compile-cplus-types.c: Fix indentation.
* compile/compile-object-load.c: Fix indentation.
* compile/compile-object-run.c: Fix indentation.
* completer.c: Fix indentation.
* corefile.c: Fix indentation.
* corelow.c: Fix indentation.
* cp-abi.h: Fix indentation.
* cp-namespace.c: Fix indentation.
* cp-support.c: Fix indentation.
* cp-valprint.c: Fix indentation.
* cris-linux-tdep.c: Fix indentation.
* cris-tdep.c: Fix indentation.
* darwin-nat-info.c: Fix indentation.
* darwin-nat.c: Fix indentation.
* darwin-nat.h: Fix indentation.
* dbxread.c: Fix indentation.
* dcache.c: Fix indentation.
* disasm.c: Fix indentation.
* dtrace-probe.c: Fix indentation.
* dwarf2/abbrev.c: Fix indentation.
* dwarf2/attribute.c: Fix indentation.
* dwarf2/expr.c: Fix indentation.
* dwarf2/frame.c: Fix indentation.
* dwarf2/index-cache.c: Fix indentation.
* dwarf2/index-write.c: Fix indentation.
* dwarf2/line-header.c: Fix indentation.
* dwarf2/loc.c: Fix indentation.
* dwarf2/macro.c: Fix indentation.
* dwarf2/read.c: Fix indentation.
* dwarf2/read.h: Fix indentation.
* elfread.c: Fix indentation.
* eval.c: Fix indentation.
* event-top.c: Fix indentation.
* exec.c: Fix indentation.
* exec.h: Fix indentation.
* expprint.c: Fix indentation.
* f-lang.c: Fix indentation.
* f-typeprint.c: Fix indentation.
* f-valprint.c: Fix indentation.
* fbsd-nat.c: Fix indentation.
* fbsd-tdep.c: Fix indentation.
* findvar.c: Fix indentation.
* fork-child.c: Fix indentation.
* frame-unwind.c: Fix indentation.
* frame-unwind.h: Fix indentation.
* frame.c: Fix indentation.
* frv-linux-tdep.c: Fix indentation.
* frv-tdep.c: Fix indentation.
* frv-tdep.h: Fix indentation.
* ft32-tdep.c: Fix indentation.
* gcore.c: Fix indentation.
* gdb_bfd.c: Fix indentation.
* gdbarch.sh: Fix indentation.
* gdbarch.c: Re-generate
* gdbarch.h: Re-generate.
* gdbcore.h: Fix indentation.
* gdbthread.h: Fix indentation.
* gdbtypes.c: Fix indentation.
* gdbtypes.h: Fix indentation.
* glibc-tdep.c: Fix indentation.
* gnu-nat.c: Fix indentation.
* gnu-nat.h: Fix indentation.
* gnu-v2-abi.c: Fix indentation.
* gnu-v3-abi.c: Fix indentation.
* go32-nat.c: Fix indentation.
* guile/guile-internal.h: Fix indentation.
* guile/scm-cmd.c: Fix indentation.
* guile/scm-frame.c: Fix indentation.
* guile/scm-iterator.c: Fix indentation.
* guile/scm-math.c: Fix indentation.
* guile/scm-ports.c: Fix indentation.
* guile/scm-pretty-print.c: Fix indentation.
* guile/scm-value.c: Fix indentation.
* h8300-tdep.c: Fix indentation.
* hppa-linux-nat.c: Fix indentation.
* hppa-linux-tdep.c: Fix indentation.
* hppa-nbsd-nat.c: Fix indentation.
* hppa-nbsd-tdep.c: Fix indentation.
* hppa-obsd-nat.c: Fix indentation.
* hppa-tdep.c: Fix indentation.
* hppa-tdep.h: Fix indentation.
* i386-bsd-nat.c: Fix indentation.
* i386-darwin-nat.c: Fix indentation.
* i386-darwin-tdep.c: Fix indentation.
* i386-dicos-tdep.c: Fix indentation.
* i386-gnu-nat.c: Fix indentation.
* i386-linux-nat.c: Fix indentation.
* i386-linux-tdep.c: Fix indentation.
* i386-nto-tdep.c: Fix indentation.
* i386-obsd-tdep.c: Fix indentation.
* i386-sol2-nat.c: Fix indentation.
* i386-tdep.c: Fix indentation.
* i386-tdep.h: Fix indentation.
* i386-windows-tdep.c: Fix indentation.
* i387-tdep.c: Fix indentation.
* i387-tdep.h: Fix indentation.
* ia64-libunwind-tdep.c: Fix indentation.
* ia64-libunwind-tdep.h: Fix indentation.
* ia64-linux-nat.c: Fix indentation.
* ia64-linux-tdep.c: Fix indentation.
* ia64-tdep.c: Fix indentation.
* ia64-tdep.h: Fix indentation.
* ia64-vms-tdep.c: Fix indentation.
* infcall.c: Fix indentation.
* infcmd.c: Fix indentation.
* inferior.c: Fix indentation.
* infrun.c: Fix indentation.
* iq2000-tdep.c: Fix indentation.
* language.c: Fix indentation.
* linespec.c: Fix indentation.
* linux-fork.c: Fix indentation.
* linux-nat.c: Fix indentation.
* linux-tdep.c: Fix indentation.
* linux-thread-db.c: Fix indentation.
* lm32-tdep.c: Fix indentation.
* m2-lang.c: Fix indentation.
* m2-typeprint.c: Fix indentation.
* m2-valprint.c: Fix indentation.
* m32c-tdep.c: Fix indentation.
* m32r-linux-tdep.c: Fix indentation.
* m32r-tdep.c: Fix indentation.
* m68hc11-tdep.c: Fix indentation.
* m68k-bsd-nat.c: Fix indentation.
* m68k-linux-nat.c: Fix indentation.
* m68k-linux-tdep.c: Fix indentation.
* m68k-tdep.c: Fix indentation.
* machoread.c: Fix indentation.
* macrocmd.c: Fix indentation.
* macroexp.c: Fix indentation.
* macroscope.c: Fix indentation.
* macrotab.c: Fix indentation.
* macrotab.h: Fix indentation.
* main.c: Fix indentation.
* mdebugread.c: Fix indentation.
* mep-tdep.c: Fix indentation.
* mi/mi-cmd-catch.c: Fix indentation.
* mi/mi-cmd-disas.c: Fix indentation.
* mi/mi-cmd-env.c: Fix indentation.
* mi/mi-cmd-stack.c: Fix indentation.
* mi/mi-cmd-var.c: Fix indentation.
* mi/mi-cmds.c: Fix indentation.
* mi/mi-main.c: Fix indentation.
* mi/mi-parse.c: Fix indentation.
* microblaze-tdep.c: Fix indentation.
* minidebug.c: Fix indentation.
* minsyms.c: Fix indentation.
* mips-linux-nat.c: Fix indentation.
* mips-linux-tdep.c: Fix indentation.
* mips-nbsd-tdep.c: Fix indentation.
* mips-tdep.c: Fix indentation.
* mn10300-linux-tdep.c: Fix indentation.
* mn10300-tdep.c: Fix indentation.
* moxie-tdep.c: Fix indentation.
* msp430-tdep.c: Fix indentation.
* namespace.h: Fix indentation.
* nat/fork-inferior.c: Fix indentation.
* nat/gdb_ptrace.h: Fix indentation.
* nat/linux-namespaces.c: Fix indentation.
* nat/linux-osdata.c: Fix indentation.
* nat/netbsd-nat.c: Fix indentation.
* nat/x86-dregs.c: Fix indentation.
* nbsd-nat.c: Fix indentation.
* nbsd-tdep.c: Fix indentation.
* nios2-linux-tdep.c: Fix indentation.
* nios2-tdep.c: Fix indentation.
* nto-procfs.c: Fix indentation.
* nto-tdep.c: Fix indentation.
* objfiles.c: Fix indentation.
* objfiles.h: Fix indentation.
* opencl-lang.c: Fix indentation.
* or1k-tdep.c: Fix indentation.
* osabi.c: Fix indentation.
* osabi.h: Fix indentation.
* osdata.c: Fix indentation.
* p-lang.c: Fix indentation.
* p-typeprint.c: Fix indentation.
* p-valprint.c: Fix indentation.
* parse.c: Fix indentation.
* ppc-linux-nat.c: Fix indentation.
* ppc-linux-tdep.c: Fix indentation.
* ppc-nbsd-nat.c: Fix indentation.
* ppc-nbsd-tdep.c: Fix indentation.
* ppc-obsd-nat.c: Fix indentation.
* ppc-ravenscar-thread.c: Fix indentation.
* ppc-sysv-tdep.c: Fix indentation.
* ppc64-tdep.c: Fix indentation.
* printcmd.c: Fix indentation.
* proc-api.c: Fix indentation.
* producer.c: Fix indentation.
* producer.h: Fix indentation.
* prologue-value.c: Fix indentation.
* prologue-value.h: Fix indentation.
* psymtab.c: Fix indentation.
* python/py-arch.c: Fix indentation.
* python/py-bpevent.c: Fix indentation.
* python/py-event.c: Fix indentation.
* python/py-event.h: Fix indentation.
* python/py-finishbreakpoint.c: Fix indentation.
* python/py-frame.c: Fix indentation.
* python/py-framefilter.c: Fix indentation.
* python/py-inferior.c: Fix indentation.
* python/py-infthread.c: Fix indentation.
* python/py-objfile.c: Fix indentation.
* python/py-prettyprint.c: Fix indentation.
* python/py-registers.c: Fix indentation.
* python/py-signalevent.c: Fix indentation.
* python/py-stopevent.c: Fix indentation.
* python/py-stopevent.h: Fix indentation.
* python/py-threadevent.c: Fix indentation.
* python/py-tui.c: Fix indentation.
* python/py-unwind.c: Fix indentation.
* python/py-value.c: Fix indentation.
* python/py-xmethods.c: Fix indentation.
* python/python-internal.h: Fix indentation.
* python/python.c: Fix indentation.
* ravenscar-thread.c: Fix indentation.
* record-btrace.c: Fix indentation.
* record-full.c: Fix indentation.
* record.c: Fix indentation.
* reggroups.c: Fix indentation.
* regset.h: Fix indentation.
* remote-fileio.c: Fix indentation.
* remote.c: Fix indentation.
* reverse.c: Fix indentation.
* riscv-linux-tdep.c: Fix indentation.
* riscv-ravenscar-thread.c: Fix indentation.
* riscv-tdep.c: Fix indentation.
* rl78-tdep.c: Fix indentation.
* rs6000-aix-tdep.c: Fix indentation.
* rs6000-lynx178-tdep.c: Fix indentation.
* rs6000-nat.c: Fix indentation.
* rs6000-tdep.c: Fix indentation.
* rust-lang.c: Fix indentation.
* rx-tdep.c: Fix indentation.
* s12z-tdep.c: Fix indentation.
* s390-linux-tdep.c: Fix indentation.
* score-tdep.c: Fix indentation.
* ser-base.c: Fix indentation.
* ser-mingw.c: Fix indentation.
* ser-uds.c: Fix indentation.
* ser-unix.c: Fix indentation.
* serial.c: Fix indentation.
* sh-linux-tdep.c: Fix indentation.
* sh-nbsd-tdep.c: Fix indentation.
* sh-tdep.c: Fix indentation.
* skip.c: Fix indentation.
* sol-thread.c: Fix indentation.
* solib-aix.c: Fix indentation.
* solib-darwin.c: Fix indentation.
* solib-frv.c: Fix indentation.
* solib-svr4.c: Fix indentation.
* solib.c: Fix indentation.
* source.c: Fix indentation.
* sparc-linux-tdep.c: Fix indentation.
* sparc-nbsd-tdep.c: Fix indentation.
* sparc-obsd-tdep.c: Fix indentation.
* sparc-ravenscar-thread.c: Fix indentation.
* sparc-tdep.c: Fix indentation.
* sparc64-linux-tdep.c: Fix indentation.
* sparc64-nbsd-tdep.c: Fix indentation.
* sparc64-obsd-tdep.c: Fix indentation.
* sparc64-tdep.c: Fix indentation.
* stabsread.c: Fix indentation.
* stack.c: Fix indentation.
* stap-probe.c: Fix indentation.
* stubs/ia64vms-stub.c: Fix indentation.
* stubs/m32r-stub.c: Fix indentation.
* stubs/m68k-stub.c: Fix indentation.
* stubs/sh-stub.c: Fix indentation.
* stubs/sparc-stub.c: Fix indentation.
* symfile-mem.c: Fix indentation.
* symfile.c: Fix indentation.
* symfile.h: Fix indentation.
* symmisc.c: Fix indentation.
* symtab.c: Fix indentation.
* symtab.h: Fix indentation.
* target-float.c: Fix indentation.
* target.c: Fix indentation.
* target.h: Fix indentation.
* tic6x-tdep.c: Fix indentation.
* tilegx-linux-tdep.c: Fix indentation.
* tilegx-tdep.c: Fix indentation.
* top.c: Fix indentation.
* tracefile-tfile.c: Fix indentation.
* tracepoint.c: Fix indentation.
* tui/tui-disasm.c: Fix indentation.
* tui/tui-io.c: Fix indentation.
* tui/tui-regs.c: Fix indentation.
* tui/tui-stack.c: Fix indentation.
* tui/tui-win.c: Fix indentation.
* tui/tui-winsource.c: Fix indentation.
* tui/tui.c: Fix indentation.
* typeprint.c: Fix indentation.
* ui-out.h: Fix indentation.
* unittests/copy_bitwise-selftests.c: Fix indentation.
* unittests/memory-map-selftests.c: Fix indentation.
* utils.c: Fix indentation.
* v850-tdep.c: Fix indentation.
* valarith.c: Fix indentation.
* valops.c: Fix indentation.
* valprint.c: Fix indentation.
* valprint.h: Fix indentation.
* value.c: Fix indentation.
* value.h: Fix indentation.
* varobj.c: Fix indentation.
* vax-tdep.c: Fix indentation.
* windows-nat.c: Fix indentation.
* windows-tdep.c: Fix indentation.
* xcoffread.c: Fix indentation.
* xml-syscall.c: Fix indentation.
* xml-tdesc.c: Fix indentation.
* xstormy16-tdep.c: Fix indentation.
* xtensa-config.c: Fix indentation.
* xtensa-linux-nat.c: Fix indentation.
* xtensa-linux-tdep.c: Fix indentation.
* xtensa-tdep.c: Fix indentation.
gdbserver/ChangeLog:
* ax.cc: Fix indentation.
* dll.cc: Fix indentation.
* inferiors.h: Fix indentation.
* linux-low.cc: Fix indentation.
* linux-nios2-low.cc: Fix indentation.
* linux-ppc-ipa.cc: Fix indentation.
* linux-ppc-low.cc: Fix indentation.
* linux-x86-low.cc: Fix indentation.
* linux-xtensa-low.cc: Fix indentation.
* regcache.cc: Fix indentation.
* server.cc: Fix indentation.
* tracepoint.cc: Fix indentation.
gdbsupport/ChangeLog:
* common-exceptions.h: Fix indentation.
* event-loop.cc: Fix indentation.
* fileio.cc: Fix indentation.
* filestuff.cc: Fix indentation.
* gdb-dlfcn.cc: Fix indentation.
* gdb_string_view.h: Fix indentation.
* job-control.cc: Fix indentation.
* signals.cc: Fix indentation.
Change-Id: I4bad7ae6be0fbe14168b8ebafb98ffe14964a695
|
|
This function is now external, and isn't really threads related. Move
it to frame.c.
gdb/ChangeLog:
* thread.c (lookup_selected_frame): Move ...
* frame.c (lookup_selected_frame): ... here.
Change-Id: Ia96b79c15767337c68efd3358bcc715ce8e26c15
|
|
If the remote target closes while we're reading registers/memory for
restoring the selected frame in scoped_restore_current_thread's dtor,
the corresponding TARGET_CLOSE_ERROR error is swallowed by the
scoped_restore_current_thread's dtor, because letting exceptions
escape from a dtor is bad. It isn't great to lose that errors like
that, though. I've been thinking about how to avoid it, and I came up
with this patch.
The idea here is to make scoped_restore_current_thread's dtor do as
little as possible, to avoid any work that might throw in the first
place. And to do that, instead of having the dtor call
restore_selected_frame, which re-finds the previously selected frame,
just record the frame_id/level of the desired selected frame, and have
get_selected_frame find the frame the next time it is called. In
effect, this implements most of Cagney's suggestion, here:
/* On demand, create the selected frame and then return it. If the
selected frame can not be created, this function prints then throws
an error. When MESSAGE is non-NULL, use it for the error message,
otherwize use a generic error message. */
/* FIXME: cagney/2002-11-28: At present, when there is no selected
frame, this function always returns the current (inner most) frame.
It should instead, when a thread has previously had its frame
selected (but not resumed) and the frame cache invalidated, find
and then return that thread's previously selected frame. */
extern struct frame_info *get_selected_frame (const char *message);
The only thing missing to fully implement that would be to make
reinit_frame_cache just clear selected_frame instead of calling
select_frame(NULL), and the call select_frame(NULL) explicitly in the
places where we really wanted reinit_frame_cache to go back to the
current frame too. That can done separately, though, I'm not
proposing to do that in this patch.
Note that this patch renames restore_selected_frame to
lookup_selected_frame, and adds a new restore_selected_frame function
that doesn't throw, to be paired with the also-new save_selected_frame
function.
There's a restore_selected_frame function in infrun.c that I think can
be replaced by the new one in frame.c.
Also done in this patch is make the get_selected_frame's parameter be
optional, so that we don't have to pass down nullptr explicitly all
over the place.
lookup_selected_frame should really move from thread.c to frame.c, but
I didn't do that here, just to avoid churn in the patch while it
collects comments. I did make it extern and declared it in frame.h
already, preparing for the move. I will do the move as a follow up
patch if people agree with this approach.
Incidentally, this patch alone would fix the crashes fixed by the
previous patches in the series, because with this,
scoped_restore_current_thread's constructor doesn't throw either.
gdb/ChangeLog:
* blockframe.c (block_innermost_frame): Use get_selected_frame.
* frame.c
(scoped_restore_selected_frame::scoped_restore_selected_frame):
Use save_selected_frame. Save language as well.
(scoped_restore_selected_frame::~scoped_restore_selected_frame):
Use restore_selected_frame, and restore language as well.
(selected_frame_id, selected_frame_level): New.
(selected_frame): Update comments.
(save_selected_frame, restore_selected_frame): New.
(get_selected_frame): Use lookup_selected_frame.
(get_selected_frame_if_set): Delete.
(select_frame): Record selected_frame_level and selected_frame_id.
* frame.h (scoped_restore_selected_frame) <m_level, m_lang>: New
fields.
(get_selected_frame): Make 'message' parameter optional.
(get_selected_frame_if_set): Delete declaration.
(select_frame): Update comments.
(save_selected_frame, restore_selected_frame)
(lookup_selected_frame): Declare.
* gdbthread.h (scoped_restore_current_thread) <m_lang>: New field.
* infrun.c (struct infcall_control_state) <selected_frame_level>:
New field.
(save_infcall_control_state): Use save_selected_frame.
(restore_selected_frame): Delete.
(restore_infcall_control_state): Use restore_selected_frame.
* stack.c (select_frame_command_core, frame_command_core): Use
get_selected_frame.
* thread.c (restore_selected_frame): Rename to ...
(lookup_selected_frame): ... this and make extern. Select the
current frame if the frame level is -1.
(scoped_restore_current_thread::restore): Also restore the
language.
(scoped_restore_current_thread::~scoped_restore_current_thread):
Don't try/catch.
(scoped_restore_current_thread::scoped_restore_current_thread):
Save the language as well. Use save_selected_frame.
Change-Id: I73fd1cfc40d8513c28e5596383b7ecd8bcfe700f
|
|
This removes the symfile_objfile macro, in favor of just spelling out
the member access.
gdb/ChangeLog
2020-10-29 Tom Tromey <tom@tromey.com>
* windows-tdep.c (windows_solib_create_inferior_hook): Update.
* target.c (info_target_command): Update.
* symfile.c (syms_from_objfile_1, finish_new_objfile)
(symbol_file_clear, reread_symbols): Update.
* symfile-mem.c (add_symbol_file_from_memory_command): Update.
* stabsread.c (scan_file_globals): Update.
* solib.c (update_solib_list): Update.
* solib-svr4.c (elf_locate_base, open_symbol_file_object)
(svr4_fetch_objfile_link_map, enable_break)
(svr4_relocate_main_executable)
(svr4_iterate_over_objfiles_in_search_order): Update.
* solib-frv.c (lm_base, enable_break)
(frv_relocate_main_executable): Update.
(main_got, frv_fdpic_find_canonical_descriptor): Update.
(frv_fetch_objfile_link_map): Update.
* solib-dsbt.c (lm_base, dsbt_relocate_main_executable): Update.
* solib-darwin.c (darwin_solib_create_inferior_hook): Update.
* solib-aix.c (solib_aix_solib_create_inferior_hook): Update.
* remote.c (remote_target::get_offsets): Update.
(remote_target::start_remote)
(extended_remote_target::post_attach): Update.
* objfiles.c (entry_point_address_query): Update.
* nto-procfs.c (nto_procfs_target::create_inferior): Update.
* minsyms.c (get_symbol_leading_char): Update.
* frame.c (inside_main_func): Update.
* progspace.h (symfile_objfile): Remove macro.
|
|
Tested by rebuilding.
gdb/ChangeLog:
2020-10-19 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* frame.c: Remove the unused 'uinteger_option_def' type alias.
|
|
Currently, GDB will only stop the backtrace at the main function if
there is a minimal symbol with the matching name. In Fortran programs
compiled with gfortran this is not the case. The main function is
present in the DWARF, and as marked as DW_AT_main_subprogram, but
there's no minimal symbol.
This commit extends `inside_main_func` to check the full symbols if no
matching minimal symbol is found.
There's an updated test case that covers this change.
gdb/ChangeLog:
* frame.c (inside_main_func): Check full symbols as well as
minimal symbols.
gdb/testsuite/ChangeLog:
* gdb.fortran/mixed-lang-stack.exp (run_tests): Update expected
output of backtrace.
|
|
This removes the target_has_registers object-like macro, replacing it
with the underlying function.
gdb/ChangeLog
2020-09-28 Tom Tromey <tom@tromey.com>
* tui/tui-regs.c (tui_get_register)
(tui_data_window::show_registers): Update.
* thread.c (scoped_restore_current_thread::restore)
(scoped_restore_current_thread::scoped_restore_current_thread):
Update.
* regcache-dump.c (regcache_print): Update.
* python/py-finishbreakpoint.c (bpfinishpy_detect_out_scope_cb):
Update.
* mi/mi-main.c (mi_cmd_data_write_register_values): Update.
* mep-tdep.c (current_me_module, current_options): Update.
* linux-thread-db.c (thread_db_load): Update.
* infcmd.c (registers_info, info_vector_command)
(info_float_command): Update.
* ia64-tdep.c (ia64_frame_prev_register)
(ia64_sigtramp_frame_prev_register): Update.
* ia64-libunwind-tdep.c (libunwind_frame_prev_register): Update.
* gcore.c (derive_stack_segment): Update.
* frame.c (get_current_frame, has_stack_frames): Update.
* findvar.c (language_defn::read_var_value): Update.
* arm-tdep.c (arm_pc_is_thumb): Update.
* target.c (target_has_registers): Rename from
target_has_registers_1.
* target.h (target_has_registers): Remove macro.
(target_has_registers): Rename from target_has_registers_1.
|
|
This removes the target_has_stack object-like macro, replacing it with
the underlying function.
gdb/ChangeLog
2020-09-28 Tom Tromey <tom@tromey.com>
* windows-tdep.c (tlb_make_value): Update.
* tui/tui-regs.c (tui_data_window::show_registers): Update.
* thread.c (scoped_restore_current_thread::restore)
(scoped_restore_current_thread::scoped_restore_current_thread)
(thread_command): Update.
* stack.c (backtrace_command_1, frame_apply_level_command)
(frame_apply_all_command, frame_apply_command): Update.
* infrun.c (siginfo_make_value, restore_infcall_control_state):
Update.
* gcore.c (derive_stack_segment): Update.
* frame.c (get_current_frame, has_stack_frames): Update.
* auxv.c (info_auxv_command): Update.
* ada-tasks.c (ada_build_task_list): Update.
* target.c (target_has_stack): Rename from target_has_stack_1.
* target.h (target_has_stack): Remove macro.
(target_has_stack): Rename from target_has_stack_1.
|
|
This removes the target_has_memory object-like macro, replacing it
with the underlying function.
gdb/ChangeLog
2020-09-28 Tom Tromey <tom@tromey.com>
* target.c (target_has_memory): Rename from target_has_memory_1.
* tui/tui-regs.c (tui_data_window::show_registers): Update.
* thread.c (scoped_restore_current_thread::restore)
(scoped_restore_current_thread::scoped_restore_current_thread):
Update.
* frame.c (get_current_frame, has_stack_frames): Update.
* target.h (target_has_memory): Remove macro.
(target_has_memory): Rename from target_has_memory_1.
|
|
I forgot to fix some nits pointed out in review before merging the
"frame inlined in outer frame series", this patch fixes them.
gdb/ChangeLog:
* frame-unwind.h (frame_prev_register_ftype): Fix adjective
ordering in comment.
* frame.c (frame_id_eq): Fix indentation.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-reg-undefined.exp: Remove spurious #.
Change-Id: Iaddde9677fc3f68382558d1a16f5a0b4beb78bac
|
|
In the following patch, we'll need to easily differentiate the frame_id
of the outer frame (or the frame id of a frame inlined into the outer
frame) from a simply invalid frame id.
Currently, the frame id of the outer frame has `stack_status` set to
FID_STACK_INVALID plus special_addr_p set. A frame inlined into the
outer frame would also have `artificial_depth` set to greater than one.
That makes the job of differntiating the frame id of the outer frame (or a
frame inlined into the outer frame) cumbersome.
To make it easier, give the outer frame id its own frame_id_stack_status
enum value. outer_frame_id then becomes very similar to
sentinel_frame_id, another "special" frame id value.
In frame_id_p, we don't need a special case for the outer frame id, as
it's no long a special case of FID_STACK_INVALID. Same goes for
frame_id_eq.
So in the end, FID_STACK_OUTER isn't even used (except in
fprint_frame_id). But that's expected: all the times we wanted to
identify an outer frame was to differentiate it from an otherwise
invalid frame. Since their frame_id_stack_status value is different
now, that is done naturally.
gdb/ChangeLog:
* frame.h (enum frame_id_stack_status) <FID_STACK_OUTER>: New.
* frame.c (fprint_frame_id): Handle FID_STACK_OUTER.
(outer_frame_id): Use FID_STACK_OUTER instead of
FID_STACK_INVALID.
(frame_id_p): Don't check for outer_frame_id.
Change-Id: I654e7f936349debc4f04f7f684b15e71a0c37619
|
|
TLDR: frame_unwind_got_optimized uses wrong frame id value, trying to
fix it makes GDB sad, return not_lval value and don't use frame id value
instead.
Longer version:
The `prev_register` method of the `frame_unwind` interface corresponds
to asking the question: "where did this frame - passed as a parameter -
save the value this register had in its caller frame?". When "this
frame" did not save that register value (DW_CFA_undefined in DWARF), the
implementation can use the `frame_unwind_got_optimized` function to
create a struct value that represents the optimized out / not saved
register.
`frame_unwind_got_optimized` marks the value as fully optimized out,
sets the lval field to lval_register and assigns the required data for
lval_register: the next frame id and the register number. The problem
is that it uses the frame id from the wrong frame (see below for in
depth explanation). In practice, this is not problematic because the
frame id is never used: the value is already not lazy (and is marked as
optimized out), so the value is never fetched from the target.
When trying to change it to put the right next frame id in the value, we
bump into problems: computing the frame id for some frame requires
unwinding some register, if that register is not saved / optimized out,
we try to get the frame id that we are currently computing.
This patch addresses the problem by changing
`frame_unwind_got_optimized` to return a not_lval value instead. Doing
so, we don't need to put a frame id, so we don't hit that problem. It
may seem like an unnecessary change today, because it looks like we're
fixing something that is not broken (from the user point of view).
However, the bug becomes user visible with the following patches, where
inline frames are involved. I put this change in its own patch to keep
it logically separate.
Let's now illustrate how we are putting the wrong frame id in the value
returned by `frame_unwind_got_optimized`. Let's assume this stack:
frame #0
frame #1
frame #2
frame #3
Let's suppose that we are calling `frame_unwind_register_value` with
frame #2 as the "next_frame" parameter and some register number X as the
regnum parameter. That is like asking the question "where did frame #2
save frame #3's value for register X".
`frame_unwind_register_value` calls the frame unwinder's `prev_register`
method, which in our case is `dwarf2_frame_prev_register`. Note that in
`dwarf2_frame_prev_register`, the parameter is now called `this_frame`,
but its value is still frame #2, and we are still looking for where
frame #2 saved frame #3's value of register X.
Let's now suppose that frame #2's CFI explicitly indicates that the
register X is was not saved (DW_CFA_undefined). We go into
`frame_unwind_got_optimized`.
In `frame_unwind_got_optimized`, the intent is to create a value that
represents register X in frame #3. An lval_register value requires that
we specify the id of the _next_ frame, that is the frame from which we
would need to unwind in order to get the value. Therefore, we would
want to put the id of frame #2 in there.
However, `frame_unwind_got_optimized` does:
VALUE_NEXT_FRAME_ID (val)
= get_frame_id (get_next_frame_sentinel_okay (frame));
where `frame` is frame #2. The get_next_frame_sentinel_okay call
returns frame #1, so we end up putting frame #1's id in the value.
Let's now pretend that we try to "fix" it by placing the right frame id,
in other words doing this change:
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -260,8 +260,7 @@ frame_unwind_got_optimized (struct frame_info *frame, int regnum)
mark_value_bytes_optimized_out (val, 0, TYPE_LENGTH (type));
VALUE_LVAL (val) = lval_register;
VALUE_REGNUM (val) = regnum;
- VALUE_NEXT_FRAME_ID (val)
- = get_frame_id (get_next_frame_sentinel_okay (frame));
+ VALUE_NEXT_FRAME_ID (val) = get_frame_id (frame);
return val;
}
This makes some tests fails, such as gdb.dwarf2/dw2-undefined-ret-addr.exp,
like so:
...
#9 0x0000557a8ab15a5d in internal_error (file=0x557a8b31ef80 "/home/simark/src/binutils-gdb/gdb/frame.c", line=623, fmt=0x557a8b31efe0 "%s: Assertion `%s' failed.") at /home/simark/src/binutils-gdb/gdbsupport/errors.cc:55
#10 0x0000557a87f816d6 in get_frame_id (fi=0x62100034bde0) at /home/simark/src/binutils-gdb/gdb/frame.c:623
#11 0x0000557a87f7cac7 in frame_unwind_got_optimized (frame=0x62100034bde0, regnum=16) at /home/simark/src/binutils-gdb/gdb/frame-unwind.c:264
#12 0x0000557a87a71a76 in dwarf2_frame_prev_register (this_frame=0x62100034bde0, this_cache=0x62100034bdf8, regnum=16) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1267
#13 0x0000557a87f86621 in frame_unwind_register_value (next_frame=0x62100034bde0, regnum=16) at /home/simark/src/binutils-gdb/gdb/frame.c:1288
#14 0x0000557a87f855d5 in frame_register_unwind (next_frame=0x62100034bde0, regnum=16, optimizedp=0x7fff5f459070, unavailablep=0x7fff5f459080, lvalp=0x7fff5f4590a0, addrp=0x7fff5f4590b0, realnump=0x7fff5f459090, bufferp=0x7fff5f459150 "") at /home/simark/src/binutils-gdb/gdb/frame.c:1191
#15 0x0000557a87f860ef in frame_unwind_register (next_frame=0x62100034bde0, regnum=16, buf=0x7fff5f459150 "") at /home/simark/src/binutils-gdb/gdb/frame.c:1247
#16 0x0000557a881875f9 in i386_unwind_pc (gdbarch=0x621000190110, next_frame=0x62100034bde0) at /home/simark/src/binutils-gdb/gdb/i386-tdep.c:1971
#17 0x0000557a87fe58a5 in gdbarch_unwind_pc (gdbarch=0x621000190110, next_frame=0x62100034bde0) at /home/simark/src/binutils-gdb/gdb/gdbarch.c:3062
#18 0x0000557a87a6267b in dwarf2_tailcall_sniffer_first (this_frame=0x62100034bde0, tailcall_cachep=0x62100034bee0, entry_cfa_sp_offsetp=0x7fff5f4593f0) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame-tailcall.c:387
#19 0x0000557a87a70cdf in dwarf2_frame_cache (this_frame=0x62100034bde0, this_cache=0x62100034bdf8) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1198
#20 0x0000557a87a711c2 in dwarf2_frame_this_id (this_frame=0x62100034bde0, this_cache=0x62100034bdf8, this_id=0x62100034be40) at /home/simark/src/binutils-gdb/gdb/dwarf2/frame.c:1226
#21 0x0000557a87f81167 in compute_frame_id (fi=0x62100034bde0) at /home/simark/src/binutils-gdb/gdb/frame.c:587
#22 0x0000557a87f81803 in get_frame_id (fi=0x62100034bde0) at /home/simark/src/binutils-gdb/gdb/frame.c:635
#23 0x0000557a87f7efef in scoped_restore_selected_frame::scoped_restore_selected_frame (this=0x7fff5f459920) at /home/simark/src/binutils-gdb/gdb/frame.c:320
#24 0x0000557a891488ae in print_frame_args (fp_opts=..., func=0x621000183b90, frame=0x62100034bde0, num=-1, stream=0x6030000caa20) at /home/simark/src/binutils-gdb/gdb/stack.c:750
#25 0x0000557a8914e87a in print_frame (fp_opts=..., frame=0x62100034bde0, print_level=0, print_what=SRC_AND_LOC, print_args=1, sal=...) at /home/simark/src/binutils-gdb/gdb/stack.c:1394
#26 0x0000557a8914c2ae in print_frame_info (fp_opts=..., frame=0x62100034bde0, print_level=0, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at /home/simark/src/binutils-gdb/gdb/stack.c:1119
...
We end up calling get_frame_id (in the hunk above, frame #10) while we are
computing it (frame #21), and that's not good.
Now, the question is how do we fix this. I suggest making the unwinder
return a not_lval value in this case.
The reason why we return an lval_register here is to make sure that this
is printed as "not saved" and not "optimized out" down the line. See
these two commits:
1. 901461f8eb40 ("Print registers not saved in the frame as "<not saved>"
instead of "<optimized out>".").
2. 6bd273ae450b ("Make "set debug frame 1" output print <not saved> instead of
<optimized out>.")
The current design (introduced by the first commit) is to check the
value's lval to choose which one to print (see val_print_optimized_out).
Making the unwinder return not_lval instead of lval_register doesn't
break "not saved" when doing "print $rax" or "info registers", because
value_fetch_lazy_register only consumes the contents and optimized-out
property from the value the unwinder returned. The value being
un-lazified stays an lval_register.
I believe that this is a correct technical solution (and not just
papering over the problem), because what we expect of unwinders is to
tell us where a given register's value is saved. If the value is saved
in memory, -> lval_memory. If the value is saved in some other register
of the next frame, -> lval_register. If the value is not saved, it
doesn't really make sense to return an lval_register value. not_lval
would be more appropriate. If the code then wants to represent an
optimized out register value (like value_fetch_lazy_register does), then
it's a separate concern which shouldn't involve the unwinder.
This change breaks the output of "set debug frame 1" though (introduced
by the second commit), since that logging statement consumes the return
value of the unwinder directly. To keep the correct behavior, just make
`frame_unwind_register_value` call `val_print_not_saved` directly,
instead of `val_print_optimized_out`. This is fine because we know in
this context that we are always talking about a register value, and that
we want to show "not saved" for those.
I augmented the gdb.dwarf2/dw2-reg-undefined.exp test case to test some
cases I stumbled on while working on this, which I think are not tested
anywhere:
- the "set debug frame 1" debug output mentioned above. It's just debug
output, but if we want to make sure it doesn't change, it should be
tested
- printing not-saved register values from the history (should print not
saved)
- copying a not-saved register value in a convenience variable. In this
case, we expect that printing the convenience variable shows
"optimized out", because we copied the value, not the property of
where the value came from.
gdb/ChangeLog:
* frame-unwind.c (frame_unwind_got_optimized): Don't set
regnum/frame in value. Call allocate_value_lazy.
* frame.c (frame_unwind_register_value): Use
val_print_not_saved.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-reg-undefined.exp: Test "set debug frame 1"
output, printing a "not saved" value from history and printing a
convenience variable created from a "not saved" value.
Change-Id: If451739a3ef7a5b453b1f50707e21ce16d74807e
|
|
I'm dealing these days with a class of bugs that involve trying to get a
certain frame's id while we are in the process of computing it. In other
words, compute_frame_id being called for a frame, eventually calling
get_frame_id for that same frame. I don't think this is ever supposed to
happen, as that creates a cyclic dependency.
Usually, these problems cause some failure down the line. I'm proposing with
this patch to catch them as early as possible, as soon as the situation
described above happens. I think that helps because the failed assertion will
be closer to the root of the problem.
To do so, the patch changes the frame_info::this_id::p flag from a boolean (is
the frame id computed or not) to a tri-state:
- the frame id is not computed
- the frame id is being computed
- the frame id is computed
Then, we can properly assert that get_frame_id doesn't get called for a frame
whose id is being computed.
To illustrate how that can help, let's imagine we apply the following change to
frame_unwind_got_optimized:
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -260,8 +260,7 @@ frame_unwind_got_optimized (struct frame_info *frame, int regnum)
mark_value_bytes_optimized_out (val, 0, TYPE_LENGTH (type));
VALUE_LVAL (val) = lval_register;
VALUE_REGNUM (val) = regnum;
- VALUE_NEXT_FRAME_ID (val)
- = get_frame_id (get_next_frame_sentinel_okay (frame));
+ VALUE_NEXT_FRAME_ID (val) = get_frame_id (frame);
return val;
}
... and run the following command, which leads to a failed assertion (you need
to run the corresponding test to generate the binary first):
$ ./gdb -q -nx testsuite/outputs/gdb.dwarf2/dw2-undefined-ret-addr/dw2-undefined-ret-addr -ex "b stop_frame" -ex r
Without this patch applied, we catch the issue indirectly, when the top-level
get_frame_id tries to stash the frame:
/home/smarchi/src/binutils-gdb/gdb/frame.c:593: internal-error: frame_id get_frame_id(frame_info*): Assertion `stashed' failed.
...
#9 0x0000000001af1c3a in internal_error (file=0x1cea060 "/home/smarchi/src/binutils-gdb/gdb/frame.c", line=593, fmt=0x1ce9f80 "%s: Assertion `%s' failed.") at /home/smarchi/src/binutils-gdb/gdbsupport/errors.cc:55
#10 0x0000000000e9b413 in get_frame_id (fi=0x6210005105e0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:593
#11 0x0000000000e99e35 in scoped_restore_selected_frame::scoped_restore_selected_frame (this=0x7fff1d8b9760) at /home/smarchi/src/binutils-gdb/gdb/frame.c:308
#12 0x000000000149a261 in print_frame_args (fp_opts=..., func=0x6210000dd7d0, frame=0x6210005105e0, num=-1, stream=0x60300008a580) at /home/smarchi/src/binutils-gdb/gdb/stack.c:750
#13 0x000000000149d938 in print_frame (fp_opts=..., frame=0x6210005105e0, print_level=0, print_what=SRC_AND_LOC, print_args=1, sal=...) at /home/smarchi/src/binutils-gdb/gdb/stack.c:1394
#14 0x000000000149c0c8 in print_frame_info (fp_opts=..., frame=0x6210005105e0, print_level=0, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at /home/smarchi/src/binutils-gdb/gdb/stack.c:1119
#15 0x0000000001498100 in print_stack_frame (frame=0x6210005105e0, print_level=0, print_what=SRC_AND_LOC, set_current_sal=1) at /home/smarchi/src/binutils-gdb/gdb/stack.c:366
#16 0x00000000010234b7 in print_stop_location (ws=0x7fff1d8ba1f0) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:8366
#17 0x000000000102362d in print_stop_event (uiout=0x607000018660, displays=true) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:8382
...
It freaks out because the frame is already in the stash: it was added by an
inner call to get_frame_id, called indirectly by compute_frame_id. Debugging
this failure is difficult because we have to backtrack to where this happened.
With the patch applied, we catch the issue earlier, here:
/home/smarchi/src/binutils-gdb/gdb/frame.c:601: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed
...
#9 0x0000000001af22bc in internal_error (file=0x1cea6e0 "/home/smarchi/src/binutils-gdb/gdb/frame.c", line=601, fmt=0x1cea600 "%s: Assertion `%s' failed.") at /home/smarchi/src/binutils-gdb/gdbsupport/errors.cc:55
#10 0x0000000000e9b7e3 in get_frame_id (fi=0x62100050dde0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:601
#11 0x0000000000e989b3 in frame_unwind_got_optimized (frame=0x62100050dde0, regnum=16) at /home/smarchi/src/binutils-gdb/gdb/frame-unwind.c:264
#12 0x0000000000cbe386 in dwarf2_frame_prev_register (this_frame=0x62100050dde0, this_cache=0x62100050ddf8, regnum=16) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:1267
#13 0x0000000000e9f569 in frame_unwind_register_value (next_frame=0x62100050dde0, regnum=16) at /home/smarchi/src/binutils-gdb/gdb/frame.c:1266
#14 0x0000000000e9eaab in frame_register_unwind (next_frame=0x62100050dde0, regnum=16, optimizedp=0x7ffca814ade0, unavailablep=0x7ffca814adf0, lvalp=0x7ffca814ae10, addrp=0x7ffca814ae20, realnump=0x7ffca814ae00, bufferp=0x7ffca814aec0 "") at /home/smarchi/src/binutils-gdb/gdb/frame.c:1169
#15 0x0000000000e9f233 in frame_unwind_register (next_frame=0x62100050dde0, regnum=16, buf=0x7ffca814aec0 "") at /home/smarchi/src/binutils-gdb/gdb/frame.c:1225
#16 0x0000000000f84262 in i386_unwind_pc (gdbarch=0x6210000eed10, next_frame=0x62100050dde0) at /home/smarchi/src/binutils-gdb/gdb/i386-tdep.c:1969
#17 0x0000000000ec95dd in gdbarch_unwind_pc (gdbarch=0x6210000eed10, next_frame=0x62100050dde0) at /home/smarchi/src/binutils-gdb/gdb/gdbarch.c:3062
#18 0x0000000000cb5e9d in dwarf2_tailcall_sniffer_first (this_frame=0x62100050dde0, tailcall_cachep=0x62100050dee0, entry_cfa_sp_offsetp=0x7ffca814b160) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame-tailcall.c:387
#19 0x0000000000cbdd38 in dwarf2_frame_cache (this_frame=0x62100050dde0, this_cache=0x62100050ddf8) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:1198
#20 0x0000000000cbe026 in dwarf2_frame_this_id (this_frame=0x62100050dde0, this_cache=0x62100050ddf8, this_id=0x62100050de40) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:1226
#21 0x0000000000e9b447 in compute_frame_id (fi=0x62100050dde0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:580
#22 0x0000000000e9b89e in get_frame_id (fi=0x62100050dde0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:613
#23 0x0000000000e99e35 in scoped_restore_selected_frame::scoped_restore_selected_frame (this=0x7ffca814b610) at /home/smarchi/src/binutils-gdb/gdb/frame.c:315
#24 0x000000000149a8e3 in print_frame_args (fp_opts=..., func=0x6210000dd7d0, frame=0x62100050dde0, num=-1, stream=0x60300008a520) at /home/smarchi/src/binutils-gdb/gdb/stack.c:750
#25 0x000000000149dfba in print_frame (fp_opts=..., frame=0x62100050dde0, print_level=0, print_what=SRC_AND_LOC, print_args=1, sal=...) at /home/smarchi/src/binutils-gdb/gdb/stack.c:1394
#26 0x000000000149c74a in print_frame_info (fp_opts=..., frame=0x62100050dde0, print_level=0, print_what=SRC_AND_LOC, print_args=1, set_current_sal=1) at /home/smarchi/src/binutils-gdb/gdb/stack.c:1119
#27 0x0000000001498782 in print_stack_frame (frame=0x62100050dde0, print_level=0, print_what=SRC_AND_LOC, set_current_sal=1) at /home/smarchi/src/binutils-gdb/gdb/stack.c:366
#28 0x0000000001023b39 in print_stop_location (ws=0x7ffca814c0a0) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:8366
#29 0x0000000001023caf in print_stop_event (uiout=0x607000018660, displays=true) at /home/smarchi/src/binutils-gdb/gdb/infrun.c:8382
...
Now, we can clearly see that get_frame_id for frame `fi=0x62100050dde0` gets
called while compute_frame_id is active for that frame. The backtrace is more
helpful to identify the root of the problem.
gdb/ChangeLog:
* frame.c (enum class frame_id_status): New.
(struct frame_info) <this_id::p>: Change type to frame_id_status.
(fprintf_frame): Update.
(compute_frame_id): Set frame id status to "computing" on entry.
Set it back to "not_computed" on failure and to "computed" on
success.
(get_frame_id): Assert the frame id is not being computed.
(create_sentinel_frame): Use frame_id_status::COMPUTED.
(create_new_frame): Likewise.
(frame_cleanup_after_sniffer): Update assert.
Change-Id: I5f1a25fafe045f756bd75f358892720b30ed20c9
|
|
Change instances of int variables and return values used as boolean
values to use the bool type.
Shorten the comments of a few functions, because I think they go a bit
too much in implementation details, which appear out of date anyway.
Make other misc changes to the functions that are already being changed,
such as using nullptr instead of NULL, dropping `struct` keywords and
declaring variables when first used.
gdb/ChangeLog:
* frame.h (frame_id_p): Return bool.
(frame_id_artificial_p): Return bool.
(frame_id_eq): Return bool.
(has_stack_frames): Return bool.
(get_selected_frame): Fix typo in comment.
(get_frame_pc_if_available): Return bool.
(get_frame_address_in_block_if_available): Return bool.
(get_frame_func_if_available): Return bool.
(read_frame_register_unsigned): Return bool.
(get_frame_register_bytes): Return bool.
(safe_frame_unwind_memory): Return bool.
(deprecated_frame_register_read): Return bool.
(frame_unwinder_is): Return bool.
* frame.c (struct frame_info) <prev_arch::p>: Change type to
bool.
<this_id::p>: Likewise.
<prev_p>: Likewise.
(frame_stash_add): Return bool.
(get_frame_id): Use bool.
(frame_id_build_special) Use bool.
(frame_id_build_unavailable_stack): Use bool.
(frame_id_build): Use bool.
(frame_id_p): Return bool, use true/false instead of 1/0.
(frame_id_artificial_p): Likewise.
(frame_id_eq): Likewise.
(frame_id_inner): Likewise.
(get_frame_func_if_available): Likewise.
(read_frame_register_unsigned): Likewise.
(deprecated_frame_register_read): Likewise.
(get_frame_register_bytes): Likewise.
(has_stack_frames): Likewise.
(inside_main_func): Likewise.
(inside_entry_func): Likewise.
(get_frame_pc_if_available): Likewise.
(get_frame_address_in_block_if_available): Likewise.
(frame_unwinder_is): Likewise.
(safe_frame_unwind_memory): Likewise.
(frame_unwind_arch): Likewise.
Change-Id: I6121fa56739b688be79d73d087d76b268ba5a46a
|
|
One might think that variable `frame_info::prev_func::p` is a simple
true/false value, but that's not the case, it can also have the value -1
to mean "unavaiable". Change it to use the `cached_copy_status` enum,
which seems designed exactly for this purpose.
Rename to `status` to be consistent with `prev_pc::status` (and be cause
`p` means `predicate`, which implies boolean, which this is not).
gdb/ChangeLog:
* frame.c (frame_info) <prev_func> <p>: Rename to status, change
type to cached_copy_status.
(fprintf_frame): Adjust.
(get_frame_func_if_available): Adjust.
(frame_cleanup_after_sniffer): Adjust.
Change-Id: I50c6ebef6c0acb076e25c741f7f417bfd101d953
|
|
This fixes yet another bug exposed by ASAN + multi-target.exp
Running an Asan-enabled GDB against gdb.multi/multi-target.exp exposed
yet another latent GDB bug. See here for the full log:
https://sourceware.org/pipermail/gdb-patches/2020-July/170761.html
As Simon described, the problem is:
- We create a new frame_info object in restore_selected_frame (by
calling find_relative_frame)
- The frame is allocated on the frame_cache_obstack
- In frame_unwind_try_unwinder, we try to find an unwinder for that
frame
- While trying unwinders, memory read fails because the remote target
closes, because of "monitor exit"
- That calls reinit_frame_cache (as shown above), which resets
frame_cache_obstack
- When handling the exception in frame_unwind_try_unwinder, we try to
set some things on the frame_info object (like *this_cache, which
in fact tries to write into frame_info::prologue_cache), but the
frame_info object is no more, it went away with the obstack.
Fix this by maintaining a frame cache generation counter. Then in
exception handling code paths, don't touch frame objects if the
generation is not the same as it was on entry.
This commit generalizes the gdb.server/server-kill.exp testcase and
reuses it to test the scenario in question. The new tests fail
without the GDB fix.
gdb/ChangeLog:
* frame-unwind.c (frame_unwind_try_unwinder): On exception, don't
touch THIS_CACHE/THIS_FRAME if the frame cache was cleared
meanwhile.
* frame.c (frame_cache_generation, get_frame_cache_generation):
New.
(reinit_frame_cache): Increment FRAME_CACHE_GENERATION.
(get_prev_frame_if_no_cycle): On exception, don't touch
PREV_FRAME/THIS_FRAME if the frame cache was cleared meanwhile.
* frame.h (get_frame_cache_generation): Declare.
gdb/testsuite/ChangeLog:
* gdb.server/server-kill.exp (prepare): New, factored out from the
top level.
(kill_server): New.
(test_tstatus, test_unwind_nosyms, test_unwind_syms): New.
(top level) : Call test_tstatus, test_unwind_nosyms, test_unwind_syms.
|
|
This started with me running into the bug described in python/22748,
in summary, if the frame sniffing code accessed any registers within
an inline frame then GDB would crash with this error:
gdb/frame.c:579: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->level == 0' failed.
The problem is that, when in the Python unwinder I write this:
pending_frame.read_register ("register-name")
This is translated internally into a call to `value_of_register',
which in turn becomes a call to `value_of_register_lazy'.
Usually this isn't a problem, `value_of_register_lazy' requires the
next frame (more inner) to have a valid frame_id, which will be the
case (if we're sniffing frame #1, then frame #0 will have had its
frame-id figured out).
Unfortunately if frame #0 is inline within frame #1, then the frame-id
for frame #0 can't be computed until we have the frame-id for #1. As
a result we can't create a lazy register for frame #1 when frame #0 is
inline.
Initially I proposed a solution inline with that proposed in bugzilla,
changing value_of_register to avoid creating a lazy register value.
However, when this was discussed on the mailing list I got this reply:
https://sourceware.org/pipermail/gdb-patches/2020-June/169633.html
Which led me to look at these two patches:
[1] https://sourceware.org/pipermail/gdb-patches/2020-April/167612.html
[2] https://sourceware.org/pipermail/gdb-patches/2020-April/167930.html
When I considered patches [1] and [2] I saw that all of the issues
being addressed here were related, and that there was a single
solution that could address all of these issues.
First I wrote the new test gdb.opt/inline-frame-tailcall.exp, which
shows that [1] and [2] regress the inline tail-call unwinder, the
reason for this is that these two patches replace a call to
gdbarch_unwind_pc with a call to get_frame_register, however, this is
not correct. The previous call to gdbarch_unwind_pc takes THIS_FRAME
and returns the $pc value in the previous frame. In contrast
get_frame_register takes THIS_FRAME and returns the value of the $pc
in THIS_FRAME; these calls are not equivalent.
The reason these patches appear (or do) fix the regressions listed in
[1] is that the tail call sniffer depends on identifying the address
of a caller and a callee, GDB then looks for a tail-call sequence that
takes us from the caller address to the callee, if such a series is
found then tail-call frames are added.
The bug that was being hit, and which was address in patch [1] is that
in order to find the address of the caller, GDB ended up creating a
lazy register value for an inline frame with to frame-id. The
solution in patch [1] is to instead take the address of the callee and
treat this as the address of the caller. Getting the address of the
callee works, but we then end up looking for a tail-call series from
the callee to the callee, which obviously doesn't return any sane
results, so we don't insert any tail call frames.
The original patch [1] did cause some breakage, so patch [2] undid
patch [1] in all cases except those where we had an inline frame with
no frame-id. It just so happens that there were no tests that fitted
this description _and_ which required tail-call frames to be
successfully spotted, as a result patch [2] appeared to work.
The new test inline-frame-tailcall.exp, exposes the flaw in patch [2].
This commit undoes patch [1] and [2], and replaces them with a new
solution, which is also different to the solution proposed in the
python/22748 bug report.
In this solution I propose that we introduce some special case logic
to value_of_register_lazy. To understand what this logic is we must
first look at how inline frames unwind registers, this is very simple,
they do this:
static struct value *
inline_frame_prev_register (struct frame_info *this_frame,
void **this_cache, int regnum)
{
return get_frame_register_value (this_frame, regnum);
}
And remember:
struct value *
get_frame_register_value (struct frame_info *frame, int regnum)
{
return frame_unwind_register_value (frame->next, regnum);
}
So in all cases, unwinding a register in an inline frame just asks the
next frame to unwind the register, this makes sense, as an inline
frame doesn't really exist, when we unwind a register in an inline
frame, we're really just asking the next frame for the value of the
register in the previous, non-inline frame.
So, if we assume that we only get into the missing frame-id situation
when we try to unwind a register from an inline frame during the frame
sniffing process, then we can change value_of_register_lazy to not
create lazy register values for an inline frame.
Imagine this stack setup, where #1 is inline within #2.
#3 -> #2 -> #1 -> #0
\______/
inline
Now when trying to figure out the frame-id for #1, we need to compute
the frame-id for #2. If the frame sniffer for #2 causes a lazy
register read in #2, either due to a Python Unwinder, or for the
tail-call sniffer, then we call value_of_register_lazy passing in
frame #2.
In value_of_register_lazy, we grab the next frame, which is #1, and we
used to then ask for the frame-id of #1, which was not computed, and
this was our bug.
Now, I propose we spot that #1 is an inline frame, and so lookup the
next frame of #1, which is #0. As #0 is not inline it will have a
valid frame-id, and so we create a lazy register value using #0 as the
next-frame-id. This will give us the exact same result we had
previously (thanks to the code we inspected above).
Encoding into value_of_register_lazy the knowledge that reading an
inline frame register will always just forward to the next frame
feels.... not ideal, but this seems like the cleanest solution to this
recursive frame-id computation/sniffing issue that appears to crop
up.
The following two commits are fully reverted with this commit, these
correspond to patches [1] and [2] respectively:
commit 5939967b355ba6a940887d19847b7893a4506067
Date: Tue Apr 14 17:26:22 2020 -0300
Fix inline frame unwinding breakage
commit 991a3e2e9944a4b3a27bd989ac03c18285bd545d
Date: Sat Apr 25 00:32:44 2020 -0300
Fix remaining inline/tailcall unwinding breakage for x86_64
gdb/ChangeLog:
PR python/22748
* dwarf2/frame-tailcall.c (dwarf2_tailcall_sniffer_first): Remove
special handling for inline frames.
* findvar.c (value_of_register_lazy): Skip inline frames when
creating lazy register values.
* frame.c (frame_id_computed_p): Delete definition.
* frame.h (frame_id_computed_p): Delete declaration.
gdb/testsuite/ChangeLog:
PR python/22748
* gdb.opt/inline-frame-tailcall.c: New file.
* gdb.opt/inline-frame-tailcall.exp: New file.
* gdb.python/py-unwind-inline.c: New file.
* gdb.python/py-unwind-inline.exp: New file.
* gdb.python/py-unwind-inline.py: New file.
|
|
Commit 5939967b355ba6a940887d19847b7893a4506067 fixed inline
frame unwinding breakage for some targets (aarch64, riscv, s390...)
but regressed a few amd64 testcases related to tailcalls.
Given the following example situation...
Frame #-1 - sentinel frame
Frame # 0 - inline frame
Frame # 1 - normal frame
... suppose we're at level #1 and call into dwarf2_tailcall_sniffer_first.
We'll attempt to fetch PC, which used to be done via the gdbarch_unwind_pc call
(before 5939967b355ba6a940887d19847b7893a4506067), but now it is being handled
by the get_frame_register function.
gdbarch_unwind_pc will attempt to use frame #1's cache to retrieve information
about the PC. Here's where different architectures behave differently.
x86_64 will find a dwarf rule to retrieve PC from memory, at a CFA + offset
location. So the PC value is readily available and there is no need to
create a lazy value.
For aarch64 (and others), GCC doesn't emit an explicit location for PC, so we
eventually will find that PC is DWARF2_FRAME_REG_UNSPECIFIED. This is known
and is handled by GDB by assuming GCC really meant DWARF2_FRAME_REG_SAME_VALUE.
This means we'll attempt to fetch the register value from frame #0, via a call
to frame_unwind_got_register, which will trigger the creation of a lazy value
that requires a valid frame id for frame #0.
We don't have a valid id for frame #0 yet, so we assert.
Given the above, the following patch attempts to handle the situation without
being too hacky. We verify if the next frame is an inline frame and if its
frame id has been computed already. If it hasn't been computed yet, then we
use the safer get_frame_register function, otherwise we use the regular
gdbarch_unwind_pc hook.
gdb/ChangeLog:
2020-04-27 Luis Machado <luis.machado@linaro.org>
* dwarf2/frame-tailcall.c (dwarf2_tailcall_sniffer_first): Handle
problematic inline frame unwinding situation.
* frame.c (frame_id_computed_p): New function.
* frame.h (frame_id_computed_p): New prototype.
|
|
Currently there are many prefix commands that do nothing but call
either help_list or cmd_show_list. I happened to notice that one such
call, for "set print type", used the wrong command list parameter,
causing incorrect output.
Rather than fix this bug in isolation, I decided to eliminate this
possibility by adding two new ways to add prefix commands, which
simply route the call to help_list or cmd_show_list, as appropriate.
This makes it impossible for a mismatch to occur.
In some cases, a bit of output was removed; however, I don't think
this output in general was very useful. It seemed redundant with
what's already printed by help_list. A representative example is this
hunk, removed from ada-lang.c:
- printf_unfiltered (_(\
-"\"set ada\" must be followed by the name of a setting.\n"));
This simplified the CLI style set/show commands quite a bit, and
allowed the deletion of a macro.
This also cleans up some unusual code in windows-tdep.c.
Tested on x86-64 Fedora 30. Note that I have no way to build the
go32-nat.c change.
gdb/ChangeLog
2020-04-17 Tom Tromey <tromey@adacore.com>
* auto-load.c (show_auto_load_cmd): Remove.
(auto_load_show_cmdlist_get): Use add_show_prefix_cmd.
* arc-tdep.c (_initialize_arc_tdep): Use add_show_prefix_cmd.
(maintenance_print_arc_command): Remove.
* tui/tui-win.c (tui_command): Remove.
(tui_get_cmd_list): Use add_basic_prefix_cmd.
* tui/tui-layout.c (tui_layout_command): Remove.
(_initialize_tui_layout): Use add_basic_prefix_cmd.
* python/python.c (user_set_python, user_show_python): Remove.
(_initialize_python): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* guile/guile.c (set_guile_command, show_guile_command): Remove.
(install_gdb_commands): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
(info_guile_command): Remove.
* dwarf2/read.c (set_dwarf_cmd, show_dwarf_cmd): Remove.
(_initialize_dwarf2_read): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* cli/cli-style.h (class cli_style_option) <add_setshow_commands>:
Remove do_set and do_show parameters.
* cli/cli-style.c (set_style, show_style): Remove.
(_initialize_cli_style): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
(cli_style_option::add_setshow_commands): Remove do_set and
do_show parameters.
(cli_style_option::add_setshow_commands): Use
add_basic_prefix_cmd, add_show_prefix_cmd.
(STYLE_ADD_SETSHOW_COMMANDS): Remove macro.
(set_style_name): Remove.
* cli/cli-dump.c (dump_command, append_command): Remove.
(srec_dump_command, ihex_dump_command, verilog_dump_command)
(tekhex_dump_command, binary_dump_command)
(binary_append_command): Remove.
(_initialize_cli_dump): Use add_basic_prefix_cmd.
* windows-tdep.c (w32_prefix_command_valid): Remove global.
(init_w32_command_list): Remove; move into ...
(_initialize_windows_tdep): ... here. Use add_basic_prefix_cmd.
* valprint.c (set_print, show_print, set_print_raw)
(show_print_raw): Remove.
(_initialize_valprint): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* typeprint.c (set_print_type, show_print_type): Remove.
(_initialize_typeprint): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* record.c (set_record_command, show_record_command): Remove.
(_initialize_record): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* cli/cli-cmds.c (_initialize_cli_cmds): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
(info_command, show_command, set_debug, show_debug): Remove.
* top.h (set_history, show_history): Don't declare.
* top.c (set_history, show_history): Remove.
* target-descriptions.c (set_tdesc_cmd, show_tdesc_cmd)
(unset_tdesc_cmd): Remove.
(_initialize_target_descriptions): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* symtab.c (info_module_command): Remove.
(_initialize_symtab): Use add_basic_prefix_cmd.
* symfile.c (overlay_command): Remove.
(_initialize_symfile): Use add_basic_prefix_cmd.
* sparc64-tdep.c (info_adi_command): Remove.
(_initialize_sparc64_adi_tdep): Use add_basic_prefix_cmd.
* sh-tdep.c (show_sh_command, set_sh_command): Remove.
(_initialize_sh_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* serial.c (serial_set_cmd, serial_show_cmd): Remove.
(_initialize_serial): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* ser-tcp.c (set_tcp_cmd, show_tcp_cmd): Remove.
(_initialize_ser_tcp): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* rs6000-tdep.c (set_powerpc_command, show_powerpc_command)
(_initialize_rs6000_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* riscv-tdep.c (show_riscv_command, set_riscv_command)
(show_debug_riscv_command, set_debug_riscv_command): Remove.
(_initialize_riscv_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* remote.c (remote_command, set_remote_cmd): Remove.
(_initialize_remote): Use add_basic_prefix_cmd.
* record-full.c (set_record_full_command)
(show_record_full_command): Remove.
(_initialize_record_full): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* record-btrace.c (cmd_set_record_btrace)
(cmd_show_record_btrace, cmd_set_record_btrace_bts)
(cmd_show_record_btrace_bts, cmd_set_record_btrace_pt)
(cmd_show_record_btrace_pt): Remove.
(_initialize_record_btrace): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* ravenscar-thread.c (set_ravenscar_command)
(show_ravenscar_command): Remove.
(_initialize_ravenscar): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* mips-tdep.c (show_mips_command, set_mips_command)
(_initialize_mips_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* maint.c (maintenance_command, maintenance_info_command)
(maintenance_check_command, maintenance_print_command)
(maintenance_set_cmd, maintenance_show_cmd): Remove.
(_initialize_maint_cmds): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
(show_per_command_cmd): Remove.
* maint-test-settings.c (maintenance_set_test_settings_cmd):
Remove.
(maintenance_show_test_settings_cmd): Remove.
(_initialize_maint_test_settings): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* maint-test-options.c (maintenance_test_options_command):
Remove.
(_initialize_maint_test_options): Use add_basic_prefix_cmd.
* macrocmd.c (macro_command): Remove
(_initialize_macrocmd): Use add_basic_prefix_cmd.
* language.c (set_check, show_check): Remove.
(_initialize_language): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* infcmd.c (unset_command): Remove.
(_initialize_infcmd): Use add_basic_prefix_cmd.
* i386-tdep.c (set_mpx_cmd, show_mpx_cmd): Remove.
(_initialize_i386_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* go32-nat.c (go32_info_dos_command): Remove.
(_initialize_go32_nat): Use add_basic_prefix_cmd.
* cli/cli-decode.c (do_prefix_cmd, add_basic_prefix_cmd)
(do_show_prefix_cmd, add_show_prefix_cmd): New functions.
* frame.c (set_backtrace_cmd, show_backtrace_cmd): Remove.
(_initialize_frame): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* dcache.c (set_dcache_command, show_dcache_command): Remove.
(_initialize_dcache): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* cp-support.c (maint_cplus_command): Remove.
(_initialize_cp_support): Use add_basic_prefix_cmd.
* btrace.c (maint_btrace_cmd, maint_btrace_set_cmd)
(maint_btrace_show_cmd, maint_btrace_pt_set_cmd)
(maint_btrace_pt_show_cmd, _initialize_btrace): Use
add_basic_prefix_cmd, add_show_prefix_cmd.
* breakpoint.c (save_command): Remove.
(_initialize_breakpoint): Use add_basic_prefix_cmd.
* arm-tdep.c (set_arm_command, show_arm_command): Remove.
(_initialize_arm_tdep): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* ada-lang.c (maint_set_ada_cmd, maint_show_ada_cmd)
(set_ada_command, show_ada_command): Remove.
(_initialize_ada_language): Use add_basic_prefix_cmd,
add_show_prefix_cmd.
* command.h (add_basic_prefix_cmd, add_show_prefix_cmd): Declare.
gdb/testsuite/ChangeLog
2020-04-17 Tom Tromey <tromey@adacore.com>
* gdb.cp/maint.exp (test_help): Simplify multiple_help_body.
Update tests.
* gdb.btrace/cpu.exp: Update tests.
* gdb.base/maint.exp: Update tests.
* gdb.base/default.exp: Update tests.
* gdb.base/completion.exp: Update tests.
|
|
This commit improves GDB's handling of inline functions when there are
more than one inline function in a stack, so for example if we have a
stack like:
main -> aaa -> bbb -> ccc -> ddd
And aaa, bbb, and ccc are all inline within main GDB should (when
given sufficient debug information) be able to step from main through
aaa, bbb, and ccc. Unfortunately, this currently doesn't work, here's
an example session:
(gdb) start
Temporary breakpoint 1 at 0x4003b0: file test.c, line 38.
Starting program: /project/gdb/tests/inline/test
Temporary breakpoint 1, main () at test.c:38
38 global_var = 0;
(gdb) step
39 return aaa () + 1;
(gdb) step
aaa () at test.c:39
39 return aaa () + 1;
(gdb) step
bbb () at test.c:39
39 return aaa () + 1;
(gdb) step
ccc () at test.c:39
39 return aaa () + 1;
(gdb) step
ddd () at test.c:32
32 return global_var;
(gdb) bt
#0 ddd () at test.c:32
#1 0x00000000004003c1 in ccc () at test.c:39
#2 bbb () at test.c:26
#3 aaa () at test.c:14
#4 main () at test.c:39
Notice that once we get to line 39 in main, GDB keeps reporting line
39 in main as the location despite understanding that the inferior is
stepping through the nested inline functions with each use of step.
The problem is that as soon as the inferior stops we call
skip_inline_frames (from inline-frame.c) which calculates the
inferiors current state in relation to inline functions - it figures
out if we're in an inline function, and if we are counts how many
inline frames there are at the current location.
So, in our example above, when we step from line 38 in main to line 39
we stop at a location that is simultaneously in all of main, aaa, bbb,
and ccc. The block structure reflects the order in which the
functions would be called, with ccc being the most inner block and
main being the most outer block. When we stop GDB naturally finds the
block for ccc, however within skip_inline_frames we spot that bbb,
aaa, and main are super-blocks of the current location and that each
layer represents an inline function. The skip_inline_frames then
records the depth of inline functions (3 in this case for aaa, bbb,
and ccc) and also the symbol of the outermost inline function (in this
case 'aaa' as main isn't an inline function, it just has things inline
within it).
Now GDB understands the stack to be main -> aaa -> bbb -> ccc,
however, the state initialised in skip_inline_frames starts off
indicating that we should hide 3 frames from the user, so we report
that we're in main at line 39. The location of main, line 39 is
derived by asking the inline function state for the last symbol in the
stack (aaa in this case), and then asking for it's location - the
location of an inlined function symbol is its call site, so main, line
39 in this case.
If the user then asks GDB to step we don't actually move the inferior
at all, instead we spot that we are in an inline function stack,
lookup the inline state data, and reduce the skip depth by 1. We then
report to the user that GDB has stopped. GDB now understands that we
are in 'aaa'. In order to get the precise location we again ask GDB
for the last symbol from the inline data structure, and we are again
told 'aaa', we then get the location from 'aaa', and report that we
are in main, line 39.
Hopefully it's clear what the mistake here is, once we've reduced the
inline skip depth we should not be using 'aaa' to compute the precise
location, instead we should be using 'bbb'. That is what this patch
does.
Now, when we call skip_inline_frames instead of just recording the
last skipped symbol we now record all symbols in the inline frame
stack. When we ask GDB for the last skipped symbol we return a symbol
based on how many frames we are skipping, not just the last know
symbol.
With this fix in place, the same session as above now looks much
better:
(gdb) start
Temporary breakpoint 1 at 0x4003b0: file test.c, line 38.
Starting program: /project/gdb/tests/inline/test
Temporary breakpoint 1, main () at test.c:38
38 global_var = 0;
(gdb) s
39 return aaa () + 1;
(gdb) s
aaa () at test.c:14
14 return bbb () + 1;
(gdb) s
bbb () at test.c:26
26 return ccc () + 1;
(gdb) s
ccc () at test.c:20
20 return ddd () + 1;
(gdb) s
ddd () at test.c:32
32 return global_var;
(gdb) bt
#0 ddd () at test.c:32
#1 0x00000000004003c1 in ccc () at test.c:20
#2 bbb () at test.c:26
#3 aaa () at test.c:14
#4 main () at test.c:39
gdb/ChangeLog:
* frame.c (find_frame_sal): Move call to get_next_frame into more
inner scope.
* inline-frame.c (inilne_state) <inline_state>: Update argument
types.
(inilne_state) <skipped_symbol>: Rename to...
(inilne_state) <skipped_symbols>: ...this, and change to a vector.
(skip_inline_frames): Build vector of skipped symbols and use this
to reate the inline_state.
(inline_skipped_symbol): Add a comment and some assertions, fetch
skipped symbol from the list.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-inline-many-frames.c: New file.
* gdb.dwarf2/dw2-inline-many-frames.exp: New file.
Change-Id: I99def5ffb44eb9e58cda4b449bf3d91ab0386c62
|
|
I'd like to enable the -Wmissing-declarations warning. However, it
warns for every _initialize function, for example:
CXX dcache.o
/home/smarchi/src/binutils-gdb/gdb/dcache.c: In function ‘void _initialize_dcache()’:
/home/smarchi/src/binutils-gdb/gdb/dcache.c:688:1: error: no previous declaration for ‘void _initialize_dcache()’ [-Werror=missing-declarations]
_initialize_dcache (void)
^~~~~~~~~~~~~~~~~~
The only practical way forward I found is to add back the declarations,
which were removed by this commit:
commit 481695ed5f6e0a8a9c9c50bfac1cdd2b3151e6c9
Author: John Baldwin <jhb@FreeBSD.org>
Date: Sat Sep 9 11:02:37 2017 -0700
Remove unnecessary function prototypes.
I don't think it's a big problem to have the declarations for these
functions, but if anybody has a better solution for this, I'll be happy
to use it.
gdb/ChangeLog:
* aarch64-fbsd-nat.c (_initialize_aarch64_fbsd_nat): Add declaration.
* aarch64-fbsd-tdep.c (_initialize_aarch64_fbsd_tdep): Add declaration.
* aarch64-linux-nat.c (_initialize_aarch64_linux_nat): Add declaration.
* aarch64-linux-tdep.c (_initialize_aarch64_linux_tdep): Add declaration.
* aarch64-newlib-tdep.c (_initialize_aarch64_newlib_tdep): Add declaration.
* aarch64-tdep.c (_initialize_aarch64_tdep): Add declaration.
* ada-exp.y (_initialize_ada_exp): Add declaration.
* ada-lang.c (_initialize_ada_language): Add declaration.
* ada-tasks.c (_initialize_tasks): Add declaration.
* agent.c (_initialize_agent): Add declaration.
* aix-thread.c (_initialize_aix_thread): Add declaration.
* alpha-bsd-nat.c (_initialize_alphabsd_nat): Add declaration.
* alpha-linux-nat.c (_initialize_alpha_linux_nat): Add declaration.
* alpha-linux-tdep.c (_initialize_alpha_linux_tdep): Add declaration.
* alpha-nbsd-tdep.c (_initialize_alphanbsd_tdep): Add declaration.
* alpha-obsd-tdep.c (_initialize_alphaobsd_tdep): Add declaration.
* alpha-tdep.c (_initialize_alpha_tdep): Add declaration.
* amd64-darwin-tdep.c (_initialize_amd64_darwin_tdep): Add declaration.
* amd64-dicos-tdep.c (_initialize_amd64_dicos_tdep): Add declaration.
* amd64-fbsd-nat.c (_initialize_amd64fbsd_nat): Add declaration.
* amd64-fbsd-tdep.c (_initialize_amd64fbsd_tdep): Add declaration.
* amd64-linux-nat.c (_initialize_amd64_linux_nat): Add declaration.
* amd64-linux-tdep.c (_initialize_amd64_linux_tdep): Add declaration.
* amd64-nbsd-nat.c (_initialize_amd64nbsd_nat): Add declaration.
* amd64-nbsd-tdep.c (_initialize_amd64nbsd_tdep): Add declaration.
* amd64-obsd-nat.c (_initialize_amd64obsd_nat): Add declaration.
* amd64-obsd-tdep.c (_initialize_amd64obsd_tdep): Add declaration.
* amd64-sol2-tdep.c (_initialize_amd64_sol2_tdep): Add declaration.
* amd64-tdep.c (_initialize_amd64_tdep): Add declaration.
* amd64-windows-nat.c (_initialize_amd64_windows_nat): Add declaration.
* amd64-windows-tdep.c (_initialize_amd64_windows_tdep): Add declaration.
* annotate.c (_initialize_annotate): Add declaration.
* arc-newlib-tdep.c (_initialize_arc_newlib_tdep): Add declaration.
* arc-tdep.c (_initialize_arc_tdep): Add declaration.
* arch-utils.c (_initialize_gdbarch_utils): Add declaration.
* arm-fbsd-nat.c (_initialize_arm_fbsd_nat): Add declaration.
* arm-fbsd-tdep.c (_initialize_arm_fbsd_tdep): Add declaration.
* arm-linux-nat.c (_initialize_arm_linux_nat): Add declaration.
* arm-linux-tdep.c (_initialize_arm_linux_tdep): Add declaration.
* arm-nbsd-nat.c (_initialize_arm_netbsd_nat): Add declaration.
* arm-nbsd-tdep.c (_initialize_arm_netbsd_tdep): Add declaration.
* arm-obsd-tdep.c (_initialize_armobsd_tdep): Add declaration.
* arm-pikeos-tdep.c (_initialize_arm_pikeos_tdep): Add declaration.
* arm-symbian-tdep.c (_initialize_arm_symbian_tdep): Add declaration.
* arm-tdep.c (_initialize_arm_tdep): Add declaration.
* arm-wince-tdep.c (_initialize_arm_wince_tdep): Add declaration.
* auto-load.c (_initialize_auto_load): Add declaration.
* auxv.c (_initialize_auxv): Add declaration.
* avr-tdep.c (_initialize_avr_tdep): Add declaration.
* ax-gdb.c (_initialize_ax_gdb): Add declaration.
* bfin-linux-tdep.c (_initialize_bfin_linux_tdep): Add declaration.
* bfin-tdep.c (_initialize_bfin_tdep): Add declaration.
* break-catch-sig.c (_initialize_break_catch_sig): Add declaration.
* break-catch-syscall.c (_initialize_break_catch_syscall): Add declaration.
* break-catch-throw.c (_initialize_break_catch_throw): Add declaration.
* breakpoint.c (_initialize_breakpoint): Add declaration.
* bsd-uthread.c (_initialize_bsd_uthread): Add declaration.
* btrace.c (_initialize_btrace): Add declaration.
* charset.c (_initialize_charset): Add declaration.
* cli/cli-cmds.c (_initialize_cli_cmds): Add declaration.
* cli/cli-dump.c (_initialize_cli_dump): Add declaration.
* cli/cli-interp.c (_initialize_cli_interp): Add declaration.
* cli/cli-logging.c (_initialize_cli_logging): Add declaration.
* cli/cli-script.c (_initialize_cli_script): Add declaration.
* cli/cli-style.c (_initialize_cli_style): Add declaration.
* coff-pe-read.c (_initialize_coff_pe_read): Add declaration.
* coffread.c (_initialize_coffread): Add declaration.
* compile/compile-cplus-types.c (_initialize_compile_cplus_types): Add declaration.
* compile/compile.c (_initialize_compile): Add declaration.
* complaints.c (_initialize_complaints): Add declaration.
* completer.c (_initialize_completer): Add declaration.
* copying.c (_initialize_copying): Add declaration.
* corefile.c (_initialize_core): Add declaration.
* corelow.c (_initialize_corelow): Add declaration.
* cp-abi.c (_initialize_cp_abi): Add declaration.
* cp-namespace.c (_initialize_cp_namespace): Add declaration.
* cp-support.c (_initialize_cp_support): Add declaration.
* cp-valprint.c (_initialize_cp_valprint): Add declaration.
* cris-linux-tdep.c (_initialize_cris_linux_tdep): Add declaration.
* cris-tdep.c (_initialize_cris_tdep): Add declaration.
* csky-linux-tdep.c (_initialize_csky_linux_tdep): Add declaration.
* csky-tdep.c (_initialize_csky_tdep): Add declaration.
* ctfread.c (_initialize_ctfread): Add declaration.
* d-lang.c (_initialize_d_language): Add declaration.
* darwin-nat-info.c (_initialize_darwin_info_commands): Add declaration.
* darwin-nat.c (_initialize_darwin_nat): Add declaration.
* dbxread.c (_initialize_dbxread): Add declaration.
* dcache.c (_initialize_dcache): Add declaration.
* disasm-selftests.c (_initialize_disasm_selftests): Add declaration.
* disasm.c (_initialize_disasm): Add declaration.
* dtrace-probe.c (_initialize_dtrace_probe): Add declaration.
* dummy-frame.c (_initialize_dummy_frame): Add declaration.
* dwarf-index-cache.c (_initialize_index_cache): Add declaration.
* dwarf-index-write.c (_initialize_dwarf_index_write): Add declaration.
* dwarf2-frame-tailcall.c (_initialize_tailcall_frame): Add declaration.
* dwarf2-frame.c (_initialize_dwarf2_frame): Add declaration.
* dwarf2expr.c (_initialize_dwarf2expr): Add declaration.
* dwarf2loc.c (_initialize_dwarf2loc): Add declaration.
* dwarf2read.c (_initialize_dwarf2_read): Add declaration.
* elfread.c (_initialize_elfread): Add declaration.
* exec.c (_initialize_exec): Add declaration.
* extension.c (_initialize_extension): Add declaration.
* f-lang.c (_initialize_f_language): Add declaration.
* f-valprint.c (_initialize_f_valprint): Add declaration.
* fbsd-nat.c (_initialize_fbsd_nat): Add declaration.
* fbsd-tdep.c (_initialize_fbsd_tdep): Add declaration.
* filesystem.c (_initialize_filesystem): Add declaration.
* findcmd.c (_initialize_mem_search): Add declaration.
* findvar.c (_initialize_findvar): Add declaration.
* fork-child.c (_initialize_fork_child): Add declaration.
* frame-base.c (_initialize_frame_base): Add declaration.
* frame-unwind.c (_initialize_frame_unwind): Add declaration.
* frame.c (_initialize_frame): Add declaration.
* frv-linux-tdep.c (_initialize_frv_linux_tdep): Add declaration.
* frv-tdep.c (_initialize_frv_tdep): Add declaration.
* ft32-tdep.c (_initialize_ft32_tdep): Add declaration.
* gcore.c (_initialize_gcore): Add declaration.
* gdb-demangle.c (_initialize_gdb_demangle): Add declaration.
* gdb_bfd.c (_initialize_gdb_bfd): Add declaration.
* gdbarch-selftests.c (_initialize_gdbarch_selftests): Add declaration.
* gdbarch.c (_initialize_gdbarch): Add declaration.
* gdbtypes.c (_initialize_gdbtypes): Add declaration.
* gnu-nat.c (_initialize_gnu_nat): Add declaration.
* gnu-v2-abi.c (_initialize_gnu_v2_abi): Add declaration.
* gnu-v3-abi.c (_initialize_gnu_v3_abi): Add declaration.
* go-lang.c (_initialize_go_language): Add declaration.
* go32-nat.c (_initialize_go32_nat): Add declaration.
* guile/guile.c (_initialize_guile): Add declaration.
* h8300-tdep.c (_initialize_h8300_tdep): Add declaration.
* hppa-linux-nat.c (_initialize_hppa_linux_nat): Add declaration.
* hppa-linux-tdep.c (_initialize_hppa_linux_tdep): Add declaration.
* hppa-nbsd-nat.c (_initialize_hppanbsd_nat): Add declaration.
* hppa-nbsd-tdep.c (_initialize_hppanbsd_tdep): Add declaration.
* hppa-obsd-nat.c (_initialize_hppaobsd_nat): Add declaration.
* hppa-obsd-tdep.c (_initialize_hppabsd_tdep): Add declaration.
* hppa-tdep.c (_initialize_hppa_tdep): Add declaration.
* i386-bsd-nat.c (_initialize_i386bsd_nat): Add declaration.
* i386-cygwin-tdep.c (_initialize_i386_cygwin_tdep): Add declaration.
* i386-darwin-nat.c (_initialize_i386_darwin_nat): Add declaration.
* i386-darwin-tdep.c (_initialize_i386_darwin_tdep): Add declaration.
* i386-dicos-tdep.c (_initialize_i386_dicos_tdep): Add declaration.
* i386-fbsd-nat.c (_initialize_i386fbsd_nat): Add declaration.
* i386-fbsd-tdep.c (_initialize_i386fbsd_tdep): Add declaration.
* i386-gnu-nat.c (_initialize_i386gnu_nat): Add declaration.
* i386-gnu-tdep.c (_initialize_i386gnu_tdep): Add declaration.
* i386-go32-tdep.c (_initialize_i386_go32_tdep): Add declaration.
* i386-linux-nat.c (_initialize_i386_linux_nat): Add declaration.
* i386-linux-tdep.c (_initialize_i386_linux_tdep): Add declaration.
* i386-nbsd-nat.c (_initialize_i386nbsd_nat): Add declaration.
* i386-nbsd-tdep.c (_initialize_i386nbsd_tdep): Add declaration.
* i386-nto-tdep.c (_initialize_i386nto_tdep): Add declaration.
* i386-obsd-nat.c (_initialize_i386obsd_nat): Add declaration.
* i386-obsd-tdep.c (_initialize_i386obsd_tdep): Add declaration.
* i386-sol2-nat.c (_initialize_amd64_sol2_nat): Add declaration.
* i386-sol2-tdep.c (_initialize_i386_sol2_tdep): Add declaration.
* i386-tdep.c (_initialize_i386_tdep): Add declaration.
* i386-windows-nat.c (_initialize_i386_windows_nat): Add declaration.
* ia64-libunwind-tdep.c (_initialize_libunwind_frame): Add declaration.
* ia64-linux-nat.c (_initialize_ia64_linux_nat): Add declaration.
* ia64-linux-tdep.c (_initialize_ia64_linux_tdep): Add declaration.
* ia64-tdep.c (_initialize_ia64_tdep): Add declaration.
* ia64-vms-tdep.c (_initialize_ia64_vms_tdep): Add declaration.
* infcall.c (_initialize_infcall): Add declaration.
* infcmd.c (_initialize_infcmd): Add declaration.
* inflow.c (_initialize_inflow): Add declaration.
* infrun.c (_initialize_infrun): Add declaration.
* interps.c (_initialize_interpreter): Add declaration.
* iq2000-tdep.c (_initialize_iq2000_tdep): Add declaration.
* jit.c (_initialize_jit): Add declaration.
* language.c (_initialize_language): Add declaration.
* linux-fork.c (_initialize_linux_fork): Add declaration.
* linux-nat.c (_initialize_linux_nat): Add declaration.
* linux-tdep.c (_initialize_linux_tdep): Add declaration.
* linux-thread-db.c (_initialize_thread_db): Add declaration.
* lm32-tdep.c (_initialize_lm32_tdep): Add declaration.
* m2-lang.c (_initialize_m2_language): Add declaration.
* m32c-tdep.c (_initialize_m32c_tdep): Add declaration.
* m32r-linux-nat.c (_initialize_m32r_linux_nat): Add declaration.
* m32r-linux-tdep.c (_initialize_m32r_linux_tdep): Add declaration.
* m32r-tdep.c (_initialize_m32r_tdep): Add declaration.
* m68hc11-tdep.c (_initialize_m68hc11_tdep): Add declaration.
* m68k-bsd-nat.c (_initialize_m68kbsd_nat): Add declaration.
* m68k-bsd-tdep.c (_initialize_m68kbsd_tdep): Add declaration.
* m68k-linux-nat.c (_initialize_m68k_linux_nat): Add declaration.
* m68k-linux-tdep.c (_initialize_m68k_linux_tdep): Add declaration.
* m68k-tdep.c (_initialize_m68k_tdep): Add declaration.
* machoread.c (_initialize_machoread): Add declaration.
* macrocmd.c (_initialize_macrocmd): Add declaration.
* macroscope.c (_initialize_macroscope): Add declaration.
* maint-test-options.c (_initialize_maint_test_options): Add declaration.
* maint-test-settings.c (_initialize_maint_test_settings): Add declaration.
* maint.c (_initialize_maint_cmds): Add declaration.
* mdebugread.c (_initialize_mdebugread): Add declaration.
* memattr.c (_initialize_mem): Add declaration.
* mep-tdep.c (_initialize_mep_tdep): Add declaration.
* mi/mi-cmd-env.c (_initialize_mi_cmd_env): Add declaration.
* mi/mi-cmds.c (_initialize_mi_cmds): Add declaration.
* mi/mi-interp.c (_initialize_mi_interp): Add declaration.
* mi/mi-main.c (_initialize_mi_main): Add declaration.
* microblaze-linux-tdep.c (_initialize_microblaze_linux_tdep): Add declaration.
* microblaze-tdep.c (_initialize_microblaze_tdep): Add declaration.
* mips-fbsd-nat.c (_initialize_mips_fbsd_nat): Add declaration.
* mips-fbsd-tdep.c (_initialize_mips_fbsd_tdep): Add declaration.
* mips-linux-nat.c (_initialize_mips_linux_nat): Add declaration.
* mips-linux-tdep.c (_initialize_mips_linux_tdep): Add declaration.
* mips-nbsd-nat.c (_initialize_mipsnbsd_nat): Add declaration.
* mips-nbsd-tdep.c (_initialize_mipsnbsd_tdep): Add declaration.
* mips-sde-tdep.c (_initialize_mips_sde_tdep): Add declaration.
* mips-tdep.c (_initialize_mips_tdep): Add declaration.
* mips64-obsd-nat.c (_initialize_mips64obsd_nat): Add declaration.
* mips64-obsd-tdep.c (_initialize_mips64obsd_tdep): Add declaration.
* mipsread.c (_initialize_mipsread): Add declaration.
* mn10300-linux-tdep.c (_initialize_mn10300_linux_tdep): Add declaration.
* mn10300-tdep.c (_initialize_mn10300_tdep): Add declaration.
* moxie-tdep.c (_initialize_moxie_tdep): Add declaration.
* msp430-tdep.c (_initialize_msp430_tdep): Add declaration.
* nds32-tdep.c (_initialize_nds32_tdep): Add declaration.
* nios2-linux-tdep.c (_initialize_nios2_linux_tdep): Add declaration.
* nios2-tdep.c (_initialize_nios2_tdep): Add declaration.
* nto-procfs.c (_initialize_procfs): Add declaration.
* objc-lang.c (_initialize_objc_language): Add declaration.
* observable.c (_initialize_observer): Add declaration.
* opencl-lang.c (_initialize_opencl_language): Add declaration.
* or1k-linux-tdep.c (_initialize_or1k_linux_tdep): Add declaration.
* or1k-tdep.c (_initialize_or1k_tdep): Add declaration.
* osabi.c (_initialize_gdb_osabi): Add declaration.
* osdata.c (_initialize_osdata): Add declaration.
* p-valprint.c (_initialize_pascal_valprint): Add declaration.
* parse.c (_initialize_parse): Add declaration.
* ppc-fbsd-nat.c (_initialize_ppcfbsd_nat): Add declaration.
* ppc-fbsd-tdep.c (_initialize_ppcfbsd_tdep): Add declaration.
* ppc-linux-nat.c (_initialize_ppc_linux_nat): Add declaration.
* ppc-linux-tdep.c (_initialize_ppc_linux_tdep): Add declaration.
* ppc-nbsd-nat.c (_initialize_ppcnbsd_nat): Add declaration.
* ppc-nbsd-tdep.c (_initialize_ppcnbsd_tdep): Add declaration.
* ppc-obsd-nat.c (_initialize_ppcobsd_nat): Add declaration.
* ppc-obsd-tdep.c (_initialize_ppcobsd_tdep): Add declaration.
* printcmd.c (_initialize_printcmd): Add declaration.
* probe.c (_initialize_probe): Add declaration.
* proc-api.c (_initialize_proc_api): Add declaration.
* proc-events.c (_initialize_proc_events): Add declaration.
* proc-service.c (_initialize_proc_service): Add declaration.
* procfs.c (_initialize_procfs): Add declaration.
* producer.c (_initialize_producer): Add declaration.
* psymtab.c (_initialize_psymtab): Add declaration.
* python/python.c (_initialize_python): Add declaration.
* ravenscar-thread.c (_initialize_ravenscar): Add declaration.
* record-btrace.c (_initialize_record_btrace): Add declaration.
* record-full.c (_initialize_record_full): Add declaration.
* record.c (_initialize_record): Add declaration.
* regcache-dump.c (_initialize_regcache_dump): Add declaration.
* regcache.c (_initialize_regcache): Add declaration.
* reggroups.c (_initialize_reggroup): Add declaration.
* remote-notif.c (_initialize_notif): Add declaration.
* remote-sim.c (_initialize_remote_sim): Add declaration.
* remote.c (_initialize_remote): Add declaration.
* reverse.c (_initialize_reverse): Add declaration.
* riscv-fbsd-nat.c (_initialize_riscv_fbsd_nat): Add declaration.
* riscv-fbsd-tdep.c (_initialize_riscv_fbsd_tdep): Add declaration.
* riscv-linux-nat.c (_initialize_riscv_linux_nat): Add declaration.
* riscv-linux-tdep.c (_initialize_riscv_linux_tdep): Add declaration.
* riscv-tdep.c (_initialize_riscv_tdep): Add declaration.
* rl78-tdep.c (_initialize_rl78_tdep): Add declaration.
* rs6000-aix-tdep.c (_initialize_rs6000_aix_tdep): Add declaration.
* rs6000-lynx178-tdep.c (_initialize_rs6000_lynx178_tdep):
Add declaration.
* rs6000-nat.c (_initialize_rs6000_nat): Add declaration.
* rs6000-tdep.c (_initialize_rs6000_tdep): Add declaration.
* run-on-main-thread.c (_initialize_run_on_main_thread): Add declaration.
* rust-exp.y (_initialize_rust_exp): Add declaration.
* rx-tdep.c (_initialize_rx_tdep): Add declaration.
* s12z-tdep.c (_initialize_s12z_tdep): Add declaration.
* s390-linux-nat.c (_initialize_s390_nat): Add declaration.
* s390-linux-tdep.c (_initialize_s390_linux_tdep): Add declaration.
* s390-tdep.c (_initialize_s390_tdep): Add declaration.
* score-tdep.c (_initialize_score_tdep): Add declaration.
* ser-go32.c (_initialize_ser_dos): Add declaration.
* ser-mingw.c (_initialize_ser_windows): Add declaration.
* ser-pipe.c (_initialize_ser_pipe): Add declaration.
* ser-tcp.c (_initialize_ser_tcp): Add declaration.
* ser-uds.c (_initialize_ser_socket): Add declaration.
* ser-unix.c (_initialize_ser_hardwire): Add declaration.
* serial.c (_initialize_serial): Add declaration.
* sh-linux-tdep.c (_initialize_sh_linux_tdep): Add declaration.
* sh-nbsd-nat.c (_initialize_shnbsd_nat): Add declaration.
* sh-nbsd-tdep.c (_initialize_shnbsd_tdep): Add declaration.
* sh-tdep.c (_initialize_sh_tdep): Add declaration.
* skip.c (_initialize_step_skip): Add declaration.
* sol-thread.c (_initialize_sol_thread): Add declaration.
* solib-aix.c (_initialize_solib_aix): Add declaration.
* solib-darwin.c (_initialize_darwin_solib): Add declaration.
* solib-dsbt.c (_initialize_dsbt_solib): Add declaration.
* solib-frv.c (_initialize_frv_solib): Add declaration.
* solib-svr4.c (_initialize_svr4_solib): Add declaration.
* solib-target.c (_initialize_solib_target): Add declaration.
* solib.c (_initialize_solib): Add declaration.
* source-cache.c (_initialize_source_cache): Add declaration.
* source.c (_initialize_source): Add declaration.
* sparc-linux-nat.c (_initialize_sparc_linux_nat): Add declaration.
* sparc-linux-tdep.c (_initialize_sparc_linux_tdep): Add declaration.
* sparc-nat.c (_initialize_sparc_nat): Add declaration.
* sparc-nbsd-nat.c (_initialize_sparcnbsd_nat): Add declaration.
* sparc-nbsd-tdep.c (_initialize_sparcnbsd_tdep): Add declaration.
* sparc-obsd-tdep.c (_initialize_sparc32obsd_tdep): Add declaration.
* sparc-sol2-tdep.c (_initialize_sparc_sol2_tdep): Add declaration.
* sparc-tdep.c (_initialize_sparc_tdep): Add declaration.
* sparc64-fbsd-nat.c (_initialize_sparc64fbsd_nat): Add declaration.
* sparc64-fbsd-tdep.c (_initialize_sparc64fbsd_tdep): Add declaration.
* sparc64-linux-nat.c (_initialize_sparc64_linux_nat): Add declaration.
* sparc64-linux-tdep.c (_initialize_sparc64_linux_tdep): Add declaration.
* sparc64-nat.c (_initialize_sparc64_nat): Add declaration.
* sparc64-nbsd-nat.c (_initialize_sparc64nbsd_nat): Add declaration.
* sparc64-nbsd-tdep.c (_initialize_sparc64nbsd_tdep): Add declaration.
* sparc64-obsd-nat.c (_initialize_sparc64obsd_nat): Add declaration.
* sparc64-obsd-tdep.c (_initialize_sparc64obsd_tdep): Add declaration.
* sparc64-sol2-tdep.c (_initialize_sparc64_sol2_tdep): Add declaration.
* sparc64-tdep.c (_initialize_sparc64_adi_tdep): Add declaration.
* stabsread.c (_initialize_stabsread): Add declaration.
* stack.c (_initialize_stack): Add declaration.
* stap-probe.c (_initialize_stap_probe): Add declaration.
* std-regs.c (_initialize_frame_reg): Add declaration.
* symfile-debug.c (_initialize_symfile_debug): Add declaration.
* symfile-mem.c (_initialize_symfile_mem): Add declaration.
* symfile.c (_initialize_symfile): Add declaration.
* symmisc.c (_initialize_symmisc): Add declaration.
* symtab.c (_initialize_symtab): Add declaration.
* target.c (_initialize_target): Add declaration.
* target-connection.c (_initialize_target_connection): Add
declaration.
* target-dcache.c (_initialize_target_dcache): Add declaration.
* target-descriptions.c (_initialize_target_descriptions): Add declaration.
* thread.c (_initialize_thread): Add declaration.
* tic6x-linux-tdep.c (_initialize_tic6x_linux_tdep): Add declaration.
* tic6x-tdep.c (_initialize_tic6x_tdep): Add declaration.
* tilegx-linux-nat.c (_initialize_tile_linux_nat): Add declaration.
* tilegx-linux-tdep.c (_initialize_tilegx_linux_tdep): Add declaration.
* tilegx-tdep.c (_initialize_tilegx_tdep): Add declaration.
* tracectf.c (_initialize_ctf): Add declaration.
* tracefile-tfile.c (_initialize_tracefile_tfile): Add declaration.
* tracefile.c (_initialize_tracefile): Add declaration.
* tracepoint.c (_initialize_tracepoint): Add declaration.
* tui/tui-hooks.c (_initialize_tui_hooks): Add declaration.
* tui/tui-interp.c (_initialize_tui_interp): Add declaration.
* tui/tui-layout.c (_initialize_tui_layout): Add declaration.
* tui/tui-regs.c (_initialize_tui_regs): Add declaration.
* tui/tui-stack.c (_initialize_tui_stack): Add declaration.
* tui/tui-win.c (_initialize_tui_win): Add declaration.
* tui/tui.c (_initialize_tui): Add declaration.
* typeprint.c (_initialize_typeprint): Add declaration.
* ui-style.c (_initialize_ui_style): Add declaration.
* unittests/array-view-selftests.c (_initialize_array_view_selftests): Add declaration.
* unittests/child-path-selftests.c (_initialize_child_path_selftests): Add declaration.
* unittests/cli-utils-selftests.c (_initialize_cli_utils_selftests): Add declaration.
* unittests/common-utils-selftests.c (_initialize_common_utils_selftests): Add declaration.
* unittests/copy_bitwise-selftests.c (_initialize_copy_bitwise_utils_selftests): Add declaration.
* unittests/environ-selftests.c (_initialize_environ_selftests): Add declaration.
* unittests/filtered_iterator-selftests.c
(_initialize_filtered_iterator_selftests): Add declaration.
* unittests/format_pieces-selftests.c (_initialize_format_pieces_selftests): Add declaration.
* unittests/function-view-selftests.c (_initialize_function_view_selftests): Add declaration.
* unittests/help-doc-selftests.c (_initialize_help_doc_selftests): Add declaration.
* unittests/lookup_name_info-selftests.c (_initialize_lookup_name_info_selftests): Add declaration.
* unittests/main-thread-selftests.c
(_initialize_main_thread_selftests): Add declaration.
* unittests/memory-map-selftests.c (_initialize_memory_map_selftests): Add declaration.
* unittests/memrange-selftests.c (_initialize_memrange_selftests): Add declaration.
* unittests/mkdir-recursive-selftests.c (_initialize_mkdir_recursive_selftests): Add declaration.
* unittests/observable-selftests.c (_initialize_observer_selftest): Add declaration.
* unittests/offset-type-selftests.c (_initialize_offset_type_selftests): Add declaration.
* unittests/optional-selftests.c (_initialize_optional_selftests): Add declaration.
* unittests/parse-connection-spec-selftests.c (_initialize_parse_connection_spec_selftests): Add declaration.
* unittests/rsp-low-selftests.c (_initialize_rsp_low_selftests): Add declaration.
* unittests/scoped_fd-selftests.c (_initialize_scoped_fd_selftests): Add declaration.
* unittests/scoped_mmap-selftests.c (_initialize_scoped_mmap_selftests): Add declaration.
* unittests/scoped_restore-selftests.c (_initialize_scoped_restore_selftests): Add declaration.
* unittests/string_view-selftests.c (_initialize_string_view_selftests): Add declaration.
* unittests/style-selftests.c (_initialize_style_selftest): Add declaration.
* unittests/tracepoint-selftests.c (_initialize_tracepoint_selftests): Add declaration.
* unittests/tui-selftests.c (_initialize_tui_selftest): Add
declaration.
* unittests/unpack-selftests.c (_initialize_unpack_selftests): Add declaration.
* unittests/utils-selftests.c (_initialize_utils_selftests): Add declaration.
* unittests/vec-utils-selftests.c (_initialize_vec_utils_selftests): Add declaration.
* unittests/xml-utils-selftests.c (_initialize_xml_utils): Add declaration.
* user-regs.c (_initialize_user_regs): Add declaration.
* utils.c (_initialize_utils): Add declaration.
* v850-tdep.c (_initialize_v850_tdep): Add declaration.
* valops.c (_initialize_valops): Add declaration.
* valprint.c (_initialize_valprint): Add declaration.
* value.c (_initialize_values): Add declaration.
* varobj.c (_initialize_varobj): Add declaration.
* vax-bsd-nat.c (_initialize_vaxbsd_nat): Add declaration.
* vax-nbsd-tdep.c (_initialize_vaxnbsd_tdep): Add declaration.
* vax-tdep.c (_initialize_vax_tdep): Add declaration.
* windows-nat.c (_initialize_windows_nat): Add declaration.
(_initialize_check_for_gdb_ini): Add declaration.
(_initialize_loadable): Add declaration.
* windows-tdep.c (_initialize_windows_tdep): Add declaration.
* x86-bsd-nat.c (_initialize_x86_bsd_nat): Add declaration.
* x86-linux-nat.c (_initialize_x86_linux_nat): Add declaration.
* xcoffread.c (_initialize_xcoffread): Add declaration.
* xml-support.c (_initialize_xml_support): Add declaration.
* xstormy16-tdep.c (_initialize_xstormy16_tdep): Add declaration.
* xtensa-linux-nat.c (_initialize_xtensa_linux_nat): Add declaration.
* xtensa-linux-tdep.c (_initialize_xtensa_linux_tdep): Add declaration.
* xtensa-tdep.c (_initialize_xtensa_tdep): Add declaration.
Change-Id: I13eec7e0ed2b3c427377a7bdb055cf46da64def9
|
|
gdb/ChangeLog:
Update copyright year range in all GDB files.
|
|
Improves readability. In the future, it will also allow making the name
private, once the name setter functions become member functions.
gdb/ChangeLog:
2019-11-22 Christian Biesinger <cbiesinger@google.com>
* ada-lang.c (ada_lookup_simple_minsym): Update.
(ada_collect_symbol_completion_matches): Update.
* ada-tasks.c (read_atcb): Update.
* amd64-windows-tdep.c (amd64_skip_main_prologue): Update.
(amd64_windows_skip_trampoline_code): Update.
* arm-tdep.c (skip_prologue_function): Update.
(arm_skip_stack_protector): Update.
* arm-wince-tdep.c (arm_pe_skip_trampoline_code): Update.
(arm_wince_skip_main_prologue): Update.
* ax-gdb.c (gen_expr): Update.
* block.c (call_site_for_pc): Update.
* blockframe.c (find_pc_partial_function): Update.
* breakpoint.c (set_breakpoint_location_function): Update.
* btrace.c (ftrace_print_function_name): Update.
(ftrace_function_switched): Update.
* c-valprint.c (print_unpacked_pointer): Update.
* coffread.c (coff_symfile_read): Update.
* compile/compile-c-symbols.c (convert_symbol_bmsym): Update.
* compile/compile-cplus-symbols.c (convert_symbol_bmsym): Update.
* dwarf-index-write.c (write_psymbols): Update.
* dwarf2loc.c (call_site_to_target_addr): Update.
(func_verify_no_selftailcall): Update.
(tailcall_dump): Update.
(call_site_find_chain_1): Update.
(dwarf_expr_reg_to_entry_parameter): Update.
* elfread.c (elf_gnu_ifunc_record_cache): Update.
* eval.c (evaluate_funcall): Update.
(evaluate_subexp_standard): Update.
(evaluate_subexp_for_sizeof): Update.
* expprint.c (print_subexp_standard): Update.
(dump_subexp_body_standard): Update.
* frame.c (get_prev_frame_always_1): Update.
* frv-tdep.c (frv_skip_main_prologue): Update.
* gnu-v2-abi.c (gnuv2_value_rtti_type): Update.
* gnu-v3-abi.c (gnuv3_rtti_type): Update.
(gnuv3_get_typename_from_type_info): Update.
(gnuv3_skip_trampoline): Update.
* hppa-tdep.c (hppa_lookup_stub_minimal_symbol): Update.
* i386-tdep.c (i386_skip_main_prologue): Update.
(i386_pe_skip_trampoline_code): Update.
* ia64-tdep.c (ia64_convert_from_func_ptr_addr): Update.
* infcall.c (get_function_name): Update.
* linespec.c (minsym_found): Update.
* linux-fork.c (info_checkpoints_command): Update.
* m32c-tdep.c (m32c_m16c_address_to_pointer): Update.
(m32c_m16c_pointer_to_address): Update.
* maint.c (maintenance_translate_address): Update.
* minsyms.c (add_minsym_to_hash_table): Update.
(add_minsym_to_demangled_hash_table): Update.
(lookup_minimal_symbol_mangled): Update.
(lookup_minimal_symbol_demangled): Update.
(lookup_minimal_symbol_linkage): Update.
(lookup_minimal_symbol_text): Update.
(lookup_minimal_symbol_by_pc_name): Update.
(minimal_symbol_is_less_than): Update.
(compact_minimal_symbols): Update.
(build_minimal_symbol_hash_tables): Update.
(find_solib_trampoline_target): Update.
* mips-tdep.c (mips_stub_frame_sniffer): Update.
(mips_skip_pic_trampoline_code): Update.
* msp430-tdep.c (msp430_skip_trampoline_code): Update.
* objc-lang.c (info_selectors_command): Update.
(info_classes_command): Update.
(find_methods): Update.
(find_imps): Update.
* p-valprint.c (pascal_val_print): Update.
* ppc-linux-tdep.c (powerpc_linux_in_dynsym_resolve_code): Update.
* ppc-sysv-tdep.c (convert_code_addr_to_desc_addr): Update.
* printcmd.c (build_address_symbolic): Update.
(info_symbol_command): Update.
* psymtab.c (psymbol_name_matches): Update.
(match_partial_symbol): Update.
(lookup_partial_symbol): Update.
(print_partial_symbols): Update.
(sort_pst_symbols): Update.
(maintenance_check_psymtabs): Update.
* python/py-framefilter.c (py_print_frame): Update.
* python/python.c (gdbpy_rbreak): Update.
* record-btrace.c (btrace_get_bfun_name): Update.
(btrace_call_history): Update.
* rs6000-tdep.c (rs6000_skip_main_prologue): Update.
(rs6000_skip_trampoline_code): Update.
* sol-thread.c (info_cb): Update.
* stabsread.c (scan_file_globals): Update.
* stack.c (find_frame_funname): Update.
(info_frame_command_core): Update.
* symmisc.c (dump_msymbols): Update.
* symtab.c (symbol_natural_name): Rename to..,
(general_symbol_info::natural_name): ...this.
(symbol_demangled_name): Rename to...
(general_symbol_info::demangled_name): ...this.
(symbol_search_name): Rename to...
(general_symbol_info::search_name): ...this.
(symbol_matches_search_name): Update.
(find_pc_sect_line): Update.
(skip_prologue_sal): Update.
(search_symbols): Update.
(print_msymbol_info): Update.
(rbreak_command): Update.
(completion_list_add_msymbol): Update.
(completion_list_objc_symbol): Update.
(get_msymbol_address): Update.
* symtab.h (struct general_symbol_info): Add member functions
natural_name (), linkage_name (), print_name (), demangled_name (),
and search_name ().
(SYMBOL_NATURAL_NAME): Update.
(symbol_natural_name): Move to a member function on general_symbol_info.
(SYMBOL_DEMANGLED_NAME): Update.
(symbol_demangled_name): Move to a member function on
general_symbol_info.
(SYMBOL_SEARCH_NAME): Update.
(symbol_search_name): Move to a member function on general_symbol_info.
(MSYMBOL_NATURAL_NAME): Remove.
(MSYMBOL_LINKAGE_NAME): Remove.
(MSYMBOL_PRINT_NAME): Remove.
(MSYMBOL_DEMANGLED_NAME): Remove.
(MSYMBOL_SEARCH_NAME): Remove.
* x86-tdep.c (x86_in_indirect_branch_thunk): Update.
Change-Id: I65aa529843a9903e174ce799037e41f954a9fcee
|
|
Fix typos in comments. NFC.
Tested on x86_64-linux.
gdb/ChangeLog:
2019-10-18 Tom de Vries <tdevries@suse.de>
* aarch64-tdep.c: Fix typos in comments.
* ada-lang.c: Same.
* ada-tasks.c: Same.
* alpha-tdep.c: Same.
* alpha-tdep.h: Same.
* amd64-nat.c: Same.
* amd64-windows-tdep.c: Same.
* arc-tdep.c: Same.
* arc-tdep.h: Same.
* arch-utils.c: Same.
* arm-nbsd-tdep.c: Same.
* arm-tdep.c: Same.
* ax-gdb.c: Same.
* blockframe.c: Same.
* btrace.c: Same.
* c-varobj.c: Same.
* coff-pe-read.c: Same.
* coffread.c: Same.
* cris-tdep.c: Same.
* darwin-nat.c: Same.
* dbxread.c: Same.
* dcache.c: Same.
* disasm.c: Same.
* dtrace-probe.c: Same.
* dwarf-index-write.c: Same.
* dwarf2-frame-tailcall.c: Same.
* dwarf2-frame.c: Same.
* dwarf2read.c: Same.
* eval.c: Same.
* exceptions.c: Same.
* fbsd-tdep.c: Same.
* findvar.c: Same.
* frame.c: Same.
* frv-tdep.c: Same.
* gnu-v3-abi.c: Same.
* go32-nat.c: Same.
* h8300-tdep.c: Same.
* hppa-tdep.c: Same.
* i386-linux-tdep.c: Same.
* i386-tdep.c: Same.
* ia64-libunwind-tdep.c: Same.
* ia64-tdep.c: Same.
* infcmd.c: Same.
* infrun.c: Same.
* linespec.c: Same.
* linux-nat.c: Same.
* linux-thread-db.c: Same.
* machoread.c: Same.
* mdebugread.c: Same.
* mep-tdep.c: Same.
* mn10300-tdep.c: Same.
* namespace.c: Same.
* objfiles.c: Same.
* opencl-lang.c: Same.
* or1k-tdep.c: Same.
* osabi.c: Same.
* ppc-linux-nat.c: Same.
* ppc-linux-tdep.c: Same.
* ppc-sysv-tdep.c: Same.
* printcmd.c: Same.
* procfs.c: Same.
* record-btrace.c: Same.
* record-full.c: Same.
* remote-fileio.c: Same.
* remote.c: Same.
* rs6000-tdep.c: Same.
* s12z-tdep.c: Same.
* score-tdep.c: Same.
* ser-base.c: Same.
* ser-go32.c: Same.
* skip.c: Same.
* sol-thread.c: Same.
* solib-svr4.c: Same.
* solib.c: Same.
* source.c: Same.
* sparc-nat.c: Same.
* sparc-sol2-tdep.c: Same.
* sparc-tdep.c: Same.
* sparc64-tdep.c: Same.
* stabsread.c: Same.
* stack.c: Same.
* symfile.c: Same.
* symtab.c: Same.
* target-descriptions.c: Same.
* target-float.c: Same.
* thread.c: Same.
* utils.c: Same.
* valops.c: Same.
* valprint.c: Same.
* value.c: Same.
* varobj.c: Same.
* windows-nat.c: Same.
* xcoffread.c: Same.
* xstormy16-tdep.c: Same.
* xtensa-tdep.c: Same.
Change-Id: I5175f1b107bfa4e1cdd4a3361ccb4739e53c75c4
|
|
Armv8.3-a Pointer Authentication causes the function return address to be
obfuscated on entry to some functions. GDB must unmask the link register in
order to produce a backtrace.
The following patch adds markers of [PAC] to the bracktrace, to indicate
which addresses needed unmasking. This includes the backtrace when using MI.
For example, consider the following backtrace:
(gdb) bt
0 0x0000000000400490 in puts@plt ()
1 0x00000000004005dc in foo ("hello") at cbreak-lib.c:6
2 0x0000000000400604 [PAC] in bar () at cbreak-lib.c:12
3 0x0000000000400620 [PAC] in main2 () at cbreak.c:17
4 0x00000000004005b4 in main () at cbreak-3.c:10
The functions in cbreak-lib use pointer auth, which masks the return address
to the previous function, causing the addresses of bar (in the library) and main2
(in the main binary) to require unmasking in order to unwind the backtrace.
An extra bool is added alongside the prev_pc in the frame structure. At the
point at which the link register is unmasked, the AArch64 port calls into frame
to sets the bool. This is the most efficient way of doing it.
The marker is also added to the python frame printer, which is always printed if
set. The marker is not explicitly exposed to the python code.
I expect this will potentially cause issues with some tests in the testsuite
when Armv8.3 pointer authentication is used. This should be fixed up in the
the future once real hardware is available for full testsuite testing.
gdb/ChangeLog:
* NEWS: Expand the Pointer Authentication entry.
* aarch64-tdep.c (aarch64_frame_unmask_address): Rename from this.
(aarch64_frame_unmask_lr): ... to this.
(aarch64_prologue_prev_register, aarch64_dwarf2_prev_register):
Call aarch64_frame_unmask_lr.
* frame.c (struct frame_info): Add "masked" variable.
(frame_set_previous_pc_masked) (frame_get_pc_masked): New functions.
(fprint_frame): Check for masked pc.
* frame.h (frame_set_previous_pc_masked) (frame_get_pc_masked): New
declarations.
* python/py-framefilter.c (py_print_frame): Check for masked pc.
* stack.c (print_frame): Check for masked pc.
gdb/doc/ChangeLog:
* gdb.texinfo (AArch64 Pointer Authentication): New subsection.
|
|
With this patch, the help docs now respect 2 invariants:
* The first line of a command help is terminated by a '.' character.
* The last character of a command help is not a newline character.
Note that the changes for the last invariant were done by Tom, as part of :
[PATCH] Remove trailing newlines from help text
https://sourceware.org/ml/gdb-patches/2019-06/msg00050.html
but some occurrences have been re-introduced since then.
Some help docs had to be rephrased/restructured to respect the above
invariants.
Before this patch, print_doc_line was printing the first line
of a command help documentation, but stopping at the first '.'
or ',' character.
This was giving inconsistent results :
* The first line of command helps was sometimes '.' terminated,
sometimes not.
* The first line of command helps was not always designed to be
readable/understandable/unambiguous when stopping at the first
'.' or ',' character.
This e.g. created the following inconsistencies/problems:
< catch exception -- Catch Ada exceptions
< catch handlers -- Catch Ada exceptions
< catch syscall -- Catch system calls by their names
< down-silently -- Same as the `down' command
while the new help is:
> catch exception -- Catch Ada exceptions, when raised.
> catch handlers -- Catch Ada exceptions, when handled.
> catch syscall -- Catch system calls by their names, groups and/or numbers.
> down-silently -- Same as the `down' command, but does not print anything.
Also, the command help doc should not be terminated by a newline
character, but this was not respected by all commands.
The cli-option -OPT framework re-introduced some occurences.
So, the -OPT build help framework was changed to not output newlines at the
end of %OPTIONS% replacement.
This patch changes the help documentations to ensure the 2 invariants
given above.
It implied to slightly rephrase or restructure some help docs.
Based on the above invariants, print_doc_line (called by
'apropos' and 'help' commands to print the first line of a command
help) now outputs the full first line of a command help.
This all results in a lot of small changes in the produced help docs.
There are less code changes than changes in the help docs, as a lot
of docs are produced by some code (e.g. the remote packet usage settings).
gdb/ChangeLog
2019-08-07 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* cli/cli-decode.h (print_doc_line): Add for_value_prefix argument.
* cli/cli-decode.c (print_doc_line): Likewise. It now prints
the full first line, except when FOR_VALUE_PREFIX. In this case,
the trailing '.' is not output, and the first character is uppercased.
(print_help_for_command): Update call to print_doc_line.
(print_doc_of_command): Likewise.
* cli/cli-setshow.c (deprecated_show_value_hack): Likewise.
* cli/cli-option.c (append_indented_doc): Do not append newline.
(build_help_option): Append newline after first appended_indented_doc
only if a second call is done.
(build_help): Append 2 new lines before each option, except the first
one.
* compile/compile.c (_initialize_compile): Add new lines after
%OPTIONS%, when not at the end of the help.
Change help doc or code
producing the help doc to respect the invariants.
* maint-test-options.c (_initialize_maint_test_options): Likewise.
Also removed the new line after 'Options:', as all other commands
do not put an empty line between 'Options:' and the first option.
* printcmd.c (_initialize_printcmd): Likewise.
* stack.c (_initialize_stack): Likewise.
* interps.c (interpreter_exec_cmd): Fix "Usage:" line that was
incorrectly telling COMMAND is optional.
* ada-lang.c (_initialize_ada_language): Change help doc or code
producing the help doc to respect the invariants.
* ada-tasks.c (_initialize_ada_tasks): Likewise.
* breakpoint.c (_initialize_breakpoint): Likewise.
* cli/cli-cmds.c (_initialize_cli_cmds): Likewise.
* cli/cli-logging.c (_initialize_cli_logging): Likewise.
* cli/cli-setshow.c (_initialize_cli_setshow): Likewise.
* cli/cli-style.c (cli_style_option::add_setshow_commands,
_initialize_cli_style): Likewise.
* corelow.c (core_target_info): Likewise.
* dwarf-index-cache.c (_initialize_index_cache): Likewise.
* dwarf2read.c (_initialize_dwarf2_read): Likewise.
* filesystem.c (_initialize_filesystem): Likewise.
* frame.c (_initialize_frame): Likewise.
* gnu-nat.c (add_task_commands): Likewise.
* infcall.c (_initialize_infcall): Likewise.
* infcmd.c (_initialize_infcmd): Likewise.
* interps.c (_initialize_interpreter): Likewise.
* language.c (_initialize_language): Likewise.
* linux-fork.c (_initialize_linux_fork): Likewise.
* maint-test-settings.c (_initialize_maint_test_settings): Likewise.
* maint.c (_initialize_maint_cmds): Likewise.
* memattr.c (_initialize_mem): Likewise.
* printcmd.c (_initialize_printcmd): Likewise.
* python/lib/gdb/function/strfns.py (_MemEq, _StrLen, _StrEq,
_RegEx): Likewise.
* ravenscar-thread.c (_initialize_ravenscar): Likewise.
* record-btrace.c (_initialize_record_btrace): Likewise.
* record-full.c (_initialize_record_full): Likewise.
* record.c (_initialize_record): Likewise.
* regcache-dump.c (_initialize_regcache_dump): Likewise.
* regcache.c (_initialize_regcache): Likewise.
* remote.c (add_packet_config_cmd, init_remote_threadtests,
_initialize_remote): Likewise.
* ser-tcp.c (_initialize_ser_tcp): Likewise.
* serial.c (_initialize_serial): Likewise.
* skip.c (_initialize_step_skip): Likewise.
* source.c (_initialize_source): Likewise.
* stack.c (_initialize_stack): Likewise.
* symfile.c (_initialize_symfile): Likewise.
* symtab.c (_initialize_symtab): Likewise.
* target-descriptions.c (_initialize_target_descriptions): Likewise.
* top.c (init_main): Likewise.
* tracefile-tfile.c (tfile_target_info): Likewise.
* tracepoint.c (_initialize_tracepoint): Likewise.
* tui/tui-win.c (_initialize_tui_win): Likewise.
* utils.c (add_internal_problem_command): Likewise.
* valprint.c (value_print_option_defs): Likewise.
gdb/testsuite/ChangeLog
2019-08-07 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* gdb.base/style.exp: Update tests for help doc new invariants.
* gdb.base/help.exp: Likewise.
|