Andrew Burgess [Wed, 5 Feb 2025 20:12:03 +0000 (20:12 +0000)]
gdb/tui: use wrefresh if output is not surpressed
Recent work in the TUI has improved GDB's use of the curses
wnoutrefresh and doupdate mechanism, which improves performance by
batching together updates and then doing a single set of writes to the
screen when doupdate is finally called.
The tui_batch_rendering type is a RAII class which, in its destructor,
calls doupdate to send the batched updates to the screen.
However, if there is no tui_batch_rendering active on the call stack
then any wnoutrefresh calls will remain batched but undisplayed until
the next time doupdate happens to be called.
This problem can be seen in PR gdb/32623. When an inferior is started
the 'Starting program' message is not immediately displayed to the
user.
The 'Starting program' message originates from run_command_1 in
infcmd.c, the message is sent to the current_uiout, which will be the
TUI ui_out. After the message is sent, ui_out::flush() is called,
here's the backtrace when that happens:
#0 tui_file::flush (this=0x36e4ab0) at ../../src/gdb/tui/tui-file.c:42
#1 0x0000000001004f4b in pager_file::flush (this=0x36d35f0) at ../../src/gdb/utils.c:1531
#2 0x0000000001004f71 in gdb_flush (stream=0x36d35f0) at ../../src/gdb/utils.c:1539
#3 0x00000000006975ab in cli_ui_out::do_flush (this=0x35a50b0) at ../../src/gdb/cli-out.c:250
#4 0x00000000009fd1f9 in ui_out::flush (this=0x35a50b0) at ../../src/gdb/ui-out.h:263
#5 0x00000000009f56ad in run_command_1 (args=0x0, from_tty=1, run_how=RUN_NORMAL) at ../../src/gdb/infcmd.c:449
#6 0x00000000009f599a in run_command (args=0x0, from_tty=1) at ../../src/gdb/infcmd.c:511
And if we check out tui_file::flush (tui-file.c) we can see that this
just calls tui_win_info::refresh_window(), which in turn, just uses
wnoutrefresh to batch any pending output.
The problem is that, in the above backtrace, there is no
tui_batch_rendering active, and so there will be no doupdate call to
flush the output to the screen.
We could add a tui_batch_rendering into tui_file::flush. And
tui_file::write. And tui_file::puts .....
... but that all seems a bit unnecessary. Instead, I propose that
tui_win_info::refresh_window() should be changed. If suppress_output
is true (i.e. a tui_batch_rendering is active) then we should continue
to call wnoutrefresh(). But if suppress_output is false, meaning that
no tui_batch_rendering is in place, then we should call wrefresh(),
which immediately writes the output to the screen.
Testing but PR gdb/32623 was a little involved. We need to 'run' the
inferior and check for the 'Starting program' message. But DejaGNUU
can only check for the message once it knows the message should have
appeared. But, as the bug is that output is not displayed, we don't
have any output hints that the inferior is started yet...
In the end, I have the inferior create a file in the test's output
directory. Now DejaGNU can send the 'run' command, and wait for the
file to appear. Once that happens, we know that the 'Starting
program' message should have appeared.
Tom de Vries [Fri, 7 Feb 2025 16:06:30 +0000 (17:06 +0100)]
[gdb/corefiles] Fix segfault in core_target_open
On x86_64-freebsd, with test-case gdb.arch/i386-biarch-core.exp I run into a
segfault here in corelow.c:core_target_open:
...
{
gdb::unique_xmalloc_ptr<char> failing_command = make_unique_xstrdup
(bfd_core_file_failing_command (current_program_space->core_bfd ()));
if (failing_command != nullptr)
gdb_printf (_("Core was generated by `%s'.\n"),
failing_command.get ());
}
...
where bfd_core_file_failing_command returns nullptr, so the segfault happens
somewhere during "strdup (nullptr)".
There doesn't seem to be a need to make a copy of the string, so fix this by
dropping the make_unique_xstrdup.
Tested on x86_64-linux.
Tested the test-case on x86_64-freebsd.
Approved-By: Tom Tromey <tom@tromey.com>
PR corefiles/32634
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32634
Simon Marchi [Wed, 29 Jan 2025 15:45:31 +0000 (10:45 -0500)]
gdb: include cli/cli-style.h in darwin-nat.c
PR 32610 says:
File gdb/darwin-nat.c is missing an #include statement of
"cli/cli-style.h". It is needed because there is a reference to class
object command_style in the .c file.
I'm not able to build-test this change (I only have access to arm64
macos machines, which GDB doesn't support yet), but I don't think I'm
doing things worse by adding this.
Tom de Vries [Wed, 29 Jan 2025 08:02:21 +0000 (09:02 +0100)]
[gdb/tui] Fix assert in tui_source_window_base::refresh_window
Say we use the executable of test-case gdb.tui/tui-missing-src.exp like this:
...
$ gdb.sh -q -tui outputs/gdb.tui/tui-missing-src/tui-missing-src \
-ex "b f2"\
-ex run
...
(from a directory not containing a file called main.c to make sure that the
missing source stays missing) and then issue finish:
...
(gdb) finish
Run till exit from #0 f2 (x=4)
at f2.c:5
0x0000000000400570 in main ()
at main.c:7
Value returned is $1 = 13
(gdb)
...
and use control-<minus> to decrease the font size (IOW increase the $LINES and
$COLUMNS) on the terminal, we get:
...
gdb/tui/tui-winsource.c:340: internal-error: refresh_window: \
Assertion `pad_x + view_width <= pad_width || m_pad.get () == nullptr' failed.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
...
The tui_source_window_base class has variable m_pad which keeps track of a
curses pad that is used to display the source code or disassembly efficiently.
The assert in tui_source_window_base::refresh_window triggers while preparing
to display part of the pad.
The problem is that the window is in a state in which the pad is not used,
because m_content.empty () == true. Instead, it simply shows
"[ No Source Available ]".
Fix this by bailing out of tui_source_window_base::refresh_window before
accessing the m_pad variable, if m_content.empty () == true.
Tested on x86_64-linux.
Approved-By: Tom Tromey <tom@tromey.com>
PR tui/32592
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32592
highlighted the following issue with GDB's 'x' packet implementation.
Unfortunately, LLDB also has an 'x' packet, but their implementation
is different to GDB's and so targets that have implemented LLDB's 'x'
packet are incompatible with GDB.
The above thread is specifically about the 'rr' tool, but there could
be other remote targets out there that have this problem.
The difference between LLDB and GDB is that GDB expects a 'b' prefix
on the reply data, while LLDB does not. The 'b' is important as it
allows GDB to distinguish between an empty reply (which will be a 'b'
prefix with no trailing data) and an unsupported packet (which will be
a completely empty packet). It is not clear to me how LLDB
distinguishes these two cases.
I propose that we add a new feature 'binary-upload' which can be
reported by a stub in its qSupported reply. By default this feature
is "off", meaning GDB will not use the 'x' packet unless a stub
advertises this feature.
I have updated gdbserver to send 'binary-upload+', and when I examine
the gdbserver log I can see this feature being sent back, and then GDB
will use the 'x' packet.
When connecting to an older gdbserver, the feature is not sent, and
GDB does not try to use the 'x' packet at all.
I also built the latest version of `rr` and tested using current HEAD
of master, where I see problems like this:
(rr) x/10i main
0x401106 <main>: Cannot access memory at address 0x401106
Then tested using this patched version of GDB, and now I see:
There is still a problem building the bfd docs from a release tar
file.
As the release tar file contains the pre-generated .texi files we
expect the bfd/doc build stage to symlink to the pre-existing .texi
files in the source tree.
However, this is still not working as expected if $(srcdir) is
relative. The problem is this line in REGEN_TEXI:
test -e $$texi || test ! -f $(srcdir)/$$texi || $(LN_S) $(srcdir)/$$texi $$texi; \
This is executed from the build/bfd/ directory, so if $(srcdir) is
relative, then this will get you from the bfd/ directory in the build
tree to the corresponding bfd/ directory in the src tree. However,
the symlink is created in the bfd/doc/ build directory. The relative
path will then fail to take you to the bfd/ directory in the src
tree.
Fix this by using $(abs_srcdir) when creating the symlink.
gdb: add gdbarch method to get execution context from core file
The above commit improves GDB's ability to display inferior arguments
when opening a core file, however, if an argument includes white
space, then this is not displayed as well as it should be. For
example:
(gdb) core-file /tmp/corefile-exec-context.2.core
[New LWP 4069711]
Reading symbols from /tmp/corefile-exec-context...
Core was generated by `/tmp/corefile-exec-context aaaaa bbbbb ccccc ddddd e e e e e'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
50 return ret;
(gdb) show args
Argument list to give program being debugged when it is started is "aaaaa bbbbb ccccc ddddd e\ e\ e\ e\ e".
(gdb)
Notice the 'Core was generated by ...' line. In this case it is not
clear if the "e e e e e" is a single argument containing white space,
or 5 single arguments.
But when we 'show args' it is immediately clear that this is a single
argument, as the white space is now escaped.
This problem was caused by the above commit building the argument
string itself, and failing to consider white space escaping.
This commit changes things around, first we place the arguments into
the inferior, then, to print the 'Core was generated by ...' line, we
ask the inferior for the argument string. In this way the quoting is
handled just as it is for 'show args'. The initial output is now:
(gdb) core-file /tmp/corefile-exec-context.2.core
[New LWP 4069711]
Reading symbols from /tmp/corefile-exec-context...
Core was generated by `/tmp/corefile-exec-context aaaaa bbbbb ccccc ddddd e\ e\ e\ e\ e'.
Program terminated with signal SIGABRT, Aborted.
#0 0x00007f4f007af625 in raise () from /lib64/libc.so.6
(gdb)
Much better. The existing test is extended to cover this case.
Reviewed-By: Guinevere Larsen <guinevere@redhat.com> Approved-By: Tom Tromey <tom@tromey.com>
Commit 3470a0e144df6c01f8479fa649f43aa907936e7e inadvertently broke
the build on MIPS because it's passing a non-existent "pid" argument
to "proc->for_each_thread". This commit fixes the problem by removing
the argument from the call.
Signed-off-by: Sergio Durigan Junior <sergiodj@sergiodj.net> Approved-By: Simon Marchi <simon.marchi@efficios.com>
In that commit, linetables were made independent from the objfile, which
requires objfile->section_offsets to be initialized. However, section_offsets
were never initialized in objfiles generated by GDB's JIT Interface
with custom jit-readers, leading to GDB crashes when stepping into JITed code
blocks with the following command already executed:
jit-reader-load libmygdbjitreader.so
This patch fixes the issue by initializing the minimum section_offsets required
for linetable parsing procedures.
A minimal test is included. The test sets up some very simple line
table information, which is enough to trigger the bug. However, the
line table information is crafted such that none of the line table
entries will end up being displayed in GDB's output when the test is
run, as such, none of the expected output actually changes.
It might be nice in the future to extend some of the jit tests to
actually test hitting line table entries added via the jit reader.
Tom Tromey [Mon, 6 Jan 2025 14:45:33 +0000 (07:45 -0700)]
Handle case where DAP line can be None
A comment in bugzilla pointed out a bug in my earlier patch to handle
the DAP "linesStartAt1" setting. In particular, in the backtrace
code, "line" can be None, which would lead to an exception from
export_line.
Tom Tromey [Mon, 6 Jan 2025 20:34:47 +0000 (13:34 -0700)]
Fix crash in DWARF indexer
Iain pointed out a crash in the DWARF indexer when run on a certain D
program. The DWARF in this case has a nameless enum class; this
causes an assertion failure.
This patch arranges to simply ignore such types. The fact that an
enum class is nameless in this case appears to be a compiler bug.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=32518 Approved-By: Tom de Vries <tdevries@suse.de>
(cherry picked from commit 66903f1d66a2648e82250a427a791286e4ed4735)
Rainer Orth [Mon, 6 Jan 2025 15:24:14 +0000 (16:24 +0100)]
Fix procfs.c compilation
procfs.c compilation is currently broken on Solaris:
/vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/procfs.c: In member function ‘virtual ptid_t procfs_target::wait(ptid_t, target_waitstatus*, target_wait_flags)’:
/vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/procfs.c:2067:34: error: ‘wait’ is not a member of ‘gdb’; did you mean ‘wait’?
2067 | wait_retval = gdb::wait (&wstat);
| ^~~~
In file included from ../gnulib/import/sys/wait.h:28,
from /usr/include/stdlib.h:16,
from /usr/gcc/14/include/c++/14.2.0/cstdlib:79,
from /vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/../gdbsupport/common-defs.h:99,
from /vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/defs.h:26,
from <command-line>:
/usr/include/sys/wait.h:85:14: note: ‘wait’ declared here
85 | extern pid_t wait(int *);
| ^~~~
/vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/procfs.c:2154:41: error: ‘wait’ is not a member of ‘gdb’; did you mean ‘wait’?
2154 | int temp = gdb::wait (&wstat);
| ^~~~
/usr/include/sys/wait.h:85:14: note: ‘wait’ declared here
85 | extern pid_t wait(int *);
| ^~~~
/vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/procfs.c: In function ‘void unconditionally_kill_inferior(procinfo*)’:
/vol/src/gnu/gdb/hg/gdb-16-branch/git/gdb/procfs.c:2566:12: error: ‘wait’ is not a member of ‘gdb’; did you mean ‘wait’?
2566 | gdb::wait (NULL);
| ^~~~
/usr/include/sys/wait.h:85:14: note: ‘wait’ declared here
85 | extern pid_t wait(int *);
| ^~~~
Tom de Vries [Mon, 6 Jan 2025 09:04:22 +0000 (10:04 +0100)]
[gdb/build] Use const_cast in fd_copy
Recent commit 6ab5d62ebc5 ("[gdb] Fix compilation error in event-top.c") did:
...
fd_copy (fd_set *dst, const fd_set *src, int n)
{
FD_ZERO (dst);
for (int i = 0; i < n; ++i)
- if (FD_ISSET (i, src))
+ if (FD_ISSET (i, (fd_set *)src))
...
but according to [1] only const_cast may be used to cast away constness.
Running selftest help_doc_invariants.
help doc broken invariant: command 'signal-event' help doc has over-long line
Self test failed: self-test failed at unittests/command-def-selftests.c:121
The reason is that doc string of 'signal-event' doesn't have
newlines at end of its line. Fix by adding newlines.
Alan Modra [Wed, 1 Jan 2025 12:01:50 +0000 (22:31 +1030)]
PR 32507, PRIx64 in error messages on 32-bit mingw
People, including me, had forgotten that the bfd_error_handler just
handled standard printf format strings, not MSC %I64 and suchlike.
Using PRIx64 and similar in errors does not work if the host compiler
headers define those formats as the Microsoft %I64 variety. (We
handled %ll OK, editing it to %I64 on such hosts.)
PR 32507
* bfd.c (_bfd_doprnt, _bfd_doprnt_scan): Handle %I64 and %I32
in input strings if the host defines PRId64 as "I64d".
Edit %ll to %I64 on detecting PRId64 as "I64d" rather than on
a preprocessor define.
Jan Beulich [Fri, 27 Dec 2024 10:37:05 +0000 (11:37 +0100)]
ld/testsuite: replace aarch64 uses of load_lib
Using $srcdir/$subdir directly doesn't work, at least not with expect
5.45, dejagnu 1.6, and an out-of-tree build (I assume it's the latter
aspect which is crucial here). Make use of load_file instead.
Xi Ruoyao [Wed, 25 Dec 2024 04:41:45 +0000 (12:41 +0800)]
LoongArch: Reword message for unresolvable relocs
For PDE, "recompiling with -fPIE" just makes no sense.
For PIE, "recompiling with -fPIE" makes sense for unresolvable absolute
relocs, but not unresolveable PC-relative relocs: if the reloc is
already PC-relative, the problem is not the reloc is PC-relative or
absolute, but the reloc is not applicable for external symbols.
If we hit an unresolvable reloc in PDE or an unresolvable PC-relative
reloc in PIE, it means the programmer has somehow wrongly instructed the
compiler to treat external symbols as local symbols. A misuse of
-mdirect-extern-access can cause the issue, so we can suggest
-mno-direct-extern-access. And in all cases (DSO/PIE/PDE) a mismatching
symbol visibility can also cause the issue, so we should also suggest to
check the visibility.
Xi Ruoyao [Wed, 25 Dec 2024 04:41:44 +0000 (12:41 +0800)]
LoongArch: Allow R_LARCH_PCALA_HI20 or R_LARCH_PCREL20_S2 against undefined weak symbols for static PIE
In a static PIE, undefined weak symbols should be just resolved to
runtime address 0, like those symbols with non-default visibility. This
was silently broken in all prior Binutils releases with "-static-pie
-mdirect-extern-access":
$ cat t.c
int x (void) __attribute__ ((weak));
int
main (void)
{
__builtin_printf("%p\n", x);
}
$ gcc t.c -static-pie -mdirect-extern-access
$ ./a.out
0x7ffff1d64000
Since commit 4cb77761d687 ("LoongArch: Check PC-relative relocations for
shared libraries), the situation has been improved: the linker errors
out instead of silently producing a wrong output file.
But logically, using -mdirect-extern-access for a static PIE perfectly
makes sense, and we should not prevent that even if the programmer uses
weak symbols. Linux kernel is such an example, and Linux < 6.10 now
fails to build with Binutils trunk. (The silent breakage with prior
Binutils releases was "benign" due to some blind luck.)
While since the 6.10 release Linux has removed those potentially
undefined weak symbols (due to performance issue), we still should
support weak symbols in -mdirect-extern-access -static-pie and unbreak
building old kernels.
Xi Ruoyao [Wed, 25 Dec 2024 04:41:43 +0000 (12:41 +0800)]
LoongArch: Fix resolution of undefined weak hidden/protected symbols
An undefined weak hidden/protect symbol should be resolved to runtime
address 0, but we were actually resolving it to link-time address 0. So
in PIE or DSO the runtime address would be incorrect.
Fix the issue by rewriting pcalau12i to lu12i.w, and pcaddi to addi.w.
The latter does not always work because the immediate field of addi.w is
narrower, report an error in the case the addend is too large.
Alan Modra [Wed, 25 Dec 2024 08:47:24 +0000 (19:17 +1030)]
buffer overflow in gas/app.c
This testcase:
.irp x x x "
.end #
.endr
manages to access lex[EOF].
xxx: Warning: end of file in string; '"' inserted
xxx:1: Warning: missing closing `"'
gas/app.c:844:16: runtime error: index -1 out of bounds for type 'char [256]
Following that there is a buffer overflow.
Stop this happening, and in other similar places, by checking for EOF.