Commit graph

9113 commits

Author SHA1 Message Date
Bruno Larsen
6619a08b25 [gdb/testsuite] update analyze-racy-logs.py to python3
Since python 2 is no longer supported on most distributions, update the
script to run under python while while still being runnable under
python2.
2021-10-04 09:29:27 -03:00
Lancelot SIX
2b014cc535 gdb: Support the c.mv insn in the riscv prologue scanner.
While working on other problems, I encountered situations where GDB
fails to properly unwind the stack because some functions use the C.MV
instruction in the prologue.  The prologue scanner stops when it hits
this instruction assuming its job is done at this point.  Unfortunately
the prologue is not necessarily finished yet, preventing GDB to properly
unwind.

This commit adds support for handling such instruction in
riscv_scan_prologue.

Note that C.MV is part of the compressed instruction set.  The MV
counterpart from the base ISA is a pseudo instruction that expands to
'ADDI RD,RS1,0' which is already supported.

Tested on riscv64-linux-gnu.

All feedback are welcome.
2021-10-03 14:00:58 +00:00
Simon Marchi
46a5b75b37 gdb/testsuite/dwarf: use options for rnglists/loclists procs
Change how rnglists and loclists procs to align them with how procs for
aranges (and other things in the DWARF assembler) work.  Instead of
using "args" (variable number of parameters in TCL) and command-line
style option arguments, use one leading "option" parameters, used as a
kind of key/value dictionary of options parsed using `parse_options`.

Change-Id: I63e60d17ae16a020ce4d6de44baf3d152ea42a1a
2021-09-30 22:21:56 -04:00
Simon Marchi
c5dfcc2188 gdb/testsuite/dwarf: don't define nested procs for rnglists/loclists
When I wrote support for rnglists and loclists in the testsuite's DWARF
assembler, I made it with nested procs, for example proc "table" inside
proc "rnglists".  The intention was that this proc "table" could only be
used by the user while inside proc "rnglists"'s body.  I had chosen very
simple names, thinking there was no chance of name clashes.  I recently
learned that this is not how TCL works.  This ends up defining a proc
"table" in the current namespace ("Dwarf" in this case).

Things still work if you generate rnglists and loclists in the same
file, as each redefines its own procedures when executing.  But if a
user of the assembler happened to define a convenience "table" or
"start_end" procedure, for example, it would get overriden.

I'd like to change how this works to reduce the chances of a name clash.

 - Move the procs out of each other, so they are not defined in a nested
   fashion.
 - Prefix them with "_rnglists_" or "_loclists_".
 - While calling $body in the various procs, temporarily make the procs
   available under their "short" name.  For example, while in rngllists'
   body, make _rnglists_table available as just "table".  This allows
   existing code to keep working and keeps it not too verbose.
 - Modify with_override to allow the overriden proc to not exist.  In
   that case, the temporary proc is deleted on exit.

Note the non-conforming indentation when calling with_override in
_loclists_list.  This is on purpose: as we implement more loclists (and
rnglists) entry types, the indentation would otherwise get larger and
larger without much value for readability.  So I think it's reasonable
here to put them on the same level.

Change-Id: I7bb48d26fcb0dba1ae4dada05c0c837212424328
2021-09-30 22:21:52 -04:00
Tom de Vries
e4860c08f9 [gdb/testsuite] Add untested for missing xml support in gdb.base/valgrind*.exp
Add untested in case missing xml support is detected in test-cases
gdb.base/valgrind*.exp.

Tested on x86_64-linux.
2021-09-30 23:46:32 +02:00
Simon Marchi
4dfef5be68 gdb/testsuite: make runto_main not pass no-message to runto
As follow-up to this discussion:

  https://sourceware.org/pipermail/gdb-patches/2020-August/171385.html

... make runto_main not pass no-message to runto.  This means that if we
fail to run to main, for some reason, we'll emit a FAIL.  This is the
behavior we want the majority of (if not all) the time.

Without this, we rely on tests logging a failure if runto_main fails,
otherwise.  They do so in a very inconsisteny mannet, sometimes using
"fail", "unsupported" or "untested".  The messages also vary widly.
This patch removes all these messages as well.

Also, remove a few "fail" where we call runto (and not runto_main).  by
default (without an explicit no-message argument), runto prints a
failure already.  In two places, gdb.multi/multi-re-run.exp and
gdb.python/py-pp-registration.exp, remove "message" passed to runto.
This removes a few PASSes that we don't care about (but FAILs will still
be printed if we fail to run to where we want to).  This aligns their
behavior with the rest of the testsuite.

Change-Id: Ib763c98c5f4fb6898886b635210d7c34bd4b9023
2021-09-30 15:27:39 -04:00
Tom de Vries
7264ba8331 [gdb/testsuite] Use untested in gdb.debuginfod/fetch_src_and_symbols.exp
With running test-case gdb.debuginfod/fetch_src_and_symbols.exp with target
board unix/-bad, I get:
...
gcc: error: unrecognized command line option '-bad'^M
compiler exited with status 1
gdb compile failed, gcc: error: unrecognized command line option '-bad'
FAIL: gdb.debuginfod/fetch_src_and_symbols.exp: compile
...

Replace the FAIL with the usual:
...
UNTESTED: gdb.debuginfod/fetch_src_and_symbols.exp: failed to compile
...

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
243c0950e2 [gdb/testsuite] Remove redundant FAIL in gdb.base/info-os.exp
When running test-case gdb.base/info-os.exp with target board unix/-bad, I run
into:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.base/info-os.exp: failed to prepare
FAIL: gdb.base/info-os.exp: cannot compile test program
...

Remove the redundant FAIL.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
50f9e7d853 [gdb/testsuite] Fix DUPLICATE in gdb.base/info-os.exp
When running test-case gdb.base/info-os.exp, I run into:
...
PASS: gdb.base/info-os.exp: get threads
PASS: gdb.base/info-os.exp: get threads
DUPLICATE: gdb.base/info-os.exp: get threads
...

Fix this not doing pass followed by exp_continue in gdb_test_multiple.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
9ebd290966 [gdb/testsuite] Check compilation result in gdb.dwarf2/dw2-opt-structptr.exp
When running test-case gdb.dwarf2/dw2-opt-structptr.exp with target board
unix/-bad, I get:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.dwarf2/dw2-opt-structptr.exp: dw2-opt-structptr.exp
UNTESTED: gdb.dwarf2/dw2-opt-structptr.exp: failed to compile
ERROR: (dw2-opt-structptr) No such file or directory
UNRESOLVED: gdb.dwarf2/dw2-opt-structptr.exp: console: set print object on
...

Merge the two UNTESTEDs.

Fix the UNRESOLVED by checking result of compilation.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
c2fd8824c8 [gdb/testsuite] Check compilation result in gdb.base/structs.exp
When running test-case gdb.base/structs.exp with target board unix/-bad, I
get:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.base/structs.exp: failed to prepare
ERROR: tcl error sourcing src/gdb/testsuite/gdb.base/structs.exp.
ERROR: can't read "use_gdb_stub": no such variable
...

Fix this by checking the compilation result.

Fix the resulting DUPLICATEs using with_test_prefix.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
dc412de5e9 [gdb/testsuite] Prepare nodebug exec in gdb.base/cvexpr.exp
When running test-case gdb.base/cvexpr.exp with target board unix/-bad, I get:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
ERROR: tcl error sourcing src/gdb/testsuite/gdb.base/cvexpr.exp.
ERROR: can't read "use_gdb_stub": no such variable
...

