In preparation for a following patch, refactor a few things that I did
find a bit awkward, and to make them a bit more reusable.
- Pass an inferior to kill_new_fork_children instead of a pid. That
allows iterating on only this inferior's threads and avoid further
filtering on the thread's pid.
- Change thread_pending_fork_status to return a non-nullptr value only
if the thread does have a pending fork status.
- Remove is_pending_fork_parent_thread, as one can just use
thread_pending_fork_status and check for nullptr.
- Replace is_pending_fork_parent with is_fork_status, which just
returns if the given target_waitkind if a fork or a vfork. Push
filtering on the pid to the callers, when it is necessary.
Change-Id: I0764ccc684d40f054e39df6fa5458cc4c5d1cd7b
Move the stop_reply and a few functions up. Some code above them in the
file will need to use them in a following patch. No behavior changes
expected here.
Change-Id: I3ca57d0e3ec253f56e1ba401289d9d167de14ad2
The following patch will add some code paths that need to ptrace-detach
a given PID. Factor out the code that does this and put it in its own
function, so that it can be re-used.
Change-Id: Ie65ca0d89893b41aea0a23d9fc6ffbed042a9705
This patch aims at fixing a bug where an inferior is unexpectedly
created when a fork happens at the same time as another event, and that
other event is reported to GDB first (and the fork event stays pending
in GDBserver). This happens for example when we step a thread and
another thread forks at the same time. The bug looks like (if I
reproduce the included test by hand):
(gdb) show detach-on-fork
Whether gdb will detach the child of a fork is on.
(gdb) show follow-fork-mode
Debugger response to a program call of fork or vfork is "parent".
(gdb) si
[New inferior 2]
Reading /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/step-while-fork-in-other-thread/step-while-fork-in-other-thread from remote target...
Reading /home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/step-while-fork-in-other-thread/step-while-fork-in-other-thread from remote target...
Reading symbols from target:/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.threads/step-while-fork-in-other-thread/step-while-fork-in-other-thread...
[New Thread 965190.965190]
[Switching to Thread 965190.965190]
Remote 'g' packet reply is too long (expected 560 bytes, got 816 bytes): ... <long series of bytes>
The sequence of events leading to the problem is:
- We are using the all-stop user-visible mode as well as the
synchronous / all-stop variant of the remote protocol
- We have two threads, thread A that we single-step and thread B that
calls fork at the same time
- GDBserver's linux_process_target::wait pulls the "single step
complete SIGTRAP" and the "fork" events from the kernel. It
arbitrarily choses one event to report, it happens to be the
single-step SIGTRAP. The fork stays pending in the thread_info.
- GDBserver send that SIGTRAP as a stop reply to GDB
- While in stop_all_threads, GDB calls update_thread_list, which ends
up querying the remote thread list using qXfer:threads:read.
- In the reply, GDBserver includes the fork child created as a result
of thread B's fork.
- GDB-side, the remote target sees the new PID, calls
remote_notice_new_inferior, which ends up unexpectedly creating a new
inferior, and things go downhill from there.
The problem here is that as long as GDB did not process the fork event,
it should pretend the fork child does not exist. Ultimately, this event
will be reported, we'll go through follow_fork, and that process will be
detached.
The remote target (GDB-side), has some code to remove from the reported
thread list the threads that are the result of forks not processed by
GDB yet. But that only works for fork events that have made their way
to the remote target (GDB-side), but haven't been consumed by the core
yet, so are still lingering as pending stop replies in the remote target
(see remove_new_fork_children in remote.c). But in our case, the fork
event hasn't made its way to the GDB-side remote target. We need to
implement the same kind of logic GDBserver-side: if there exists a
thread / inferior that is the result of a fork event GDBserver hasn't
reported yet, it should exclude that thread / inferior from the reported
thread list.
This was actually discussed a while ago, but not implemented AFAIK:
https://pi.simark.ca/gdb-patches/1ad9f5a8-d00e-9a26-b0c9-3f4066af5142@redhat.com/#thttps://sourceware.org/pipermail/gdb-patches/2016-June/133906.html
Implementation details-wise, the fix for this is all in GDBserver. The
Linux layer of GDBserver already tracks unreported fork parent / child
relationships using the lwp_info::fork_relative, in order to avoid
wildcard actions resuming fork childs unknown to GDB. This information
needs to be made available to the handle_qxfer_threads_worker function,
so it can filter the reported threads. Add a new thread_pending_parent
target function that allows the Linux target to return the parent of an
eventual fork child.
Testing-wise, the test replicates pretty-much the sequence of events
shown above. The setup of the test makes it such that the main thread
is about to fork. We stepi the other thread, so that the step completes
very quickly, in a single event. Meanwhile, the main thread is resumed,
so very likely has time to call fork. This means that the bug may not
reproduce every time (if the main thread does not have time to call
fork), but it will reproduce more often than not. The test fails
without the fix applied on the native-gdbserver and
native-extended-gdbserver boards.
At some point I suspected that which thread called fork and which thread
did the step influenced the order in which the events were reported, and
therefore the reproducibility of the bug. So I made the test try both
combinations: main thread forks while other thread steps, and vice
versa. I'm not sure this is still necessary, but I left it there
anyway. It doesn't hurt to test a few more combinations.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28288
Change-Id: I2158d5732fc7d7ca06b0eb01f88cf27bf527b990
There are some loops in gdb that use ARRAY_SIZE (or a wordier
equivalent) to loop over a static array. This patch changes some of
these to use foreach instead.
Regression tested on x86-64 Fedora 34.
In my earlier C++-ization patch for file_and_directory, I introduced
an error:
- if (strcmp (fnd.name, "<unknown>") != 0)
+ if (fnd.is_unknown ())
This change inverted the sense of the test, which causes failures with
.debug_names.
This patch fixes the bug. Regression tested on x86-64 Fedora 34. I
also tested it using the AdaCore internal test suite, with
.debug_names -- this was failing before, and now it works.
The documentation suggests that we implement gdb.Value.__init__,
however, this is not currently true, we really implement
gdb.Value.__new__. This will cause confusion if a user tries to
sub-class gdb.Value. They might write:
class MyVal (gdb.Value):
def __init__ (self, val):
gdb.Value.__init__(self, val)
obj = MyVal(123)
print ("Got: %s" % obj)
But, when they source this code they'll see:
(gdb) source ~/tmp/value-test.py
Traceback (most recent call last):
File "/home/andrew/tmp/value-test.py", line 7, in <module>
obj = MyVal(123)
File "/home/andrew/tmp/value-test.py", line 5, in __init__
gdb.Value.__init__(self, val)
TypeError: object.__init__() takes exactly one argument (the instance to initialize)
(gdb)
The reason for this is that, as we don't implement __init__ for
gdb.Value, Python ends up calling object.__init__ instead, which
doesn't expect any arguments.
The Python docs suggest that the reason why we might take this
approach is because we want gdb.Value to be immutable:
https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_new
But I don't see any reason why we should require gdb.Value to be
immutable when other types defined in GDB are not. This current
immutability can be seen in this code:
obj = gdb.Value(1234)
print("Got: %s" % obj)
obj.__init__ (5678)
print("Got: %s" % obj)
Which currently runs without error, but prints:
Got: 1234
Got: 1234
In this commit I propose that we switch to using __init__ to
initialize gdb.Value objects.
This does introduce some additional complexity, during the __init__
call a gdb.Value might already be associated with a gdb value object,
in which case we need to cleanly break that association before
installing the new gdb value object. However, the cost of doing this
is not great, and the benefit - being able to easily sub-class
gdb.Value seems worth it.
After this commit the first example above works without error, while
the second example now prints:
Got: 1234
Got: 5678
In order to make it easier to override the gdb.Value.__init__ method,
I have tweaked the definition of gdb.Value.__init__. The second,
optional argument to __init__ is a gdb.Type, if this argument is not
present then GDB figures out a suitable type.
However, if we want to override the __init__ method in a sub-class,
and still support the default argument, it is easier to write:
class MyVal (gdb.Value):
def __init__ (self, val, type=None):
gdb.Value.__init__(self, val, type)
Currently, passing None for the Type will result in an error:
TypeError: type argument must be a gdb.Type.
After this commit I now allow the type argument to be None, in which
case GDB figures out a suitable type just as if the type had not been
passed at all.
Unless a user is trying to reinitialize a value, or create sub-classes
of gdb.Value, there should be no user visible changes after this
commit.
While investigating some disassembler problems I ran into this case;
GDB compiled on a 32-bit arm target, with --enable-targets=all. Then
in GDB:
(gdb) set architecture i386
(gdb) disassemble 0x0,+4
unknown disassembler error (error = -1)
This is interesting because it shows a case where the libopcodes
disassembler is returning -1 without first calling the
memory_error_func callback. Indeed, the return from libopcodes
happens from this code snippet in i386-dis.c in the print_insn
function:
if (address_mode == mode_64bit && sizeof (bfd_vma) < 8)
{
(*info->fprintf_func) (info->stream,
_("64-bit address is disabled"));
return -1;
}
Notice how, prior to the return the disassembler tries to print a
helpful message out, but GDB doesn't print this message.
The reason this message goes missing is the call stack, it looks like
this:
gdb_pretty_print_disassembler::pretty_print_insn
gdb_disassembler::print_insn
gdbarch_print_insn
...
i386-dis.c:print_insn
When i386-dis.c:print_insn returns -1 this is handled in
gdb_disassembler::print_insn, where an exception is thrown. However,
the actual printing of the disassembler output is done in
gdb_pretty_print_disassembler::pretty_print_insn, and is only done if
an exception is not thrown.
In this commit I change this. The pretty_print_insn now uses
try/catch around the call to gdb_disassembler::print_insn, if we catch
an error then we first print any pending output in the instruction
buffer, before rethrowing the exception. As a result, even if an
exception is thrown we still print any pending disassembler output to
the screen; in the above case the helpful message will now be shown.
Before my patch we might expect to see this output:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000: unknown disassembler error (error = -1)
(gdb)
But now we see this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000: 64-bit address is disabled
unknown disassembler error (error = -1)
If the disassembler returns -1 without printing a helpful message then
we would still expect a change in output, something like:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x0000000000000000:
unknown disassembler error (error = -1)
Which I think is still acceptable, though at this point I think a
strong case can be made that this is a disassembler bug (not printing
anything, but still returning -1).
Notice however, that the error message is always printed on a new line
now. This is also true for the memory error case, where before we
might see this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x00000000: Cannot access memory at address 0x0
We now get this:
(gdb) disassemble 0x0,+4
Dump of assembler code from 0x0 to 0x4:
0x00000000:
Cannot access memory at address 0x0
For me, I'm happy to accept this change, having the error on a line by
itself, rather than just appended to the end of the previous line,
seems like an improvement, but I'm aware others might feel
differently, so I'd appreciate any feedback.
Permanent program breakpoints (ones inserted into the code) other than
the one GDB uses for POWER (0x7fe00008) did not result in stop but
caused GDB to loop infinitely.
This was because GDB did not recognize trap instructions other than
"trap". For example, "tw 12, 4, 4" was not be recognized, causing GDB
to loop forever.
This commit fixes this by providing POWER specific hook
(gdbarch_program_breakpoint_here_p) recognizing all tw, twi, td and tdi
instructions.
Tested on Linux on PowerPC e500 and on QEMU PPC64le.
Power ISA 3.0 B spec [1], sections 3.3.11 "Fixed-Point Trap Instructions"
and section C.6 "Trap Mnemonics" specify "tw, 31, 0, 0" (encoded as
0x7fe00008) as canonical unconditional trap instruction.
This commit changes the breakpoint instruction used by GDB from
"tw 12, r2, r2" to unconditional "trap".
[1]: https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0
struct linespec contains pointers to vectors, instead of containing
vectors directly. This is probably historical, when linespec_parser
(which contains a struct linespec field) was not C++-ified yet. But it
seems easy to change the pointers to vectors to just vectors today.
This simplifies the code, we don't need to manually allocate and delete
the vectors and there's no pointer that can be NULL.
As far as I understand, there was not meaningful distinction between a
NULL pointer to vector and an empty vector. So all NULL checks are
changed for !empty checks.
Change-Id: Ie759707da14d9d984169b93233343a86e2de9ee6
We can remove the empty check: if the vector has size 1, it is obviously
not empty. This code ended up like this because the empty check used to
be a NULL check.
Change-Id: I1571bd0228818ca93f6a6b444e9b010dc2da4c08
Functions agent_eval_command and agent_command are used to implement
maintenance commands, rename them accordingly (with the maint_ prefix),
as well as the agent_command_1 helper function.
Change-Id: Iacf96d4a0a26298e8dd4648a0f38da649ea5ef61
FreeBSD's kernel has recently added two new ELF auxiliary vector
entries. AT_FXRNG points to a root seed version for the kernel's
PRNG. Userland can use this to reseed a userland PRNG after the
kernel's PRNG has reseeded. AT_KPRELOAD is the base address of a
kernel-provided vDSO.
This change displays the proper name and description of these entries
in 'info auxv'.
include/ChangeLog:
* elf/common.h (AT_FREEBSD_FXRNG, AT_FREEBSD_KPRELOAD): Define.
I noticed that global_symbol_searcher::expand_symtabs always passes a
file matcher to expand_symtabs_matching. However, if 'filenames' is
empty, then this always returns true. It's slightly more efficient to
pass a null file matcher in this case, because that lets the "quick"
symbol implementations skip any filename checks.
Regression tested on x86-64 Fedora 34.
In commit 80ad340c90 ("[gdb/testsuite] use -Ttext-segment for jit-elf tests")
the following change was made:
...
proc compile_jit_elf_main_as_so {main_solib_srcfile main_solib_binfile options} {
- set options [concat $options debug]
+ global jit_load_address jit_load_increment
+
+ set options [list \
+ additional_flags="-DMAIN=jit_dl_main" \
+ additional_flags=-DLOAD_ADDRESS=$jit_load_address \
+ additional_flags=-DLOAD_INCREMENT=$jit_load_increment \
+ debug]
...
Before the change, the options argument was used, but after the change not
anymore.
Fix this by reverting back to using "set options [concat $options ...]".
Fixing this gets us twice the -DMAIN=jit_dl_main bit, once from a caller, and
once from compile_jit_elf_main_as_so. Fix this by removing the bit from
compile_jit_elf_main_as_so, which makes the code similar to compile_jit_main.
Tested on x86_64-linux.
On openSUSE Leap 15.2 aarch64 I ran into:
...
FAIL: gdb.tui/basic.exp: check main is where we expect on the screen
...
while this is passing on x86_64.
On x86_64-linux we have at the initial screen dump for "list -q main":
...
0 +-/home/vries/gdb_versions/devel/src/gdb/testsuite/gdb.tui/tui-layout.c--+
1 | 15 You should have received a copy of the GNU General Public |
2 | 16 along with this program. If not, see <http://www.gnu.org/|
3 | 17 |
4 | 18 int |
5 | 19 main () |
6 | 20 { |
7 | 21 return 0; |
8 | 22 } |
9 | 23 |
...
but on aarch64:
...
0 +-/home/tdevries/gdb/src/gdb/testsuite/gdb.tui/tui-layout.c--------------+
1 | 16 along with this program. If not, see <http://www.gnu.org/|
2 | 17 |
3 | 18 int |
4 | 19 main () |
5 | 20 { |
6 | 21 return 0; |
7 | 22 } |
8 | 23 |
9 | 24 |
...
The cause of the diffferent placement is that we have as line number for main
on x86_64:
...
$ gdb -q -batch outputs/gdb.tui/basic/basic -ex "info line main"
Line 20 of "tui-layout.c" starts at address 0x4004a7 <main> \
and ends at 0x4004ab <main+4>.
...
and on aarch64 instead:
...
$ gdb -q -batch outputs/gdb.tui/basic/basic -ex "info line main"
Line 21 of "tui-layout.c" starts at address 0x4005f4 <main> \
and ends at 0x4005f8 <main+4>.
...
Fix this by using a new source file main-one-line.c, that implements the
entire main function on a single line, in order to force the compiler to use
that line number.
Also try to do less hard-coding in the test-case.
Tested on x86_64-linux and aarch64-linux.
Consider test-case test.c:
...
int main (void) {
void *p = malloc (10);
return 0;
}
...
When compiled to a non-PIE exec:
...
$ gcc -m32 test.c
...
the call sequence looks like:
...
8048447: 83 ec 0c sub $0xc,%esp
804844a: 6a 0a push $0xa
804844c: e8 bf fe ff ff call 8048310 <malloc@plt>
...
which calls to:
...
08048310 <malloc@plt>:
8048310: ff 25 0c a0 04 08 jmp *0x804a00c
8048316: 68 00 00 00 00 push $0x0
804831b: e9 e0 ff ff ff jmp 8048300 <.plt>
...
where the first insn at 0x8048310 initially jumps to the following address
0x8048316, read from the .got.plt @ 0x804a00c:
...
804a000 0c9f0408 00000000 00000000 16830408 ................
804a010 26830408 &...
...
Likewise, when compiled as a PIE:
...
$ gcc -m32 -fPIE -pie test.c
...
we have this call sequence (with %ebx setup to point to the .got.plt):
...
0000055d <main>:
579: 83 ec 0c sub $0xc,%esp
57c: 6a 0a push $0xa
57e: 89 c3 mov %eax,%ebx
580: e8 6b fe ff ff call 3f0 <malloc@plt>
...
which calls to:
...
000003f0 <malloc@plt>:
3f0: ff a3 0c 00 00 00 jmp *0xc(%ebx)
3f6: 68 00 00 00 00 push $0x0
3fb: e9 e0 ff ff ff jmp 3e0 <.plt>
...
where the insn at 0x3f0 initially jumps to following address 0x3f6, read from
the .got.plt at offset 0xc:
...
2000 f41e0000 00000000 00000000 f6030000 ................
2010 06040000 ....
...
When instead doing an inferior call to malloc (with nosharedlib to force
malloc to resolve to malloc@plt rather than the functions in ld.so or libc.so)
with the non-PIE exec, we have the expected:
...
$ gdb -q -batch a.out -ex start -ex nosharedlib -ex "p /x (void *)malloc (10)"
Temporary breakpoint 1 at 0x8048444
Temporary breakpoint 1, 0x08048444 in main ()
$1 = 0x804b160
...
But with the PIE exec, we run into:
...
$ gdb -q -batch a.out -ex start -ex nosharedlib -ex "p /x (void *)malloc (10)"
Temporary breakpoint 1 at 0x56c
Temporary breakpoint 1, 0x5655556c in main ()
Program received signal SIGSEGV, Segmentation fault.
0x565553f0 in malloc@plt ()
...
The segfault happens because:
- the inferior call mechanism doesn't setup %ebx
- %ebx instead is 0
- the jump to "*0xc(%ebx)" reads from memory at 0xc
Fix this by setting up %ebx properly in i386_thiscall_push_dummy_call.
Fixes this failure with target board unix/-m32/-pie/-fPIE reported in
PR28467:
...
FAIL: gdb.base/nodebug.exp: p/c (int) array_index("abcdef",2)
...
Tested on x86_64-linux, with target board unix/-m32 and unix/-m32/-fPIE/-pie.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28467
When running test-case gdb.base/cached-source-file.exp with target board
readnow, we run into:
...
FAIL: gdb.base/cached-source-file.exp: rerun program (the program exited)
...
The problem is that when rereading, the readnow is ignored.
Fix this by copying the readnow handling code from symbol_file_add_with_addrs
to reread_symbols.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26800
On openSUSE Leap 42.3, with system compiler gcc 4.8.5 I run into:
...
(gdb) print u_one_two_three^M
src/gdb/gdbtypes.h:1050: internal-error: field: \
Assertion `idx >= 0 && idx < num_fields ()' failed.^M
...
We run into trouble while doing this in
ada_is_unconstrained_packed_array_type:
...
1953 return TYPE_FIELD_BITSIZE (type, 0) > 0;
...
which tries to get field 0 from a type without fields:
...
(gdb) p type->num_fields ()
$6 = 0
...
which is the case because the type is a typedef:
...
(gdb) p type->code ()
$7 = TYPE_CODE_TYPEDEF
...
Fix this by using the type referenced by the typedef instead.
Tested on x86_64-linux.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28323
This patch adds an #elif defined for PowerPC to setup the exit_0 macro.
This patch addes the needed macro definitionald logic to handle both elfV1
and elfV2.
The patch has been successfully tested on both PowerPC BE, Powerpc LE and
X86_64 with no regressions.
Test-cases gdb.arch/i386-{avx,sse}.exp use assembly instructions that require
the memory operands to be aligned to a certain boundary, and the test-cases
use C11's _Alignas to make that happen.
The draw-back of using _Alignas is that while it does enforce a minimum
alignment, the actual alignment may be bigger, which makes the following
scenario possible:
- copy say, gdb.arch/i386-avx.c as basis for a new test-case
- run the test-case and observe a PASS
- commit the new test-case in the supposition that the test-case is correct
and well-tested
- run later into a failure on a different test setup (which may be a setup
where reproduction and investigation is more difficult and time-consuming),
and find out that the specified alignment was incorrect and should have been
updated to say, 64 bytes. The initial PASS occurred only because the actual
alignment happened to be greater than required.
The idea of having precise alignment as a means of having more predictable
execution which allows flushing out bugs earlier, has been filed as PR
gcc/103095.
Add a new file lib/precise-aligned-alloc.c with functions
precise_aligned_alloc and precise_aligned_dup, to support precise alignment.
Use precise_aligned_dup in aforementioned test-cases to:
- verify that the specified alignment is indeed sufficient, rather
than too little but accidentally over-aligned.
- prevent the same type of problems in any new test-cases based on these
Tested on x86_64-linux, with both gcc and clang.
When running test-case gdb.arch/i386-avx.exp with clang I ran into:
...
(gdb) PASS: gdb.arch/i386-avx.exp: set first breakpoint in main
continue^M
Continuing.^M
^M
Program received signal SIGSEGV, Segmentation fault.^M
0x000000000040052b in main (argc=1, argv=0x7fffffffd3c8) at i386-avx.c:54^M
54 asm ("vmovaps 0(%0), %%ymm0\n\t"^M
(gdb) FAIL: gdb.arch/i386-avx.exp: continue to breakpoint: \
continue to first breakpoint in main
...
The problem is that the vmovaps insn requires an 256-bit (or 32-byte) aligned
address, and it's only 16-byte aligned:
...
(gdb) p /x $rax
$1 = 0x601030
...
Fix this by using a sufficiently aligned address, using _Alignas.
Compile using -std=gnu11 to support _Alignas.
Likewise in gdb.arch/i386-sse.exp.
Tested on x86_64-linux, with both gcc and clang.
This fixes a use-after-free that Simon pointed out.
process_psymtab_comp_unit_reader was allocating an artificial name for
a CU, and then discarding it. However, this name was preserved in the
cached file_and_directory. This patch arranges for the allocated name
to be preserved there.
This changes the DWARF reader to cache the result of
find_file_and_directory. This is not especially important now, but it
will help the new DWARF indexer.
This moves file_and_directory to a new file, and then C++-izes it --
replacing direct assignments with methods, and arranging for it to own
any string that must be computed. Finally, the CU's objfile will only
be used on demand; this is an important property for the new DWARF
indexer's parallel mode.
I don't think it's very useful to show deprecated aliases to the
user. It encourages the user to use them, when the goal is the
opposite.
For example, before:
(gdb) help set index-cache enabled
set index-cache enabled, set index-cache off, set index-cache on
alias set index-cache off = set index-cache enabled off
alias set index-cache on = set index-cache enabled on
Enable the index cache.
When on, enable the use of the index cache.
(gdb) help set index-cache on
Warning: 'set index-cache on', an alias for the command 'set index-cache enabled', is deprecated.
Use 'set index-cache enabled on'.
set index-cache enabled, set index-cache off, set index-cache on
alias set index-cache off = set index-cache enabled off
alias set index-cache on = set index-cache enabled on
Enable the index cache.
When on, enable the use of the index cache.
After:
(gdb) help set index-cache enabled
Enable the index cache.
When on, enable the use of the index cache.
(gdb) help set index-cache on
Warning: 'set index-cache on', an alias for the command 'set index-cache enabled', is deprecated.
Use 'set index-cache enabled on'.
Enable the index cache.
When on, enable the use of the index cache.
Change-Id: I989b618a5ad96ba975367e9d16db95523cd57a4c
Commit 92228a334b ("gdb: small "maintenance info line-table"
readability improvements") change the output format of "maint info
line-table" slightly, adding some empty lines between each
line-table. This causes two tests to start failing, update them to
account for those empty lines.
Change-Id: I9d33a58fce3e860ba0554b25f5582e8066a5c519
Commit 4bce7cdaf4 ("gdbsupport: add array_view copy function") caused
an internal error when running gdb.ada/packed_array_assign.exp:
print pra(1) := pr^M
/home/smarchi/src/binutils-gdb/gdb/../gdbsupport/array-view.h:217: internal-error: copy: Assertion `dest.size () == src.size ()' failed.^M
I am not sure what's the root cause of this, whether it is a GDB bug
exposed by using the array_view copy function or not. Back out the
change that triggers the internal error for now, while we investigate
it.
Change-Id: I055ab14143e4cfd3ca7ce8f4855c6c3c05db52a7
- separate each entry with a newline, to visually separate them
- style filenames with the filename style
- print the name of the compunit_symtab
A header now looks like this, with the compunit_symtab name added (and
the coloring, but you can't really see it here):
objfile: /home/simark/build/babeltrace/src/cli/.libs/babeltrace2 ((struct objfile *) 0x613000005980)
compunit_symtab: babeltrace2-cfg-cli-args.c ((struct compunit_symtab *) 0x62100da1ed10)
symtab: /usr/include/glib-2.0/glib/gdatetime.h ((struct symtab *) 0x62100d9ee530)
linetable: ((struct linetable *) 0x0):
Change-Id: Idc23e10aaa66e2e692adb0a6a74144f72c4fa1c7
Now that we use intrusive list to link aliases, it becomes easier to
pass cmd_list_element arguments by const-reference rather than by
pointer to some functions, change a few.
Change-Id: Id0df648ed26e9447da0671fc2c858981cda31df8
Change the manually-implemented linked list to use intrusive_list. This
is not strictly necessary, but it makes the code much simpler.
Change-Id: Idd08090ebf2db8bdcf68e85ef72a9635f1584ccc
Change a few relatively obvious spots using value contents to propagate
the use array_view a bit more.
Change-Id: I5338a60986f06d5969fec803d04f8423c9288a15
I think it would make sense for extract_integer, extract_signed_integer
and extract_unsigned_integer to take an array_view. This way, when we
extract an integer, we can validate that we don't overflow the buffer
passed by the caller (e.g. ask to extract a 4-byte integer but pass a
2-byte buffer).
- Change extract_integer to take an array_view
- Add overloads of extract_signed_integer and extract_unsigned_integer
that take array_views. Keep the existing versions so we don't
need to change all callers, but make them call the array_view
versions.
This shortens some places like:
result = extract_unsigned_integer (value_contents (result_val).data (),
TYPE_LENGTH (value_type (result_val)),
byte_order);
into
result = extract_unsigned_integer (value_contents (result_val), byte_order);
value_contents returns an array view that is of length
`TYPE_LENGTH (value_type (result_val))` already, so the length is
implicitly communicated through the array view.
Change-Id: Ic1c1f98c88d5c17a8486393af316f982604d6c95
An assertion was recently added to array_view::operator[] to ensure we
don't do out of bounds accesses. However, when the array_view is copied
to or from using memcpy, it bypasses that safety.
To address this, add a `copy` free function that copies data from an
array view to another, ensuring that the destination and source array
views have the same size. When copying to or from parts of an
array_view, we are expected to use gdb::array_view::slice, which does
its own bounds check. With all that, any copy operation that goes out
of bounds should be caught by an assertion at runtime.
copy is implemented using std::copy and std::copy_backward, which, at
least on libstdc++, appears to pick memmove when copying trivial data.
So in the end there shouldn't be much difference vs using a bare memcpy,
as we do right now. When copying non-trivial data, std::copy and
std::copy_backward assigns each element in a loop.
To properly support overlapping ranges, we must use std::copy or
std::copy_backward, depending on whether the destination is before the
source or vice-versa. std::copy and std::copy_backward don't support
copying exactly overlapping ranges (where the source range is equal to
the destination range). But in this case, no copy is needed anyway, so
we do nothing.
The order of parameters of the new copy function is based on std::copy
and std::copy_backward, where the source comes before the destination.
Change a few randomly selected spots to use the new function, to show
how it can be used.
Add a test for the new function, testing both with arrays of a trivial
type (int) and of a non-trivial type (foo). Test non-overlapping
ranges as well as three kinds of overlapping ranges: source before dest,
dest before source, and dest == source.
Change-Id: Ibeaca04e0028410fd44ce82f72e60058d6230a03
store_waitstatus is basically a translation function between a status
integer and an equivalent target_waitstatus object. It would make sense
for it to take the integer as a parameter and return the
target_waitstatus by value. Do that, and rename to
host_status_to_waitstatus. Users can then do:
ws = host_status_to_waitstatus (status)
which does the right thing, given the move constructor of
target_waitstatus.
Change-Id: I7a07d59d3dc19d3ed66929642f82f44f3e85d61b
While playing with some code creating target_waitstatus objects, I was
mildly annoyed by the fact that we can't just return a new
target_waitstatus object. We have to do:
target_waitstatus ws;
ws.set_exited (123);
return ws;
Make the setters return the "this" object as a reference, such that it's
possible to do:
return target_waitstatus ().set_exited (123);
I initially thought of adding static creation functions, which you would
use like:
return target_waitstatus::make_exited (123);
However, making the setters return a reference to the object achieves
pretty much the same thing, with less new code.
Change-Id: I45159b7f9fcd9db5b20603480e323020b14ed147
The function value_subscripted_rvalue is only used in valarith.c, so
lets make it a static function.
There should be no user visible change after this commit.
A test in gdb.python/py-send-packet.exp added in this commit:
commit 24b2de7b77
Date: Tue Aug 31 14:04:36 2021 +0100
gdb/python: add gdb.RemoteTargetConnection.send_packet
included a large amount of binary data in the command sent to GDB. As
this test didn't have a real test name the binary data was included in
the gdb.sum file. The contents of the binary data could change
between different runs of GDB, and this makes comparing results
harder.
This commit gives the test a real test name.
This commit:
commit 288712bbac
Date: Mon Nov 22 15:16:27 2021 +0000
gdb/remote: use scoped_restore to control starting_up flag
introduced a use after free bug. The scoped restore added in the
above commit resets a flag within a remote_target's remote_state
object.
However, in some situations, the remote_target can be unpushed before
the error is thrown. If the only reference to the target is the one
in the target stack, then unpushing the target will cause the
remote_target to be deleted, which, in turn, will delete the
remote_state object. The scoped restore will then try to reset the
flag within a deleted object.
This problem was caught in the gdb.server/server-connect.exp test,
which, when run with the address sanitizer enabled, highlights the
write after free bug described above.
This commit resolves this issue by adding a new class specifically for
the purpose of managing the starting_up flag. As well as setting, and
then clearing the starting_up flag, this new class increments, and
then decrements the reference count on the remote_target object. This
prevents the remote_target from being deleted until after the flag has
been reset.
The gdb.server/server-connect.exp now runs cleanly with the address
sanitizer enabled.
That xstrdup is not correct, since we are assigning an std::string. The
result of xstrdup is used to initialize the string, and then lost
forever. Remove it.
Change-Id: Ief7771055e4bfd643ef3b285ec9fb7b1bfd14335
Commit ab557072b8 ("gdb: use actual DWARF version in compunit's
debugformat field") changes the debug format string in "info source" to
show the actual DWARF version, rather than always show "DWARF 2".
However, it failed to consider that some tests checked for the "DWARF 2"
string to see if the test program is compiled with DWARF debug
information. Since everything is compiled with DWARF 4 or 5 nowadays,
that changed the behavior of those tests. Notably, it prevent the
tests using skip_inline_var_tests to run.
Grep through the testsuite for "DWARF 2" and change all occurrences I
could find to use "DWARF [0-9]" instead (that string is passed to TCL's
string match).
Change-Id: Ic7fb0217fb9623880c6f155da6becba0f567a885
In the gdb.ada/fixed_points_function.exp testcase, we have the following
Ada code...
type FP1_Type is delta 0.1 range -1.0 .. +1.0; -- Ordinary
function Call_FP1 (F : FP1_Type) return FP1_Type is
begin
FP1_Arg := F;
return FP1_Arg;
end Call_FP1;
... used as follow:
F1 : FP1_Type := 1.0;
F1 := Call_FP1 (F1);
The testcase, among other things, verifies that "return" works
properly as follow:
| (gdb) return 1.0
| Make pck.call_fp1 return now? (y or n) y
| [...]
| 9 F1 := Call_FP1 (F1);
| (gdb) next
| (gdb) print f1
| $1 = 0.0625
The output of the last command shows that we returned the wrong
value. The value printed gives a clue about the problem, since
it is 1/16th of the value we expected, where 1/16 is FP1_Type's
scaling factor.
The problem, here, comes from the fact that the function
handling return values for base types (ppc64_sysv_abi_return_value_base)
writes the return value using unpack_long which, upon seeing that
the value being unpacked is a fixed point type, applies the scaling
factor, to get the integer-representation of our fixed-point value
(similar to what it does with floats, for instance).
So, the fix consists in teaching ppc64_sysv_abi_return_value_base
about fixed-point types, and to avoid the unwanted application
of the scaling factor.
Note that the "finish" function, on the other hand, does not
suffer from this issue, simply becaue the value returned by
the function is read from register without the use of a type,
thus avoiding an unwanted application of a scaling factor.
No test added, as this change is already tested by
gdb.ada/fixed_points_function.exp.
Co-Authored-By: Tristan Gingold <gingold@adacore.com>
This commit adds support for TYPE_CODE_FIXED_POINT types for
"finish" and "return" commands.
Consider the following Ada code...
type FP1_Type is delta 0.1 range -1.0 .. +1.0; -- Ordinary
function Call_FP1 (F : FP1_Type) return FP1_Type is
begin
FP1_Arg := F;
return FP1_Arg;
end Call_FP1;
... used as follow:
F1 : FP1_Type := 1.0;
F1 := Call_FP1 (F1);
"finish" currently behaves as follow:
| (gdb) finish
| [...]
| Value returned is $1 = 0
We expect the returned value to be "1".
Similarly, "return" makes the function return the wrong value:
| (gdb) return 1.0
| Make pck.call_fp1 return now? (y or n) y
| [...]
| 9 F1 := Call_FP1 (F1);
| (gdb) next
| (gdb) print f1
| $1 = 0.0625
(we expect it to print "1" instead).
This problem comes from the handling of integral return values
when the return value is actually fixed point type. Our type
here is actually a range of a fixed point type, but the same
principles should also apply to pure fixed-point types. For
the record, here is what the debugging info looks like:
<1><238>: Abbrev Number: 2 (DW_TAG_subrange_type)
<239> DW_AT_lower_bound : -16
<23a> DW_AT_upper_bound : 16
<23b> DW_AT_name : pck__fp1_type
<23f> DW_AT_type : <0x248>
<1><248>: Abbrev Number: 4 (DW_TAG_base_type)
<249> DW_AT_byte_size : 1
<24a> DW_AT_encoding : 13 (signed_fixed)
<24b> DW_AT_binary_scale: -4
<24c> DW_AT_name : pck__Tfp1_typeB
<250> DW_AT_artificial : 1
... where the scaling factor is 1/16.
Looking at the "finish" command, what happens is that riscv_arg_location
determines that our return value should be returned by parameter using
an integral convention (via builtin type long). And then,
riscv_return_value uses a cast to that builtin type long to
store the value of into a buffer with the right register size.
This doesn't work in our case, because the underlying value
returned by the function is unscaled, which means it is 16,
and thus the cast is like doing:
arg_val = (FP1_Type) 16
... In other words, it is trying to create an FP1_Type enty whose
value is 16. Applying the scaling factor, that's 256, and because
the size of FP1_Type is 1 byte, we overflow and thus it ends up
being zero.
The same happen with the "return" function, but the other way around.
The fix consists in handling fixed-point types separately from
integral types.
Consider the following Ada code:
type FP1_Type is delta 0.1 range -1.0 .. +1.0; -- Ordinary
FP1_Arg : FP1_Type := 0.0;
function Call_FP1 (F : FP1_Type) return FP1_Type is
begin
FP1_Arg := F;
return FP1_Arg;
end Call_FP1;
After having stopped inside function Call_FP1 as follow:
Breakpoint 1, pck.call_fp1 (f=1) at /[...]/pck.adb:5
5 FP1_Arg := F;
Returning from that function call using "finish" should show
that the function return "1.0" (the same value as was passed
as an argument). However, this is not the case:
(gdb) finish
Run till exit from #0 pck.call_fp1 (f=1)
[...]
9 F1 := Call_FP1 (F1);
Value returned is $1 = 0
This patch enhances the extraction of the return value to know about
fixed point types.