I noticed that iterating over the index yields non-const
cooked_index_entry objects. However, after finalization, they should
not be modified. This patch enforces this by adding const where
needed.
v2 makes the find, all_entries, and wait methods const as well.
Recent commit 1d98e564c97 ("[gdb/testsuite] Add
gdb.base/unwind-on-each-insn-{amd64,i386}.exp") broke commit eb015bf86b6
("[gdb/testsuite] Avoid using .eh_frame in gdb.base/unwind-on-each-insn.exp"),
in the sense that gdb.base/unwind-on-each-insn.exp no longer uses
-fno-asynchronous-unwind-tables, due to trying to concatenate two lists using:
...
lappend srcfile2_flags $nodebug_flags
...
which should instead be:
...
lappend srcfile2_flags {*}$nodebug_flags
...
Fix this by simplifying gdb.base/unwind-on-each-insn.exp.tcl, completely
leaving the responsibility to set srcfile_flags and srcfile2_flags to each
includer.
Tested on x86_64-linux.
Add some additional debug output that I've found really useful while
working on the previous set of patches.
Unless tui debug is turned on, then there should be no user visible
changes with this commit.
While working on the previous couple of patches I noticed that when I
scroll the src and asm windows vertically, I get two refresh_window
calls.
The two calls can be traced back to
tui_source_window_base::update_source_window_as_is, in here we call
show_source_content, which calls refresh_window, and then
update_exec_info, which also calls refresh_window.
In this commit I propose making the refresh_window call in
update_exec_info optional. In update_source_window_as_is I'll then
call update_exec_info before calling show_source_content, and pass a
flag to update_exec_info to defer the refresh.
There are places where update_exec_info is used without any subsequent
refresh_window call (e.g. when a breakpoint is updated), so
update_exec_info does not to call refresh_window in some cases, which
is why I'm using a flag to control the refresh.
With this changes I'm now only seeing a single refresh_window call for
each vertical scroll.
There should be no user visible changes after this commit.
While working on the previous patches I noticed that in some cases I
was seeing two calls to tui_source_window_base::refresh_window when
scrolling the window horizontally.
The two calls would trigger in for the tui-disasm-long-lines.exp test
when the pad needed to be refilled. The two called both come from
tui_source_window_base::show_source_content. The first call is nested
within check_and_display_highlight_if_needed, while the second call is
done directly at the end of show_source_content.
The check_and_display_highlight_if_needed is being used to draw the
window box to the window, this is needed here because
show_source_content is what gets called when the window needs
updating, e.g. after a resize. We could potentially do the boxing in
refresh_window, but then we'd be doing it each time we scroll, even
though the box doesn't need changing in this case.
However, we can move the check_and_display_highlight_if_needed to be
the last thing done in show_source_content, this means that we can
rely on the refresh_window call within it to be our single refresh
call.
There should be no user visible changes after this commit.
This commit addresses an issue that is exposed by the test script
gdb.tui/tui-disasm-long-lines.exp, that is, tui_source_window_base
does not handle very long lines.
The problem can be traced back to the newpad call in
tui_source_window_base::show_source_content, this is where we allocate
a backing pad to hold the window content.
Unfortunately, there appears to be a limit to the size of pad that can
be allocated, and the gdb.tui/tui-disasm-long-lines.exp test goes
beyond this limit. As a consequence the newpad call fails and returns
nullptr.
It just so happens that the reset of the tui_source_window_base code
can handle the pad being nullptr (this happens anyway when the window
is first created, so we already depend on nullptr handling), so all
that happens is the source window displays no content.
... well, sort of ... something weird does happen in the command
window, we seem to see a whole bunch of blank lines. I've not
bothered to track down exactly what's happening there, but it's some
consequence of GDB attempting to write content to a WINDOW* that is
nullptr.
Before explaining my solution, I'll outline how things currently work:
Consider we have the following window content to display:
aaaaaaaaaa
bbbbbbbbbbbbbbbbbbbb
ccccccccccccccc
the longest line here is 20 characters. If our display window is 10
characters wide, then we will create a pad that is 20 characters wide,
and then copy the lines of content into the pad:
.--------------------.
|aaaaaaaaaa |
|bbbbbbbbbbbbbbbbbbbb|
|ccccccccccccccc |
.--------------------.
Now we will copy a 10 character wide view into this pad to the
display, our display will then see:
.----------.
|aaaaaaaaaa|
|bbbbbbbbbb|
|cccccccccc|
.----------.
As the user scrolls left and right we adjust m_horizontal_offset and
use this to select which part of the pad is copied onto the display.
The benefit of this is that we only need to copy the content to the
pad once, which includes processing the ansi escape sequences, and
then the user can scroll left and right as much as they want
relatively cheaply.
The problem then, is that if the longest content line is very long,
then we try to allocate a very large pad, which can fail.
What I propose is that we allow both the pad and the display view to
scroll. Once we allow this, then it becomes possible to allocate a
pad that is smaller than the longest display line. We then copy part
of the content into the pad. As the user scrolls the view left and
right GDB will continue to copy content from the pad just as it does
right now. But, when the user scrolls to the edge of the pad, GDB
will copy a new block of content into the pad, and then update the
view as normal. This all works fine so long as the maximum pad size
is larger than the current window size - which seems a reasonable
restriction, if ncurses can't support a pad of a given size it seems
likely it will not support a display window of that size either.
If we return to our example above, but this time we assume that the
maximum pad size is 15 characters, then initially the pad would be
loaded like this:
.---------------.
|aaaaaaaaaa |
|bbbbbbbbbbbbbbb|
|ccccccccccccccc|
.---------------.
Notice that the last 5 characters from the 'b' line are no longer
included in the pad. There is still enough content though to fill the
10 character wide display, just as we did before.
The pad contents remain unchanged until the user scrolls the display
right to this point:
.----------.
|aaaaa |
|bbbbbbbbbb|
|cccccccccc|
.----------.
Now, when the user scrolls right once more GDB spots that the user has
reached the end of the pad, and the pad contents are reloaded, like
this:
.---------------.
|aaaaa |
|bbbbbbbbbbbbbbb|
|cccccccccc |
.---------------.
The display can now be updated from the pad again just like normal.
With this change in place the gdb.tui/tui-disasm-long-lines.exp test
now correctly loads the assembler code, and we can scroll around as
expected.
Most of the changes are pretty mundane, just updating to match the
above. One interesting change though is the new member function
tui_source_window_base::puts_to_pad_with_skip. This replaces direct
calls to tui_puts when copying content to the pad.
The content strings contain ansi escape sequences. When these strings
are written to the pad these escape sequences are translated into
ncurses attribute setting calls.
Now however, we sometimes only write a partial string to the pad,
skipping some of the leading content. Imagine then that we have a
content line like this:
"\033[31mABCDEFGHIJKLM\033[0m"
Now the escape sequences in this content mean that the actual
content (the 'ABCDEFGHIJKLM') will have a red foreground color.
If we want to copy this to the pad, but skip the first 3 characters,
then what we expect is to have the pad contain 'DEFGHIJKLM', but this
text should still have a red foreground color.
It is this problem that puts_to_pad_with_skip solves. This function
skips some number of printable characters, but processes all the
escape sequences. This means that when we do start printing the
actual content the content will have the expected attributes.
/
I noticed that tui_source_window_base::m_horizontal_offset was
protected, but could be made private, so lets do that.
This makes more sense in the context of a later commit where I plan to
add another member variable that is similar to m_horizontal_offset.
The new member variable could also be private.
So I had to choose, place the new member variable next to
m_horizontal_offset making it protected, but grouping similar
variables together, or make m_horizontal_offset private, and then add
the new variable as private too.
I chose to make m_horizontal_offset private, which is this commit.
There should be no user visible changes after this commit.
When an assert triggers in tui mode the output is not great, the
internal backtrace that is generated is printed directly to the file
descriptor for gdb_stderr, and, as a result, does not currently format
itself correctly - the output uses only '\n' at the end of each line,
and so, when the terminal is in raw mode, the cursor does not return
to the start of each line after the '\n'.
This is mostly fixable, we could update bt-utils.c to use '\r\n'
instead of just '\n', and this would fix most of the problems. The
one we can't easily fix is if/when GDB is built to use execinfo
instead of libbacktrace, in this case we use backtrace_symbols_fd to
print the symbols, and this function only uses '\n' as the line
terminator. Fixing this would require switching to backtrace_symbols,
but that API uses malloc, which is something we're trying to
avoid (this code is called when GDB hits an error, so ideally we don't
want to rely on malloc).
However, the execinfo code is only used when libbacktrace is not
available (or the user specifically disables libbacktrace) so maybe we
can ignore that problem...
... but there is another problem. When the backtrace is printed in
raw mode, it is possible that the backtrace fills the screen. With
the terminal in raw mode we don't have the ability to scroll back,
which means we loose some of the backtrace, which isn't ideal.
In this commit I propose that we should disable tui mode whenever we
handle a fatal signal, or when we hit the internal error code
path (e.g. when an assert triggers). With this done then we don't
need to update the bt-utils.c code, and the execinfo version of the
code (using backtrace_symbols_fd) works just fine. We also get the
ability to scroll back to view the error message and all of the
backtrace, assuming the users terminal supports scrolling back.
The only downside I see with this change is if the tui_disable call
itself causes an error for some reason, or, if we handle a single at a
time when it is not safe to call tui_disable, in these cases the extra
tui_disable call might cause GDB to loose the original error.
However, I think (just from personal experience) that the above two
issues are pretty rare and the benefits from this change far out
weighs the possible drawbacks.
This commit improves (I think) the errors from the tui focus command.
There are a number of errors that can be triggered by the focus
command, they include:
(1) Window name "NAME" is ambiguous
(2) Unrecognized window name "NAME"
(3) Window "NAME" cannot be focused
Error (1) is triggered when the user gives a partial window name, and
the name matches multiple windows in the current layout.
It is worth noting that the ambiguity must be within the current
layout; if the partial name matches one window in the current layout,
and one or more windows not in the current layout, then this is not
ambiguous, and focus will shift to the matching window in the current
layout.
This error was not previous being tested, but in this commit I make
use of the Python API to trigger and test this error.
Error (3) is simple enough, and was already being tested. This is
triggered by something like 'focus status'. The named window needs to
be present in the current layout, and non-focusable in order to
trigger the error.
Error (2) is what I'd like to improve in this commit. This error
triggers if the name the user gives doesn't match any window in the
current layout. Even if GDB does know about the window, but the
window isn't in the current layout, then GDB will say it doesn't
recognize the window name.
In this commit I propose to to split this error into three different
errors. These will be:
(a) Unrecognized window name "NAME"
(b) No windows matching "NAME" in the current layout
(c) Window "NAME" is not in the current layout
Error (a) is the same as before, but will now only trigger if GDB
doesn't know about window NAME at all. If the window is known, but
not in the current layout then one of the other errors will trigger.
Error (b) will trigger if NAME is ambiguous for multiple windows that
are not in the current layout. If NAME identifies a single window in
the current layout then that window will continue to be selected, just
as it currently is. Only in the case where NAME doesn't identify a
window in the current layout do we then check all the other known
windows, if NAME matches multiple of these, then (b) is triggered.
Finally, error (c) is used when NAME uniquely identifies a single
window that is not in the current layout.
The hope with these new errors is that the user will have a better
understanding of what went wrong. Instead of GDB claiming to not know
about a window, the mention of the current layout will hint to the
user that they should first switch layouts.
There are tests included for all the new errors.
In a following commit I managed to trigger the line feed scrolling
case in tuiterm.exp. This case is currently unhandled, and this
commit fills in this missing functionality.
The implementation is pretty simple, just scroll all the content up
one line at a time until the cursor is back on the screen (a single
line of scroll is all that should be needed).
This change is untested in this commit, but is required by the next
commit.
This changes a number of MI tests to use mi_clean_restart rather than
separate calls. This reduces the number of lines, which is nice, and
also provides a nicer model to copy for future tests.
A lot of the MI tests start gdb and only then build the executable.
This just seemed weird to me, so I've fixed this up. In this patch,
no other cleanups are done, the startup is just moved to a more
logical (to me) spot.
An early "return" in this test case prevents a test from running.
This seems to have been intentional and has been in place since:
commit d57cbee932f86df06251498daa93154046dc77c0
Author: Andrew Burgess <andrew.burgess@embecosm.com>
Date: Tue Dec 3 13:18:43 2019 +0000
gdb/testsuite/fortran: Fix info-modules/info-types for gfortran 8+
This patch removes the dead code.
clean_restart accepts a single optional argument. Rather than using
{args} and handling the argument by hand, change it to use Tcl's own
argument-checking.
Due to a GDB bug (visible when building with -D_GLIBCXX_DEBUG), GDB
crashes somewhere in the middle of gdb.cp/cpexprs.exp, and thus fails to
read the string, at gdb.cp/cpexprs.exp.tcl:725. The "correct" variable
doesn't get set, and I then see this TCL error:
ERROR: can't read "correct": no such variable
Avoid the TCL error by initializing the "correct" variable to a dummy
value.
Change-Id: I828968d9b2d105ef47f8da2ef598aa16a518c059
Prior to this patch, I get:
>>> {"seq": 17, "type": "request", "command": "disassemble", "arguments": {"memoryReference": "0x115d", "instructionCount": 1}}
Content-Length: 147
{"request_seq": 17, "type": "response", "command": "disassemble", "success": false, "message": "Cannot access memory at address 0x115d", "seq": 41}FAIL: gdb.dap/basic-dap.exp: disassemble one instruction success
FAIL: gdb.dap/basic-dap.exp: instructions in disassemble output
The problem is that the PC to disassemble is taken from the breakpoint
insertion response, which happens before running. With a PIE
executable, that PC is unrelocated, but the disassembly request happens
after relocation.
I chose to fix this by watching for a breakpoint changed event giving
the new breakpoint address, and recording the address from there. I
think this is an interesting way to fix it, because it adds a bit of
test coverage, I don't think these events are checked right now.
Other ways to fix it would be:
- Get the address by doing a breakpoint insertion after the program is
started, or some other way.
- Do the disassembly by symbol instead of by address.
- Do the disassembly before running the program.
Change-Id: I3c396f796ac4c8b22e7dfd2fa1c5467f7a47e84e
In the following patch, I change gdb.dap/basic-dap.exp such that after
waiting for some event, it checks if it received another event
meanwhile. To help with this, make dap_wait_for_event_and_check and
_dap_dap_wait_for_event return a list with everything received before
the event of interest. This is similar to what
dap_check_request_and_response returns.
Change-Id: I85c8980203a2dec833937e7552c2196bc137935d
I think that name describes a bit better what the proc does, it is
similar to "wait_for" in tuiterm.exp.
Change-Id: Ie55aa011e6595dd1b5a874db13881ba572ace419
The DAP helper functions generally return TON objects. However, callers
almost all immediately use ton::2dict to convert them to dicts, to
access their contents. This commits makes things a bit simpler for them
by having function return dicts directly instead.
The downside is that the TON objects contain type information. For
instance, a "2" in a TCL dict could have been the integer 2 or the
string "2" in JSON. By converting to TCL dicts, we lose that
information. If some tests specifically want to check the types of some
fields, I think we can add intermediary functions that return TON
objects, without having to complicate other callers who don't care.
Change-Id: I2ca47bea355bf459090bae8680c6a917350b5c3f
This catch didn't cause me any trouble, but for the same reason as the
preceding patch, I think it's a bit better to just let any exception
propagate, to make for easier debugging.
Change-Id: I1779e62c788b77fef2d50434edf4c3d2ec5e1c4c
Following some of my changes, dap_request_and_response was failing and I
didn't know why. I think it's better to make it not catch any
exception, and just make it do a simple "send request, read response".
If an exception is thrown while sending a request or reading a response,
things are going really badly, it's not like we'll want to recover from
that and continue the test.
Change-Id: I27568d3547f753c3a74e3e5a730d38a8caef9356
This helps following what happens when reading gdb.log. The downside is
that it becomes harder to tell what text is from GDB and what text is
going to GDB, but I think that seeing responses without seeing requests
is even more confusing. At least, the lines are prefix with >>>, so
when you see this, you know that until the end of the line, it's
something that was sent to GDB, and not GDB output.
Change-Id: I1ba1acd8b16f4e64686c5ad268cc41082951c874
Prefix some procs that are only used internally with an underscore, to
make it clear they are internal. If they need to be used by some test
later, we can always un-prefix them.
Change-Id: Iacb8e77363b5d1f8b98d9ba5a6d115aee5c8925d
The gcc 4.4.x (and earlier) compilers had the problem that the unwind info in
the epilogue was inaccurate.
In order to work around this in gdb, epilogue unwinders were added with a
higher priority than the dwarf unwinders in the amd64 and i386 targets:
- amd64_epilogue_frame_unwind, and
- i386_epilogue_frame_unwind.
Subsequently, the epilogue unwind info problem got fixed in gcc 4.5.0.
However, the epilogue unwinders prevented gdb from taking advantage of the
fixed epilogue unwind info, so the scope of the epilogue unwinders was
limited, bailing out for gcc >= 4.5.0.
There was no regression test added for this preference scheme, so if we now
declare epilogue unwind info from all gcc versions as trusted, no test will
start failing.
Fix this by adding an amd64 and i386 regression test for this.
I have no gcc 4.4.x lying around, so I fabricated the assembly files by:
- commenting out some .cfi directives to break the epilogue unwind info, and
- hand-editing the producer info to 4.4.7 to activate the fix.
Tested on x86_64-linux, target boards unix/{-m64,-m32}.