This is triggered in a part of the test that claims to require no debug
information, but uses the exec containing either dwarf or ctf.

Fix this by preparing another executable compiled with nodebug, and using
that one instead.

Also use with_test_prefix to mark the nodebug part, such that we have:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.base/cvexpr.exp: dwarf: failed to prepare
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.base/cvexpr.exp: nodebug: failed to prepare
...

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
85d74f2936 [gdb/testsuite] Fix DUPLICATE in gdb.base/cvexpr.exp
Fix:
...
DUPLICATE: gdb.base/cvexpr.exp: ptype int * restrict
...
using with_test_prefix.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
e46da7ec1b [gdb/testsuite] Check compilation result in gdb.base/call-sc.exp
When running test-case gdb.base/call-sc.exp with target board unix/-bad, I
get:
...
gdb compile failed, gcc: error: unrecognized command line option '-bad'
UNTESTED: gdb.base/call-sc.exp: failed to prepare
ERROR: tcl error sourcing src/gdb/testsuite/gdb.base/call-sc.exp.
ERROR: can't read "use_gdb_stub": no such variable
...

Fix this by checking the compilation result.

Fix the resulting DUPLICATE:
...
DUPLICATE: gdb.base/call-sc.exp: failed to prepare
...
using with_test_prefix.

Tested on x86_64-linux.
2021-09-30 19:07:48 +02:00
Tom de Vries
b6107a72ba [gdb/testsuite] Fix untested messages in gdb.mi/*.exp
The effect of:
...
untested "y.exp"
...
in a gdb.x/y.exp is:
...
UNTESTED: gdb.x/y.exp: y.exp
...
which is a bit pointless.

Replace these untested messages in gdb.mi/*.exp with the usual "failed to
compile".

Likewise for an:
...
untested $testname
...
where the variable is undefined.

Tested on x86_64-linux.
2021-09-30 19:07:47 +02:00
Tom de Vries
6010fb0c49 [gdb/testsuite] Fix full buffer in gdb.rust/dwindex.exp
On ubuntu 18.04.5, I run into:
...
(gdb) mt print objfiles dwindex^M
^M
Object file build/gdb/testsuite/outputs/gdb.rust/dwindex/dwindex:  \
  Objfile at 0x55dab0b87a50, bfd at 0x55dab0b0cfa0, 1095 minsyms^M
^M
Psymtabs:^M
vendor/compiler_builtins/src/int/specialized_div_rem/mod.rs at 0x55dab0db0720^M
  ...
library/std/src/sys/unix/stdio.rs at 0x55dab0d96320^M
ERROR: internal buffer is full.
UNRESOLVED: gdb.rust/dwindex.exp: check if index present
...

Fix this by using -lbl in proc ensure_gdb_index.

Tested on x86_64-linux.
2021-09-30 12:02:14 +02:00
Tom de Vries
215b6d107c [gdb/testsuite] Fix gdb.base/break-interp.exp for ld.so without debug
When running test-case gdb.base/break-interp.exp on openSUSE Leap 42.3, I get:
...
(gdb) info addr dl_main^M
Symbol "dl_main" is at 0x1750 in a file compiled without debugging.^M
(gdb) FAIL: gdb.base/break-interp.exp: info addr dl_main
...
while the regexp expects "Symbol \"dl_main\" is a function at address $hex\\."

Fix this by also accepting this variant.

Tested on x86_64-linux.
2021-09-30 00:29:32 +02:00
Pedro Alves
8e4e0c7a49 Fix gdb.multi/multi-term-settings.exp race
The gdb.multi/multi-term-settings.exp testcase sometimes fails like so:

 Running /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.multi/multi-term-settings.exp ...
 FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c (SIGINT)

It's easier to reproduce if you stress the machine at the same time, like e.g.:

  $ stress -c 24

Looking at gdb.log, we see:

 (gdb) attach 60422
 Attaching to program: build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings, process 60422
 [New Thread 60422.60422]
 Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
 Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.31.so...
 Reading symbols from /lib64/ld-linux-x86-64.so.2...
 (No debugging symbols found in /lib64/ld-linux-x86-64.so.2)
 0x00007f2fc2485334 in __GI___clock_nanosleep (clock_id=<optimized out>, clock_id@entry <mailto:clock_id@entry>=0, flags=flags@entry <mailto:flags@entry>=0, req=req@entry <mailto:req@entry>=0x7ffe23126940, rem=rem@entry <mailto:rem@entry>=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
 78	../sysdeps/unix/sysv/linux/clock_nanosleep.c: No such file or directory.
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: inf2: attach
 set schedule-multiple on
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: set schedule-multiple on
 info inferiors
   Num  Description       Connection                         Executable
   1    process 60404     1 (extended-remote localhost:2349) build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings
 * 2    process 60422     1 (extended-remote localhost:2349) build/gdb/testsuite/outputs/gdb.multi/multi-term-settings/multi-term-settings
 (gdb) PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: info inferiors
 pid=60422, count=46
 pid=60422, count=47
 pid=60422, count=48
 pid=60422, count=49
 pid=60422, count=50
 pid=60422, count=51
 pid=60422, count=52
 pid=60422, count=53
 pid=60422, count=54
 pid=60422, count=55
 pid=60422, count=56
 pid=60422, count=57
 pid=60422, count=58
 pid=60422, count=59
 pid=60422, count=60
 pid=60422, count=61
 pid=60422, count=62
 pid=60422, count=63
 pid=60422, count=64
 pid=60422, count=65
 pid=60422, count=66
 pid=60422, count=67
 pid=60422, count=68
 pid=60422, count=69
 pid=60404, count=54
 pid=60404, count=55
 pid=60404, count=56
 pid=60404, count=57
 pid=60404, count=58
 PASS: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: continue
 Quit
 (gdb) FAIL: gdb.multi/multi-term-settings.exp: inf1_how=attach: inf2_how=attach: stop with control-c (SIGINT)

If you look at the testcase's sources, you'll see that the intention
is to resumes the program with "continue", wait to see a few of those
"pid=..., count=..." lines, and then interrupt the program with
Ctrl-C.  But somehow, that resulted in GDB printing "Quit", instead of
the Ctrl-C stopping the program with SIGINT.

Here's what is happening:

 #1 - those "pid=..., count=..." lines we see above weren't actually
      output by the inferior after it has been continued (see #1).
      Note that "inf1_how" and "inf2_how" are "attach".  What happened
      is that those "pid=..., count=..." lines were output by the
      inferiors _before_ they were attached to.  We see them at that
      point instead of earlier, because that's where the testcase
      reads from the inferiors' spawn_ids.

 #2 - The testcase mistakenly thinks those "pid=..., count=..." lines
      happened after the continue was processed by GDB, meaning it has
      waited enough, and so sends the Ctrl-C.  GDB hasn't yet passed
      the terminal to the inferior, so the Ctrl-C results in that
      Quit.

The fix here is twofold:

 #1 - flush inferior output right after attaching

 #2 - consume the "Continuing" printed by "continue", indicating the
      inferior has the terminal.  This is the same as done throughout
      the testsuite to handle this exact problem of sending Ctrl-C too
      soon.

gdb/testsuite/ChangeLog:
yyyy-mm-dd  Pedro Alves  <pedro@palves.net <mailto:pedro@palves.net>>

	* gdb.multi/multi-term-settings.exp (create_inferior): Flush
	inferior output.
	(coretest): Use $gdb_test_name.  After issuing "continue", wait
	for "Continuing".

Change-Id: Iba7671dfe1eee6b98d29cfdb05a1b9aa2f9defb9
2021-09-29 15:53:52 +02:00
Tom de Vries
607679092f [gdb/testsuite] Disable vgdb tests if xml not supported
I build gdb without xml support using --without-expat, and ran into:
...
(gdb) target remote | vgdb --wait=2 --max-invoke-ms=2500 --pid=22032^M
Remote debugging using | vgdb --wait=2 --max-invoke-ms=2500 --pid=22032^M
relaying data between gdb and process 22032^M
warning: Can not parse XML target description; XML support was disabled at \
  compile time^M
  ...
(gdb) PASS: gdb.base/valgrind-infcall.exp: continue #1
p gdb_test_infcall ()^M
Remote 'g' packet reply is too long (expected 560 bytes, got 800 bytes): ...^M
(gdb) FAIL: gdb.base/valgrind-infcall.exp: p gdb_test_infcall ()
...

After googling the error message with context valgrind gdbserver, I found
indications that the Remote 'g' packet reply error is due to missing xml
support.

And here ( https://www.valgrind.org/docs/manual/manual-core-adv.html ) I
found:
...
GDB version needed for ARM and PPC32/64.

You must use a GDB version which is able to read XML target description sent
by a gdbserver.  This is the standard setup if GDB was configured and built
with the "expat" library.  If your GDB was not configured with XML support, it
will report an error message when using the "target" command.  Debugging will
not work because GDB will then not be able to fetch the registers from the
Valgrind gdbserver.
...

So I guess I'm running into the same problem for x86_64.

Fix this by skipping all gdb.base/valgrind-*.exp tests if xml support is not
available.  Although only the gdb.base/valgrind-infcall*.exp produce fails,
the Remote 'g' packet reply error occurs in all tests, so it seems prudent to
disable them all.

Tested on x86_64-linux.
2021-09-29 15:53:52 +02:00
Tom de Vries
6767cc642c [gdb/testsuite] Fix gdb.python/py-breakpoint.exp with python 2
With a gdb build using python 2.7, I run into:
...
(gdb) python \
  gdb.events.breakpoint_modified.connect(lambda bp: print(bp.enabled))^M
  File "<string>", line 1^M
    gdb.events.breakpoint_modified.connect(lambda bp: print(bp.enabled))^M
                                                          ^^M
SyntaxError: invalid syntax^M
Error while executing Python code.^M
(gdb) FAIL: gdb.python/py-breakpoint.exp: test_bkpt_auto_disable: \
  trap breakpoint_modified event
...

This is caused by the following:
- a lambda function body needs to be an expression
- in python 2, print is a statement, while in python 3 it's a function
- a function call is an expression, and a statement is not.

Fix this by defining a function print_bp_enabled:
...
def print_bp_enabled (bp):
    print (bp.enabled)
end
...
and using that instead.

Tested on x86_64-linux.
2021-09-29 15:53:52 +02:00
Tom de Vries
f15ec499bf [gdb/testsuite] Fix breakpoint detection in gdb.gdb/python-helper.exp
With a gdb configured to be somewhat minimal, while still supporting python:
...
$ gdb --configuration
This GDB was configured as follows:
   configure --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --without-expat
             --with-gdb-datadir=$install/share/gdb (relocatable)
             --with-jit-reader-dir=$install/lib64/gdb (relocatable)
             --without-libunwind-ia64
             --without-lzma
             --without-babeltrace
             --without-intel-pt
             --with-mpfr
             --without-xxhash
             --with-python=/usr
             --with-python-libdir=/usr/lib
             --with-debuginfod
             --without-guile
             --disable-source-highlight
             --with-separate-debug-dir=/usr/lib/debug
             --with-system-gdbinit=$devel/system-gdbinit
...
and using gcc 4.8 to build gdb (causing std::thread not to be used due to
PR28318) I ran into:
...
(gdb) PASS: gdb.gdb/python-helper.exp: start inner gdb
print 1^M
^M
Breakpoint 2, value_print () at src/gdb/valprint.c:1174^M
1174      scoped_value_mark free_values;^M
(xgdb) FAIL: gdb.gdb/python-helper.exp: hit breakpoint in inner gdb (timeout)
...

The problem is that the regexp expects "hit Breakpoint $decimal".  The "hit"
part is missing.

The "hit" is printed by maybe_print_thread_hit_breakpoint, when
show_thread_that_caused_stop returns true:
...
int
show_thread_that_caused_stop (void)
{
  return highest_thread_num > 1;
}
...
Apparently, that's not the case.

Fix this by removing "hit" from the regexp, making the regexp more similar to
what is used in say, continue_to_breakpoint.

Tested on x86_64-linux.
2021-09-29 15:53:52 +02:00
Simon Marchi
abe8cab7cb gdb: enable target_async around stop_all_threads call in process_initial_stop_replies
The following scenario hangs:

 - maint set target-non-stop on
 - `gdbserver --attach`
 - a multi-threaded program

For example:

Terminal 1:

    $ gnome-calculator&
    [1] 495731
    $ ../gdbserver/gdbserver --once --attach :1234 495731
    Attached; pid = 495731
    Listening on port 1234

Terminal 2:

    $ ./gdb -nx -q --data-directory=data-directory /usr/bin/gnome-calculator -ex "maint set target-non-stop on" -ex "tar rem :1234"
    Reading symbols from /usr/bin/gnome-calculator...
    (No debugging symbols found in /usr/bin/gnome-calculator)
    Remote debugging using :1234
    * hangs *

What happens is:

 - The protocol between gdb and gdbserver is in non-stop mode, but the
   user-visible behavior is all-stop
 - On connect, gdbserver sends one stop reply for one thread that is
   stops, the others stay running
 - In process_initial_stop_replies, gdb calls stop_all_threads to stop
   these other threads, because we are using the all-stop user-visible
   mode
 - stop_all_threads sends a stop request for all the running threads and
   then waits for resulting events
 - At this point, the remote target is in target_async(0) mode, which
   makes stop_all_threads not consider it for events
 - stop_all_threads loops indefinitely (it does not even block
   indefinitely, it is in an infinite busy loop) because there are no
   event sources.  wait_one_event returns a TARGET_WAITKIND_NO_RESUMED
   wait status.

Fix that by making the remote target async around the stop_all_threads
call.

I haven't implemented it because I'm not sure how to do it, but I think
it would be a good idea to have, in stop_all_threads / wait_one /
handle_one, an assert to check that if we are expecting one or more
event, then there are some targets that are in a state where they can
supply some events.  Otherwise, we'll necessarily be stuck in this
infinite loop, and it's probably due to a bug in GDB.  I'm not too sure
where to put this or how to express it though.  Perhaps in
stop_all_threads, here:

	  for (int i = 0; i < waits_needed; i++)
	    {
	      wait_one_event event = wait_one ();
	      *here*
	      if (handle_one (event))
		break;
	    }

If at that point, the returned event is TARGET_WAITKIND_NO_RESUMED,
there's a problem.  We expect some event, because we've asked some
threads to stop, but all targets are answering that they won't have any
events for us.  That's a contradiction, and a sign that something has
gone wrong.  It could perhaps event be:

    gdb_assert (event.ws.kind != TARGET_WAITKIND_NO_RESUMED);

in handle_one, as the idea is the same in prepare_for_detach.

A bit more sophisticated would be: we know which targets we are
expecting waits from, since we know which threads we have asked to
stop.  So if any of these targets returns TARGET_WAITKIND_NO_RESUMED,
something is fishy.

Add a test that tests attaching with gdbserver's --attach flag to a
multi-threaded program, and then connecting to it.  Without the fix, the
test reproduces the hang.

Change-Id: If6f6690a4887ca66693ef1af64791dda4c65f24f
2021-09-28 20:18:30 -04:00
Simon Marchi
4872f9a1b5 gdb.base/foll-fork.exp: accept "info breakpoints" output in any order
The test currently requires the "inf 1" breakpoint to be before the "inf
2" breakpoint.  This is not always the case:

    info breakpoints 2
    Num     Type           Disp Enb Address            What
    2       breakpoint     keep y   <MULTIPLE>
    2.1                         y   0x0000555555554730 in callee at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/foll-fork.c:9 inf 2
    2.2                         y   0x0000555555554730 in callee at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/foll-fork.c:9 inf 1
    (gdb) FAIL: gdb.base/foll-fork.exp: follow-fork-mode=parent: detach-on-fork=off: cmd=next 2: test_follow_fork: info breakpoints

Since add_location_to_breakpoint uses only the address as a criterion to
sort locations, the order of locations at the same address is not
stable: it will depend on the insertion order.  Here, the insertion
order comes from the order of SALs when creating the breakpoint, which
can vary from machine to machine.  While it would be more user-friendly
to have a more stable order for printed breakpoint locations, it doesn't
really matter for this test, and it would be hard to define an order
that will be the same everywhere, all the time.

So, loosen the regexp to accept "inf 1" and "inf 2" in any order.

Co-Authored-By: Pedro Alves <pedro@palves.net>
Change-Id: I5ada2e0c6ad0669e0d161bfb6b767229c0970d16
2021-09-28 19:30:41 -04:00
Andrew Burgess
91f2597bd2 gdb: print backtrace for internal error/warning
This commit builds on previous work to allow GDB to print a backtrace
of itself when GDB encounters an internal-error or internal-warning.
This fixes PR gdb/26377.

There's not many places where we call internal_warning, and I guess in
most cases the user would probably continue their debug session.  And
so, in order to avoid cluttering up the output, by default, printing
of a backtrace is off for internal-warnings.

In contrast, printing of a backtrace is on by default for
internal-errors, as I figure that in most cases hitting an
internal-error is going to be the end of the debug session.

Whether a backtrace is printed or not can be controlled with the new
settings:

  maintenance set internal-error backtrace on|off
  maintenance show internal-error backtrace

  maintenance set internal-warning backtrace on|off
  maintenance show internal-warning backtrace

Here is an example of what an internal-error now looks like with the
backtrace included:

  (gdb) maintenance internal-error blah
  ../../src.dev-3/gdb/maint.c:82: internal-error: blah
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  ----- Backtrace -----
  0x5c61ca gdb_internal_backtrace_1
  	../../src.dev-3/gdb/bt-utils.c:123
  0x5c626d _Z22gdb_internal_backtracev
  	../../src.dev-3/gdb/bt-utils.c:165
  0xe33237 internal_vproblem
  	../../src.dev-3/gdb/utils.c:393
  0xe33539 _Z15internal_verrorPKciS0_P13__va_list_tag
  	../../src.dev-3/gdb/utils.c:470
  0x1549652 _Z14internal_errorPKciS0_z
  	../../src.dev-3/gdbsupport/errors.cc:55
  0x9c7982 maintenance_internal_error
  	../../src.dev-3/gdb/maint.c:82
  0x636f57 do_simple_func
  	../../src.dev-3/gdb/cli/cli-decode.c:97
   .... snip, lots more backtrace lines ....
  ---------------------
  ../../src.dev-3/gdb/maint.c:82: internal-error: blah
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  Quit this debugging session? (y or n) y

  This is a bug, please report it.  For instructions, see:
  <https://www.gnu.org/software/gdb/bugs/>.

  ../../src.dev-3/gdb/maint.c:82: internal-error: blah
  A problem internal to GDB has been detected,
  further debugging may prove unreliable.
  Create a core file of GDB? (y or n) n

My hope is that this backtrace might make it slightly easier to
diagnose GDB issues if all that is provided is the console output, I
find that we frequently get reports of an assert being hit that is
located in pretty generic code (frame.c, value.c, etc) and it is not
always obvious how we might have arrived at the assert.

Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=26377
2021-09-28 12:21:22 +01:00
Simon Marchi
da474da158 gdb: don't share aspace/pspace on fork with "detach-on-fork on" and "follow-fork-mode child"
We found that when handling forks, two inferiors can unexpectedly share
their program space and address space.  To reproduce:

 1. Using a test program that forks...
 2. "set follow-fork-mode child"
 3. "set detach-on-fork on" (the default)
 4. run to a breakpoint somewhere after the fork

Step 4 should have created a new inferior:

    (gdb) info inferiors
      Num  Description       Connection           Executable
      1    <null>                                 /home/smarchi/build/wt/amd/gdb/fork
    * 2    process 251425    1 (native)           /home/smarchi/build/wt/amd/gdb/fork

By inspecting the state of GDB, we can see that the two inferiors now
share one program space and one address space:

Inferior 1:

    (top-gdb) p inferior_list.m_front.num
    $2 = 1
    (top-gdb) p inferior_list.m_front.aspace
    $3 = (struct address_space *) 0x5595e2520400
    (top-gdb) p inferior_list.m_front.pspace
    $4 = (struct program_space *) 0x5595e2520440

Inferior 2:

    (top-gdb) p inferior_list.m_front.next.num
    $5 = 2
    (top-gdb) p inferior_list.m_front.next.aspace
    $6 = (struct address_space *) 0x5595e2520400
    (top-gdb) p inferior_list.m_front.next.pspace
    $7 = (struct program_space *) 0x5595e2520440

You can then run inferior 1 again and the two inferiors will still
erroneously share their spaces, but already at this point this is wrong.

The cause of the bad {a,p}space sharing is in follow_fork_inferior.
When following the child and detaching from the parent, we just re-use
the parent's spaces, rather than cloning them.  When we switch back to
inferior 1 and run again, we find ourselves with two unrelated inferiors
sharing spaces.

Fix that by creating new spaces for the parent after having moved them
to the child.  My initial implementation created new spaces for the
child instead.  Doing this breaks doing "next" over fork().  When "next"
start, we record the symtab of the starting location.  When the program
stops, we compare that symtab with the symtab the program has stopped
at.  If the symtab or the line number has changed, we conclude the
"next" is done.  If we create a new program space for the child and copy
the parent's program space to it with clone_program_space, it creates
new symtabs for the child as well.  When the child stop, but still on
the fork() line, GDB thinks the "next" is done because the symtab
pointers no longer match.  In reality they are two symtab instances that
represent the same file.  But moving the spaces to the child and
creating new spaces for the parent, we avoid this problem.

Note that the problem described above happens today with "detach-on-fork
off" and "follow-fork-mode child", because we create new spaces for the
child.  This will have to be addressed later.

Test-wise, improve gdb.base/foll-fork.exp to set a breakpoint that is
expected to have a location in each inferiors.  Without the fix, when
the two inferiors erroneously share a program space, GDB reports a
single location.

Change-Id: Ifea76e14f87b9f7321fc3a766217061190e71c6e
2021-09-27 16:55:46 -04:00
Simon Marchi
8188f382a1 gdb.base/foll-fork.exp: use foreach_with_prefix to handle prefixes
No behavior change in the test expected, other than in the test names.

Change-Id: I111137483858ab0f23138439f2930009779a2b3d
2021-09-27 16:55:46 -04:00
Simon Marchi
cfda0b5619 gdb.base/foll-fork.exp: rename variables
Rename the variables / parameters used to match the corresponding GDB
setting name, I find that easier to follow.

Change-Id: Idcbddbbb369279fcf1e808b11a8c478f21b2a946
2021-09-27 16:55:46 -04:00
Simon Marchi
b45781ddac gdb.base/foll-fork.exp: refactor to restart GDB between each portion of the test
This test is difficult to follow and modify because the state of GDB is
preserved some tests.  Add a setup proc, which starts a new GDB and runs
to main, and use it in all test procs.  Use proc_with_prefix to avoid
duplicates.

The check_fork_catchpoints proc also seems used to check for follow-fork
support by checking if catchpoints are supported.  If they are not, it
uses "return -code return", which makes its caller return.  I find this
unnecessary complex, versus just returning a boolean.  Modify it to do
so.

Change-Id: I23e62b204286c5e9c5c86d2727f7d33fb126ed08
2021-09-27 16:55:46 -04:00
Simon Marchi
09c0623ade gdb.base/foll-fork.exp: remove gating based on target triplet
It looks like this test has some code to check at runtime the support of
fork handling of the target (see check_fork_catchpoints).  So, it seems
to me that the check based on target triplet at the beginning of the
test is not needed.  This kind of gating is generally not desirable,
because we wouldn't think of updating it when adding fork support to a
target.  For example, FreeBSD supports fork, but it wasn't listed here.

Change-Id: I6b55f2298edae6b37c3681fb8633d8ea1b5aabee
2021-09-27 16:55:46 -04:00
Simon Marchi
59767d3c39 gdb.base/foll-fork.exp: remove DUPLICATEs
Remove DUPLICATEs, and and at the same time replace two uses of
gdb_test_multiple with gdb_test.  I don't think using gdb_test_multiple
is necessary here.

Change-Id: I8dcf097c3364e92d4f0e11f0c0f05dbb88e86742
2021-09-27 16:55:46 -04:00
Andrew Burgess
fde1a9a3ee gdb: add setting to disable reading source code files
In some situations it is possible that a user might not want GDB to
try and access source code files, for example, the source code might
be stored on a slow to access network file system.

It is almost certainly possible that using some combination of 'set
directories' and/or 'set substitute-path' a user can trick GDB into
being unable to find the source files, but this feels like a rather
crude way to solve the problem.

In this commit a new option is add that stops GDB from opening and
reading the source files.  A user can run with source code reading
disabled if this is required, then re-enable later if they decide
that they now want to view the source code.
2021-09-27 11:31:35 +01:00
Andrew Burgess
275ee935b3 gdb: prevent an assertion when computing the frame_id for an inline frame
I ran into this assertion while GDB was trying to unwind the stack:

  gdb/inline-frame.c:173: internal-error: void inline_frame_this_id(frame_info*, void**, frame_id*): Assertion `frame_id_p (*this_id)' failed.

That is, when building the frame_id for an inline frame, GDB asks for
the frame_id of the previous frame.  Unfortunately, no valid frame_id
was returned for the previous frame, and so the assertion triggers.

What is happening is this, I had a stack that looked something like
this (the arrows '->' point from caller to callee):

  normal_frame -> inline_frame

However, for whatever reason (e.g. broken debug information, or
corrupted stack contents in the inferior), when GDB tries to unwind
"normal_frame", it ends up getting back effectively the same frame,
thus the call stack looks like this to GDB:

  .-> normal_frame -> inline_frame
  |     |
  '-----'

Given such a situation we would expect GDB to terminate the stack with
an error like this:

  Backtrace stopped: previous frame identical to this frame (corrupt stack?)

However, the inline_frame causes a problem, and here's why:

When unwinding we start from the sentinel frame and call
get_prev_frame.  We eventually end up in get_prev_frame_if_no_cycle,
in here we create a raw frame, and as this is frame #0 we immediately
return.

However, eventually we will try to unwind the stack further.  When we
do this we inevitably needing to know the frame_id for frame #0, and
so, eventually, we end up in compute_frame_id.

In compute_frame_id we first find the right unwinder for this frame,
in our case (i.e. for inline_frame) the $pc is within the function
normal_frame, but also within a block associated with the inlined
function inline_frame, as such the inline frame unwinder claims this
frame.

Back in compute_frame_id we next compute the frame_id, for our
inline_frame this means a call to inline_frame_this_id.

The ID of an inline frame is based on the id of the previous frame, so
from inline_frame_this_id we call get_prev_frame_always, this
eventually calls get_prev_frame_if_no_cycle again, which creates
another raw frame and calls compute_frame_id (for frames other than
frame 0 we immediately compute the frame_id).

In compute_frame_id we again identify the correct unwinder for this
frame.  Our $pc is unchanged, however, the fact that the next frame is
of type INLINE_FRAME prevents the inline frame unwinder from claiming
this frame again, and so, the standard DWARF frame unwinder claims
normal_frame.

We return to compute_frame_id and call the standard DWARF function to
build the frame_id for normal_frame.

With the frame_id of normal_frame figured out we return to
compute_frame_id, and then to get_prev_frame_if_no_cycle, where we add
the ID for normal_frame into the frame_id cache, and return the frame
back to inline_frame_this_id.

From inline_frame_this_id we build a frame_id for inline_frame and
return to compute_frame_id, and then to get_prev_frame_if_no_cycle,
which adds the frame_id for inline_frame into the frame_id cache.

So far, so good.

However, as we are trying to unwind the complete stack, we eventually
ask for the previous frame of normal_frame, remember, at this point
GDB doesn't know the stack is corrupted (with a cycle), GDB still
needs to figure that out.

So, we eventually end up in get_prev_frame_if_no_cycle where we create
a raw frame and call compute_frame_id, remember, this is for the frame
before normal_frame.

The first task for compute_frame_id is to find the unwinder for this
frame, so all of the frame sniffers are tried in order, this includes
the inline frame sniffer.

The inline frame sniffer asks for the $pc, this request is sent up the
stack to normal_frame, which, due to its cyclic behaviour, tells GDB
that the $pc in the previous frame was the same as the $pc in
normal_frame.

GDB spots that this $pc corresponds to both the function normal_frame
and also the inline function inline_frame.  As the next frame is not
an INLINE_FRAME then GDB figures that we have not yet built a frame to
cover inline_frame, and so the inline sniffer claims this new frame.
Our stack is now looking like this:

  inline_frame -> normal_frame -> inline_frame

But, we have not yet computed the frame id for the outer most (on the
left) inline_frame.  After the frame sniffer has claimed the inline
frame GDB returns to compute_frame_id and calls inline_frame_this_id.

In here GDB calls get_prev_frame_always, which eventually ends up
in get_prev_frame_if_no_cycle again, where we create a raw frame and
call compute_frame_id.

Just like before, compute_frame_id tries to find an unwinder for this
new frame, it sees that the $pc is within both normal_frame and
inline_frame, but the next frame is, again, an INLINE_FRAME, so, just
like before the standard DWARF unwinder claims this frame.  Back in
compute_frame_id we again call the standard DWARF function to build
the frame_id for this new copy of normal_frame.

At this point the stack looks like this:

  normal_frame -> inline_frame -> normal_frame -> inline_frame

After compute_frame_id we return to get_prev_frame_if_no_cycle, where
we try to add the frame_id for the new normal_frame into the frame_id
cache, however, unlike before, we fail to add this frame_id as it is
a duplicate of the previous normal_frame frame_id.  Having found a
duplicate get_prev_frame_if_no_cycle unlinks the new frame from the
stack, and returns nullptr, the stack now looks like this:

  inline_frame -> normal_frame -> inline_frame

The nullptr result from get_prev_frame_if_no_cycle is fed back to
inline_frame_this_id, which forwards this to get_frame_id, which
immediately returns null_frame_id.  As null_frame_id is not considered
a valid frame_id, this is what triggers the assertion.

In summary then:

 - inline_frame_this_id currently assumes that as the inline frame
   exists, we will always get a valid frame back from
   get_prev_frame_always,

 - get_prev_frame_if_no_cycle currently assumes that it is safe to
   return nullptr when it sees a cycle.

Notice that in frame.c:compute_frame_id, this code:

  fi->this_id.value = outer_frame_id;
  fi->unwind->this_id (fi, &fi->prologue_cache, &fi->this_id.value);
  gdb_assert (frame_id_p (fi->this_id.value));

The assertion makes it clear that the this_id function must always
return a valid frame_id (e.g. null_frame_id is not a valid return
value), and similarly in inline_frame.c:inline_frame_this_id this
code:

  *this_id = get_frame_id (get_prev_frame_always (this_frame));
  /* snip comment */
  gdb_assert (frame_id_p (*this_id));

