Use a separate iteration variable for inner loop (😊). This
generally prevented any debug directory entries after a
IMAGE_DEBUG_TYPE_CODEVIEW entry from being reported.
Don't leak the memory allocated for the section containing the debug
directory.
bfd/ChangeLog:
2020-01-16 Jon Turney <jon.turney@dronecode.org.uk>
* peXXigen.c (pe_print_debugdata): Fix the iteration variable for
inner loop. Fix a memory leak.
This patch fixes the neg/neg32 BPF instructions, which have K (=0)
instead of X (=1) in their header source bit, despite operating on
registes.
cpu/ChangeLog:
2020-01-30 Jose E. Marchesi <jose.marchesi@oracle.com>
* bpf.cpu (define-alu-insn-un): The unary BPF instructions
(neg and neg32) use OP_SRC_K even if they operate only in
registers.
opcodes/ChangeLog:
2020-01-30 Jose E. Marchesi <jose.marchesi@oracle.com>
* bpf-opc.c: Regenerate.
gas/ChangeLog:
2020-01-30 Jose E. Marchesi <jose.marchesi@oracle.com>
* testsuite/gas/bpf/alu.d: Update expected opcode for `neg'.
* testsuite/gas/bpf/alu-be.d: Likewise.
* testsuite/gas/bpf/alu32.d: Likewise for `neg32'.
* testsuite/gas/bpf/alu32-be.d: Likewise.
While vendors agree about default operand size (64 bits) and hence
unavilability of a 32-bit form, AMD honors a 16-bit operand size
override (0x66) while Intel doesn't.
Other than near returns these default to 32-bit operand size, and hence
it isn't really unlikely that 64-bit forms are meant. Hence these should
have disambiguating suffixes. In Intel mode, however, don't error in
these cases unconditionally - MASM accepts these without suffix _and_
without warning.
- 64-bit CALL permitting just a single operand size doesn't need it.
- FLDENV et al should never have had it.
It remains suspicious that a number of 64-bit only insns continue to
have the attribute, despite this being intended for .code16gcc handling
only.
The patch also fixes a case where libopcodes built for a 64-bit
bfd_vma may print different results to libopcodes built for a 32-bit
bfd_vma.
* tic4x-dis.c (tic4x_dp): Make unsigned.
While testing a GCC 10 build of our git HEAD, Sergio noticed an error
triggered by -Werror-stringop on
infcmd.c:construct_inferior_arguments. One of the things the function
does is calculate the length of the string that will hold the
inferior's arguments. GCC warns us that 'length' can be 0, which can
lead to undesired behaviour:
../../gdb/infcmd.c: In function 'char* construct_inferior_arguments(int, char**)':
../../gdb/infcmd.c:369:17: error: writing 1 byte into a region of size 0 [-Werror=stringop-overflow=]
369 | result[0] = '\0';
| ~~~~~~~~~~^~~~~~
../../gdb/infcmd.c:368:33: note: at offset 0 to an object with size 0 allocated by 'xmalloc' here
368 | result = (char *) xmalloc (length);
| ~~~~~~~~^~~~~~~~
The solution here is to assert that 'argc' is greater than 0 on entry,
which makes GCC understand that the loops always run at least once,
and thus 'length' is always > 0.
Tested by rebuilding.
gdb/ChangeLog:
2020-01-29 Pedro Alves <palves@redhat.com>
Sergio Durigan Junior <sergiodj@redhat.com>
* infcmd.c (construct_inferior_arguments): Assert that
'argc' is greater than 0.
Change-Id: Ide8407cbedcb4921de1843a6a15bbcb7676c7d26
The move of gdbsupport to the top level directory requires a small
change to src-release.sh's "getver" function, which is responsible for
determining the version string that will be appended to the release
tarball: now the create-version.sh script lives under ./gdbsupport,
and not under gdb/gdbsupport anymore.
This patch unbreaks the snapshot generation, which hasn't been working
since January 14th.
ChangeLog:
2020-01-29 Sergio Durigan Junior <sergiodj@redhat.com>
* src-release.sh (getver): Look for gdbsupport's
create-version.sh script at the current directory if tool is
"gdb".
Change-Id: Id3b8bed6583a1aaa120c07009366f6c94a62d5db
An error in commit 42cd72aa02 caused
srv_tgtobj to be overwritten and linux-ppc-low.o to be missed when
linking gdbserver for Linux on PowerPC. This patch fixes the error.
gdb/gdbserver/ChangeLog:
2020-01-29 Pedro Franco de Carvalho <pedromfc@linux.ibm.com>
* configure.srv (powerpc*-*-linux*): Use srv_tgtobj in second
assignment instead of srv_linux_obj.
New in v5:
- Use gdb_test_name for gdb_test_multiple.
- Use gdb_assert.
- Verify count matches the expected sigtraps exactly.
New in v4:
- Fix formatting nit in gdb/testsuite/gdb.arch/aarch64-brk-patterns.c.
New in v3:
- Minor formatting and code cleanups.
- Added count check to validate number of brk SIGTRAP's.
- Moved count to SIGTRAP check conditional block.
This test exercises the previous patch's code and makes sure GDB can
properly get a SIGTRAP from various brk instruction patterns.
GDB needs to be able to see the program exiting normally. If GDB doesn't
support the additional brk instructions, we will see timeouts.
We bail out with the first timeout since we won't be able to step through
the program breakpoint anyway, so it is no use carrying on.
gdb/testsuite/ChangeLog:
2020-01-29 Luis Machado <luis.machado@linaro.org>
* gdb.arch/aarch64-brk-patterns.c: New source file.
* gdb.arch/aarch64-brk-patterns.exp: New test.
New in v3:
- Code cleanups based on reviews.
New in v2:
- Fixed misc problems based on reviews.
- Switched to using gdbarch_program_breakpoint_here_p as opposed to
gdbarch_insn_is_breakpoint.
- Fixed matching of brk instructions. Previously the mask was incorrect, which
was showing up as a few failures in the testsuite. Now it is clean.
- New testcase (separate patch).
- Moved program_breakpoint_here () to arch-utils.c and made it the default
implementation of gdbarch_program_breakpoint_here_p.
--
It was reported to me that program breakpoints (permanent ones inserted into
the code itself) other than the one GDB uses for AArch64 (0xd4200000) do not
generate visible stops when continuing, and GDB will continue spinning
infinitely.
This happens because GDB, upon hitting one of those program breakpoints, thinks
the SIGTRAP came from a delayed breakpoint hit...
(gdb) x/i $pc
=> 0x4005c0 <problem_function>: brk #0x90f
(gdb) c
Continuing.
infrun: clear_proceed_status_thread (process 14198)
infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
infrun: proceed: resuming process 14198
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14198] at 0x4005c0
infrun: infrun_async(1)
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14198.14198.0 [process 14198],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: delayed software breakpoint trap, ignoring
infrun: no stepping, continue
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14198] at 0x4005c0
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14198.14198.0 [process 14198],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: delayed software breakpoint trap, ignoring
infrun: no stepping, continue
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14198] at 0x4005c0
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14198.14198.0 [process 14198],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: delayed software breakpoint trap, ignoring
infrun: no stepping, continue
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14198] at 0x4005c0
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14198.14198.0 [process 14198],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: delayed software breakpoint trap, ignoring
infrun: no stepping, continue
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14198] at 0x4005c0
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14198.14198.0 [process 14198],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
...
... which is not the case.
If the program breakpoint is one GDB recognizes, then it will stop when it
hits it.
(gdb) x/i $pc
=> 0x4005c0 <problem_function>: brk #0x0
(gdb) c
Continuing.
infrun: clear_proceed_status_thread (process 14193)
infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
infrun: proceed: resuming process 14193
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 14193] at 0x4005c0
infrun: infrun_async(1)
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 14193.14193.0 [process 14193],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: random signal (GDB_SIGNAL_TRAP)
infrun: stop_waiting
infrun: stop_all_threads
infrun: stop_all_threads, pass=0, iterations=0
infrun: process 14193 not executing
infrun: stop_all_threads, pass=1, iterations=1
infrun: process 14193 not executing
infrun: stop_all_threads done
Program received signal SIGTRAP, Trace/breakpoint trap.
problem_function () at brk_0.c:7
7 asm("brk %0\n\t" ::"n"(0x0));
infrun: infrun_async(0)
Otherwise GDB will keep trying to resume the inferior and will keep
seeing the SIGTRAP's, without stopping.
To the user it appears GDB has gone into an infinite loop, interruptible only
by Ctrl-C.
Also, windbg seems to use a different variation of AArch64 breakpoint compared
to GDB. This causes problems when debugging Windows on ARM binaries, when
program breakpoints are being used.
The proposed patch creates a new gdbarch method (gdbarch_program_breakpoint_here_p)
that tells GDB whether the underlying instruction is a breakpoint instruction
or not.
This is more general than only checking for the instruction GDB uses as
breakpoint.
The existing logic is still preserved for targets that do not implement this
new gdbarch method.
The end result is like so:
(gdb) x/i $pc
=> 0x4005c0 <problem_function>: brk #0x90f
(gdb) c
Continuing.
infrun: clear_proceed_status_thread (process 16417)
infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
infrun: proceed: resuming process 16417
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [process 16417] at 0x4005c0
infrun: infrun_async(1)
infrun: prepare_to_wait
infrun: target_wait (-1.0.0, status) =
infrun: 16417.16417.0 [process 16417],
infrun: status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: handle_inferior_event status->kind = stopped, signal = GDB_SIGNAL_TRAP
infrun: stop_pc = 0x4005c0
infrun: random signal (GDB_SIGNAL_TRAP)
infrun: stop_waiting
infrun: stop_all_threads
infrun: stop_all_threads, pass=0, iterations=0
infrun: process 16417 not executing
infrun: stop_all_threads, pass=1, iterations=1
infrun: process 16417 not executing
infrun: stop_all_threads done
Program received signal SIGTRAP, Trace/breakpoint trap.
problem_function () at brk.c:7
7 asm("brk %0\n\t" ::"n"(0x900 + 0xf));
infrun: infrun_async(0)
gdb/ChangeLog:
2020-01-29 Luis Machado <luis.machado@linaro.org>
* aarch64-tdep.c (BRK_INSN_MASK): Define to 0xffe0001f.
(BRK_INSN_MASK): Define to 0xd4200000.
(aarch64_program_breakpoint_here_p): New function.
(aarch64_gdbarch_init): Set gdbarch_program_breakpoint_here_p hook.
* arch-utils.c (default_program_breakpoint_here_p): Moved from
breakpoint.c.
* arch-utils.h (default_program_breakpoint_here_p): Moved from
breakpoint.h
* breakpoint.c (bp_loc_is_permanent): Changed return type to bool and
call gdbarch_program_breakpoint_here_p.
(program_breakpoint_here): Moved to arch-utils.c, renamed to
default_program_breakpoint_here_p, changed return type to bool and
simplified.
* breakpoint.h (program_breakpoint_here): Moved prototype to
arch-utils.h, renamed to default_program_breakpoint_here_p and changed
return type to bool.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
* gdbarch.sh (program_breakpoint_here_p): New method.
* infrun.c (handle_signal_stop): Call
gdbarch_program_breakpoint_here_p.
There exist expected failures in the pass-by-ref.exp and
pass-by-ref-2.exp tests based on the GCC and Clang version.
* GCC version <= 6 and Clang do not emit DW_AT_deleted and
DW_AT_defaulted.
* Clang version >= 7 emits DW_AT_calling_convention, which helps the
debugger make the right calling convention decision in some cases
despite lacking the 'defaulted' and 'deleted' attributes.
Mark the related tests as XFAIL based on the compiler version.
Tested on X86_64 using GCC 5.5.0, 6.5.0, 7.4.0, 8.3.0, 9.2.1;
and Clang 5.0.1, 6.0.0, 7.0.0, 8.0.0, 9.0.1, 10.0.0.
gdb/testsuite/ChangeLog:
2020-01-29 Tankut Baris Aktemur <tankut.baris.aktemur@intel.com>
* gdb.cp/pass-by-ref-2.exp: Mark some tests as XFAIL based on the
GCC/Clang version.
* gdb.cp/pass-by-ref.exp: Ditto.
Change-Id: I1d8440aa438049f7c4da7f4f76f201c48550f1e4
I ran into:
...
Thread 3.1 "watchpoint-fork" hit Breakpoint 3, marker () at \
watchpoint-fork-mt.c:42^M
42 }^M
(gdb) parent2: 1945^M
FAIL: gdb.threads/watchpoint-fork.exp: child: multithreaded: breakpoint (A) \
after the second fork (timeout)
...
The problem is that the FAILing gdb_test expects '(gdb) ' to be the last thing
printed, but the inferior prints something after that.
A similar FAIL is described in the sources in watchpoint-fork-parent.c:
...
printf ("child%d: %d\n", nr, (int) getpid ());
/* Delay to get both the "child%d" and "parent%d" message printed
without a race breaking expect by its endless wait on `$gdb_prompt$':
Breakpoint 3, marker () at watchpoint-fork.c:33
33 }
(gdb) parent2: 14223 */
i = sleep (1);
...
I noticed that while the executables print output, the output is not verified in
the test-case, so it's merely debug output.
Fix this by:
- guarding the prints in the executables (as well as related
sleep and setbuf calls) with #if DEBUG, and
- compiling by default with DEBUG=0.
gdb/testsuite/ChangeLog:
2020-01-29 Tom de Vries <tdevries@suse.de>
* gdb.threads/watchpoint-fork-child.c: Guard prints with #if DEBUG.
* gdb.threads/watchpoint-fork-mt.c: Same.
* gdb.threads/watchpoint-fork-parent.c: Same.
* gdb.threads/watchpoint-fork-st.c: Same.
* gdb.threads/watchpoint-fork.exp: Compile with DEBUG=0.
Change-Id: I63efd4c7771f96b5f5cd87ef2ab36795484ae2be
The address was written as a long value, but long is always a 32bit value
on Windows, which lead to truncated addresses.
The solution was to use paddress instead.
gdb/gdbserver/ChangeLog:
2020-01-28 Hannes Domani <ssbssa@yahoo.de>
* server.c (handle_qxfer_libraries): Write segment-address with
paddress.
Maciej reported a problem found by his RISC-V gdbserver port.
warning: while parsing target description (at line 4): Target description specified unknown architecture "riscv:rv64id"
warning: Could not load XML target description; ignoring
We only have two arches defined, riscv:rv32 and riscv:rv64. Both bfd and
gdb are creating arch strings that have extension letters added to the base
architecture. The bfd_default_scan function requires an exact match, so
these strings fail to map to a bfd_arch. I think we should ignore the
extension letters in a RISC-V specific scan function.
bfd/
* cpu-riscv.c (riscv_scan): New.
(N): Change bfd_default_scan to riscv_scan.
Change-Id: I096476705e1da5cb8934c5005b1eed2a8989f7a7
New in v3:
- Verify if the syscall number matches what is expected for the target.
- Used gdb_assert for one more check.
New in v2:
- Set initial values to -1 instead of 0.
- Rewrote RE to prevent unexpected matching when parsing one character at a
time.
- Used gdb_assert for an additional check.
- Validated with check-read1
There are a couple problems with this test.
First
--
gdb.base/step-over-syscall.exp records the address of a syscall instruction
within fork/vfork/clone functions and also the address of the instruction
after that syscall instruction.
It uses these couples addresses to make sure we stepped over a syscall
instruction (fork/vfork/clone events) correctly.
The way the test fetches the addresses of the instructions is by stepi-ing
its way through the fork/vfork/clone functions until it finds a match for
a syscall. Then it stepi's once again to get the address of the next
instruction.
This assumes that stepi-ing over a syscall is working correctly and landing
in the right PC. This is not the case for AArch64/Linux, where we're
landing a couple instructions after the syscall in some cases.
The following patch lets the test execute as before, but adds a new instruction
address check using the x command as opposed to stepi.
I didn't want to change how the test works since we may also be
interested in checking if stepi-ing over the syscall under different
conditions (displaced stepping on/off) yields the same results. I don't
feel strongly about this, so i'm OK with changing how we compare PC's for
the entire test if folks decide it is reasonable.
Second
--
FAIL: gdb.base/step-over-syscall.exp: vfork: displaced=off: continue to vfork (3rd time) (the program exited)
FAIL: gdb.base/step-over-syscall.exp: vfork: displaced=off: continue to syscall insn vfork (the program is no longer running)
FAIL: gdb.base/step-over-syscall.exp: vfork: displaced=off: single step over vfork (the program is no longer running)
Depending on the glibc version we may have different code generated for the
fork/vfork/clone functions.
I ran into the situation where vfork for newer glibc's on AArch64/Linux is
very short, so "break vfork" will put a breakpoint right at the syscall
instruction, which is something the testcase isn't expecting (a off-by-1
of sorts).
The patch adds extra code to handle this case. If the test detects we're
already sitting at a syscall instruction, it records the address and moves
on to record the address after that particular instruction.
Another measure is to "break *$syscall" instead of "break $syscall". That
guarantees we're stopping at the first instruction of the syscall function,
if it ever happens that the syscall instruction is the first instruction of
those functions.
With these changes i can fix some failures for aarch64-linux-gnu and also
expose the problems i've reported here:
https://sourceware.org/ml/gdb-patches/2019-12/msg01071.html
These tests now fail for aarch64-linux-gnu (patch for this is going through
reviews):
FAIL: gdb.base/step-over-syscall.exp: vfork: displaced=off: pc after stepi matches insn addr after syscall
FAIL: gdb.base/step-over-syscall.exp: vfork: displaced=on: pc after stepi matches insn addr after syscall
gdb/testsuite/ChangeLog:
2020-01-27 Luis Machado <luis.machado@linaro.org>
* gdb.base/step-over-syscall.exp (setup): Check if we're already
sitting at a syscall instruction when we hit the syscall function's
breakpoint.
Check PC against one obtained with the x command.
Validate syscall number.
(step_over_syscall): Don't continue to the syscall instruction if
we're already there.
movsxd is a 64-bit only instruction. It supports both 16-bit and 32-bit
destination registers. Its AT&T mnemonic is movslq which only supports
64-bit destination register. There is also a discrepancy between AMD64
and Intel64 on movsxd with 16-bit destination register. AMD64 supports
32-bit source operand and Intel64 supports 16-bit source operand.
This patch updates movsxd encoding and decoding to alow 16-bit and 32-bit
destination registers. It also handles movsxd with 16-bit destination
register for AMD64 and Intel 64.
gas/
PR binutils/25445
* config/tc-i386.c (check_long_reg): Also convert to QWORD for
movsxd.
* doc/c-i386.texi: Add a node for AMD64 vs. Intel64 ISA
differences. Document movslq and movsxd.
* testsuite/gas/i386/i386.exp: Run PR binutils/25445 tests.
* testsuite/gas/i386/x86-64-movsxd-intel.d: New file.
* testsuite/gas/i386/x86-64-movsxd-intel64-intel.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64-inval.l: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64-inval.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd-intel64.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd-inval.l: Likewise.
* testsuite/gas/i386/x86-64-movsxd-inval.s: Likewise.
* testsuite/gas/i386/x86-64-movsxd.d: Likewise.
* testsuite/gas/i386/x86-64-movsxd.s: Likewise.
opcodes/
PR binutils/25445
* i386-dis.c (MOVSXD_Fixup): New function.
(movsxd_mode): New enum.
(x86_64_table): Use MOVSXD_Fixup and movsxd_mode on movsxd.
(intel_operand_size): Handle movsxd_mode.
(OP_E_register): Likewise.
(OP_G): Likewise.
* i386-opc.tbl: Remove Rex64 and allow 32-bit destination
register on movsxd. Add movsxd with 16-bit destination register
for AMD64 and Intel64 ISAs.
* i386-tbl.h: Regenerated.
This fixes the preferred disassembly for cfinv. The Armv8.4-a instruction
overlaps with the possible encoding space for msr. This because msr allows you
to use unallocated encoding space using the general sA_B_cC_cD_E form.
However when an encoding does become allocated then we need to ensure that it's
used as the preferred disassembly. The problem with cfinv is that its mask has
all bits sets because it has no arguments.
This causes issues for the Alias resolver in gas as it uses the mask to build
alias graph. In this case it can't do it since it thinks almost everything
would alias with cfinv. So instead we can only fix this by moving cfinv before
msr.
gas/ChangeLog:
PR 25403
* testsuite/gas/aarch64/armv8_4-a.d: Add cfinv.
* testsuite/gas/aarch64/armv8_4-a.s: Likewise.
opcodes/ChangeLog:
PR 25403
* aarch64-tbl.h (struct aarch64_opcode): Re-order cfinv.
* aarch64-asm-2.c: Regenerate
* aarch64-dis-2.c: Likewise.
* aarch64-opc-2.c: Likewise.
I noticed a couple of minor issues in ctfread.c, both fixed by this
patch:
* ctf_fp_info was not indented properly; and
* _initialize_ctfread is no longer needed
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* ctfread.c (struct ctf_fp_info): Reindent.
(_initialize_ctfread): Remove.
Change-Id: I72707b74bc59e6e426b3a7bc8843d96c0d786f1e
This patch removes the "readin" and "compunit_symtab" members from
partial_symtab, replacing them with methods. Then it introduces a new
"standard_psymtab" class, which restores these members; and changes
the symbol readers to use this intermediate class as the base class of
their partial symtab subclasses.
The reason for this is to make it possible for a symbol reader to
implement an alternate mapping between partial and full symbol tables.
This is important in order to be able to share psymtabs across
objfiles -- whether a psymtab has been "readin" is objfile-dependent,
as are the pointers to the full symbol tables.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* psymtab.c (partial_map_expand_apply)
(psym_find_pc_sect_compunit_symtab, psym_lookup_symbol)
(psymtab_to_symtab, psym_find_last_source_symtab, dump_psymtab)
(psym_print_stats, psym_expand_symtabs_for_function)
(psym_map_symbol_filenames, psym_map_matching_symbols)
(psym_expand_symtabs_matching)
(partial_symtab::read_dependencies, maintenance_info_psymtabs)
(maintenance_check_psymtabs): Use new methods.
* psympriv.h (struct partial_symtab) <readin_p,
get_compunit_symtab>: New methods.
<readin, compunit_symtab>: Remove members.
(struct standard_psymtab): New.
(struct legacy_psymtab): Derive from standard_psymtab.
* dwarf2read.h (struct dwarf2_psymtab): Derive from
standard_psymtab.
* ctfread.c (struct ctf_psymtab): Derive from standard_psymtab.
Change-Id: Idb923f196d7e03bf7cb9cfc8134ed06dd3f211ce
Most of the symbol readers have code to iterate over a partial symtabs
dependencies, expanding each one and optionally printing a message.
Now that the "second-stage" psymtab expansion is available as a
method, these implementations can all be merged.
This patch also changes a couple more warnings into assertions.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (xcoff_psymtab_to_symtab_1): Call
read_dependencies. Add assert.
* psymtab.c (partial_symtab::read_dependencies): New method.
* psympriv.h (struct partial_symtab) <read_dependencies>: New
method.
* mdebugread.c (psymtab_to_symtab_1): Call read_dependencies.
* dwarf2read.c (dwarf2_psymtab::expand_psymtab): Call
read_dependencies.
* dbxread.c (dbx_psymtab_to_symtab_1): Call read_dependencies.
Add assert.
Change-Id: I8151e05677794e90223edc1a4cb70f7f69137d46
The symbol readers generally used two functions to expand a partial
symtab: an outer function (now the "read_symtab" method), and an inner
function, typically named something like "psymtab_to_symtab".
This patch changes this second step to be a method on partial_symtab,
and updates all the callers. For legacy_psymtab, a new function
pointer member is introduced.
This patch enables a subsequent cleanup.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (xcoff_psymtab_to_symtab_1): Change argument order.
Call expand_psymtab.
(xcoff_read_symtab): Call expand_psymtab.
(xcoff_start_psymtab, xcoff_end_psymtab): Set
legacy_expand_psymtab.
* psympriv.h (struct partial_symtab) <expand_psymtab>: New
method.
(struct legacy_psymtab) <expand_psymtab>: Implement.
<legacy_expand_psymtab>: New member.
* mdebugread.c (mdebug_read_symtab): Call expand_psymtab.
(parse_partial_symbols): Set legacy_expand_psymtab.
(psymtab_to_symtab_1): Change argument order. Call
expand_psymtab.
(new_psymtab): Set legacy_expand_psymtab.
* dwarf2read.h (struct dwarf2_psymtab) <expand_psymtab>: Declare.
* dwarf2read.c (dwarf2_psymtab::read_symtab): Call
expand_psymtab.
(dwarf2_psymtab::expand_psymtab): Rename from
psymtab_to_symtab_1. Call expand_psymtab.
* dbxread.c (start_psymtab): Set legacy_expand_psymtab.
(dbx_end_psymtab): Likewise.
(dbx_psymtab_to_symtab_1): Change argument order. Call
expand_psymtab.
(dbx_read_symtab): Call expand_psymtab.
* ctfread.c (struct ctf_psymtab) <expand_psymtab>: Declare.
(ctf_psymtab::expand_psymtab): Rename from psymtab_to_symtab.
(ctf_psymtab::read_symtab): Call expand_psymtab.
Change-Id: Ic39a2d7aa7b424088d910b59dbd21271fa1c3430
Each symbol reader implemented its own "Reading..." messages, and most
of them double-checked that a previously-expanded psymtab could not be
re-read.
This patch consolidates the message-printing, and changes these checks
into asserts.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (xcoff_read_symtab): Remove prints. Add assert.
* psymtab.c (psymtab_to_symtab): Print verbose "Reading"
messages.
* mdebugread.c (mdebug_read_symtab): Remove prints.
* dwarf2read.c (dwarf2_psymtab::read_symtab): Remove prints. Add
assert.
* dbxread.c (dbx_read_symtab): Remove prints. Add assert.
Change-Id: I795be9710d42708299bb7b44972cffd27aec9413
This introduces a new partial_symtab::read_symtab method, and updates
the symbol readers to subclass partial_symtab and implement this
method. The old read_symtab and read_symtab_private members are
removed.
In practice, only DWARF and CTF are truly updated to take advantage of
the new setup. The other symbol readers are less actively maintained,
and so this patch also introduces a "legacy_psymtab", which
essentially works the same way as the old partial_symtab.
(Note that, without more knowledge of the interaction between these
symbol readers, fixing this to remove the new (small) overhead is not
trivial, because these readers copy the read_symtab pointer between
partial symtabs.)
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (this_symtab_psymtab, read_xcoff_symtab)
(xcoff_psymtab_to_symtab_1, xcoff_read_symtab)
(xcoff_start_psymtab, xcoff_end_psymtab, scan_xcoff_symtab): Use
legacy_symtab.
* stabsread.h (dbx_end_psymtab): Use legacy_symtab.
* psymtab.c (psymtab_to_symtab): Call method.
(dump_psymtab): Update.
* psympriv.h (struct partial_symtab): Add virtual destructor.
<read_symtab>: New method.
(struct legacy_symtab): New.
* mdebugread.c (mdebug_read_symtab): Use legacy_psymtab.
(struct pst_map) <pst>: Now a legacy_psymtab.
(parse_procedure, parse_partial_symbols, psymtab_to_symtab_1)
(new_psymtab): Use legacy_psymtab.
* dwarf2read.h (struct dwarf2_psymtab): New.
(struct dwarf2_per_cu_data) <psymtab>: Use it.
* dwarf2read.c (dwarf2_create_include_psymtab)
(dwarf2_build_include_psymtabs, create_type_unit_group)
(create_partial_symtab, process_psymtab_comp_unit_reader)
(build_type_psymtabs_reader, build_type_psymtab_dependencies)
(set_partial_user): Use dwarf2_psymtab.
(dwarf2_psymtab::read_symtab): Rename from dwarf2_read_symtab.
(psymtab_to_symtab_1, process_full_comp_unit)
(process_full_type_unit, dwarf2_ranges_read)
(dwarf2_get_pc_bounds, psymtab_include_file_name)
(dwarf_decode_lines): Use dwarf2_psymtab.
* dwarf-index-write.c (psym_index_map): Use dwarf2_psymtab.
(add_address_entry_worker, write_one_signatured_type)
(recursively_count_psymbols, recursively_write_psymbols)
(write_one_signatured_type, psyms_seen_size, write_gdbindex)
(write_debug_names): Likewise.
* dbxread.c (struct header_file_location): Take a legacy_psymtab.
<pst>: Now a legacy_psymtab.
(find_corresponding_bincl_psymtab): Return a legacy_psymtab.
(read_dbx_symtab, start_psymtab, dbx_end_psymtab)
(dbx_psymtab_to_symtab_1, read_ofile_symtab): Use legacy_psymtab.
* ctfread.c (struct ctf_psymtab): New.
(ctf_start_symtab, ctf_end_symtab, psymtab_to_symtab): Take a
ctf_psymtab.
(ctf_psymtab::read_symtab): Rename from ctf_read_symtab.
(create_partial_symtab): Return a ctf_psymtab.
(scan_partial_symbols): Update.
Change-Id: Ia57a828786867d6ad03200af8f996f48ed15285e
This turns start_psymtab_common into a constructor, and then changes
the callers to use "new" directly. This completes the psymtab
allocation transition -- now it is possible for symbol readers to
subclass struct partial_symtab.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (xcoff_start_psymtab): Use new.
* psymtab.c (partial_symtab::partial_symtab): New constructor,
renamed from start_psymtab_common.
* psympriv.h (struct partial_symtab): Add new constructor.
(start_psymtab_common): Don't declare.
* mdebugread.c (parse_partial_symbols): Use new.
* dwarf2read.c (create_partial_symtab): Use new.
* dbxread.c (start_psymtab): Use new.
* ctfread.c (create_partial_symtab): Use new.
Change-Id: I5a0217bcb52bcfa442559771954bb66bd9ccbf02
This is the next step in getting the symbol readers to allocate
psymtabs themselves: change allocate_psymtab to be an ordinary
constructor, and then use "new" at the previous call sites. Note that
this doesn't get us all the way -- start_psymtab_common is still
allocating a partial symtab.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* xcoffread.c (xcoff_end_psymtab): Use new.
* psymtab.c (start_psymtab_common): Use new.
(partial_symtab::partial_symtab): Rename from allocate_psymtab.
Update.
* psympriv.h (struct partial_symtab): Add parameters to
constructor. Don't inline.
(allocate_psymtab): Don't declare.
* mdebugread.c (new_psymtab): Use new.
* dwarf2read.c (dwarf2_create_include_psymtab): Use new.
* dbxread.c (dbx_end_psymtab): Use new.
Change-Id: Iffeae64c925050b90b9916cbc36e15b26ff42226
Currently, partial symbol tables are allocated by a method in
psymtab_storage. However, eventually we want to subclass partial
symtabs in the symbol readers, so the calls to "new" will have to
happen there. This patch is a first step, moving the allocation from
psymtab_storage and into allocate_psymtab.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* psymtab.h (class psymtab_storage) <install_psymtab>: Rename from
allocate_psymtab. Update documentation.
* psymtab.c (psymtab_storage::install_psymtab): Rename from
allocate_psymtab. Do not use new.
(allocate_psymtab): Use new. Update.
Change-Id: Iba6a9bf3ee1e78062fdb9f007c3010f826f64bc8
This changes psymtabs to be allocated with new and destroyed with
delete. As a consequence, the psymtab free-list is also removed.
The motivation for this is to let symbol readers subclass
partial_symtab.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* mdebugread.c (parse_partial_symbols): Use discard_psymtab.
* psymtab.h (class psymtab_storage) <free_psymtabs>: Remove.
* psymtab.c (psymtab_storage): Delete psymtabs.
(psymtab_storage::allocate_psymtab): Use new.
(psymtab_storage::discard_psymtab): Use delete.
* psympriv.h (struct partial_symtab): Add constructor and
initializers.
Change-Id: I4e78ac538fc0ea52b57489c1afb8f935a30941ef
machoread.c does not need to include psympriv.h.
gdb/ChangeLog
2020-01-26 Tom Tromey <tom@tromey.com>
* machoread.c: Do not include psympriv.h.
Change-Id: I6362bd2e95e7416cb9bae3d48b69dd6dbe4f2cc8
From what I can tell, The m68k floating point target feature should
apparently always be called "org.gnu.gdb.coldfire.fp" -- even when the
primary feature is not "coldfire", because m68k_gdbarch_init only
checks for this feature when assigning register numbers.
However, the floating point registers are expected to match what gdb
thinks are the register sizes for the primary feature. For example,
if the main feature is "coldfire", then the floating point registers
should be 64 bits.
See this note for some an instance of this confusion:
https://lists.gnu.org/archive/html/qemu-devel/2017-06/msg04564.html
This patch documents the oddity.
Let me know what you think. An alternate approach here might be to
make gdb adapt to the register sizes as actually reported. I'm not
sure if this makes sense or not.
gdb/doc/ChangeLog
2020-01-26 Tom Tromey <tromey@adacore.com>
* gdb.texinfo (M68K Features): Document floating-point feature
correspondence.
Change-Id: I4cd86acbe3449a29ce38327524c508c206b25b8f
Mention in NEWS the new option and the set/show commands.
Document in gdb.texinfo the new option and the set/show commands.
gdb/ChangeLog
2020-01-25 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* NEWS: Mention the new option and the set/show commands.
gdb/doc/ChangeLog
2020-01-25 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* gdb.texinfo (Attach): Document the new option and the
set/show commands.
(Connecting): Reference the exec-file-mismatch option.
Modify gdb.base/attach.exp to test the behaviour of the option
exec-file-mismatch. Note that this test can also be run using/
make check RUNTESTFLAGS="--target_board=native-extended-gdbserver" TESTS=gdb.base/attach.exp
to test the behaviour of attaching to running program using a gdb server.
Note: when running the test with a gdbserver, the tests in
test_command_line_attach_run fail because the command "run" is not supported.
I tried to extend the condition
if ![isnative] then {
unsupported "commandline attach run test"
return 0
}
but unclear to me how to best do that. The below trials all failed
to work properly:
if { ![isnative] || [target_is_gdbserver] } then {
if { ![isnative] || [use_gdb_stub] } then {
if { ![isnative] || [is_remote target] } then {
=> could never obtain a condition that was true with gdbserver.
2020-01-25 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* gdb.base/attach.exp: Test 'set exec-file-mismatch'.
This option allows to tell GDB to detect and possibly handle mismatched exec-files.
A recurrent problem with GDB is that GDB uses the wrong exec-file
when using the attach/detach commands successively.
Also, in case the user specifies a file on the command line but attaches
to the wrong PID, this error is not made visible and gives a not user
understandable behaviour.
For example:
$ gdb
...
(gdb) atta 2682 ############################################ PID running 'sleepers' executable
Attaching to process 2682
[New LWP 2683]
[New LWP 2684]
[New LWP 2685]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f5ff829f603 in select () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) det
Detaching from program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 2682
[Inferior 1 (process 2682) detached]
(gdb) atta 31069 ############################################ PID running 'gdb' executable
Attaching to program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 31069
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/60/6df9c355103e82140d513bc7a25a635591c153.debug...
0x00007f43c23478a0 in ?? ()
(gdb) bt
#0 0x00007f43c23478a0 in ?? ()
#1 0x0000558909e3ad91 in ?? ()
#2 0x0000202962646700 in ?? ()
#3 0x00007ffc69c74e70 in ?? ()
#4 0x000055890c1d2350 in ?? ()
#5 0x0000000000000000 in ?? ()
(gdb)
The second attach has kept the executable of the first attach.
(in this case, 31069 is the PID of a GDB, that has nothing to do
with the first determined 'sleepers' executable).
Similarly, if specifying an executable, but attaching to a wrong pid,
we get:
gdb /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers
...
Reading symbols from /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers...
(gdb) atta 31069 ############################################ PID running 'gdb' executable
Attaching to program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 31069
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/60/6df9c355103e82140d513bc7a25a635591c153.debug...
0x00007f43c23478a0 in ?? ()
(gdb) bt
#0 0x00007f43c23478a0 in ?? ()
#1 0x0000558909e3ad91 in ?? ()
#2 0x0000202962646700 in ?? ()
#3 0x00007ffc69c74e70 in ?? ()
#4 0x000055890c1d2350 in ?? ()
#5 0x0000000000000000 in ?? ()
(gdb)
And it is unclear to the user what has happened/what is going wrong.
This patch series implements a new option:
(gdb) apropos exec-file-mismatch
set exec-file-mismatch -- Set exec-file-mismatch handling (ask|warn|off).
show exec-file-mismatch -- Show exec-file-mismatch handling (ask|warn|off).
(gdb) help set exec-file-mismatch
Set exec-file-mismatch handling (ask|warn|off).
Specifies how to handle a mismatch between the current exec-file name
loaded by GDB and the exec-file name automatically determined when attaching
to a process:
ask - warn the user and ask whether to load the determined exec-file.
warn - warn the user, but do not change the exec-file.
off - do not check for mismatch.
"ask" means: in case of mismatch between the current exec-file name
and the automatically determined exec-file name of the PID we are attaching to,
give a warning to the user and ask whether to load the automatically determined
exec-file.
"warn" means: in case of mismatch, just give a warning to the user.
"off" means: do not check for mismatch.
This fixes PR gdb/17626.
There was a previous trial to fix this PR.
See https://sourceware.org/ml/gdb-patches/2015-07/msg00118.html
This trial was however only fixing the problem for the automatically
determined executable files when doing attach.
It was differentiating the 'user specified executable files' ("sticky")
from the executable files automatically found by GDB.
But such user specified sticky executables are in most cases due
to a wrong manipulation by the user, giving unexpected results
such as backtrace showing no function like in the above example.
This patch ensures that whenever a process executable can be
determined, that the user is warned if there is a mismatch.
The same tests as above then give:
(gdb) atta 2682
Attaching to process 2682
[New LWP 2683]
[New LWP 2684]
[New LWP 2685]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f5ff829f603 in select () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(gdb) det
Detaching from program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 2682
[Inferior 1 (process 2682) detached]
(gdb) atta 31069
Attaching to program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 31069
warning: Mismatch between current exec-file /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers
and automatically determined exec-file /bd/home/philippe/gdb/git/build_fixes/gdb/gdb
exec-file-mismatch handling is currently "ask"
Load new symbol table from "/bd/home/philippe/gdb/git/build_fixes/gdb/gdb"? (y or n) y
Reading symbols from /bd/home/philippe/gdb/git/build_fixes/gdb/gdb...
Setting up the environment for debugging gdb.
...
Reading symbols from /usr/lib/debug/.build-id/60/6df9c355103e82140d513bc7a25a635591c153.debug...
0x00007f43c23478a0 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: No such file or directory.
(top-gdb) bt
During symbol reading: incomplete CFI data; unspecified registers (e.g., rax) at 0x7f43c23478ad
During symbol reading: unsupported tag: 'DW_TAG_unspecified_type'
During symbol reading: cannot get low and high bounds for subprogram DIE at 0x12282a7
During symbol reading: Child DIE 0x12288ba and its abstract origin 0x1228b26 have different parents
During symbol reading: DW_AT_call_target target DIE has invalid low pc, for referencing DIE 0x1229540 [in module /bd/home/philippe/gdb/git/build_fixes/gdb/gdb]
#0 0x00007f43c23478a0 in __poll_nocancel () at ../sysdeps/unix/syscall-template.S:84
#1 0x0000558909e3ad91 in poll (__timeout=-1, __nfds=<optimized out>, __fds=<optimized out>) at /usr/include/x86_64-linux-gnu/bits/poll2.h:46
#2 gdb_wait_for_event (block=block@entry=1) at ../../fixes/gdb/event-loop.c:772
#3 0x0000558909e3aef4 in gdb_do_one_event () at ../../fixes/gdb/event-loop.c:347
#4 0x0000558909e3b085 in gdb_do_one_event () at ../../fixes/gdb/common/common-exceptions.h:219
#5 start_event_loop () at ../../fixes/gdb/event-loop.c:371
During symbol reading: Member function "~_Sp_counted_base" (offset 0x1c69bf7) is virtual but the vtable offset is not specified
During symbol reading: Multiple children of DIE 0x1c8f5a0 refer to DIE 0x1c8f0ee as their abstract origin
#6 0x0000558909ed3b78 in captured_command_loop () at ../../fixes/gdb/main.c:331
#7 0x0000558909ed4b6d in captured_main (data=<optimized out>) at ../../fixes/gdb/main.c:1174
#8 gdb_main (args=<optimized out>) at ../../fixes/gdb/main.c:1190
#9 0x0000558909c1e9a8 in main (argc=<optimized out>, argv=<optimized out>) at ../../fixes/gdb/gdb.c:32
(top-gdb)
gdb /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers
...
Reading symbols from /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers...
(gdb) atta 31069
Attaching to program: /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers, process 31069
warning: Mismatch between current exec-file /home/philippe/valgrind/git/trunk_untouched/gdbserver_tests/sleepers
and automatically determined exec-file /bd/home/philippe/gdb/git/build_fixes/gdb/gdb
exec-file-mismatch handling is currently "ask"
Load new symbol table from "/bd/home/philippe/gdb/git/build_fixes/gdb/gdb"? (y or n) y
Reading symbols from /bd/home/philippe/gdb/git/build_fixes/gdb/gdb...
Setting up the environment for debugging gdb.
....
In other words, it now works as intuitively expected by the user.
If ever the user gave the correct executable on the command line,
then attached to the wrong pid, then confirmed loading the wrong executable,
the user can simply fix this by detaching, and attaching to the correct pid,
GDB will then tell again to the user that the exec-file might better
be loaded.
The default value of "ask" is chosen instead of e.g. "warn" as in most
cases, switching of executable will be the correct action,
and in any case, the user can decide to not load the executable,
as GDB asks a confirmation to the user to load the new executable.
For settings "ask" and "warn", the new function validate_exec_file ()
tries to get the inferior pid exec file and compares it with the current
exec file. In case of mismatch, it warns the user and optionally load
the executable.
This function is called in the attach_command implementation to cover
most cases of attaching to a running process.
It must also be called in remote.c, as the attach command is not supported
for all types of remote gdbserver.
gdb/ChangeLog
2020-01-25 Philippe Waroquiers <philippe.waroquiers@skynet.be>
* exec.c (exec_file_mismatch_names, exec_file_mismatch_mode)
(show_exec_file_mismatch_command, set_exec_file_mismatch_command)
(validate_exec_file): New variables, enums, functions.
(exec_file_locate_attach, print_section_info): Style the filenames.
(_initialize_exec): Install show_exec_file_mismatch_command and
set_exec_file_mismatch_command.
* gdbcore.h (validate_exec_file): Declare.
* infcmd.c (attach_command): Call validate_exec_file.
* remote.c ( remote_target::remote_add_inferior): Likewise.
This commit improves GDB's handling of inline functions when there are
more than one inline function in a stack, so for example if we have a
stack like:
main -> aaa -> bbb -> ccc -> ddd
And aaa, bbb, and ccc are all inline within main GDB should (when
given sufficient debug information) be able to step from main through
aaa, bbb, and ccc. Unfortunately, this currently doesn't work, here's
an example session:
(gdb) start
Temporary breakpoint 1 at 0x4003b0: file test.c, line 38.
Starting program: /project/gdb/tests/inline/test
Temporary breakpoint 1, main () at test.c:38
38 global_var = 0;
(gdb) step
39 return aaa () + 1;
(gdb) step
aaa () at test.c:39
39 return aaa () + 1;
(gdb) step
bbb () at test.c:39
39 return aaa () + 1;
(gdb) step
ccc () at test.c:39
39 return aaa () + 1;
(gdb) step
ddd () at test.c:32
32 return global_var;
(gdb) bt
#0 ddd () at test.c:32
#1 0x00000000004003c1 in ccc () at test.c:39
#2 bbb () at test.c:26
#3 aaa () at test.c:14
#4 main () at test.c:39
Notice that once we get to line 39 in main, GDB keeps reporting line
39 in main as the location despite understanding that the inferior is
stepping through the nested inline functions with each use of step.
The problem is that as soon as the inferior stops we call
skip_inline_frames (from inline-frame.c) which calculates the
inferiors current state in relation to inline functions - it figures
out if we're in an inline function, and if we are counts how many
inline frames there are at the current location.
So, in our example above, when we step from line 38 in main to line 39
we stop at a location that is simultaneously in all of main, aaa, bbb,
and ccc. The block structure reflects the order in which the
functions would be called, with ccc being the most inner block and
main being the most outer block. When we stop GDB naturally finds the
block for ccc, however within skip_inline_frames we spot that bbb,
aaa, and main are super-blocks of the current location and that each
layer represents an inline function. The skip_inline_frames then
records the depth of inline functions (3 in this case for aaa, bbb,
and ccc) and also the symbol of the outermost inline function (in this
case 'aaa' as main isn't an inline function, it just has things inline
within it).
Now GDB understands the stack to be main -> aaa -> bbb -> ccc,
however, the state initialised in skip_inline_frames starts off
indicating that we should hide 3 frames from the user, so we report
that we're in main at line 39. The location of main, line 39 is
derived by asking the inline function state for the last symbol in the
stack (aaa in this case), and then asking for it's location - the
location of an inlined function symbol is its call site, so main, line
39 in this case.
If the user then asks GDB to step we don't actually move the inferior
at all, instead we spot that we are in an inline function stack,
lookup the inline state data, and reduce the skip depth by 1. We then
report to the user that GDB has stopped. GDB now understands that we
are in 'aaa'. In order to get the precise location we again ask GDB
for the last symbol from the inline data structure, and we are again
told 'aaa', we then get the location from 'aaa', and report that we
are in main, line 39.
Hopefully it's clear what the mistake here is, once we've reduced the
inline skip depth we should not be using 'aaa' to compute the precise
location, instead we should be using 'bbb'. That is what this patch
does.
Now, when we call skip_inline_frames instead of just recording the
last skipped symbol we now record all symbols in the inline frame
stack. When we ask GDB for the last skipped symbol we return a symbol
based on how many frames we are skipping, not just the last know
symbol.
With this fix in place, the same session as above now looks much
better:
(gdb) start
Temporary breakpoint 1 at 0x4003b0: file test.c, line 38.
Starting program: /project/gdb/tests/inline/test
Temporary breakpoint 1, main () at test.c:38
38 global_var = 0;
(gdb) s
39 return aaa () + 1;
(gdb) s
aaa () at test.c:14
14 return bbb () + 1;
(gdb) s
bbb () at test.c:26
26 return ccc () + 1;
(gdb) s
ccc () at test.c:20
20 return ddd () + 1;
(gdb) s
ddd () at test.c:32
32 return global_var;
(gdb) bt
#0 ddd () at test.c:32
#1 0x00000000004003c1 in ccc () at test.c:20
#2 bbb () at test.c:26
#3 aaa () at test.c:14
#4 main () at test.c:39
gdb/ChangeLog:
* frame.c (find_frame_sal): Move call to get_next_frame into more
inner scope.
* inline-frame.c (inilne_state) <inline_state>: Update argument
types.
(inilne_state) <skipped_symbol>: Rename to...
(inilne_state) <skipped_symbols>: ...this, and change to a vector.
(skip_inline_frames): Build vector of skipped symbols and use this
to reate the inline_state.
(inline_skipped_symbol): Add a comment and some assertions, fetch
skipped symbol from the list.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-inline-many-frames.c: New file.
* gdb.dwarf2/dw2-inline-many-frames.exp: New file.
Change-Id: I99def5ffb44eb9e58cda4b449bf3d91ab0386c62