If DWARF contains a reference to a "dwz" file, but there is no
.gnu_debugaltlink section, then gdb will crash. This happens because
dwarf2_get_dwz_file will return NULL, but some callers do not expect
this.
This patch changes dwarf2_get_dwz_file so that callers can require a
dwz file. Then, it updates the callers that are attempting to process
references to the dwz file to require one.
This includes a new testcase. The dwarf.exp changes don't handle the
new forms exactly correctly -- they are only handled well enough to
let this test case complete.
gdb/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* dwarf2/read.h (dwarf2_get_dwz_file): Add 'require' parameter.
* dwarf2/read.c (dwarf2_get_dwz_file): Add 'require' parameter.
(get_abbrev_section_for_cu, read_attribute_value)
(get_debug_line_section): Update.
* dwarf2/macro.c (dwarf_decode_macro_bytes): Update.
gdb/testsuite/ChangeLog
2021-03-06 Tom Tromey <tom@tromey.com>
* lib/dwarf.exp (_handle_DW_FORM): Treat DW_FORM_GNU_ref_alt and
DW_FORM_GNU_strp_alt like DW_FORM_sec_offset.
* gdb.dwarf2/dwznolink.exp: New file.
On my setup some valgrind tests failed somewhat reliably because
the target remote | vgdb command couldn't find the vgdb-pipe files
because valgrind startup hadn't finished yet.
I tried to fix this by replacing the "Memcheck, a memory error detector"
match to "TO DEBUG THIS PROCESS USING GDB: start GDB like this" which is
right before valgrind creates the vgdb-pipe files. But even that didn't
guarantee that the vgdb-pipe files were there (maybe valgrind should
print that text after it has created them?). But also not all tests
use --vgdb-error=0, so the text isn't always printed.
To make the tests reliable I added --wait=1 to the vgdb invocation.
That tells vgdb to try to find the vgdb-pipe files, and if they aren't
there yet, to wait 1 second and try again.
gdb/testsuite/ChangeLog:
* lib/valgrind.exp (vgdb_start): Add --wait=1 to vgdbcmd.
Added this support in read_func_kind_type after gcc started generating
CTF for function arguments.
Replaced XNEW with std::vector and NULL with nullptr.
Expanded gdb.base/ctf-ptype.exp to test function arguments. Also fixed
some typos.
gdb/ChangeLog:
* ctfread.c (read_func_kind_type): Set up function arguments.
gdb/testsuite/ChangeLog:
* gdb.base/ctf-ptype.exp: Add function tests and fix typos.
In gdb.btrace/rn-dl-bind.exp we test that we can reverse-step over
recorded dynamic linking. The test covers specific behaviour to support
_dl_runtime_resolve calling the resolved function by returning to it.
This would normally mess up stepping as we'd end up with backtraces that
contain the same functions but different frame ids.
Since GDB needs to recognize a return from _dl_runtime_resolve, the test
only passes when debug information for _dl_runtime_resolve is available.
The test requires that symbols are bound lazily. Otherwise, we won't
record dynamic linking and the test will be fairly pointless.
Recent GCC pass -z now by default to bind symbols eagerly. Add -z lazy to
the test's ldflags to enforce lazy binding.
In gdb.btrace/non-stop.exp, we hard-code expected source lines assuming we
know how they would match to the recorded trace. Despite the fact that we
should really have been using an assembly source, the assumptions work
pretty well.
With clang-6 -m32, we found a case where the assumptions do not hold.
Adjust the expected source lines a little bit to cover that case, as well.
Should we run into more cases like this, we will have to switch to an
assembly source file.
We use pre-compiled assembly including debug information for stepi, yet we
compiled with -g, which was implicitly set by prepare_for_testing.
Add {} options to avoid the implicit {debug}.
Clang generates slightly different debug information. Adjust the expected
output of gdb.btrace/function_call_history.exp to work with both gcc and
clang.
Also modify gdb.btrace/exception.cc to reliably trace into main and update
the corresponding patterns in gdb.btrace/exception.exp.
In gdb.btrace/unknown_functions.exp we need the linker to discard local
symbols so GDB wouldn't know about them from the symbol table.
When building with clang, it complains about the option not being used at
compile-time. Move the option to ldflags to only pass it at link-time.
Clang generates slightly different debug information causing
gdb.btrace/rn-dl-bind.exp to fail on its way to the actual test.
Modify the test to remove that dependency.
In gdb.btrace/delta.exp, we test that we do not extend the trace
unintentionally. This can be tested by checking the number of
instructions.
If we wanted to check the instruction history, as well, we'd need to work
on an assembly file to have deterministic behaviour. This isn't really
necessary for this test, however, and covered elsewhere. Also remove the
function call history check for the same reason.
Some older GCC, e.g. 7.5.0 on Ubuntu 18.04 need -fno-pie to be passed to
the compiler in addition to -no-pie to be passed to the linker for non-pie
code generation.
The gdb,nopie_flag is already documented as getting passed to the
compiler, not the linker. Use that for the new -fno-pie compiler flag and
add a new gdb,nopie_ldflag for the existing -no-pie linker flag.
CAUTION: this might break existing board files that specify
gdb,nopie_flag. Affected board files need to rename
gdb,nopie_flag into gdb,nopie_ldflag.
gdb currently supports two different styles of fixed-point. The
original style, where fixed point types are "GNAT encoded", is handled
primarily in the Ada code. The newer style, encoded using DWARF, is
handled by the core of gdb.
This patch changes gdb to read the GNAT encodings in the DWARF reader
as well. This removes some code and unifies the two paths. As a
result, GNAT-encoded fixed-point now works a bit better.
One possible drawback of this change is that, if someone uses stabs,
then fixed-point might now stop working. I consider stabs to be fully
obsolete, though, so I don't intend to address this.
gdb/ChangeLog
2021-03-02 Tom Tromey <tromey@adacore.com>
* ada-lang.c (cast_from_gnat_encoded_fixed_point_type)
(cast_to_gnat_encoded_fixed_point_type): Remove.
(ada_value_cast, ada_evaluate_subexp): Update.
(gnat_encoded_fixed_point_type_info)
(ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Remove.
* ada-lang.h (ada_is_gnat_encoded_fixed_point_type)
(gnat_encoded_fixed_point_delta)
(gnat_encoded_fixed_point_scaling_factor): Don't declare.
* ada-typeprint.c (print_gnat_encoded_fixed_point_type): Remove.
(ada_print_type): Update.
* ada-valprint.c (ada_value_print_num): Update.
* dwarf2/read.c (ada_get_gnat_encoded_number)
(ada_get_gnat_encoded_ratio): New functions.
(finish_fixed_point_type): Use them. Add parameters.
(GNAT_FIXED_POINT_SUFFIX): New define.
(gnat_encoded_fixed_point_type_info): New function.
(read_base_type): Handle gnat encodings.
gdb/testsuite/ChangeLog
2021-03-02 Tom Tromey <tromey@adacore.com>
* gdb.ada/fixed_points.exp: Remove most special cases for minimal
encodings.
As reported in gdb/27393, the 'directory' and 'set directories' commands
fail when parsing an empty dir name:
(gdb) set directories ""
/home/lsix/dev/gnu/binutils-gdb/gdbsupport/pathstuff.cc:132: internal-error: gdb::unique_xmalloc_ptr<char> gdb_abspath(const char*): Assertion `path != NULL && path[0] != '\0'' failed.
or
(gdb) dir :
/home/lsix/dev/gnu/binutils-gdb/gdbsupport/pathstuff.cc:132: internal-error: gdb::unique_xmalloc_ptr<char> gdb_abspath(const char*): Assertion `path != NULL && path[0] != '\0'' failed.
This patch fixes this issue by ignoring any attempt to add an empty
name to the source directories list. 'set dir ""' will reset the
directories list the same way 'set dir' would do it.
Tested on x86_64.
I noticed an oddity in skip_ctf_tests -- for me it ends up caching the
string "!0", because it ends with 'return ![...]'. In Tcl, this is
just string concatenation.
The result works because the users of this function have unbraced if
conditions, like:
if [skip_ctf_tests] {
... which works because "if" re-parses the returned string as an
expression, and evaluates that.
There's only a latent bug here, but this is also un-idiomatic, so I am
checking in this patch to fix it. This way, if someone in the future
uses a braced condition (which is what I normally recommend), it will
continue to work.
gdb/testsuite/ChangeLog
2021-02-26 Tom Tromey <tom@tromey.com>
* lib/gdb.exp (skip_ctf_tests): Use expr on result.
Commit 2450ad54 removed extra trailing \n from tsv notifications but
did not update gdb.trace/mi-tsv-changed.exp accordingly. This commit
removes the extra \n from expected output so gdb.trace/mi-tsv-changed.exp
passes again.
gdb/testsuite/ChangeLog:
* gdb.trace/mi-tsv-changed.exp (test_create_delete_modify_tsv):
Remove trailing \n from expected output.
This change fixes the initial state of the main thread of remote
targets which have no concept of threading. Such targets are
treated as single-threaded by gdb, and this single thread needs
to be initially set to the "resumed" state, in the same manner as
threads in thread-aware remote targets (see remote.c,
remote_target::remote_add_thread).
Without this fix, the following assert was triggered on thread-
unaware remote targets:
remote_target::select_thread_for_ambiguous_stop_reply(const target_waitstatus*): Assertion `first_resumed_thread != nullptr' failed.
The bug can be reproduced using gdbserver
* by disabling packets 'T' and 'qThreadInfo', or
* by disabling all thread-related packets.
The test suite has been updated to include these two scenarios, see
gdb.server/stop-reply-no-thread.exp.
Change-Id: I2c39c9de17e8d6922a8c1b9e259eb316a554a43d
In commit:
commit faeb9f13c179a4c78bc295a0d0bbd788239704d9
Date: Wed Feb 24 12:50:00 2021 +0000
gdb/fortran: add support for ASSOCIATED builtin
A test was added that fails to process the trailing gdb prompt inside
a gdb_test_multiple call, this will cause a failure if the tests are
run with READ1=1, or randomly at other times depending on how the
expect buffers are read in.
Fixed by adding a -wrap argument.
gdb/testsuite/ChangeLog:
* gdb.fortran/associated.exp: Add missing '-wrap' argument.
When attempting to call a Fortran function for which there is no debug
information we currently trigger undefined behaviour in GDB by
accessing non-existent type fields.
The reason is that in order to prepare the arguments, for a call to a
Fortran function, we need to know the type of each argument. If the
function being called has no debug information then obviously GDB
doesn't know about the argument types and we should either give the
user an error or pick a suitable default. What we currently do is
just assume the field exist and access undefined memory, which is
clearly wrong.
The reason GDB needs to know the argument type is to tell if the
argument is artificial or not, artificial arguments will be passed by
value while non-artificial arguments will be passed by reference.
An ideal solution for this problem would be to allow the user to cast
the function to the correct type, we already do this to some degree
with the return value, for example:
(gdb) print some_func_ ()
'some_func_' has unknown return type; cast the call to its declared return type
(gdb) print (integer) some_func_ ()
$1 = 1
But if we could extend this to allow casting to the full function
type, GDB could figure out from the signature what are real
parameters, and what are artificial parameters. Maybe something like
this:
(gdb) print ((integer () (integer, double)) some_other_func_ (1, 2.3)
Alas, right now the Fortran expression parser doesn't seem to support
parsing function signatures, and we certainly don't have support for
figuring out real vs artificial arguments from a signature.
Still, I think we can prevent GDB from accessing undefined memory and
provide a reasonable default behaviour.
In this commit I:
- Only ask if the argument is artificial if the type of the argument
is actually known.
- Unknown arguments are assumed to be artificial and passed by
value (non-artificial arguments are pass by reference).
- If an artificial argument is prefixed with '&' by the user then we
treat the argument as pass-by-reference.
With these three changes we avoid undefined behaviour in GDB, and
allow the user, in most cases, to get a reasonably natural default
behaviour.
gdb/ChangeLog:
PR fortran/26155
* f-lang.c (fortran_argument_convert): Delete declaration.
(fortran_prepare_argument): New function.
(evaluate_subexp_f): Move logic to new function
fortran_prepare_argument.
gdb/testsuite/ChangeLog:
PR fortran/26155
* gdb.fortran/call-no-debug-func.f90: New file.
* gdb.fortran/call-no-debug-prog.f90: New file.
* gdb.fortran/call-no-debug.exp: New file.
This commit adds support for the ASSOCIATED builtin to the Fortran
expression evaluator. The ASSOCIATED builtin takes one or two
arguments.
When passed a single pointer argument GDB returns a boolean indicating
if the pointer is associated with anything.
When passed two arguments the second argument should either be some a
pointer could point at or a second pointer.
If the second argument is a pointer target, then the result from
associated indicates if the pointer is pointing at this target.
If the second argument is another pointer, then the result from
associated indicates if the two pointers are pointing at the same
thing.
gdb/ChangeLog:
* f-exp.y (f77_keywords): Add 'associated'.
* f-lang.c (fortran_associated): New function.
(evaluate_subexp_f): Handle FORTRAN_ASSOCIATED.
(operator_length_f): Likewise.
(print_unop_or_binop_subexp_f): New function.
(print_subexp_f): Make use of print_unop_or_binop_subexp_f for
FORTRAN_ASSOCIATED, FORTRAN_LBOUND, and FORTRAN_UBOUND.
(dump_subexp_body_f): Handle FORTRAN_ASSOCIATED.
(operator_check_f): Likewise.
* std-operator.def: Add FORTRAN_ASSOCIATED.
gdb/testsuite/ChangeLog:
* gdb.fortran/associated.exp: New file.
* gdb.fortran/associated.f90: New file.
gfortran supports .xor. as an alias for .neqv., see:
https://gcc.gnu.org/onlinedocs/gfortran/_002eXOR_002e-operator.html
this commit adds support for this operator to GDB.
gdb/ChangeLog:
* f-exp.y (fortran_operators): Add ".xor.".
gdb/testsuite/ChangeLog:
* gdb.fortran/dot-ops.exp (dot_operations): Test ".xor.".
The 'section' command uses a fixed size buffer into which a section
name is copied. This commit replaces this with a use of std::string
so we can now display very long section names.
The expected results of one test need to be updated.
gdb/ChangeLog:
* exec.c (set_section_command): Move variable declarations into
the function body, and use std::string instead of a fixed size
buffer.
gdb/testsuite/ChangeLog:
* gdb.base/sect-cmd.exp: Update expected results.
The only target that implements target_ops::get_section_table in a
meaningful way is exec_target. This target calls back into the
program space to return the current global section_table.
The global section table is populated whenever the user provides GDB
with an executable, or when a symbol file is loaded, e.g. when a
dynamic library is loaded, or when the user does add-symbol-file.
I recently ran into a situation where a user, debugging a remote
target, was not supplying GDB with a main executable at all. Instead
the user attached to the target then did add-symbol-file, and then
proceeded to debug the target.
This works fine, but it was noticed that even when
trust-readonly-sections was on GDB was still accessing the target to
get the contents of readonly sections.
The problem is that by not providing an executable there was no
exec_target in the target stack, and so when GDB calls the
target_ops::get_section_table function GDB ends up in
dummy_target::get_section_table, which just returns NULL.
What I want is that even when GDB doesn't have an exec_target in the
target stack, a call to target_ops::get_section_table will still
return the section_table from the current program space.
When considering how to achieve this my first though was, why is the
request for the section table going via the target stack at all? The
set of sections loaded is a property of the program space, not the
target. This is, after all, why the data is being stored in the
program space.
So I initially tried changing target_get_section_table so that,
instead of calling into the target it just returns
current_program_space->target_sections ().
This would be fine except for one issue, target_bfd (from
bfd-target.c). This code is used from solib-svr4.c to create a
temporary target_ops structure that implements two functions
target_bfd::xfer_partial and target_bfd::get_section_table.
The purpose behind the code is to enable two targets, ppc64 and frv to
decode function descriptors from the dynamic linker, based on the
non-relocated addresses from within the dynamic linker bfd object.
Both of the implemented functions in target_bfd rely on the target_bfd
object holding a section table, and the ppc64 target requires that the
target_bfd implement ::get_section_table.
The frv target doesn't require ::get_section_table, instead it
requires the ::xfer_partial. We could in theory change the ppc64
target to use the same approach as frv, however, this would be a bad
idea. I believe that the frv target approach is broken. I'll
explain:
The frv target calls get_target_memory_unsigned to read the function
descriptor. The address being read is the non-relocated address read
from the dynamic linker in solib-srv4.c:enable_break. Calling
get_target_memory_unsigned eventually ends up in target_xfer_partial
with an object type of TARGET_OBJECT_RAW_MEMORY. This will then call
memory_xfer_check_region. I believe that it is quite possible that a
the non-relocated addresses pulled from the dynamic linker could be in
a memory region that is not readable, while the relocated addresses
are in a readable memory region. If this was ever the case for the
frv target then GDB would reject the attempt to read the non-relocated
function pointer.
In contrast the ppc64 target calls target_section_by_addr, which calls
target_get_section_table, which then calls the ::get_section_table
function on the target.
Thus, when reflecting on target_bfd we see two functions,
::xfer_partial and ::get_section_table. The former is required by the
frv target, but that target is (I think) potentially broken. While
the latter is required by the ppc64 target, but this forces
::get_section_table to exist as a target_ops member function.
So my original plan, have target_get_section_table NOT call a
target_ops member function appears to be flawed.
My next idea was to remove exec_target::get_section_table, and instead
move the implementation into dummy_target::get_section_table.
Currently the dummy_target implementation always returns NULL
indicating no section table, but plenty of other dummy_target member
functions do more than just return null values.
So now, dummy_target::get_section_table returns the section table from
the current program space. This allows target_bfd to remain
unchanged, so ppc64 and frv should not be affected.
Making this change removes the requirement for the user to provide an
executable, GDB can now always access the section_table, as the
dummy_target always exists in the target stack.
Finally, there's a test that the target_section table is not empty in
the case where the user does add-symbol-file without providing an
executable.
gdb/ChangeLog:
* exec.c (exec_target::get_section_table): Delete member function.
(section_table_read_available_memory): Use current_top_target, not
just the exec_ops target.
* target-delegates.c: Regenerate.
* target.c (default_get_section_table): New function.
* target.h (target_ops::get_section_table): Change default
behaviour to call default_get_section_table.
(default_get_section_table): Declare.
During review of the next patch (which changes the 'section' command),
a bug was pointed out. I wondered why no tests spotted this bug and I
found that the 'section' command test (sect-cmd.exp) is only run on
hppa targets!
In this commit I have given this test script a bit of a spring clean,
bringing it up to date with current testsuite style. I have made some
of the patterns a little more robust, but in general my intention was
not to change the underlying meaning of any of these tests.
gdb/testsuite/ChangeLog:
* gdb.base/sect-cmd.exp: Rewrite using modern testsuite
techniques. Enable the test for all targets.
We already have a command 'maint info sections', this command prints
all sections from all known object files.
However, GDB maintains a second section table internally. This
section table is used when GDB wants to read directly from an object
file rather than actually reading memory on the target. As such only
some sections (the allocatable ones) are added to this secondary
section table.
I recently ran into a situation where some of GDB's optimisations for
reading directly from the files were not working. In 'maint info
sections' I could see that GDB knew about the object file, and did
know about the sections that it _should_ have been reading from. But
I couldn't ask GDB which sections it had copied into its secondary
section table.
This commit adds a new command 'maint info target-sections' that fills
this gap. This command lists only those sections that GDB has copied
into its secondary table.
You'll notice that the testsuite includes a comment indicating that
there's a bug in GDB. Normally this is not something I would add to
the testsuite, instead we should raise an actual bugzilla bug and then
mark an xfail, however, a later patch in this series will remove this
comment once the actual bug in GDB is fixed.
gdb/ChangeLog:
* NEWS: Mention new 'maint info target-sections' command.
* maint.c (maintenance_info_target_sections): New function.
(_initialize_maint_cmds): Register new command.
gdb/doc/ChangeLog:
* gdb.texinfo (Files): Document new 'maint info target-sections'
command.
gdb/testsuite/ChangeLog:
* gdb.base/maint-info-sections.exp: Add new tests.
(check_maint_info_target_sections_output): New proc.
GDB for RISC-V always uses target descriptions. When the target
doesn't provide a target description then a default is selected.
Usually this default is selected based on the properties of the
executable being debugged. However, when there is no executable being
debugged we currently fallback to the riscv:rv64 target description as
the default. This leads to strange behaviour like this:
$ gdb
(gdb) set architecture riscv:rv32
(gdb) p sizeof ($pc)
$1 = 8
Despite the users specifically setting the architecture to riscv:rv32
GDB still thinks that the target has riscv:rv64 register sizes.
The above is a bit of a contrived situation. I actually ran into this
situation while trying to connect to a running riscv:rv32 target
without supplying an executable (the target didn't provide a target
description). When I tried to set a register on the target I ran into
errors because GDB was passing 8 bytes to the target rather than the
expected 4. Even when I manually specified the architecture (as
above) I couldn't convince GDB to only send 4 bytes.
This patch fixes this issue. Now, when we selected a default target
description we will make use of the user selected architecture to
guide our choice. In the above example we now get:
$ gdb
(gdb) set architecture riscv:rv32
(gdb) p sizeof ($pc)
$1 = 4
And my real world example of connecting to a remote without an
executable works fine.
I've used the fact that we can ask GDB about $pc even when no
executable is loaded as the basis for a test to cover this situation.
gdb/ChangeLog:
* riscv-tdep.c (riscv_features_from_gdbarch_info): Rename to...
(riscv_features_from_bfd): ...this. Change parameter type to
'bfd*', and update as required.
(riscv_find_default_target_description): Update call to
riscv_features_from_bfd. Select a default xlen based on
info.bfd_arch_info.
(riscv_gdbarch_init): Update call to riscv_features_from_bfd.
gdb/testsuite/ChangeLog:
* gdb.arch/riscv-default-tdesc.exp: New file.
When evaluating and expression containing UNOP_IND in mode
EVAL_AVOID_SIDE_EFFECTS, GDB currently (mostly) returns the result of
a call to value_zero meaning we get back an object with the correct
type, but its contents are all zero.
If the target type contains fields with dynamic type then in order to
resolve these dynamic fields GDB will need to read the value of the
field from within the parent object. In this case the field value
will be zero as a result of the call to value_zero mentioned above.
The idea behind EVAL_AVOID_SIDE_EFFECTS is to avoid the chance that
doing something like `ptype` will modify state within the target, for
example consider: ptype i++.
However, there is already precedence within GDB that sometimes, in
order to get accurate type results, we can't avoid reading from the
target, even when EVAL_AVOID_SIDE_EFFECTS is in effect. For example I
would point to eval.c:evaluate_var_value, the handling of OP_REGISTER,
the handling of value_x_unop in many places. I believe the Ada
expression evaluator also ignore EVAL_AVOID_SIDE_EFFECTS in some
cases.
I am therefor proposing that, in the case where a pointer points at a
dynamic type, we allow UNOP_IND to perform the actual indirection.
This allows accurate types to be displayed in more cases.
gdb/ChangeLog:
* eval.c (evaluate_subexp_standard): Call value_ind for points to
dynamic types in UNOP_IND.
gdb/testsuite/ChangeLog:
* gdb.fortran/pointer-to-pointer.exp: Additional tests.
Restrict the test gdb.arch/i386-biarch-core.exp to only run on
suitable targets.
gdb/testsuite/ChangeLog:
* gdb.arch/i386-biarch-core.exp: Add target check.
Please consider output of objdump for the executable generated from pr13961.S
-------------
Contents of the .debug_info section:
...
<1><62>: Abbrev Number: 2 (DW_TAG_class_type)
<63> DW_AT_name : foo2
<68> DW_AT_byte_size : 4
<69> DW_AT_decl_file : 1
<6a> DW_AT_decl_line : 1
<6b> DW_AT_sibling : <0x3f> !!! There is no DIE <0x3f>
...
Contents of the .debug_types section:
...
<1><25>: Abbrev Number: 8 (DW_TAG_class_type) !! Hand-inserted of size=5
<26> DW_AT_specification: <0x2a>
<1><2a>: Abbrev Number: 2 (DW_TAG_class_type)
<2b> DW_AT_name : foo
<2f> DW_AT_byte_size : 4
<30> DW_AT_decl_file : 1
<31> DW_AT_decl_line : 1
<32> DW_AT_sibling : <0x3f> !!! There is no DIE <0x3f>, should be <44>
<2><36>: Abbrev Number: 3 (DW_TAG_member)
<37> DW_AT_name : bar
<3b> DW_AT_decl_file : 1
<3c> DW_AT_decl_line : 4
<3d> DW_AT_type : <0x3f> !!! There is no DIE <0x3f>
<41> DW_AT_data_member_location: 0
<42> DW_AT_accessibility: 1 (public)
<2><43>: Abbrev Number: 0
<1><44>: Abbrev Number: 4 (DW_TAG_base_type)
<45> DW_AT_byte_size : 4
<46> DW_AT_encoding : 5 (signed)
<47> DW_AT_name : int
...
---------------
The original assembly is generated from a source file and then
modified to insert DIE, with that the subsequent DIE references
should have been updated, which were not.
It is now getting updated to replace hardcoded DIE references with
label-calculated references.
gdb/testsuite/ChangeLog:
2021-02-16 Alok Kumar Sharma <AlokKumar.Sharma@amd.com>
* gdb.dwarf2/pr13961.S: Corrected invalide DIE references.
In commit:
commit e92c8eb86dcef673652644694c832c504cf9a9a9
Date: Tue Feb 9 15:46:13 2021 +0000
gdb/fortran: add parser support for lbound and ubound
When I created the test gdb/testsuite/gdb.fortran/lbound-ubound.exp, I
copied the script from a different file and failed to delete the test
description comment at the top (even though I added a new
description). Fixed in this commit.
gdb/testsuite/ChangeLog:
* gdb.fortran/lbound-ubound.exp: Remove old comment.
The 'maintenance info sections' command currently takes a list of
filters on the command line. It can also accept the magic string
'ALLOBJ' which acts more like a command line flag, telling the command
to print information about all objfiles.
The manual has this to say about the options and filters:
... In addition, 'maint info sections' provides the following
command options (which may be arbitrarily combined): ...
Implying (to me at least) that I can do this:
(gdb) maint info sections ALLOBJ READONLY
to list all the read-only sections from all currently loaded object
files.
Unfortunately, this doesn't work. The READONLY filter will work, but
ALLOBJ will not be detected correctly.
It would be fairly simple to fix the ALLOBJ detection. However, I
dislike this mixing of command options (ALLOBJ) with command data (the
filters, e.g. READONLY, etc).
As this is a maintenance command, so not really intended for end
users, I think we can be a little more aggressive in "fixing" the
option parsing. So that's what I do in this commit.
The ALLOBJ mechanism is replaced with a real command
option (-all-objects). The rest of the command operates just as
before. The example above would now become:
(gdb) maint info sections -all-objects READONLY
The manual has been updated, and I added a NEWS entry to document the
change.
gdb/ChangeLog:
* NEWS: Mention changes to 'maint info sections'.
* maint.c (match_substring): Return a bool, fix whitespace issue.
(struct single_bfd_flag_info): New struct.
(bfd_flag_info): New static global.
(match_bfd_flags): Return a bool, use bfd_flag_info.
(print_bfd_flags): Use bfd_flag_info.
(maint_print_section_info): Delete trailing whitespace.
(struct maint_info_sections_opts): New struct.
(maint_info_sections_option_defs): New static global.
(maint_info_sections_completer): New function.
(maintenance_info_sections): Use option parsing mechanism.
(_initialize_maint_cmds): Register command completer.
gdb/doc/ChangeLog:
* gdb.texinfo (Files): Update documentation for 'maint info
sections'.
gdb/testsuite/ChangeLog:
* gdb.base/maint-info-sections.exp: Update expected output, and
add additional tests. Again.
The 'maint info sections' command is split into two blocks or work,
first if there's an executable then the sections from the executable,
and optionally all other loaded object files are printed. Then all
the sections from any core file are printed.
I ran into a situation where (for various reasons) I wasn't using a
main executable. Instead I connected to a remote target and used
add-symbol-file. This allowed me to debug an image that was already
loaded on the remote system.
Unfortunately, when I tried to use 'maint info sections' I saw
nothing. The reason is that the loop over all object files is hidden
behind a check that we have a main executable.
This commit removes this check and merges together some duplicate
code. I also (I think) made the output of this command cleaner.
Here is the original output of 'maint info sections':
Exec file:
`/tmp/hello.x', file type elf64-x86-64.
[0] 0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
And my modified output:
Exec file: `/home/andrew/tmp/hello.x', file type elf64-x86-64.
[0] 0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
The forced newline after 'Exec file: ' has been removed. This is now
a wrap point (in case the filename is very long).
Here is the original output of 'maint info sections ALLOBJ':
Exec file:
`/tmp/hello.x', file type elf64-x86-64.
Object file: /tmp/hello.x
[0] 0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
Object file: /lib64/ld-linux-x86-64.so.2
[0] 0x7ffff7fd12a8->0x7ffff7fd12c8 at 0x000002a8: .note.gnu.property ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x7ffff7fd12c8->0x7ffff7fd12ec at 0x000002c8: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
And my modified output:
Exec file: `/tmp/hello.x', file type elf64-x86-64.
[0] 0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
Object file: `/lib64/ld-linux-x86-64.so.2', file type elf64-x86-64.
[0] 0x7ffff7fd12a8->0x7ffff7fd12c8 at 0x000002a8: .note.gnu.property ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x7ffff7fd12c8->0x7ffff7fd12ec at 0x000002c8: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
The executable now only gets a single header line. The header line
for the additional object files is no longer indented as it was
before, and the line is laid out in a similar style to the main
executable line (with quotes and file type information).
And of course, the biggest change. If GDB is started with no
executable, but then the user does 'add-symbol-file ....' followed by
'maint info sections ALLOBJ', previously they got nothing, now they
get:
Object file: `/tmp/hello.x', file type elf64-x86-64.
[0] 0x004002a8->0x004002c4 at 0x000002a8: .interp ALLOC LOAD READONLY DATA HAS_CONTENTS
[1] 0x004002c4->0x004002e8 at 0x000002c4: .note.gnu.build-id ALLOC LOAD READONLY DATA HAS_CONTENTS
...
gdb/ChangeLog:
* maint.c (print_bfd_section_info_maybe_relocated): Delete,
functionality merged into...
(maint_print_all_sections): ...this new function.
(maintenance_info_sections): Make use of maint_print_all_sections,
allow all objects to be printed even where there's no executable.
gdb/testsuite/ChangeLog:
* gdb.base/maint-info-sections.exp: Update expected output, and
add additional tests.
The next couple of patches are going to add more tests for the 'maint
info sections' command. Rather than try to jam these tests into the
already quite long gdb.base/maint.c, this commit moves all of the
tests for 'maint info sections' into a new file.
I've updated the tests to make use of some newer testsuite constructs,
like -wrap and $gdb_test_name for gdb_test_multiple, but otherwise the
tests should not have changed with this commit.
gdb/testsuite/ChangeLog:
* gdb.base/maint-info-sections.exp: New file, content is moved
from gdb.base/maint.exp and cleaned up to use latest testsuite
techniques.
* gdb.base/maint.exp: Tests moved out to
gdb.base/maint-info-sections.exp.
The multi-target tests involve some inferiors using remote targets. By
default, GDB uses target: as the sysroot, which makes it read loaded
libraries and their debug info through GDBserver. This makes the tests
run slower than necessary.
Pass `-ex "set sysroot"` when launching GDB in these tests, so that GDB
always reads from its local file system.
On a system where I don't have debug info for libc, that reduces run
time for
$ make check TESTS="gdb.multi/multi-target-*.exp"
from 1:15 to 0:45.
On this other system where debug info is installed though, it reduces it
from 13:00 to 1:45.
gdb/testsuite/ChangeLog:
* gdb.multi/multi-target.exp.tcl (setup): Add "set sysroot" to
GDBFLAGS.
Change-Id: I9d24f3def843472d35dfb5667c12d70ae1d7e984
Add support for the LBOUND and UBOUND built in functions to the
Fortran expression parser.
Both support taking one or two arguments. A single argument, which
must be an array, returns an array containing all of the lower or
upper bound data.
When passed two arguments, the second argument is the dimension being
asked about. In this case the result is a scalar containing the lower
or upper bound just for that dimension.
Some examples of usage taken from the new test:
# Given:
# integer, dimension (-8:-1,-10:-2) :: neg_array
#
(gdb) p lbound (neg_array)
$1 = (-8, -10)
(gdb) p lbound (neg_array, 1)
$3 = -8
(gdb) p lbound (neg_array, 2)
$5 = -10
gdb/ChangeLog:
* f-exp.y (UNOP_OR_BINOP_INTRINSIC): New token.
(exp): New pattern using UNOP_OR_BINOP_INTRINSIC.
(one_or_two_args): New pattern.
(f77_keywords): Add lbound and ubound.
* f-lang.c (fortran_bounds_all_dims): New function.
(fortran_bounds_for_dimension): New function.
(evaluate_subexp_f): Handle FORTRAN_LBOUND and FORTRAN_UBOUND.
(operator_length_f): Likewise.
(print_subexp_f): Likewise.
(dump_subexp_body_f): Likewise.
(operator_check_f): Likewise.
* std-operator.def (FORTRAN_LBOUND): Define.
(FORTRAN_UBOUND): Define.
gdb/testsuite/ChangeLog:
* gdb.fortran/lbound-ubound.F90: New file.
* gdb.fortran/lbound-ubound.exp: New file.
In commit cf2b2075299 "[gdb/symtab] Fix element type modification in
read_array_type" I factored out new proc with_complaints out of proc
gdb_load_no_complaints, but when fixing a rebase conflict pre-commit I made a
mistake in gdb_load_no_complaints that is now causing:
...
ERROR: tcl error sourcing dw2-ranges-psym.exp.
ERROR: can't read "save": no such variable
while executing
"gdb_test_no_output "set complaints $save" """
(procedure "gdb_load_no_complaints" line 14)
invoked from within
"gdb_load_no_complaints $binfile"
...
Fix this by removing the offending line.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-02-10 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (gdb_load_no_complaints): Remove unnecessary
"Restore saved setting of complaints".
When running test-case gdb.fortran/function-calls.exp with target board
unix/gdb:debug_flags=-gdwarf-5, I run into:
...
(gdb) PASS: gdb.fortran/function-calls.exp: \
p derived_types_and_module_calls::pass_cart(c)
p derived_types_and_module_calls::pass_cart_nd(c_nd)^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x0000000000400f73 in derived_types_and_module_calls::pass_cart_nd \
(c=<error reading variable: Cannot access memory at address 0xc>) at \
function-calls.f90:130^M
130 pass_cart_nd = ubound(c%d,1,4)^M
The program being debugged was signaled while in a function called from GDB.^M
GDB has restored the context to what it was before the call.^M
To change this behavior use "set unwindonsignal off".^M
Evaluation of the expression containing the function^M
(derived_types_and_module_calls::pass_cart_nd) will be abandoned.^M
(gdb) FAIL: gdb.fortran/function-calls.exp: p
...
The problem originates in read_array_type, when reading a DW_TAG_array_type
with a dwarf-5 DW_TAG_generic_subrange child. This is not supported, and the
fallout of this is that rather than constructing a new array type, the code
proceeds to modify the element type.
Fix this conservatively by issuing a complaint and bailing out in
read_array_type when not being able to construct an array type, such that we
have:
...
(gdb) maint expand-symtabs function-calls.f90^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
During symbol reading: unable to find array range \
- DIE at 0xe1e [in module function-calls]^M
(gdb) KFAIL: gdb.fortran/function-calls.exp: no complaints in srcfile \
(PRMS: symtab/27388)
...
Tested on x86_64-linux.
gdb/ChangeLog:
2021-02-09 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* dwarf2/read.c (read_array_type): Return NULL when not being able to
construct an array type. Add assert to ensure that element_type is
not being modified.
gdb/testsuite/ChangeLog:
2021-02-09 Tom de Vries <tdevries@suse.de>
PR symtab/27341
* lib/gdb.exp (with_complaints): New proc, factored out of ...
(gdb_load_no_complaints): ... here.
* gdb.fortran/function-calls.exp: Add test-case.
While running tests on arm-none-eabi, I noticed following errors in some
gdb.threads tests.
ERROR: can't read "testfile": no such variable
These were being caused by ${testfile} being used before 'standard_testfile'
which sets it. This patch just moves standard_testfile before the use.
2021-02-09 Abid Qadeer <abidh@codesourcery.com>
gdb/testsuite/ChangeLog:
* gdb.threads/signal-command-handle-nopass.exp: Call
'standard_testfile' before using 'testfile'.
* gdb.threads/signal-command-multiple-signals-pending.exp: Likewise.
* gdb.threads/signal-delivered-right-thread.exp: Likewise
* gdb.threads/signal-sigtrap.exp: Likewise
The test expects the ifunc resolver to run lazily, at a later stage.
Depending on the distro and toolchain configuration, this is not the
case. Some configurations use non-lazy binding and thus the ifunc resolver
resolves all the ifunc references very early in the process startup, before
main.
Ubuntu is one such case. It has switched its toolchains to pass -Wl,z,now by
default, since 16.04. This wasn't a problem before 20.04 (at least for
aarch64) because the toolchains did not support ifunc's.
Forcing lazy binding makes the test run as expected, as opposed to the 80 or
so failures it showed before the change.
Tested on aarch64-linux/x86_64-linux Ubuntu 20.04.
gdb/testsuite:
2021-02-08 Luis Machado <luis.machado@linaro.org>
* gdb.base/gnu-ifunc.exp (build): Pass -Wl,z,lazy.
When running test-case gdb.dwarf2/enqueued-cu-base-addr.exp with target board
cc-with-dwz, I get:
...
gdb compile failed, dwz: enqueued-cu-base-addr: \
Couldn't find DIE at [100] referenced by DW_AT_type from DIE at [d8]
...
At 0xd8 we have DIE:
...
<1><d8>: Abbrev Number: 3 (DW_TAG_variable)
<d9> DW_AT_name : foo
<dd> DW_AT_type : <0x100>
<e1> DW_AT_const_value : 1
...
referring to:
...
<1><100>: Abbrev Number: 3 (DW_TAG_base_type)
<101> DW_AT_byte_size : 4
<102> DW_AT_encoding : 5 (signed)
<103> DW_AT_name : int
...
The reference is inter-CU, but the used abbrev uses DW_FORM_ref4:
...
3 DW_TAG_variable [no children]
DW_AT_name DW_FORM_string
DW_AT_type DW_FORM_ref4
DW_AT_const_value DW_FORM_sdata
DW_AT value: 0 DW_FORM value: 0
...
which is for intra-CU references.
Fix this by using a '%' instead of a ':' label prefix in the dwarf assembly.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-02-08 Tom de Vries <tdevries@suse.de>
* gdb.dwarf2/enqueued-cu-base-addr.exp: Fix inter-CU reference.
If the user implements a TUI window in Python, and this window
responds to GDB events and then redraws its window contents then there
is currently an edge case which can lead to problems.
The Python API documentation suggests that calling methods like erase
or write on a TUI window (from Python code) will raise an exception if
the window is not valid.
And the description for is_valid says:
This method returns True when this window is valid. When the user
changes the TUI layout, windows no longer visible in the new layout
will be destroyed. At this point, the gdb.TuiWindow will no longer
be valid, and methods (and attributes) other than is_valid will
throw an exception.
From this I, as a user, would expect that if I did 'tui disable' to
switch back to CLI mode, then the window would no longer be valid.
However, this is not the case.
When the TUI is disabled the windows in the TUI are not deleted, they
are simply hidden. As such, currently, the is_valid method continues
to return true.
This means that if the users Python code does something like:
def event_handler (e):
global tui_window_object
if tui_window_object->is_valid ():
tui_window_object->erase ()
tui_window_object->write ("Hello World")
gdb.events.stop.connect (event_handler)
Then when a stop event arrives GDB will try to draw the TUI window,
even when the TUI is disabled.
This exposes two bugs. First, is_valid should be returning false in
this case, second, if the user forgot to add the is_valid call, then I
believe the erase and write calls should be throwing an
exception (when the TUI is disabled).
The solution to both of these issues is I think bound together, as it
depends on having a working 'is_valid' check.
There's a rogue assert added into tui-layout.c as part of this
commit. While working on this commit I managed to break GDB such that
TUI_CMD_WIN was nullptr, this was causing GDB to abort. I'm leaving
the assert in as it might help people catch issues in the future.
This patch is inspired by the work done here:
https://sourceware.org/pipermail/gdb-patches/2020-December/174338.html
gdb/ChangeLog:
* python/py-tui.c (gdbpy_tui_window) <is_valid>: New member
function.
(REQUIRE_WINDOW): Call is_valid member function.
(REQUIRE_WINDOW_FOR_SETTER): New define.
(gdbpy_tui_is_valid): Call is_valid member function.
(gdbpy_tui_set_title): Call REQUIRE_WINDOW_FOR_SETTER instead.
* tui/tui-data.h (struct tui_win_info) <is_visible>: Check
tui_active too.
* tui/tui-layout.c (tui_apply_current_layout): Add an assert.
* tui/tui.c (tui_enable): Move setting of tui_active earlier in
the function.
gdb/doc/ChangeLog:
* python.texinfo (TUI Windows In Python): Extend description of
TuiWindow.is_valid.
gdb/testsuite/ChangeLog:
* gdb.python/tui-window-disabled.c: New file.
* gdb.python/tui-window-disabled.exp: New file.
* gdb.python/tui-window-disabled.py: New file.
There's a bug in the python tui API. If the user tries to delete the
window title attribute then this will trigger undefined behaviour in
GDB due to a missing nullptr check.
gdb/ChangeLog:
* python/py-tui.c (gdbpy_tui_set_title): Check that the new value
for the title is not nullptr.
gdb/testsuite/ChangeLog:
* gdb.python/tui-window.exp: Add new tests.
* gdb.python/tui-window.py (TestWindow) <__init__>: Store
TestWindow object into global the_window.
<remote_title>: New method.
(delete_window_title): New function.
This commit was inspired by this mailing list patch:
https://sourceware.org/pipermail/gdb-patches/2021-January/174713.html
Currently, calling tui_layout_window::apply will add the window from
the layout object to the global tui_windows list.
Unfortunately, when the user runs the 'winheight' command, this calls
tui_adjust_window_height, which calls the tui_layout_base::adjust_size
function, which can then call tui_layout_base::apply. The consequence
of this is that when the user does 'winheight' duplicate copies of a
window can be added to the global tui_windows list.
The original patch fixed this by changing the apply function to only
update the global list some of the time.
This patch takes a different approach. The apply function no longer
updates the global tui_windows list. Instead a new virtual function
is added to tui_layout_base which is used to gather all the currently
applied windows into a vector. Finally tui_apply_current_layout is
updated to make use of this new function to update the tui_windows
list.
The benefits I see in this approach are, (a) the apply function now no
longer touches global state, this solves the immediate problem,
and (b) now that tui_windows is updated directly in the function
tui_apply_current_layout, we can drop the saved_tui_windows global.
gdb/ChangeLog:
* tui-layout.c (saved_tui_windows): Delete.
(tui_apply_current_layout): Don't make use of saved_tui_windows,
call new get_windows member function instead.
(tui_get_window_by_name): Check in tui_windows.
(tui_layout_window::apply): Don't add to tui_windows.
* tui-layout.h (tui_layout_base::get_windows): New member function.
(tui_layout_window::get_windows): Likewise.
(tui_layout_split::get_windows): Likewise.
gdb/testsuite/ChangeLog:
* gdb.tui/winheight.exp: Add more tests.
While working on another patch I noticed an oddly formatted error
message in the Python code.
When 'set python print-stack message' is in effect then consider this
Python script:
class TestCommand (gdb.Command):
def __init__ (self):
gdb.Command.__init__ (self, "test-cmd", gdb.COMMAND_DATA)
def invoke(self, args, from_tty):
raise RuntimeError ("bad")
TestCommand ()
And this GDB session:
(gdb) source path/to/python/script.py
(gdb) test-cmd
Python Exception <class 'RuntimeError'> bad:
Error occurred in Python: bad
The line 'Python Exception <class 'RuntimeError'> bad:' doesn't look
terrible in this situation, the colon at the end of the first line
makes sense given the second line.
However, there are places in GDB where there is no second line
printed, for example consider this python script:
def stop_listener (e):
raise RuntimeError ("bad")
gdb.events.stop.connect (stop_listener)
Then this GDB session:
(gdb) file helloworld.exe
(gdb) start
Temporary breakpoint 1 at 0x40112a: file hello.c, line 6.
Starting program: helloworld.exe
Temporary breakpoint 1, main () at hello.c:6
6 printf ("Hello World\n");
Python Exception <class 'RuntimeError'> bad:
(gdb) si
0x000000000040112f 6 printf ("Hello World\n");
Python Exception <class 'RuntimeError'> bad:
In this case there is no auxiliary information displayed after the
warning, and the line ending in the colon looks weird to me.
A quick survey of the code seems to indicate that it is not uncommon
for there to be no auxiliary information line printed, its not just
the one case I found above.
I propose that the line that currently looks like this:
Python Exception <class 'RuntimeError'> bad:
Be reformatted like this:
Python Exception <class 'RuntimeError'>: bad
I think this looks fine then in either situation. The first now looks
like this:
(gdb) test-cmd
Python Exception <class 'RuntimeError'>: bad
Error occurred in Python: bad
And the second like this:
(gdb) si
0x000000000040112f 6 printf ("Hello World\n");
Python Exception <class 'RuntimeError'>: bad
There's just two tests that needed updating. Errors are checked for
in many more tests, but most of the time the pattern doesn't care
about the colon.
gdb/ChangeLog:
* python/python.c (gdbpy_print_stack): Reformat an error message.
gdb/testsuite/ChangeLog:
* gdb.python/py-framefilter.exp: Update expected results.
* gdb.python/python.exp: Update expected results.
My initial goal was to fix our gdb/testsuite/lib/tuiterm.exp such that
it would correctly support (some limited) scrolling of the command
window.
What I observe is that when sending commands to the tui command window
in a test script with:
Term::command "p 1"
The command window would be left looking like this:
(gdb)
(gdb) p 1$1 = 1
(gdb)
When I would have expected it to look like this:
(gdb) p 1
$1 = 1
(gdb)
Obviously a bug in our tuiterm.exp library, right???
Wrong!
Turns out there's a bug in GDB.
If in GDB I enable the tui and then type (slowly) the 'p 1\r' (the \r
is pressing the return key at the end of the string), then you do
indeed get the "expected" terminal output.
However, if instead I copy the 'p 1\r' string and paste it into the
tui in one go then I now see the same corrupted output as we do when
using tuiterm.exp.
It turns out the problem is that GDB fails when handling lots of input
arriving quickly with a \r (or \n) on the end.
The reason for this bug is as follows:
When the tui is active the terminal is in no-echo mode, so characters
sent to the terminal are not echoed out again. This means that when
the user types \r, this is not echoed to the terminal.
The characters read in are passed to readline and \r indicates that
the command line is complete and ready to be processed. However, the
\r is not included in readlines command buffer, and is NOT printed by
readline when is displays its buffer to the screen.
So, in GDB we have to manually spot the \r when it is read in and
update the display. Printing a newline character to the output and
moving the cursor to the next line. This is done in tui_getc_1.
Now readline tries to reduce the number of write calls. So if we very
quickly (as in paste in one go) the text 'p 1' to readline (this time
with no \r on the end), then readline will fetch the fist character
and add it to its internal buffer. But before printing the character
out readline checks to see if there's more input incoming. As we
pasted multiple characters, then yes, readline sees the ' ' and adds
this to its buffer, and finally the '1', this too is added to the
buffer.
Now if at this point we take a break, readline sees there is no more
input available, and so prints its buffer out.
Now when we press \r the code in tui_getc_1 kicks in, adds a \n to the
output and moves the cursor to the next line.
But, if instead we paste 'p 1\r' in one go then readline adds 'p 1' to
its buffer as before, but now it sees that there is still more input
available. Now it fetches the '\r', but this triggers the newline
behaviour, we print '\n' and move to the next line - however readline
has not printed its buffer yet!
So finally we end up on the next line. There's no more input
available so readline prints its buffer, then GDB gets passed the
buffer, handles it, and prints the result.
The solution I think is to put of our special newline insertion code
until we know that readline has finished printing its buffer. Handily
we know when this is - the next thing readline does is pass us the
command line buffer for processing. So all we need to do is hook in
to the command line processing, and before we pass the command line to
GDB's internals we do all of the magic print a newline and move the
cursor to the next line stuff.
Luckily, GDB's interpreter mechanism already provides the hooks we
need to do this. So all I do here is move the newline printing code
from tui_getc_1 into a new function, setup a new input_handler hook
for the tui, and call my new newline printing function.
After this I can enable the tui and paste in 'p 1\r' and see the
correct output.
Also the tuiterm.exp library will now see non-corrupted output.
gdb/ChangeLog:
* tui/tui-interp.c (tui_command_line_handler): New function.
(tui_interp::resume): Register tui_command_line_handler as the
input_handler.
* tui/tui-io.c (tui_inject_newline_into_command_window): New
function.
(tui_getc_1): Delete handling of '\n' and '\r'.
* tui-io.h (tui_inject_newline_into_command_window): Declare.
gdb/testsuite/ChangeLog:
* gdb.tui/scroll.exp: Tighten expected results. Remove comment
about bug in GDB, update expected results, and add more tests.
The implementation of the delete line escape sequence in tuiterm.exp
was wrong. Delete should take a count and then delete COUNT lines at
the current cursor location, all remaining lines in the scroll region
are moved up to replace the deleted lines, with blank lines being
added at the end of the scroll region.
It's not clear to me what "scroll region" means here (or at least how
that is defined), but for now I'm just treating the whole screen as
the scroll region, which seems to work fine.
In contrast the current broken implementation deletes COUNT lines at
the cursor location moving the next COUNT lines up to fill the gap.
The rest of the screen is then cleared.
gdb/testsuite/ChangeLog:
* gdb.tui/scroll.exp: New file.
* gdb.tui/tui-layout-asm-short-prog.exp: Update expected results.
* lib/tuiterm.exp (Term::_csi_M): Delete count lines, scroll
remaining lines up.
(Term::check_region_contents): New proc.
(Term::check_box_contents): Use check_region_contents.