Makes it clear that every inline frame expects to be able to get a
previous frame, which will have a valid frame_id.

As I have discussed above, these assumptions don't currently hold in
all cases.

One possibility would be to move the call to get_prev_frame_always
forward from inline_frame_this_id to inline_frame_sniffer, however,
this falls foul of (in frame.c:frame_cleanup_after_sniffer) this
assertion:

  /* No sniffer should extend the frame chain; sniff based on what is
     already certain.  */
  gdb_assert (!frame->prev_p);

This assert prohibits any sniffer from trying to get the previous
frame, as getting the previous frame is likely to depend on the next
frame, I can understand why this assertion is a good thing, and I'm in
no rush to alter this rule.

The solution proposed here takes onboard feedback from both Pedro, and
Simon (see the links below).  The get_prev_frame_if_no_cycle function
is renamed to get_prev_frame_maybe_check_cycle, and will now not do
cycle detection for inline frames, even when we spot a duplicate frame
it is still returned.  This is fine, as, if the normal frame has a
duplicate frame-id then the inline frame will also have a duplicate
frame-id.  And so, when we reject the inline frame, the duplicate
normal frame, which is previous to the inline frame, will also be
rejected.

In inline-frame.c the call to get_prev_frame_always is no longer
nested inside the call to get_frame_id.  There are reasons why
get_prev_frame_always can return nullptr, for example, if there is a
memory error while trying to get the previous frame, if this should
happen then we now give a more informative error message.

