This adds emit_style_escape and reset_style methods to ui_file. These
aren't used yet, but they will be once the pager is converted to be a
ui_file subclass.
When the pager is rewritten as a ui_file, gdb will still need a way to
bypass the filtering. After examining a few approaches, I chose this
patch, which adds a puts_unfiltered method to ui_file. For most
implementations of ui_file, this will just delegate to puts. This
patch also switches printf_unfiltered to use the new method.
At the end of this series, the use of unfiltered output will be very
restricted -- only places that definitely need it will use it. To
this end, I thought it would be good to reduce the number of
_unfiltered APIs that are exposed. This patch changes gdb so that
only printf_unfiltered exists. (After this patch, the f* variants
still exist as well, but those will be removed later.)
A number of spots call printf_unfiltered only because they are in code
that should not be interrupted by the pager. However, I believe these
cases are all handled by infrun's blanket ban on paging, and so can be
converted to the default (_filtered) API.
After this patch, I think all the remaining _unfiltered calls are ones
that really ought to be. A few -- namely in complete_command -- could
be replaced by a scoped assignment to pagination_enabled, but for the
remainder, the code seems simple enough like this.
It seems to me that annotations should not be filtered. While it
might be weird for an annotation-based UI to use the pager, it's not,
I think, out of the question. This patch makes this change.
When parsing the ptid out of a reply package, if the multi-process
extensions are not supported, use current_inferior's pid as the pid of
the reported thread, instead of inferior_ptid. This is needed because
the inferior_ptid may be null_ptid although a legit context exists,
due to a prior context switch via switch_to_inferior_no_thread.
Below is a scenario that illustrates what could go wrong. First,
setup a multi-target scenario. This is needed, because in a
multi-target setting, the inferior_ptid is cleared out before waiting
on targets. The second inferior below sits on top of a remote target.
Multi-process packets are disabled.
$ # First, spawn a process with PID 26253 to attach to later.
$ gdb-up a.out
Reading symbols from a.out...
(gdb) maint set target-non-stop on
(gdb) set remote multiprocess-feature-packet off
(gdb) start
...
(gdb) add-inferior -no-connection
[New inferior 2]
Added inferior 2
(gdb) inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
(gdb) target extended-remote | gdbserver --multi -
Remote debugging using | gdbserver --multi -
Remote debugging using stdio
(gdb) attach 26253
Attaching to Remote target
Attached; pid = 26253
[New Thread 26253]
[New inferior 3]
Reading /tmp/a.out from remote target...
...
[New Thread 26253]
...
Reading /usr/local/lib/debug/....debug from remote target...
>>> GDB seems to hang here.
After attaching to a process and reading some library files, GDB
seems to hang. One interesting thing to note is that
[New Thread 26253]
appears twice. We also see
[New inferior 3]
Running the same scenario with "debug infrun on" reveals more details.
...
(gdb) attach 26253
[infrun] scoped_disable_commit_resumed: reason=attaching
Attaching to Remote target
Attached; pid = 26253
[New Thread 26253]
[infrun] infrun_async: enable=1
[infrun] attach_command: immediately after attach:
[infrun] attach_command: thread 26253.26253.0, executing = 1, resumed = 0, state = RUNNING
[infrun] clear_proceed_status_thread: 26253.26253.0
[infrun] reset: reason=attaching
[infrun] maybe_set_commit_resumed_all_targets: not requesting commit-resumed for target native, no resumed threads
[infrun] maybe_set_commit_resumed_all_targets: enabling commit-resumed for target extended-remote
[infrun] fetch_inferior_event: enter
[infrun] scoped_disable_commit_resumed: reason=handling event
[infrun] do_target_wait: Found 2 inferiors, starting at #1
[infrun] random_pending_event_thread: None found.
[infrun] print_target_wait_results: target_wait (-1.0.0 [Thread 0], status) =
[infrun] print_target_wait_results: 26253.26253.0 [Thread 26253],
[infrun] print_target_wait_results: status->kind = STOPPED, sig = GDB_SIGNAL_0
[infrun] handle_inferior_event: status->kind = STOPPED, sig = GDB_SIGNAL_0
[infrun] start_step_over: enter
[infrun] start_step_over: stealing global queue of threads to step, length = 0
[infrun] operator(): step-over queue now empty
[infrun] start_step_over: exit
[infrun] context_switch: Switching context from 0.0.0 to 26253.26253.0
[infrun] handle_signal_stop: stop_pc=0x7f849d8cf151
[infrun] stop_waiting: stop_waiting
[infrun] stop_all_threads: starting
[infrun] stop_all_threads: pass=0, iterations=0
[New inferior 3]
Reading /tmp/a.out from remote target...
warning: File transfers from remote targets can be slow. Use "set sysroot" to access files locally instead.
Reading /tmp/a.out from remote target...
Reading symbols from target:/tmp/a.out...
[New Thread 26253]
[infrun] stop_all_threads: 4723.4723.0 not executing
[infrun] stop_all_threads: 26253.26253.0 not executing
[infrun] stop_all_threads: 42000.26253.0 executing, need stop
[infrun] print_target_wait_results: target_wait (-1.0.0 [Thread 0], status) =
[infrun] print_target_wait_results: -1.0.0 [Thread 0],
[infrun] print_target_wait_results: status->kind = IGNORE
[infrun] print_target_wait_results: target_wait (-1.0.0 [Thread 0], status) =
[infrun] print_target_wait_results: -1.0.0 [Thread 0],
[infrun] print_target_wait_results: status->kind = IGNORE
GDB tried to stop Thread 42000.26253.0, which does not exist, and we
are waiting for a stop event that will never happen. The PID in
'42000.26253.0', namely 42000, is the PID of magic_null_ptid.
It comes from gdb/remote.c:read_ptid:
/* Since the stub is not sending a process id, then default to
what's in inferior_ptid, unless it's null at this point. If so,
then since there's no way to know the pid of the reported
threads, use the magic number. */
if (inferior_ptid == null_ptid)
pid = magic_null_ptid.pid ();
else
pid = inferior_ptid.pid ();
if (obuf)
*obuf = pp;
return ptid_t (pid, tid);
Because multi-process was turned off, GDB did not parse an explicitly
specified PID. Furthermore, inferior_ptid == null_ptid, and
eventually GDB picked the PID from magic_null_ptid.
If target-non-stop is not turned on at the beginning, the same bug
reveals itself as a duplicated thread as shown below.
# Same setup as above, without 'maint set target-non-stop on'.
...
(gdb) attach 26253
Attaching to Remote target
Attached; pid = 26253
[New inferior 3]
...
[New Thread 26253]
...
(gdb) info threads
Id Target Id Frame
1.1 process 13517 "a.out" main () at test.c:3
* 2.1 Thread 26253 "a.out" 0x00007f12750c5151 in read () from target:/lib/x86_64-linux-gnu/libc.so.6
3.1 Thread 26253 "a.out" Remote 'g' packet reply is too long (expected 560 bytes, got 2496 bytes): 00feffffffffffff000a3a75127f000051510c75127f0000000400000000000060d24ef6af5500000000000000000000680d000000000000b85b31e3fc7f0000c0283a75127f000000e55b75127f000010d04ef6af550000460200000000000060c73975127f0000a0d23975127f0000000a3a75127f0000000000000000000051510c75127f000046020000330000002b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f03000000000000ffff0000000000000000000000000000000000000000000080143a75127f000080143a75127f000040143a75127f000040143a75127f00007d0000007e0000007f00000080000000300c3a75127f0000300c3a75127f00000e000000000000000e0000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffff0400000004000000040000000400000020143a75127f000020143a75127f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f0000000000000000000000e55b75127f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
(gdb)
Fix the problem by preferring current_inferior()'s pid instead of
magic_null_ptid.
Regression-tested on X86-64 Linux.
Co-authored-by: Aleksandar Paunovic <aleksandar.paunovic@intel.com>
The test added in the commit:
commit a6b413d24c
Date: Fri Mar 11 14:44:03 2022 +0000
gdb: work around prompt corruption caused by bracketed-paste-mode
Was not written with readline 7 in mind, only readline 8+. Between
readline 7 and 8 the escape sequence used to disable bracketed paste
mode changed, an additional '\r' character was added to the end. In
fact, it was the addition of this '\r' character that triggered the
issue for which the above commit is part of the solution.
Anyway, the test tries to spot the case where the output from GDB is
not perfect, but does have the above work around applied. However,
the pattern in the test assumes that the problematic '\r' will be
present, and this is only true for readline 8+. With readline 7 the
test was failing.
In this commit I generalise the pattern a little so that the test will
still KFAIL with readline 7.
It's a little unfortunate that the test is KFAILing with readline 7,
as without the problematic '\r' there's actually no reason that GDB
couldn't "do the right thing" in this case, in which case, the test
would PASS, but that would require changes within GDB itself.
My preference then is that initially we patch the test to get it
KFAILing, then in a separate commit I can modify GDB so that it can
PASS with readline 7.
The test gdb.python/py-format-address.exp, added in commit:
commit 25209e2c69
Date: Sat Oct 23 09:59:25 2021 +0100
gdb/python: add gdb.format_address function
included 3 copy & paste errors where the wrong address was used in the
expected output patterns.
The test compiles two almost identical test binaries (one function
changes its name, that's the only difference), two inferiors are
created, each inferior using one of the test binaries.
We then take the address of the name changing function in both
inferiors ('foo' in inferior 1 and 'bar' in inferior 2) and the tests
are carried out using these addresses.
What we're checking for is that symbols 'foo' and 'bar' show up in the
correct inferior, and that (as this test is for a Python API feature),
the user can have one inferior selected, but ask about the other
inferior, and see the correct symbol in the result.
The hope is that the two binaries will be laid out identically by the
compiler, and that 'foo' and 'bar' will be at the same address. This
is fine, unless the executable is compiled as PIE (position
independent executable), in which case there is a problem.
The problem is that though inferior 1 is set running, the inferior 2
never is. If the executables are compiled as PIE, then the address in
the inferior 2 will not have been resolved, while the address in the
inferior 1 will have been, and so the two addresses we use in the
tests will be different.
This issue was reported here:
https://sourceware.org/pipermail/gdb-patches/2022-March/186911.html
The first part of the fix is to use the correct address variable in
the expected output patterns, with this change the tests pass even
when the executables are compiled as PIE.
A second part of this fix is to pass the 'nopie' option when we
compile the tests, this should ensure that the address obtained in
inferior 2 is the same as the address from inferior 1, which makes the
test more useful.
In commit:
commit a2757c4ed6
Date: Wed Mar 16 15:08:22 2022 +0000
gdb/mi: consistently notify user when GDB/MI client uses -thread-select
Changes were made to GDB to address some inconsistencies in when
notifications are sent from a MI terminal to a CLI terminal (when
multiple terminals are in use, see new-ui command).
Unfortunately, in order to track when the currently selected frame has
changed, that commit grabs a frame_info pointer before and after an MI
command has executed, and compares the pointers to see if the frame
has changed.
This is not safe.
If the frame cache is deleted for any reason then the frame_info
pointer captured before the command started, is no longer valid, and
any comparisons based on that pointer are undefined.
This was leading to random test failures for some folk, see:
https://sourceware.org/pipermail/gdb-patches/2022-March/186867.html
This commit changes GDB so we no longer hold frame_info pointers, but
instead store the frame_id and frame_level, this is safe even when the
frame cache is flushed.
Include the language identifier emitted by gas in the set of ones where
no mangled names are expected. Even if there could be "hand-mangled"
names, gas doesn't emit DW_AT_linkage_name in the first place.
Prior to entering the enclosing "else if()" the earlier associated if()
checks function->is_linkage and, if set, uses function->name. The
comment in patch context precedes (and explains) the setting
function->is_linkage. Yet with the flag set, we should then also return
the function name, just like said earlier if() would do when we came
here a 2nd time for the same "addr". And indeed passing the same address
twice on addr2line's command line would resolve the function for the 2nd
instance, but not for the 1st (if this code path is taken). (This,
obviously, is particularly relevant when there's no ELF symbol table in
the first place, like would be the case - naturally - in PE/COFF
binaries, for example.)
Restrict the PR gas/16908 workaround to just macros, matching the
original intention as well as the comment there. For constructs like
.irp or .rept the reasoning doesn't apply, as there's no separate
"invocation" point which may be of interest to record (for, as said
there, short macros).
While the spec isn't explicit about this, it pointing out the similarity
with the D extension ought to extend to the ignoring of a meaningless
rounding mode: "Note FCVT.D.W[U] always produces an exact result and is
unaffected by rounding mode." Hence the chosen encodings also ought to
match.
Note that to avoid breaking existing code the forms with a 3rd operand
are not removed, which means there continues to be a difference to
FCVT.D.W[U].
I noticed that "print 5," passed in Rust -- the parser wasn't checking
that the entire input was used. This patch fixes the problem. This
in turn pointed out another bug in the parser, namely that it didn't
lex the next token after handling a string token. This is also fixed
here.
Currently, timestamps for logging are done by looking for the use of
gdb_stdlog in vfprintf_unfiltered. This seems potentially buggy, in
that during logging or other redirects (like execute_fn_to_ui_file) we
might have gdb_stdout==gdb_stdlog and so, conceivably, wind up with
timestamps in a log when they were not desired.
It seems better, instead, for timestamps to be a property of the
ui_file itself.
This patch changes gdb to use the new timestamped_file for gdb_stdlog
where appropriate, and removes the special case from
vfprintf_unfiltered.
Note that this may somewhat change the output in some cases -- in
particular, when going through execute_fn_to_ui_file (or the _string
variant), timestamps won't be emitted. This could be fixed in those
functions, but it wasn't clear to me whether this is really desirable.
Note also that this changes the TUI to send gdb_stdlog to gdb_stderr.
I imagine that the previous use of gdb_stdout here was inadvertent.
(And in any case it probably doesn't matter.)
This adds a "timestamped_file" subclass of ui_file. This class adds a
timestamp to its output when appropriate. That is, it follows the
rule already used in vfprintf_unfiltered of adding a timestamp at most
once per write.
The new class is not yet used.
This changes the CLI logging code to avoid manual memory management
(to the extent possible) by using unique_ptr in a couple of spots.
This will come in handy in a later patch.
The CLI's set_logging logic seemed unnecessarily complicated to me.
This patch simplifies it, with an eye toward changing it to use RAII
objects in a subsequent patch.
I did not touch the corresponding MI code. That code seems incorrect
(nothing ever uses raw_stdlog, and nothing ever sets
saved_raw_stdlog). I didn't attempt to fix this, because I question
whether this is even useful for MI.
A large customer program has a function that is partitioned into hot
and cold parts. A variable in a callee of this function is described
using DW_OP_GNU_entry_value, but gdb gets confused when trying to find
the caller. I tracked this down to dwarf2_get_pc_bounds interpreting
the function's changes so that the returned low PC is the "wrong"
function.
Intead, when processing DW_TAG_call_site, the low PC of each range in
DW_AT_ranges should be preserved in the call_site_target. This fixes
the variable lookup in the test case I have.
I didn't write a standalone test for this as it seemed excessively
complicated.
In order to handle the case where a call site target might refer to
multiple addresses, we change the code to use a callback style. Any
spot using call_site_target::address now passes in a callback function
that may be called multiple times.
call_site_find_chain_1 has a comment claiming that recursive calls
would be too expensive. However, I doubt this is so expensive; and
furthermore the explicit state management approach here is difficult
both to understand and to modify. This patch changes this code to use
explicit recursion, so that a subsequent patch can generalize this
code without undue trauma.
Additionally, I think this patch detects a latent bug in the recursion
code. (It's hard for me to be completely certain.) The bug is that
when a new target_call_site is entered, the code does:
if (target_call_site)
{
if (addr_hash.insert (target_call_site->pc ()).second)
{
/* Successfully entered TARGET_CALL_SITE. */
chain.push_back (target_call_site);
break;
}
}
Here, if entering the target_call_site fails, then any tail_call_next
elements in this call site are not visited. However, if this code
does happen to enter a call site, then the tail_call_next elements
will be visited during backtracking. This applies when doing the
backtracking as well -- it will only continue through a given chain as
long as each element in the chain can successfully be visited.
I'd appreciate some review of this. If this behavior is intentional,
it can be added to the new implementation.
While investigating this bug, I wasn't sure if chain_candidate might
update 'chain'. I changed it to accept a const reference, making it
clear that it cannot. This simplifies the code a tiny bit as well.
This makes the data members of call_site_target 'private'. This lets
us remove most of its public API. call_site_to_target_addr is changed
to be a method of this type. This is a preparatory refactoring for
the fix at the end of this series.
call_site_target reuses field_loc_kind and field_location. However,
it has never used the full range of the field_loc_kind enum. In a
subsequent patch, I plan to add a new 'kind' here, so it seemed best
to avoid this reuse and instead introduce new types here.
value.h has a declaration of value_print_array_elements that is
incorrect. In C, this would have been an error, but in C++ this is a
declaration of an overload that is neither defined nor used. This
patch removes the declaration.
My previous nm patch handled all cases but one -- if the user set NM in
the environment to a path which contained an option, libtool's nm
detection tries to run nm against a copy of nm with the options in it:
e.g. if NM was set to "nm --blargle", and nm was found in /usr/bin, the
test would try to run "/usr/bin/nm --blargle /usr/bin/nm --blargle".
This is unlikely to be desirable: in this case we should run
"/usr/bin/nm --blargle /usr/bin/nm".
Furthermore, as part of this nm has to detect when the passed-in $NM
contains a path, and in that case avoid doing a path search itself.
This too was thrown off if an option contained something that looked
like a path, e.g. NM="nm -B../prev-gcc"; libtool then tries to run
"nm -B../prev-gcc nm" which rarely works well (and indeed it looks
to see whether that nm exists, finds it doesn't, and wrongly concludes
that nm -p or whatever does not work).
Fix all of these by clipping all options (defined as everything
including and after the first " -") before deciding whether nm
contains a path (but not using the clipped value for anything else),
and then removing all options from the path-modified nm before
looking to see whether that nm existed.
NM=my-nm now does a path search and runs e.g.
/usr/bin/my-nm -B /usr/bin/my-nm
NM=/usr/bin/my-nm now avoids a path search and runs e.g.
/usr/bin/my-nm -B /usr/bin/my-nm
NM="my-nm -p../wombat" now does a path search and runs e.g.
/usr/bin/my-nm -p../wombat -B /usr/bin/my-nm
NM="../prev-binutils/new-nm -B../prev-gcc" now avoids a path search:
../prev-binutils/my-nm -B../prev-gcc -B ../prev-binutils/my-nm
This seems to be all combinations, including those used by GCC bootstrap
(which, before this commit, fails to bootstrap when configured
--with-build-config=bootstrap-lto, because the lto plugin is now using
--export-symbols-regex, which requires libtool to find a working nm,
while also using -B../prev-gcc to point at the lto plugin associated
with the GCC just built.)
Regenerate all affected configure scripts.
* libtool.m4 (LT_PATH_NM): Handle user-specified NM with
options, including options containing paths.
Currently debuginfod progress update messages include the size of
each download:
Downloading 7.5 MB separate debug info for /lib/libxyz.so.0
This value originates from the Content-Length HTTP header of the
transfer. However this header is not guaranteed to be present for
each download. This can happen when debuginfod servers compress files
on-the-fly at the time of transfer. In this case gdb wrongly prints
"-0.00 MB" as the size.
This patch removes download sizes from progress messages when they are
not available. It also removes usage of the progress bar until
a more thorough reworking of progress updating is implemented. [1]
[1] https://sourceware.org/pipermail/gdb-patches/2022-February/185798.html
This amends e961c696dc ("x86: drop L1OM/K1OM support from ld"). Also
remove the marker that I mistakenly added in c085ab00c7 ("x86: drop
L1OM/K1OM support from gas").
This test was added without a corresponding fix, with some setup_kfails.
However, it results in UNRESOLVED results when GDB is built with ASan.
ERROR: GDB process no longer exists
GDB process exited with wait status 1946871 exp7 0 1
UNRESOLVED: gdb.python/pretty-print-call-by-hand.exp: frame print: backtrace test (PRMS gdb/28856)
Remove the test from the tree, I'll attach it to the Bugzilla bug
instead [1].
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=28856
Change-Id: Id95d8949fb8742874bd12aeac758aa4d7564d678
I much appreciate Nick offering this role to me. Nevertheless there's
still a lot for me to learn here.
At this occasion also update my email address in the pre-existing, much
more narrow entry.
The gdb.mi/mi-multi-commands.exp test was added in commit:
commit d08cbc5d32
Date: Wed Dec 22 12:57:44 2021 +0000
gdb: unbuffer all input streams when not using readline
And then tweaked in commit:
commit 144459531d
Date: Mon Feb 7 20:35:58 2022 +0000
gdb/testsuite: relax pattern in new gdb.mi/mi-multi-commands.exp test
The second of these commits was intended to address periodic test
failures that I was seeing, and this change did fix some problems,
but, unfortunately, introduced other issues.
The problem is that the test relies on sending two commands to GDB in
a single write. As the characters that make these two commands arrive
they are echoed to GDB's console. However, there is a race between
how quickly the characters are echoed and how quickly GDB decides to
act on the incoming commands.
Usually, both commands are echoed in full before GDB acts on the first
command, but sometimes this is not the case, and GDB can execute the
first command before both commands are fully echoed to the console.
In this case, the output of the first command will be mixed in with
the echoing of the second command.
This mixing of the command echoing and the first command output is
what was causing failures in the original version of the test.
The second commit relaxed the expected output pattern a little, but
was still susceptible to failures, so this commit further relaxes the
pattern.
Now, we look for the first command output with no regard to what is
before, or after the command. Then we look for the first mi prompt to
indicate that the first command has completed.
I believe that this change should make the test more stable than it
was before.
libctf has always handled endianness differences by detecting
foreign-endian CTF dicts on the input and endian-flipping them: dicts
are always written in native endianness. This makes endian-awareness
very low overhead, but it means that the foreign-endian code paths
almost never get routinely tested, since "make check" usually reads in
dicts ld has just written out: only a few corrupted-CTF tests are
actually in fixed endianness, and even they only test the foreign-
endian code paths when you run make check on a big-endian machine.
(And the fix is surely not to add more .s-based tests like that, because
they are a nightmare to maintain compared to the C-code-based ones.)
To improve on this, add a new environment variable,
LIBCTF_WRITE_FOREIGN_ENDIAN, which causes libctf to unconditionally
endian-flip at ctf_write time, so the output is always in the wrong
endianness. This then tests the foreign-endian read paths properly
at open time.
Make this easier by restructuring the writeout code in ctf-serialize.c,
which duplicates the maybe-gzip-and-write-out code three times (once
for ctf_write_mem, with thresholding, and once each for
ctf_compress_write and ctf_write just so those can avoid thresholding
and/or compression). Instead, have the latter two call the former
with thresholds of 0 or (size_t) -1, respectively.
The endian-flipping code itself gains a bit of complexity, because
one single endian-flipper (flip_types) was assuming the input to be
in foreign-endian form and assuming it could pull things out of the
input once they had been flipped and make sense of them. At the
cost of a few lines of duplicated initializations, teach it to
read before flipping if we're flipping to foreign-endianness instead
of away from it.
libctf/
* ctf-impl.h (ctf_flip_header): No longer static.
(ctf_flip): Likewise.
* ctf-open.c (flip_header): Rename to...
(ctf_flip_header): ... this, now it is not private to one file.
(flip_ctf): Rename...
(ctf_flip): ... this too. Add FOREIGN_ENDIAN arg.
(flip_types): Likewise. Use it.
(ctf_bufopen_internal): Adjust calls.
* ctf-serialize.c (ctf_write_mem): Add flip_endian path via
a newly-allocated bounce buffer.
(ctf_compress_write): Move below ctf_write_mem and reimplement
in terms of it.
(ctf_write): Likewise.
(ctf_gzwrite): Note that this obscure writeout function does not
support endian-flipping.
The last section in a CTF dict is the string table, at an offset
represented by the cth_stroff header field. Its length is recorded in
the next field, cth_strlen, and the two added together are taken as the
size of the CTF dict. Upon opening a dict, we check that none of the
header offsets exceed this size, and we check when uncompressing a
compressed dict that the result of the uncompression is the same length:
but CTF dicts need not be compressed, and short ones are not.
Uncompressed dicts just use the ctf_size without checking it. This
field is thankfully almost unused: it is mostly used when reserializing
a dict, which can't be done to dicts read off disk since they're
read-only.
However, when opening an uncompressed foreign-endian dict we have to
copy it out of the mmaped region it is stored in so we can endian-
swap it, and we use ctf_size when doing that. When the cth_strlen is
corrupt, this can overrun.
Fix this by checking the ctf_size in all uncompressed cases, just as we
already do in the compressed case. Add a new test.
This came to light because various corrupted-CTF raw-asm tests had an
incorrect cth_strlen: fix all of them so they produce the expected
error again.
libctf/
PR libctf/28933
* ctf-open.c (ctf_bufopen_internal): Always check uncompressed
CTF dict sizes against the section size in case the cth_strlen is
corrupt.
ld/
PR libctf/28933
* testsuite/ld-ctf/diag-strlen-invalid.*: New test,
derived from diag-cttname-invalid.s.
* testsuite/ld-ctf/diag-cttname-invalid.s: Fix incorrect cth_strlen.
* testsuite/ld-ctf/diag-cttname-null.s: Likewise.
* testsuite/ld-ctf/diag-cuname.s: Likewise.
* testsuite/ld-ctf/diag-parlabel.s: Likewise.
* testsuite/ld-ctf/diag-parname.s: Likewise.
The CTF variable section is an optional (usually-not-present) section in
the CTF dict which contains name -> type mappings corresponding to data
symbols that are present in the linker input but not in the output
symbol table: the idea is that programs that use their own symbol-
resolution mechanisms can use this section to look up the types of
symbols they have found using their own mechanism.
Because these removed symbols (mostly static variables, functions, etc)
all have names that are unlikely to appear in the ELF symtab and because
very few programs have their own symbol-resolution mechanisms, a special
linker flag (--ctf-variables) is needed to emit this section.
Historically, we emitted only removed data symbols into the variable
section. This seemed to make sense at the time, but in hindsight it
really doesn't: functions are symbols too, and a C program can look them
up just like any other type. So extend the variable section so that it
contains all static function symbols too (if it is emitted at all), with
types of kind CTF_K_FUNCTION.
This is a little fiddly. We relied on compiler assistance for data
symbols: the compiler simply emits all data symbols twice, once into the
symtypetab as an indexed symbol and once into the variable section.
Rather than wait for a suitably adjusted compiler that does the same for
function symbols, we can pluck unreported function symbols out of the
symtab and add them to the variable section ourselves. While we're at
it, we do the same with data symbols: this is redundant right now
because the compiler does it, but it costs very little time and lets the
compiler drop this kludge and save a little space in .o files.
include/
* ctf.h: Mention the new things we can see in the variable
section.
ld/
* testsuite/ld-ctf/data-func-conflicted-vars.d: New test.
libctf/
* ctf-link.c (ctf_link_deduplicating_variables): Duplicate
symbols into the variable section too.
* ctf-serialize.c (symtypetab_delete_nonstatic_vars): Rename
to...
(symtypetab_delete_nonstatics): ... this. Check the funchash
when pruning redundant variables.
(ctf_symtypetab_sect_sizes): Adjust accordingly.
* NEWS: Describe this change.
The test for -gctf support in the compiler is used to determine when to
run the ld-ctf tests and most of those in libctf. Unfortunately,
because it uses check_compiler_available and compile_one_cc, it will
fail whenever the compiler emits anything on stderr, even if it
actually does support CTF perfectly well.
So, instead, ask the compiler to emit assembler output and grep it for
references to ".ctf": this is highly unlikely to be present if the
compiler does not support CTF. (This will need adjusting when CTF grows
support for non-ELF platforms that don't dot-prepend their section
names, but right now the linker doesn't link CTF on any such platforms
in any case.)
With this in place we can do things like run all the libctf tests under
leak sanitizers etc even if those spray warnings on simple CTF
compilations, rather than being blocked from doing so just when we would
most like to.
ld/
* testsuite/lib/ld-lib.exp (check_ctf_available): detect CTF
even if a CTF-capable compiler emits warnings.
New in this version:
- Rebase on master, fix a few more issues that appeared.
python-internal.h contains a number of macros that helped make the code
work with both Python 2 and 3. Remove them and adjust the code to use
the Python 3 functions.
Change-Id: I99a3d80067fb2d65de4f69f6473ba6ffd16efb2d
New in this version:
- Add a PY_MAJOR_VERSION check in configure.ac / AC_TRY_LIBPYTHON. If
the user passes --with-python=python2, this will cause a configure
failure saying that GDB only supports Python 3.
Support for Python 2 is a maintenance burden for any patches touching
Python support. Among others, the differences between Python 2 and 3
string and integer types are subtle. It requires a lot of effort and
thinking to get something that behaves correctly on both. And that's if
the author and reviewer of the patch even remember to test with Python
2.
See this thread for an example:
https://sourceware.org/pipermail/gdb-patches/2021-December/184260.html
So, remove Python 2 support. Update the documentation to state that GDB
can be built against Python 3 (as opposed to Python 2 or 3).
Update all the spots that use:
- sys.version_info
- IS_PY3K
- PY_MAJOR_VERSION
- gdb_py_is_py3k
... to only keep the Python 3 portions and drop the use of some
now-removed compatibility macros.
I did not update the configure script more than just removing the
explicit references to Python 2. We could maybe do more there, like
check the Python version and reject it if that version is not
supported. Otherwise (with this patch), things will only fail at
compile time, so it won't really be clear to the user that they are
trying to use an unsupported Python version. But I'm a bit lost in the
configure code that checks for Python, so I kept that for later.
Change-Id: I75b0f79c148afbe3c07ac664cfa9cade052c0c62