forked from Imagelibrary/binutils-gdb
1bf074fb6b5474f94e315d7047c0500535f0a2ef
472 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
425d5e76e0 |
Convert compunit_language to a method
This changes compunit_language to be a method on compunit_symtab. Approved-By: Simon Marchi <simon.marchi@efficios.com> |
||
|
|
9efe17a3a0 |
gdb: remove spurious spaces after frame_info_ptr
Fix some whitespace issues introduced with the frame_info_ptr patch. Change-Id: I158d30d8108c97564276c647fc98283ff7b12163 |
||
|
|
f34652de0b |
internal_error: remove need to pass __FILE__/__LINE__
Currently, every internal_error call must be passed __FILE__/__LINE__
explicitly, like:
internal_error (__FILE__, __LINE__, "foo %d", var);
The need to pass in explicit __FILE__/__LINE__ is there probably
because the function predates widespread and portable variadic macros
availability. We can use variadic macros nowadays, and in fact, we
already use them in several places, including the related
gdb_assert_not_reached.
So this patch renames the internal_error function to something else,
and then reimplements internal_error as a variadic macro that expands
__FILE__/__LINE__ itself.
The result is that we now should call internal_error like so:
internal_error ("foo %d", var);
Likewise for internal_warning.
The patch adjusts all calls sites. 99% of the adjustments were done
with a perl/sed script.
The non-mechanical changes are in gdbsupport/errors.h,
gdbsupport/gdb_assert.h, and gdb/gdbarch.py.
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Change-Id: Ia6f372c11550ca876829e8fd85048f4502bdcf06
|
||
|
|
bd2b40ac12 |
Change GDB to use frame_info_ptr
This changes GDB to use frame_info_ptr instead of frame_info *
The substitution was done with multiple sequential `sed` commands:
sed 's/^struct frame_info;/class frame_info_ptr;/'
sed 's/struct frame_info \*/frame_info_ptr /g' - which left some
issues in a few files, that were manually fixed.
sed 's/\<frame_info \*/frame_info_ptr /g'
sed 's/frame_info_ptr $/frame_info_ptr/g' - used to remove whitespace
problems.
The changed files were then manually checked and some 'sed' changes
undone, some constructors and some gets were added, according to what
made sense, and what Tromey originally did
Co-Authored-By: Bruno Larsen <blarsen@redhat.com>
Approved-by: Tom Tomey <tom@tromey.com>
|
||
|
|
ba380b3e51 |
Introduce frame_info_ptr smart pointer class
This adds frame_info_ptr, a smart pointer class. Every instance of the class is kept on an intrusive list. When reinit_frame_cache is called, the list is traversed and all the pointers are invalidated. This should help catch the typical GDB bug of keeping a frame_info pointer alive where a frame ID was needed instead. Co-Authored-By: Bruno Larsen <blarsen@redhat.com> Approved-by: Tom Tomey <tom@tromey.com> |
||
|
|
a0cbd6505e |
Remove frame_id_eq
This replaces frame_id_eq with operator== and operator!=. I wrote this for a version of this series that I later abandoned; but since it simplifies the code, I left this patch in. Approved-by: Tom Tomey <tom@tromey.com> |
||
|
|
df86565b31 |
gdb: remove TYPE_LENGTH
Remove the macro, replace all uses with calls to type::length. Change-Id: Ib9bdc954576860b21190886534c99103d6a47afb |
||
|
|
7017529261 |
gdb: new 'maint print frame-id' command
When debugging a certain class of GDB bug, I often end up wanting to know what GDB thinks the frame-id is in a particular frame. It's not too hard to pull this from some debug output, but I thought it might be nice if there was a maintenance command that could tell us. This commit adds 'maint print frame-id' which prints the frame-id of the currently selected frame. You can also pass a frame level number to find the frame-id for a specific frame. There's a new test too. |
||
|
|
4b8791e10e |
gdb: remove BLOCK_{START,END} macros
Replace with equivalent methods. Change-Id: I10a6c8a2a86462d9d4a6a6409a3f07a6bea66310 |
||
|
|
4206d69e96 |
Replace symbol_symtab with symbol::symtab
This turns symbol_symtab into a method on symbol. It also replaces symbol_set_symtab with a method. |
||
|
|
4aeddc50d7 |
gdb: remove symbol value macros
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
|
||
|
|
6cb06a8cda |
Unify gdb printf functions
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. |
||
|
|
5d0027b9ba |
gdb: remove SYMBOL_LINE macro
Add a getter and a setter for a symbol's line. Remove the corresponding macro and adjust all callers. Change-Id: I229f2b8fcf938c07975f641361313a8761fad9a5 |
||
|
|
bf31fd38f0 |
Move gdb obstack code to gdbsupport
This moves the gdb-specific obstack code -- both extensions like obconcat and obstack_strdup, and things like auto_obstack -- to gdbsupport. |
||
|
|
4a94e36819 |
Automatic Copyright Year update after running gdb/copyright.py
This commit brings all the changes made by running gdb/copyright.py as per GDB's Start of New Year Procedure. For the avoidance of doubt, all changes in this commits were performed by the script. |
||
|
|
46680d22de |
gdb: trivial changes to use array_view
Change a few relatively obvious spots using value contents to propagate the use array_view a bit more. Change-Id: I5338a60986f06d5969fec803d04f8423c9288a15 |
||
|
|
2a50938ab7 |
gdb: make extract_integer take an array_view
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 |
||
|
|
f54bdb6d27 |
gdb: add add_setshow_prefix_cmd
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 |
||
|
|
50888e42dc |
gdb: change functions returning value contents to use gdb::array_view
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 |
||
|
|
275ee935b3 |
gdb: prevent an assertion when computing the frame_id for an inline frame
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 |
||
|
|
611841bb1a |
gdb: make thread_info::executing private
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. |
||
|
|
8085fa01a5 |
gdb: Use unwinder name in frame_info::to_string
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
|
||
|
|
ca89bdf8b2 |
gdb: remove VALUE_FRAME_ID and fix another frame debug issue
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
|
||
|
|
fe67a58f98 |
gdb: introduce FRAME_SCOPED_DEBUG_ENTER_EXIT
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
|
||
|
|
a05a883fba |
gdb: introduce frame_debug_printf
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 |
||
|
|
dd4f75f2b6 |
gdb: make frame_debug a boolean
gdb/ChangeLog: * frame.h (frame_debug): Change type to bool. * frame.c (frame_debug): Change type to bool. (_initialize_frame): Adjust. Change-Id: I27b5359a25ad53ac42618b5708a025c348a1eeda |
||
|
|
2f822da535 |
gdb: generate the prefix name for prefix commands on demand
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
|
||
|
|
927c4e355e |
gdb: replace fprint_frame_id
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. |
||
|
|
c90e7d6352 |
gdbsupport, gdb: give names to observers
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 |
||
|
|
328d42d87e |
gdb: remove current_top_target function
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 |
||
|
|
bdec2917b1 |
Convert some frame functions to use gdb::array_view.
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. |
||
|
|
3666a04883 |
Update copyright year range in all GDB files
This commits the result of running gdb/copyright.py as per our Start
of New Year procedure...
gdb/ChangeLog
Update copyright year range in copyright header of all GDB files.
|
||
|
|
e512699ac8 |
Remove trailing white spaces in gdb/frame.{c,h}
gdb/ChangeLog: * frame.c: Remove trailing white spaces. * frame.h: Likewise. |
||
|
|
2b3cb4006a |
Fix frame cycle detection
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 |
||
|
|
dda83cd783 |
gdb, gdbserver, gdbsupport: fix leading space vs tabs issues
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 |
||
|
|
d70bdd3cc4 |
Move lookup_selected_frame to frame.c
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 |
||
|
|
79952e6963 |
Make scoped_restore_current_thread's cdtors exception free (RFC)
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
|
||
|
|
a42d7dd873 |
Remove symfile_objfile macro
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. |
||
|
|
267037210c |
gdb/frame: remove an unused type alias
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. |
||
|
|
9370fd51eb |
gdb: detect main function even when there's no matching msymbol
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. |
||
|
|
9dccd06e8a |
Remove target_has_registers macro
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. |
||
|
|
841de12014 |
Remove target_has_stack macro
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. |
||
|
|
a739972c7c |
Remove target_has_memory macro
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. |
||
|
|
f3bd50f198 |
gdb: fix nits in previous patches
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 |
||
|
|
84154d166a |
gdb: introduce explicit outer frame id kind
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 |
||
|
|
8efaf6b352 |
gdb: make frame_unwind_got_optimized return a not_lval value
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.
|
||
|
|
d19c3068ab |
gdb: assert that we don't try to get a frame's id while it is computed
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
|
||
|
|
97916bfedf |
gdb: use bool in frame code
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 |
||
|
|
fedfee8850 |
gdb: change frame_info::prev_func::p type to cached_copy_status
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 |
||
|
|
e7bc9db8f4 |
Don't touch frame_info objects if frame cache was reinitialized
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. |