Historical Links:

 Patch v2: https://sourceware.org/pipermail/gdb-patches/2021-June/180208.html
 Feedback: https://sourceware.org/pipermail/gdb-patches/2021-July/180651.html
           https://sourceware.org/pipermail/gdb-patches/2021-July/180663.html

 Patch v3: https://sourceware.org/pipermail/gdb-patches/2021-July/181029.html
 Feedback: https://sourceware.org/pipermail/gdb-patches/2021-July/181035.html

 Additional input: https://sourceware.org/pipermail/gdb-patches/2021-September/182040.html
2021-09-27 11:17:21 +01:00
Tom de Vries
ee2ff2eaa5 [gdb/testsuite] Fix gdb.base/dcache-flush.exp
When running test-case gdb.base/dcache-flush.exp on ubuntu 18.04.5, I run into:
...
(gdb) PASS: gdb.base/dcache-flush.exp: p var2
info dcache^M
Dcache 4096 lines of 64 bytes each.^M
Contains data for Thread 0x7ffff7fc6b80 (LWP 3551)^M
Line 0: address 0x7fffffffd4c0 [47 hits]^M
Line 1: address 0x7fffffffd500 [31 hits]^M
Line 2: address 0x7fffffffd5c0 [7 hits]^M
Cache state: 3 active lines, 85 hits^M
(gdb) FAIL: gdb.base/dcache-flush.exp: check dcache before flushing
...
The regexp expects "Contains data for process $decimal".

This is another case of thread_db_target::pid_to_str being used.

Fix this by updating the regexp.

Tested on x86_64-linux.
2021-09-27 11:33:12 +02:00
Tom de Vries
203a982434 [gdb/testsuite] Test sw watchpoint in gdb.threads/process-dies-while-detaching.exp
The test-case gdb.threads/process-dies-while-detaching.exp takes about 20s
when using hw watchpoints, but when forcing sw watchpoints (using the patch
mentioned in PR28375#c0), the test-case takes instead 3m14s.

Also, it show a FAIL:
...
(gdb) continue^M
Continuing.^M
Cannot find user-level thread for LWP 10324: generic error^M
(gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process:
continue: watchpoint: continue
...
for which PR28375 was filed.

Modify the test-case to:
- add the hw/sw axis to the watchpoint testing, to ensure that we
  observe the sw watchpoint behaviour also on can-use-hw-watchpoints
  architectures.
- skip the hw breakpoint testing if not supported
- set the sw watchpoint later to avoid making the test
  too slow.  This still triggers the same PR, but now takes just 24s.

This patch adds a KFAIL for PR28375.

Tested on x86_64-linux.
2021-09-27 10:16:57 +02:00
Tom de Vries
98bf5c02cf [gdb/testsuite] Minimize gdb restarts
Minimize gdb restarts, applying the following rules:
- don't use prepare_for_testing unless necessary
- don't use clean_restart unless necessary

Also, if possible, replace build_for_executable + clean_restart
with prepare_for_testing for brevity.

Touches 68 test-cases.

Tested on x86_64-linux.
2021-09-25 09:28:57 +02:00
Pedro Alves
a13af434cf Fix 'FAIL: gdb.perf/disassemble.exp: python Disassemble().run()'
We currently have one FAIL while running "make check-perf":

  PerfTest::assemble, run ...
  python Disassemble().run()
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
    File "/home/pedro/rocm/gdb/src/gdb/testsuite/gdb.perf/lib/perftest/perftest.py", line 64, in run
      self.warm_up()
    File "<string>", line 25, in warm_up
  gdb.error: No symbol "ada_evaluate_subexp" in current context.
  Error while executing Python code.
  (gdb) FAIL: gdb.perf/disassemble.exp: python Disassemble().run()
  ...

The gdb.perf/disassemble.exp testcase debugs GDB with itself, runs to
main, and then disassembles a few GDB functions.  The problem is that
most(!) functions it is trying to disassemble are now gone...

This commit fixes the issue by simply picking some other functions to
disassemble.

It would perhaps be better to come up with some test program to
disassemble, one that would stay the same throughout the years,
instead of disassembling GDB itself.  I don't know why that wasn't
done to begin with.  I'll have to leave that for another rainy day,
though.

gdb/testsuite/
yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

	* gdb.perf/disassemble.py (Disassemble::warm_up): Disassemble
	evaluate_subexp_do_call instead of ada_evaluate_subexp.
	(Disassemble::warm_up): Disassemble "captured_main",
	"run_inferior_call" and "update_global_location_list" instead of
	"evaluate_subexp_standard" and "c_parse_internal".

Change-Id: I89d1cca89ce2e495dea5096e439685739cc0d3df
2021-09-24 17:35:37 +01:00
Pedro Alves
fbfdbdab95 Fix all PATH problems in testsuite/gdb.perf/
Currently "make check-perf" triggers ~40 PATH messages in gdb.sum:

  ...
  PATH: gdb.perf/backtrace.exp: python sys.path.insert(0, os.path.abspath("/home/pedro/rocm/gdb/build/gdb/../../src/gdb/testsuite/gdb.perf/lib"))
  PATH: gdb.perf/backtrace.exp: python exec (open ('/home/pedro/rocm/gdb/build/gdb/testsuite/outputs/gdb.perf/backtrace/backtrace.py').read ())
  ...

This commit fixes them.  E.g. before/after gdb.sum diff:

 -PASS: gdb.perf/backtrace.exp: python import os, sys
 -PASS: gdb.perf/backtrace.exp: python sys.path.insert(0, os.path.abspath("/home/pedro/rocm/gdb/build-master/gdb/../../src/gdb/testsuite/gdb.perf/lib"))
 -PATH: gdb.perf/backtrace.exp: python sys.path.insert(0, os.path.abspath("/home/pedro/rocm/gdb/build-master/gdb/../../src/gdb/testsuite/gdb.perf/lib"))
 -PASS: gdb.perf/backtrace.exp: python exec (open ('/home/pedro/rocm/gdb/build-master/gdb/testsuite/outputs/gdb.perf/backtrace/backtrace.py').read ())
 -PATH: gdb.perf/backtrace.exp: python exec (open ('/home/pedro/rocm/gdb/build-master/gdb/testsuite/outputs/gdb.perf/backtrace/backtrace.py').read ())
 +PASS: gdb.perf/backtrace.exp: setup perftest: python import os, sys
 +PASS: gdb.perf/backtrace.exp: setup perftest: python sys.path.insert(0, os.path.abspath("${srcdir}/gdb.perf/lib"))
 +PASS: gdb.perf/backtrace.exp: setup perftest: python exec (open ('${srcdir}/gdb.perf/backtrace.py').read ())

gdb/testsuite/
yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

	* lib/perftest.exp (PerfTest::_setup_perftest): Use
	with_test_prefix.  Add explicit test names to python invocations,
	with "$srcdir" not expanded.

Change-Id: I50a31b04b7abdea754139509e4a34ae9263118a4
2021-09-24 17:35:37 +01:00
Pedro Alves
d8767a720e Fix all DUPLICATE problems in testsuite/gdb.perf/
Currently running "make check-perf" shows:

 ...
 # of duplicate test names       6008
 ...

All those duplicate test names come from gdb.perf/skip-command.exp.
This commit fixes them, using with_test_prefix.

gdb/testsuite/
yyyy-mm-dd  Pedro Alves  <pedro@palves.net>

	* gdb.perf/skip-command.exp (run_skip_bench): Wrap each for
	iteration in with_test_prefix.

Change-Id: I38501cf70bc6b60306ee7228996ee7bcd858dc1b
2021-09-24 17:35:37 +01:00
Tom Tromey
6ad036d703 Fix handling of DW_AT_data_bit_offset
A newer version of GCC will now emit member locations using just
DW_AT_data_bit_offset, like:

 <3><14fe>: Abbrev Number: 1 (DW_TAG_member)
    <14ff>   DW_AT_name        : (indirect string, offset: 0x215e): nb_bytes
    <1503>   DW_AT_decl_file   : 1
    <1503>   DW_AT_decl_line   : 10
    <1504>   DW_AT_decl_column : 7
    <1505>   DW_AT_type        : <0x150b>
    <1509>   DW_AT_bit_size    : 31
    <150a>   DW_AT_data_bit_offset: 64

whereas earlier versions would emit something like:

 <3><164f>: Abbrev Number: 7 (DW_TAG_member)
    <1650>   DW_AT_name        : (indirect string, offset: 0x218d): nb_bytes
    <1654>   DW_AT_decl_file   : 1
    <1655>   DW_AT_decl_line   : 10
    <1656>   DW_AT_decl_column : 7
    <1657>   DW_AT_type        : <0x165f>
    <165b>   DW_AT_byte_size   : 4
    <165c>   DW_AT_bit_size    : 31
    <165d>   DW_AT_bit_offset  : 1
    <165e>   DW_AT_data_member_location: 8

That is, DW_AT_data_member_location is not emitted any more.  This is
a change due to the switch to DWARF 5 by default.

This change pointed out an existing bug in gdb, namely that the
attr_to_dynamic_prop depends on the presence of
DW_AT_data_member_location.  This patch moves the handling of
DW_AT_data_bit_offset into handle_data_member_location, and updates
attr_to_dynamic_prop to handle this new case.

A new test case is included.  This test fails with GCC 11, but passes
with an earlier version of GCC.
2021-09-24 09:29:09 -06:00
Tom de Vries
fbd6ddfdbf [gdb/testsuite] Don't leave gdb instance running after function_range
A typical dwarf assembly test-case start like this:
...
standard_testfile .c -debug.S

set asm_file [standard_output_file $srcfile2]
Dwarf::assemble $asm_file {
  ...
}

if { [prepare_for_testing "failed to prepare" ${testfile} \
	  [list $srcfile $asm_file] {nodebug}] } {
    return -1
}
...

When accidentally using build_for_executable instead of
prepare_for_testing (or intentionally using it but forgetting to add
clean_restart $binfile or some such) the mistake may not be caught, because
another gdb instance is still running, and we may silently end up testing
compiler-generated DWARF.

This can be caused by something relatively obvious, like an earlier
prepare_for_testing or clean_restart, but also by something more obscure like
function_range, which may even be triggered by dwarf assembly like this:
...
  {MACRO_AT_func {main}}
...

Fix this by calling gdb_exit at the end of function_range.

Also fix the fallout of that in test-case gdb.dwarf2/dw2-bad-elf.exp, where a
get_sizeof call used the gdb instance left lingering by function_range.

[ A better and more complete fix would add a new proc get_exec_info, that would
be called at the start of the dwarf assembly body:
...
Dwarf::assemble $asm_file {
  get_exec_info {main foo} {int void*}
...
that would:
- do a prepare_for_testing with $srcfile (roughtly equivalent to what
  MACRO_AT_func does,
- call function_range for all functions main and foo, without starting a
  new gdb instance
- set corresponding variables at the call-site: main_start, main_len,
  main_end, foo_start, foo_len, foo_end.
- get size for types int and void*
- set corresponding variables at the call-site: int_size, void_ptr_size.
- do a gdb_exit. ]

Tested on x86_64-linux.
2021-09-24 16:56:50 +02:00
Tom de Vries
66484acafd [gdb/testsuite] Use pie instead of -fpie/-pie
I noticed two test-cases where -fpie is used.  Using the canonical pie option
will usually get one -fPIE instead.

That choice is justified here in gdb_compile:
...
  # For safety, use fPIE rather than fpie. On AArch64, m68k, PowerPC
  # and SPARC, fpie can cause compile errors due to the GOT exceeding
  # a maximum size.  On other architectures the two flags are
  # identical (see the GCC manual). Note Debian9 and Ubuntu16.10
  # onwards default GCC to using fPIE.  If you do require fpie, then
  # it can be set using the pie_flag.
  set flag "additional_flags=-fPIE"
...

There is no indication that using -fpie rather than -fPIE is on purpose, so
use pie instead.

Tested on x86_64-linux.
2021-09-24 16:56:50 +02:00
Tom de Vries
85a0bae983 [gdb/testsuite] Factor out dump_info in gdb.testsuite/dump-system-info.exp
Factor out new proc dump_info in test-case gdb.testsuite/dump-system-info.exp,
and in the process:
- fix a few typos
- remove unnecessary "test -r /proc/cpuinfo"

Tested on x86_64-linux.

Co-Authored-By: Pedro Alves <pedro@palves.net>
2021-09-24 16:56:50 +02:00
Pedro Alves
62df62b230 gdb/testsuite: Make it possible to use TCL variables in DWARF assembler loclists
It is currently not possible to use variables in locations lists.  For
example, with:

  diff --git a/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp b/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp
  index 6b4f5c8cbb8..cdbf948619f 100644
  --- a/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp
  +++ b/gdb/testsuite/gdb.dwarf2/loclists-multiple-cus.exp
  @@ -30,6 +30,8 @@ if {![dwarf2_support]} {
       return 0
   }

  +set myconst 0x123456
  +
   # Test with 32-bit and 64-bit DWARF.
   foreach_with_prefix is_64 {false true} {
       if { $is_64 } {
  @@ -49,6 +51,7 @@ foreach_with_prefix is_64 {false true} {
	  global func1_addr func1_len
	  global func2_addr func2_len
	  global is_64
  +       global myconst

	  # The CU uses the DW_FORM_loclistx form to refer to the .debug_loclists
	  # section.
  @@ -107,7 +110,7 @@ foreach_with_prefix is_64 {false true} {
		  list_ {
		      # When in func1.
		      start_length $func1_addr $func1_len {
  -                       DW_OP_constu 0x123456
  +                       DW_OP_constu $myconst
			  DW_OP_stack_value
		      }

we get:

  $ make check TESTS="*/loclists-multiple-cus.exp"
  ...
  gdb compile failed, build/gdb/testsuite/outputs/gdb.dwarf2/loclists-multiple-cus/loclists-multiple-cus-dw32.S: Assembler messages:
  build/gdb/testsuite/outputs/gdb.dwarf2/loclists-multiple-cus/loclists-multiple-cus-dw32.S:78: Error: leb128 operand is an undefined symbol: $myconst
  ...

That means $myconst was copied literally to the generated assembly
file.

This patch fixes it, by running subst on the location list body, in
the context of the caller.  The fix is applied to both
Dwarf::loclists::table::list_::start_length and
Dwarf::loclists::table::list_::start_end.

Reported-by: Zoran Zaric <Zoran.Zaric@amd.com>

Change-Id: I615a64431857242d9f477d5699e3732df1b31322
2021-09-24 13:03:34 +01:00
Tom de Vries
d8f2441d85 [gdb/testsuite] Fix DUPLICATEs in gdb.dwarf2/implptr-64bit.exp
When running test-case gdb.dwarf2/implptr-64bit.exp with target board
unix/-m32, I noticed:
...
DUPLICATE: gdb.dwarf2/implptr-64bit.exp: failed to prepare
...

Fix this by using with_test_prefix.

Tested on x86_64-linux.
2021-09-24 12:39:15 +02:00
Tom de Vries
11a607f8cb [gdb/testsuite] Fix DUPLICATEs gdb.dwarf2/dw2-is-stmt.exp
Fix these DUPLICATEs by using with_test_prefix:
...
DUPLICATE: gdb.dwarf2/dw2-is-stmt.exp: ensure we saw a valid line pattern, 1
DUPLICATE: gdb.dwarf2/dw2-is-stmt.exp: ensure we saw a valid line pattern, 2
...

Tested on x86_64-linux.
2021-09-24 12:39:15 +02:00
Tom de Vries
dfca0ed23f [gdb/testsuite] Fix set $var val in gdb.dwarf2/dw2-is-stmt.exp
When doing a testrun with:
...
$ make check RUNTESTFLAGS=$(cd $src/gdb/testsuite/; echo gdb.dwarf2/*.exp)
...
I ran into:
...
ERROR: tcl error sourcing gdb.dwarf2/dw2-is-stmt.exp.
ERROR: expected integer but got "dw2-abs-hi-pc-world.c"
    while executing
"incr i"
...

The variable i is set in gdb.dwarf2/dw2-abs-hi-pc.exp, and leaks to
gdb.dwarf2/dw2-is-stmt.exp.  It's not removed by gdb_cleanup_globals because i
is set as global variable by runtest.exp, which does:
...
for { set i 0 } { $i < $argc } { incr i } {
...
at toplevel but forgets to unset the variable.

Fix this by removing '$' in front of the variable name when doing set:
...
-set $i 0
+set i 0
...

Tested on x86_64-linux.
2021-09-24 12:39:14 +02:00
Tom de Vries
d294324cc2 [gdb/testsuite] Fix DUPLICATE in gdb.base/load-command.exp
Fix this duplicate:
...
DUPLICATE: gdb.base/load-command.exp: check initial value of the_variable
...
by using with_test_prefix.

Tested on x86_64-linux.
2021-09-24 12:39:14 +02:00
Tom de Vries
dbb17692ec [gdb/testsuite] Use pie/nopie instead of ldflags=-pie/-no-pie
I noticed two test-case that use ldflags=-pie and ldflags-no-pie, instead of
the canonical pie and nopie options, which would typically also add
additional_flags=-fPIE respectively additional_flags=-fno-pie.

There is no indication that this is on purpose, so replace these with pie and
nopie.

Tested on x86_64-linux.
2021-09-24 12:39:14 +02:00
Tom de Vries
b4e4386a2e [gdb/testsuite] Add gdb.testsuite/dump-system-info.exp
When interpreting the testsuite results, it's often relevant what kind of
machine the testsuite ran on.  On a local machine one can just do
/proc/cpuinfo, but in case of running tests using a remote system
that distributes test runs to other remote systems that are not directly
accessible, that's not possible.

Fix this by dumping /proc/cpuinfo into the gdb.log, as well as lsb_release -a
and uname -a.

We could do this at the start of each test run, by putting it into unix.exp
or some such.  However, this might be too verbose, so we choose to put it into
its own test-case, such that it get triggered in a full testrun, but not when
running one or a subset of tests.

We put the test-case into the gdb.testsuite directory, which is currently the
only place in the testsuite where we do not test gdb.   [ Though perhaps this
could be put into a new gdb.info directory, since the test-case doesn't
actually test the testsuite. ]

Tested on x86_64-linux.
2021-09-24 12:39:14 +02:00
Tom de Vries
0086a91cee [gdb/testsuite] Support -fPIE/-fno-PIE/-pie/-no-pie in gdb_compile_rust
When running gdb.rust/*.exp test-cases with target board unix/-fPIE/-pie, I
run into:
...
builtin_spawn -ignore SIGHUP rustc --color never gdb.rust/watch.rs \
  -g -lm -fPIE -pie -o outputs/gdb.rust/watch/watch^M
error: Unrecognized option: 'f'^M
^M
compiler exited with status 1
...

The problem is that -fPIE and -fpie are gcc options, but for rust we use
rustc, which has different compilation options.

Fix this by translating the gcc options to rustc options in gdb_compile_rust,
similar to how that is done for ada in target_compile_ada_from_dir.

Likewise for unix/-fno-PIE/-no-pie.

Tested on x86_64-linux, with:
- native
- unix/-fPIE/-pie
- unix/-fno-PIE/-no-pie
specifically, on openSUSE Leap 15.2 both with package gcc-PIE:
- installed (making gcc default to PIE)
- uninstalled (making gcc default to non-PIE).
and rustc 1.52.1.
2021-09-23 22:52:51 +02:00