Age | Commit message (Collapse) | Author | Files | Lines |
|
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.
|
|
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.
|
|
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.
|
|
Replace {additional_flags=-fPIE ldflags=-pie} with {pie}.
This makes sure that the test-cases properly error out when using target board
unix/-fno-PIE/-no-pie.
Tested on x86_64-linux.
|
|
When running test-case gdb.base/break-interp.exp on ubuntu 18.04.5, we have:
...
(gdb) bt^M
#0 0x00007eff7ad5ae12 in ?? () from break-interp-LDprelinkNOdebugNO^M
#1 0x00007eff7ad71f50 in ?? () from break-interp-LDprelinkNOdebugNO^M
#2 0x00007eff7ad59128 in ?? () from break-interp-LDprelinkNOdebugNO^M
#3 0x00007eff7ad58098 in ?? () from break-interp-LDprelinkNOdebugNO^M
#4 0x0000000000000002 in ?? ()^M
#5 0x00007fff505d7a32 in ?? ()^M
#6 0x00007fff505d7a94 in ?? ()^M
#7 0x0000000000000000 in ?? ()^M
(gdb) FAIL: gdb.base/break-interp.exp: ldprelink=NO: ldsepdebug=NO: \
first backtrace: dl bt
...
Using the backtrace, the test-case tries to establish that we're stopped in
dl_main.
However, the backtrace only shows an address, because:
- the dynamic linker contains no minimal symbols and no debug info, and
- gdb is build without --with-separate-debug-dir so it can't find the
corresponding .debug file, which does contain the mimimal symbols and
debug info.
As in "[gdb/testsuite] Improve probe detection in gdb.base/break-probes.exp",
fix this by doing info probes and grepping for the address.
Tested on x86_64-linux.
|
|
When running test-case gdb.base/break-probes.exp on ubuntu 18.04.5, we have:
...
(gdb) run^M
Starting program: break-probes^M
Stopped due to shared library event (no libraries added or removed)^M
(gdb) bt^M
#0 0x00007ffff7dd6e12 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#1 0x00007ffff7dedf50 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#2 0x00007ffff7dd5128 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#3 0x00007ffff7dd4098 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#4 0x0000000000000001 in ?? ()^M
#5 0x00007fffffffdaac in ?? ()^M
#6 0x0000000000000000 in ?? ()^M
(gdb) UNSUPPORTED: gdb.base/break-probes.exp: probes not present on this system
...
Using the backtrace, the test-case tries to establish that we're stopped in
dl_main, which is used as proof that we're using probes.
However, the backtrace only shows an address, because:
- the dynamic linker contains no minimal symbols and no debug info, and
- gdb is build without --with-separate-debug-dir so it can't find the
corresponding .debug file, which does contain the mimimal symbols and
debug info.
Fix this by instead printing the pc and grepping for the value in the
info probes output:
...
(gdb) p /x $pc^M
$1 = 0x7ffff7dd6e12^M
(gdb) info probes^M
Type Provider Name Where Object ^M
...
stap rtld init_start 0x00007ffff7dd6e12 /lib64/ld-linux-x86-64.so.2 ^M
...
(gdb)
...
Tested on x86_64-linux.
|
|
When running test-case gdb.base/break-probes.exp on ubuntu 18.04.5, we have:
...
(gdb) bt^M
#0 0x00007ffff7dd6e12 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#1 0x00007ffff7dedf50 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#2 0x00007ffff7dd5128 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#3 0x00007ffff7dd4098 in ?? () from /lib64/ld-linux-x86-64.so.2^M
#4 0x0000000000000001 in ?? ()^M
#5 0x00007fffffffdaac in ?? ()^M
#6 0x0000000000000000 in ?? ()^M
(gdb) FAIL: gdb.base/break-probes.exp: ensure using probes
...
The test-case intends to emit an UNTESTED in this case, but fails to do so
because it tries to do it in a regexp clause in a gdb_test_multiple, which
doesn't trigger. Instead, a default clause triggers which produces the FAIL.
Also the use of UNTESTED is not appropriate, and we should use UNSUPPORTED
instead.
Fix this by silencing the FAIL, and emitting an UNSUPPORTED after the
gdb_test_multiple:
...
if { ! $using_probes } {
+ unsupported "probes not present on this system"
return -1
}
...
Tested on x86_64-linux.
|
|
Reduce indentation and improve readability in test-case
gdb.base/break-probes.exp by replacing:
...
if { <cond> } {
<lots-of-code>
}
...
with:
...
if { ! <cond> } {
return -1
}
<lots-of-code>
...
Tested on x86_64-linux.
|
|
This adds a testcase that tests that the unwinder produces consistent
frame info and frame IDs by making sure that "info frame" shows the
same result when stopped at a function (level == 0), compared to when
we find the same frame in the stack at a level > 0.
E.g., on x86-64, right after running to main, we see:
(gdb) info frame
Stack level 0, frame at 0x7fffffffd340:
rip = 0x555555555168 in main (gdb.base/backtrace.c:41); saved rip = 0x7ffff7dd90b3
source language c.
Arglist at 0x7fffffffd330, args:
Locals at 0x7fffffffd330, Previous frame's sp is 0x7fffffffd340
Saved registers:
rbp at 0x7fffffffd330, rip at 0x7fffffffd338
(gdb)
and then after continuing to a function called by main, and selecting
the "main" frame again, we see:
(gdb) info frame
Stack level 3, frame at 0x7fffffffd340:
rip = 0x555555555172 in main (gdb.base/backtrace.c:41); saved rip = 0x7ffff7dd90b3
caller of frame at 0x7fffffffd330
source language c.
Arglist at 0x7fffffffd330, args:
Locals at 0x7fffffffd330, Previous frame's sp is 0x7fffffffd340
Saved registers:
rbp at 0x7fffffffd330, rip at 0x7fffffffd338
(gdb)
The only differences should be in the stack level, the 'rip = '
address, and the presence of the "caller of frame at" info. All the
rest should be the same. If it isn't, it probably means that the
frame base, the frame ID, etc. aren't stable & consistent.
The testcase exercises both the DWARF and the heuristic unwinders,
using "maint set dwarf unwinder on/off".
Tested on {x86-64 -m64, x86-64 -m32, Aarch64, Power8} GNU/Linux.
Change-Id: I795001c82cc70d543d197415e3f80ce5dc7f3452
|
|
This patch changes gdb to use the 'highlight' style on the "XXX" text
in the output of ptype/o.
|
|
In test-case gdb.base/gdb-caching-proc.exp, we run all procs declared with
gdb_caching_proc. Some of these require a gdb instance, some not.
We could just do a clean_restart every time, but that would amount to 44 gdb
restarts. We try to minimize this by doing this only for the few procs that
need it, and hardcoding those in the test-case.
For those procs, we do a clean_restart, execute the proc, and then do a
gdb_exit, to make sure the gdb instance doesn't linger such that we detect
procs that need a gdb instance but are not listed in the test-case.
However, that doesn't work in the case of gnat_runtime_has_debug_info. This
proc doesn't require a gdb instance because it starts its own. But it doesn't
clean up the gdb instance, and since it's not listed, the test-case
doesn't clean up the gdb instance eiter. Consequently, the proc
supports_memtag (which should be listed, but isn't) uses the gdb instance
started by gnat_runtime_has_debug_info rather than throwing an error. Well,
unless gnat_runtime_has_debug_info fails before starting a gdb instance, in
which case we do run into the error.
Fix this by:
- doing gdb_exit unconditionally
- fixing the resulting error by adding supports_memtag in the test-case to
the "needing gdb instance" list
Tested on x86_64-linux.
|
|
Now gdb is capable of debugging executable, which consists of multiple
compilation units (CUs) with the CTF debug info. An executable could
potentially have one or more archives, which, in CTF context, contain
conflicting types.
all changes were made in ctfread.c in which elfctf_build_psymtabs was
modified to handle archives, via the ctf archive iterator and its callback
build_ctf_archive_member and scan_partial_symbols was modified to scan
archives, which are treated as subfiles, to build the psymtabs.
Also changes were made to handle CTF's data object section and function
info section which now share the same format of their contents - an array
of type IDs. New functions ctf_psymtab_add_stt_entries, which is called by
ctf_psymtab_add_stt_obj and ctf_psymtab_add_stt_func, and add_stt_entries,
which is called by add_stt_obj and add_stt_func when setting up psymtabs
and full symtab, respectively.
|
|
When running test-case gdb.threads/continue-pending-status.exp with native, I
have:
...
(gdb) continue^M
Continuing.^M
PASS: gdb.threads/continue-pending-status.exp: attempt 0: continue for ctrl-c
^C^M
Thread 1 "continue-pendin" received signal SIGINT, Interrupt.^M
[Switching to Thread 0x7ffff7fc4740 (LWP 1276)]^M
0x00007ffff758e4c0 in __GI___nanosleep () at nanosleep.c:27^M
27 return SYSCALL_CANCEL (nanosleep, requested_time, remaining);^M
(gdb) PASS: gdb.threads/continue-pending-status.exp: attempt 0: caught interrupt
...
but with target board unix/-m32, I run into:
...
(gdb) continue^M
Continuing.^M
PASS: gdb.threads/continue-pending-status.exp: attempt 0: continue for ctrl-c
[Thread 0xf74aeb40 (LWP 31957) exited]^M
[Thread 0xf7cafb40 (LWP 31956) exited]^M
[Inferior 1 (process 31952) exited normally]^M
(gdb) Quit^M
...
The problem is that the sleep (300) call at the end of main is interrupted,
which causes the inferior to exit before the ctrl-c can be send.
This problem is described at "Interrupted System Calls" in the docs, and the
suggested solution (using a sleep loop) indeed fixes the problem.
Fix this instead using the more prevalent:
...
alarm (300);
...
while (1) sleep (1);
...
which is roughly equivalent because the sleep is called at the end of main,
but slightly better because it guards against hangs from the start rather than
from the end of main.
Likewise in gdb.base/watch_thread_num.exp.
Likewise in gdb.btrace/enable-running.exp, but use the sleep loop there,
because the sleep is not called at the end of main.
Tested on x86_64-linux.
|
|
When running gdb.base/batch-exit-status.exp I noticed that the test name
contains a newline:
...
PASS: gdb.base/batch-exit-status.exp: : No such file or directory\.^M
: No such file or directory\.: [lindex $result 2] == 0
...
The mistake is that I passed an output regexp argument to a parameter
interpreted as testname prefix. Fix this by passing a testname prefix
instead.
Add support for checking output, to be able to handle the output regexp
argument.
Tested on x86_64-linux.
|
|
Fix DUPLICATE in gdb.base/global-var-nested-by-dso.exp by naming commands more
uniquely.
|
|
Fix DUPLICATE in gdb.base/skip-solib.exp by using with_test_prefix.
Also fix indentation style and long lines, remove outdated question/answer
bits, and use multi_line.
|
|
On openSUSE Leap 42.3 with eu-unstrip 0.158, we run into:
...
(gdb) PASS: gdb.base/coredump-filter-build-id.exp: save corefile
First line of eu-unstrip: \
0x400000+0x202000 f4ae8502bd6a14770182382316bc595e9dc6f08b@0x400284 - - [exe]
FAIL: gdb.base/coredump-filter-build-id.exp: gcore dumped mapping with build-id
...
The test expects an actual file name instead of '[exe]', but that only got
introduced with eu-unstrip 0.161. Before it printed '[exe]' or '[pie]'.
Fix this by updating the regexp.
Tested on x86_64-linux.
|
|
With current gdb we run into:
...
$ gdb -batch '' ''
: No such file or directory.
pathstuff.cc:132: internal-error: \
gdb::unique_xmalloc_ptr<char> gdb_abspath(const char*): \
Assertion `path != NULL && path[0] != '\0'' failed.
...
Fix this by skipping the call to gdb_abspath in core_target_open in the
empty-string case, such that we have instead:
...
$ gdb -batch '' ''
: No such file or directory.
: No such file or directory.
$
...
Tested on x86_64-linux.
gdb/ChangeLog:
2021-08-30 Tom de Vries <tdevries@suse.de>
PR cli/28290
* gdb/corelow.c (core_target_open): Skip call to gdb_abspath in the
empty-string case.
gdb/testsuite/ChangeLog:
2021-08-30 Tom de Vries <tdevries@suse.de>
PR cli/28290
* gdb.base/batch-exit-status.exp: Add gdb '' and gdb '' '' tests.
|
|
With trying to load a non-executable file into gdb, we run into PR26880:
...
$ gdb -q -batch test.c
"0x7ffc87bfc8d0s": not in executable format: \
file format not recognized
...
The problem is caused by using %ps in combination with the error function
(note that confusingly, it does work in combination with the warning
function).
Fix this by using plain "%s" instead.
Tested on x86_64-linux.
gdb/ChangeLog:
2021-08-22 Tom de Vries <tdevries@suse.de>
PR gdb/26880
* gdb/exec.c (exec_file_attach): Use %s instead of %ps in call to
error function.
gdb/testsuite/ChangeLog:
2021-08-22 Tom de Vries <tdevries@suse.de>
PR gdb/26880
* gdb.base/non-executable.exp: New file.
|
|
Currently, when GDB hits an internal error, and the user selects to
dump core, the recently added feature to write a backtrace to the
console will kick in, and print a backtrace as well as dumping the
core.
This was certainly not my intention when adding the backtrace on fatal
signal functionality, this feature was intended to produce a backtrace
when GDB crashes due to some fatal signal, internal errors should have
continued to behave as they did before, unchanged.
In this commit I set the signal disposition of SIGABRT back to SIG_DFL
just prior to the call to abort() that GDB uses to trigger the core
dump, this prevents GDB reaching the code that writes the backtrace to
the console.
I've also added a test that checks we don't see a backtrace on the
console after an internal error.
|
|
Register handlers for SIGBUS, SIGFPE, and SIGABRT. All of these
signals are setup as fatal signals that will cause GDB to terminate.
However, by passing these signals through the handle_fatal_signal
function, a user can arrange to see a backtrace when GDB
terminates (see maint set backtrace-on-fatal-signal).
In normal use of GDB there should be no user visible changes after
this commit. Only if GDB terminates with one of the above signals
will GDB change slightly, potentially printing a backtrace before
aborting.
I've added new tests for SIGFPE, SIGBUS, and SIGABRT.
|
|
This commit adds a new maintenance feature, the ability to print
a (limited) backtrace if GDB dies due to a fatal signal.
The backtrace is produced using the backtrace and backtrace_symbols_fd
functions which are declared in the execinfo.h header, and both of
which are async signal safe. A configure check has been added to
check for these features, if they are not available then the new code
is not compiled into GDB and the backtrace will not be printed.
The motivation for this new feature is to aid in debugging GDB in
situations where GDB has crashed at a users site, but the user is
reluctant to share core files, possibly due to concerns about what
might be in the memory image within the core file. Such a user might
be happy to share a simple backtrace that was written to stderr.
The production of the backtrace is on by default, but can switched off
using the new commands:
maintenance set backtrace-on-fatal-signal on|off
maintenance show backtrace-on-fatal-signal
Right now, I have hooked this feature in to GDB's existing handling of
SIGSEGV only, but this will be extended to more signals in a later
commit.
One additional change I have made in this commit is that, when we
decide GDB should terminate due to the fatal signal, we now
raise the same fatal signal rather than raising SIGABRT.
Currently, this is only effecting our handling of SIGSEGV. So,
previously, if GDB hit a SEGV then we would terminate GDB with a
SIGABRT. After this commit we will terminate GDB with a SIGSEGV.
This feels like an improvement to me, we should still get a core dump,
but in many shells, the user will see a more specific message once GDB
exits, in bash for example "Segmentation fault" rather than "Aborted".
Finally then, here is an example of the output a user would see if GDB
should hit an internal SIGSEGV:
Fatal signal: Segmentation fault
----- Backtrace -----
./gdb/gdb[0x8078e6]
./gdb/gdb[0x807b20]
/lib64/libpthread.so.0(+0x14b20)[0x7f6648c92b20]
/lib64/libc.so.6(__poll+0x4f)[0x7f66484d3a5f]
./gdb/gdb[0x1540f4c]
./gdb/gdb[0x154034a]
./gdb/gdb[0x9b002d]
./gdb/gdb[0x9b014d]
./gdb/gdb[0x9b1aa6]
./gdb/gdb[0x9b1b0c]
./gdb/gdb[0x41756d]
/lib64/libc.so.6(__libc_start_main+0xf3)[0x7f66484041a3]
./gdb/gdb[0x41746e]
---------------------
A fatal error internal to GDB has been detected, further
debugging is not possible. GDB will now terminate.
This is a bug, please report it. For instructions, see:
<https://www.gnu.org/software/gdb/bugs/>.
Segmentation fault (core dumped)
It is disappointing that backtrace_symbols_fd does not actually map
the addresses back to symbols, this appears, in part, to be due to GDB
not being built with -rdynamic as the manual page for
backtrace_symbols_fd suggests, however, even when I do add -rdynamic
to the build of GDB I only see symbols for some addresses.
We could potentially look at alternative libraries to provide the
backtrace (e.g. libunwind) however, the solution presented here, which
is available as part of glibc is probably a good baseline from which
we might improve things in future.
|
|
native-extended-gdbserver
In gdb.base/attach.exp, proc do_attach_failure_tests, we attach to a
process. When then try to attach to the same process in another
inferior, expecting it to fail. We then come back to the first inferior
and try to kill it, to clean up the test. When using the
native-extended-gdbserver board, this "kill" test passes, even though it
didn't actually work:
add-inferior
[New inferior 2]
Added inferior 2 on connection 1 (extended-remote localhost:2347)
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: add empty inferior 2
inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 2
attach 817032
Attaching to process 817032
Attaching to process 817032 failed
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: fail to attach again
inferior 1
[Switching to inferior 1 [process 817032] (/home/simark/build/binutils-gdb/gdb/testsuite/outputs/gdb.base/attach/attach)]
[Switching to thread 1.1 (Thread 817032.817032)]
#0 main () at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/attach.c:19
19 while (! should_exit)
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: switch to inferior 1
kill
Kill the program being debugged? (y or n) y
Remote connection closed <==== That's unexpected
(gdb) PASS: gdb.base/attach.exp: do_attach_failure_tests: exit after attach failures
When the second attach fails, gdbserver seems to break the connection
(it hangs up on the existing remote target) and start listening again
for incoming connections. This is documented in PR 19558 [1].
Make the expected output regexp for the kill command tighter (it
currently accepts anything). Use "set confirm off" so we don't have to
deal with the confirmation. And to be really sure the extended-remote
target still works, try to run the inferior again after killing. The
now tests are kfail'ed when the target is gdbserver.
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=19558
gdb/testsuite/ChangeLog:
* gdb.base/attach.exp (do_attach_failure_tests): Make kill
regexp tighter, run inferior after killing it. Kfail when
target is gdbserver.
Change-Id: I99c5cd3968ce2ec962ace35b016f842a243b7a0d
|
|
test_command_line_attach_run
When running this test with the native-extended-gdbserver, we get:
main () at /home/simark/src/binutils-gdb/gdb/testsuite/gdb.base/attach.c:19
19 while (! should_exit)
The program being debugged has been started already.
Start it from the beginning? (y or n) PASS: gdb.base/attach.exp: cmdline attach run: run to prompt
y
Don't know how to run. Try "help target".
(gdb) FAIL: gdb.base/attach.exp: cmdline attach run: run to main
This test tests using both "-p <pid>" and "-ex start" on the command line,
making sure that we first attach and then run.
Normally, after that "y", we should see the program running again.
However, a particuliarity of the native-extended-gdbserver is that it
uses "set auto-connect-native-target off" on the command line. The full
GDB command line is:
./gdb -nw -nx -data-directory /home/simark/build/binutils-gdb/gdb/testsuite/../data-directory \
-iex set height 0 -iex set width 0 -ex set auto-connect-native-target off \
-ex set sysroot -quiet -iex set height 0 -iex set width 0 --pid=536609 -ex start
The attach succeeds. I guess it is done before "set
auto-connect-native-target off", or it somehow bypasses it. When the
"start" is executed, the native target is unpushed, while killing the
existing process, but not re-pushed, due to "set
auto-connect-native-target off". So we get that "Don't know how to run"
message.
Really, I think it's a case of the test doing things incompatible with
the board, I think it should just be skipped. And as we can see with
the current code, there were some attempts at doing this, just using the
wrong checks:
- isnative: this is a dejagnu proc which checks if the target board has
the same triplet as the build machine. In the case of
native-extended-gdbserver, it does.
- is_remote target: this checks whether the target board is remote, as
in executing on a different machin. native-extended-gdbserver is not
remote.
Since the --pid option specifically attaches to a process using the
native target, change the test to use gdb_is_target_native instead.
gdb/testsuite/ChangeLog:
* gdb.base/attach.exp (test_command_line_attach_run): Use
gdb_is_target_native to check if test is supported.
Change-Id: I762e127f39623889999dc9ed2185540a0951bfb0
|
|
I was looking at PR gdb/19675 and the related test
gdb.base/step-over-syscall.exp. This test includes a call to kfail
when we are testing a displaced step over a clone syscall.
While looking at the test I removed the call to kfail and ran the
test, and was surprised that the test passed.
I ran the test a few times and it does sometimes fail, but mostly it
passed fine.
PR gdb/19675 describes how, when we displaced step over a clone, the
new thread is created with a $pc in the displaced step buffer. GDB
then fails to "fix" this $pc (for the new thread), and the thread will
be set running with its current $pc value. This means that the new
thread will just start executing from whatever happens to be after the
displaced stepping buffer.
In the original PR gdb/19675 bug report Yao Qi was seeing the new
thread cause a segfault, the problem is, what actually happens is
totally undefined.
On my machine, I'm seeing the new thread reenter main, it then starts
trying to run the test again (in the new thread). This just happens
to be safe enough (in this simple test) that most of the time the
inferior doesn't crash.
In this commit I try to make the test slightly more likely to fail by
doing a couple of things.
First, I added a static variable to main, this is set true when the
first thread enters main, if a second thread ever enters main then I
force an abort.
Second, when the test is finishing I want to ensure that the new
threads have had a chance to do "something bad" if they are going to.
So I added a global counter, as each thread starts successfully it
decrements the counter. The main thread does not proceed to the final
marker function (where GDB has placed a breakpoint) until all threads
have started successfully. This means that if the newly created
thread doesn't successfully enter clone_fn then the counter will never
reach zero and the test will timeout.
With these two changes my hope is that the test should fail more
reliably, and so, I have also changed the test to call setup_kfail
before the specific steps that we expect to misbehave instead of just
calling kfail and skipping parts of the test completely. The benefit
of this is that if/when we fix GDB this test will start to KPASS and
we'll know to update this test to remove the setup_kfail call.
|
|
The test gdb.base/info-macros.exp says that it doesn't pass the "debug"
option to prepare_for_testing because that would cause -g to appear
after -g3 on the command line, and that would cause some gcc versions to
not include macro info. I don't know what gcc versions this refers to.
I tested with gcc 4.8, and that works fine with -g after -g3.
The current state is problematic when testing with CC_FOR_TARGET=clang,
because then only -fdebug-macro is included. No -g switch if included,
meaning we get a binary without any debug info, and the test fails.
One way to fix it would be to add "debug" to the options when the
compiler is clang.
However, the solution I chose was to specify "debug" in any case, even
for gcc. Other macro tests such as gdb.base/macscp.exp do perfectly
fine with it. Also, this lets the test use the debug flag specified by
the board file. For example, we can test with GCC and DWARF 5, with:
$ make check RUNTESTFLAGS="--target_board unix/gdb:debug_flags=-gdwarf-5" TESTS="gdb.base/info-macros.exp"
With the hard-coded -g3, this wouldn't actually test with DWARF 5.
Change-Id: I33fa92ee545007d3ae9c52c4bb2d5be6b5b698f1
|
|
With target board cc-with-gdb-index we run into:
...
FAIL: gdb.base/maint.exp: maint print statistics
...
The output that is checked is:
...
Statistics for 'maint':^M
Number of "minimal" symbols read: 53^M
Number of "full" symbols read: 40^M
Number of "types" defined: 60^M
Number of symbol tables: 7^M
Number of symbol tables with line tables: 2^M
Number of symbol tables with blockvectors: 2^M
Number of read CUs: 2^M
Number of unread CUs: 5^M
Total memory used for objfile obstack: 20320^M
Total memory used for BFD obstack: 4064^M
Total memory used for string cache: 4064^M
...
and the regexp doesn't match because it expects the "Number of read/unread
CUs" lines in a different place.
Fix this by updating the regexp.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-08-01 Tom de Vries <tdevries@suse.de>
* gdb.base/maint.exp: Update "maint print statistics" to match
output with target board cc-with-gdb-index.
|
|
With target board cc-with-gdb-index we run into:
...
FAIL: gdb.base/index-cache.exp: couldn't remove files in temporary cache dir
...
The problem is that there are no files to remove, because the index cache
isn't used, as indicated by $expecting_index_cache_use.
Fix this by only FAILing when $expecting_index_cache_use.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-08-01 Tom de Vries <tdevries@suse.de>
* gdb.base/index-cache.exp:
|
|
Fixes PR gdb/28121. When a user declares an array like this:
int * const foo_1[3];
And in GDB the user does this:
(gdb) info variables foo
All variables matching regular expression "foo":
File test.c:
1: int * constfoo_1[3];
Notice the missing space between 'const' and 'foo_1'. This is fixed
in c_type_print_varspec_prefix (c-typeprint.c) by passing through the
flag that indicates if a trailing space is needed, rather than hard
coding the flag to false as we currently do.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28121
|
|
This commit was originally part of this patch series:
(v1): https://sourceware.org/pipermail/gdb-patches/2021-May/179357.html
(v2): https://sourceware.org/pipermail/gdb-patches/2021-June/180208.html
(v3): https://sourceware.org/pipermail/gdb-patches/2021-July/181028.html
However, that series is being held up in review, so I wanted to break
out some of the non-related fixes in order to get these merged.
This commit addresses two semi-related issues, both of which are
problems exposed by using 'set debug frame on'.
The first issue is in frame.c in get_prev_frame_always_1, and was
introduced by this commit:
commit a05a883fbaba69d0f80806e46a9457727fcbe74c
Date: Tue Jun 29 12:03:50 2021 -0400
gdb: introduce frame_debug_printf
This commit replaced fprint_frame with frame_info::to_string.
However, the former could handle taking a nullptr while the later, a
member function, obviously requires a non-nullptr in order to make the
function call. In one place we are not-guaranteed to have a
non-nullptr, and so, there is the possibility of triggering undefined
behaviour.
The second issue addressed in this commit has existed for a while in
GDB, and would cause this assertion:
gdb/frame.c:622: internal-error: frame_id get_frame_id(frame_info*): Assertion `fi->this_id.p != frame_id_status::COMPUTING' failed.
We attempt to get the frame_id for a frame while we are computing the
frame_id for that same frame.
What happens is that when GDB stops we create a frame_info object for
the sentinel frame (frame #-1) and then we attempt to unwind this
frame to create a frame_info object for frame #0.
In the test case used here to expose the issue we have created a
Python frame unwinder. In the Python unwinder we attemt to read the
program counter register.
Reading this register will initially create a lazy register value.
The frame-id stored in the lazy register value will be for the
sentinel frame (lazy register values hold the frame-id for the frame
from which the register will be unwound).
However, the Python unwinder does actually want to examine the value
of the program counter, and so the lazy register value is resolved
into a non-lazy value. This sends GDB into value_fetch_lazy_register
in value.c.
Now, inside this function, if 'set debug frame on' is in effect, then
we want to print something like:
frame=%d, regnum=%d(%s), ....
Where 'frame=%d' will be the relative frame level of the frame for
which the register is being fetched, so, in this case we would expect
to see 'frame=0', i.e. we are reading a register as it would be in
frame #0. But, remember, the lazy register value actually holds the
frame-id for frame #-1 (the sentinel frame).
So, to get the frame_info for frame #0 we used to call:
frame = frame_find_by_id (VALUE_FRAME_ID (val));
Where VALUE_FRAME_ID is:
#define VALUE_FRAME_ID(val) (get_prev_frame_id_by_id (VALUE_NEXT_FRAME_ID (val)))
That is, we start with the frame-id for the next frame as obtained by
VALUE_NEXT_FRAME_ID, then call get_prev_frame_id_by_id to get the
frame-id of the previous frame.
The get_prev_frame_id_by_id function finds the frame_info for the
given frame-id (in this case frame #-1), calls get_prev_frame to get
the previous frame, and then calls get_frame_id.
The problem here is that calling get_frame_id requires that we know
the frame unwinder, so then have to try each frame unwinder in turn,
which would include the Python unwinder.... which is where we started,
and thus we have a loop!
To prevent this loop GDB has an assertion in place, which is what
actually triggers.
Solving the assertion failure is pretty easy, if we consider the code
in value_fetch_lazy_register and get_prev_frame_id_by_id then what we
do is:
1. Start with a frame_id taken from a value,
2. Lookup the corresponding frame,
3. Find the previous frame,
4. Get the frame_id for that frame, and
5. Lookup the corresponding frame
6. Print the frame's level
Notice that steps 3 and 5 give us the exact same result, step 4 is
just wasted effort. We could shorten this process such that we drop
steps 4 and 5, thus:
1. Start with a frame_id taken from a value,
2. Lookup the corresponding frame,
3. Find the previous frame,
6. Print the frame's level
This will give the exact same frame as a result, and this is what I
have done in this patch by removing the use of VALUE_FRAME_ID from
value_fetch_lazy_register.
Out of curiosity I looked to see how widely VALUE_FRAME_ID was used,
and saw it was only used in one other place in valops.c:value_assign,
where, once again, we take the result of VALUE_FRAME_ID and pass it to
frame_find_by_id, thus introducing a redundant frame_id lookup.
I don't think the value_assign case risks triggering the assertion
though, as we are unlikely to call value_assign while computing the
frame_id for a frame, however, we could make value_assign slightly
more efficient, with no real additional complexity, by removing the
use of VALUE_FRAME_ID.
So, in this commit, I completely remove VALUE_FRAME_ID, and replace it
with a use of VALUE_NEXT_FRAME_ID, followed by a direct call to
get_prev_frame_always, this should make no difference in either case,
and resolves the assertion issue from value.c.
As I said, this patch was originally part of another series, the
original test relied on the fixes in that original series. However, I
was able to create an alternative test for this issue by enabling
frame debug within an existing test script.
This commit probably fixes bug PR gdb/27938, though the bug doesn't
have a reproducer attached so it is not possible to know for sure.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=27938
|
|
Fix:
DUPLICATE: gdb.base/setshow.exp: test_setshow_args: show args
by giving some explicit test names.
Change-Id: I2a738d3d3675ab9b45929e71f5aee0ea6bf92072
|
|
Split in multiple procs, one per topic, and start with a fresh GDB in
each. I find it easier to work on a test with multiple smaller
independent test procedures. For example, it's possible to comment all
but one when working on one. It's also easier to add things without
having to think about the impact on existing tests, and vice-versa.
Change-Id: I19691eed8f9bcb975b2eeff7577cac66251bcbe2
|
|
Using save_vars is a bit better than what we have now, as it ensures the
variable gets restored if the code within it throws an error.
Change-Id: I3bd6836e5b7efb61b078acadff1a1c8182c19a27
|
|
When running test-case gdb.base/ptype-offsets.exp with gcc-11 (with -gdwarf-5
default) or gcc-10 with target board unix/gdb:debug_flags=-gdwarf-5 we run
into this regression:
...
(gdb) ptype/o static_member^M
/* offset | size */ type = struct static_member {^M
- static static_member Empty;^M
/* 0 | 4 */ int abc;^M
^M
/* total size (bytes): 4 */^M
}^M
-(gdb) PASS: gdb.base/ptype-offsets.exp: ptype/o static_member
+(gdb) FAIL: gdb.base/ptype-offsets.exp: ptype/o static_member
...
This is caused by missing debug info, which I filed as gcc PR101452 - "[debug,
dwarf-5] undefined static member removed by
-feliminate-unused-debug-symbols".
It's not clear yet whether this is a bug or a feature, but work around this in
the test-cases by:
- defining the static member
- adding additional_flags=-fno-eliminate-unused-debug-types.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-07-20 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (gcc_major_version): New proc.
* gdb.base/ptype-offsets.cc: Define static member static_member::Empty.
* gdb.cp/templates.exp: Define static member using -DGCC_BUG.
* gdb.cp/m-static.exp: Add
additional_flags=-fno-eliminate-unused-debug-types.
* gdb.cp/pr-574.exp: Same.
* gdb.cp/pr9167.exp: Same.
|
|
PR gdb/28093 points out that gdb crashes when language is set to
"unknown" and expression parsing is attempted. At first I thought
this was a regression due to the expression rewrite, but it turns out
that older versions crash as well.
This patch avoids the crash by changing the default expression parser
to throw an exception. I think this is preferable -- the current
behavior of silently doing nothing does not really make sense.
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=28093
|
|
GDB doesn't handle well the case of an inferior using the JIT interface
to register JIT-ed objfiles and forking. If an inferior registers a
code object using the JIT interface and then forks, the child process
conceptually has the same code object loaded, so GDB should look it up
and learn about it (it currently doesn't).
To achieve this, I think it would make sense to have the
inferior_created observable called when an inferior is created due to a
fork in follow_fork_inferior. The inferior_created observable is
currently called both after starting a new inferior and after attaching
to an inferior, allowing various sub-components to learn about that new
executing inferior. We can see handling a fork child just like
attaching to it, so any work done when attaching should also be done in
the case of a fork child.
Instead of just calling the inferior_created observable, this patch
makes follow_fork_inferior call the whole post_create_inferior function.
This way, the attach and follow-fork code code paths are more alike.
Given that post_create_inferior calls solib_create_inferior_hook,
follow_fork_inferior doesn't need to do it itself, so those calls to
solib_create_inferior_hook are removed.
One question you may have: why not just call post_create_inferior at the
places where solib_create_inferior_hook is currently called, instead of
after target_follow_fork?
- there's something fishy for the second solib_create_inferior_hook
call site: at this point we have switched the current program space
to the child's, but not the current inferior nor the current thread.
So solib_create_inferior_hook (and everything under, including
check_for_thread_db, for example) is called with inferior 1 as the
current inferior and inferior 2's program space as the current
program space. I think that's wrong, because at this point we are
setting up inferior 2, and all that code relies on the current
inferior. We could just add a switch_to_thread call before it to
make inferior 2 the current one, but there are other problems (see
below).
- solib_create_inferior_hook is currently not called on the
`follow_child && detach_fork` path. I think we need to call it,
because we still get a new inferior in that case (even though we
detach the parent). If we only call post_create_inferior where
solib_create_inferior_hook used to be called, then the JIT
subcomponent doesn't get informed about the new inferior, and that
introduces a failure in the new gdb.base/jit-elf-fork.exp test.
- if we try to put the post_create_inferior just after the
switch_to_thread that was originally at line 662, or just before the
call to target_follow_fork, we introduce a subtle failure in
gdb.threads/fork-thread-pending.exp. What happens then is that
libthread_db gets loaded (somewhere under post_create_inferior)
before the linux-nat target learns about the LWPs (which happens in
linux_nat_target::follow_fork). As a result, the ALL_LWPS loop in
try_thread_db_load_1 doesn't see the child LWP, and the thread-db
target doesn't have the chance to fill in thread_info::priv. A bit
later, when the test does "info threads", and
thread_db_target::pid_to_str is called, the thread-db target doesn't
recognize the thread as one of its own, and delegates the request to
the target below. Because the pid_to_str output is not the expected
one, the test fails.
This tells me that we need to call the process target's follow_fork
first, to make the process target create the necessary LWP and thread
structures. Then, we can call post_create_inferior to let the other
components of GDB do their thing.
But then you may ask: check_for_thread_db is already called today,
somewhere under solib_create_inferior_hook, and that is before
target_follow_fork, why don't we see this ordering problem!? Well,
because of the first bullet point: when check_for_thread_db /
thread_db_load are called, the current inferior is (erroneously)
inferior 1, the parent. Because libthread_db is already loaded for
the parent, thread_db_load early returns. check_for_thread_db later
gets called by linux_nat_target::follow_fork. At this point, the
current inferior is the correct one and the child's LWP exists, so
all is well.
Since we now call post_create_inferior after target_follow_fork, which
calls the inferior_created observable, which calls check_for_thread_db,
I don't think linux_nat_target needs to explicitly call
check_for_thread_db itself, so that is removed.
In terms of testing, this patch adds a new gdb.base/jit-elf-fork.exp
test. It makes an inferior register a JIT code object and then fork.
It then verifies that whatever the detach-on-fork and follow-fork-child
parameters are, GDB knows about the JIT code object in all the inferiors
that survive the fork. It verifies that the inferiors can unload that
code object.
There isn't currently a way to get visibility into GDB's idea of the JIT
code objects for each inferior. For the purpose of this test, add the
"maintenance info jit" command. There isn't much we can print about the
JIT code objects except their load address. So the output looks a bit
bare, but it's good enough for the test.
gdb/ChangeLog:
* NEWS: Mention "maint info jit" command.
* infrun.c (follow_fork_inferior): Don't call
solib_create_inferior_hook, call post_create_inferior if a new
inferior was created.
* jit.c (maint_info_jit_cmd): New.
(_initialize_jit): Register new command.
* linux-nat.c (linux_nat_target::follow_fork): Don't call
check_for_thread_db.
* linux-nat.h (check_for_thread_db): Remove declaration.
* linux-thread-db.c (check_thread_signals): Make static.
gdb/doc/ChangeLog:
* gdb.texinfo (Maintenance Commands): Mention "maint info jit".
gdb/testsuite/ChangeLog:
* gdb.base/jit-elf-fork-main.c: New test.
* gdb.base/jit-elf-fork-solib.c: New test.
* gdb.base/jit-elf-fork.exp: New test.
Change-Id: I9a192e55b8a451c00e88100669283fc9ca60de5c
|
|
When running test-case gdb.base/gold-gdb-index.exp on openSUSE Tumbleweed,
I run into:
...
FAIL: gdb.base/gold-gdb-index.exp: maint info symtabs
...
This is due to a dummy .gdb_index:
...
Contents of the .gdb_index section:
Version 7
CU table:
TU table:
Address table:
Symbol table:
...
The dummy .gdb_index is ignored when loading the symbols, and instead partial
symbols are used. Consequently, we get the same result as if we'd removed
-Wl,--gdb-index from the compilation.
Presumably, gold fails to generate a proper .gdb_index because it lacks
DWARF5 support.
Anyway, without a proper .gdb_index we can't test the gdb behaviour we're
trying to excercise. Fix this by detecting whether we actually used a
.gdb_index for symbol loading.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-07-14 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (have_index): New proc.
* gdb.base/gold-gdb-index.exp: Use have_index.
|
|
When building gdb with --disable-tui, we run into:
...
(gdb) frame apply all -- -^M
Undefined command: "-". Try "help".^M
(gdb) ERROR: Undefined command "frame apply all -- -".
UNRESOLVED: gdb.base/options.exp: test-frame-apply: frame apply all -- -
...
Fix this by detecting whether tui is supported, and skipping the tui-related
tests otherwise. Same in some gdb.tui test-cases.
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-07-13 Tom de Vries <tdevries@suse.de>
* gdb.base/options.exp: Skip tui-related tests when tui is not
supported.
* gdb.python/tui-window-disabled.exp: Same.
* gdb.python/tui-window.exp: Same.
|
|
Commit 408f66864a1a823591b26420410c982174c239a2 ("detach in all-stop
with threads running") regressed "detach" with "target remote":
(gdb) detach
Detaching from program: target:/any/program, process 3671843
Detaching from process 3671843
Ending remote debugging.
[Inferior 1 (process 3671843) detached]
In main
terminate called after throwing an instance of 'gdb_exception_error'
Aborted (core dumped)
Here's the exception above being thrown:
(top-gdb) bt
#0 throw_error (error=TARGET_CLOSE_ERROR, fmt=0x555556035588 "Remote connection closed") at src/gdbsupport/common-exceptions.cc:222
#1 0x0000555555bbaa46 in remote_target::readchar (this=0x555556a11040, timeout=10000) at src/gdb/remote.c:9440
#2 0x0000555555bbb9e5 in remote_target::getpkt_or_notif_sane_1 (this=0x555556a11040, buf=0x555556a11058, forever=0, expecting_notif=0, is_notif=0x0) at src/gdb/remote.c:9928
#3 0x0000555555bbbda9 in remote_target::getpkt_sane (this=0x555556a11040, buf=0x555556a11058, forever=0) at src/gdb/remote.c:10030
#4 0x0000555555bc0e75 in remote_target::remote_hostio_send_command (this=0x555556a11040, command_bytes=13, which_packet=14, remote_errno=0x7fffffffcfd0, attachment=0x0, attachment_len=0x0) at src/gdb/remote.c:12137
#5 0x0000555555bc1b6c in remote_target::remote_hostio_close (this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12455
#6 0x0000555555bc1bb4 in remote_target::fileio_close (During symbol reading: .debug_line address at offset 0x64f417 is 0 [in module build/gdb/gdb]
this=0x555556a11040, fd=8, remote_errno=0x7fffffffcfd0) at src/gdb/remote.c:12462
#7 0x0000555555c9274c in target_fileio_close (fd=3, target_errno=0x7fffffffcfd0) at src/gdb/target.c:3365
#8 0x000055555595a19d in gdb_bfd_iovec_fileio_close (abfd=0x555556b9f8a0, stream=0x555556b11530) at src/gdb/gdb_bfd.c:439
#9 0x0000555555e09e3f in opncls_bclose (abfd=0x555556b9f8a0) at src/bfd/opncls.c:599
#10 0x0000555555e0a2c7 in bfd_close_all_done (abfd=0x555556b9f8a0) at src/bfd/opncls.c:847
#11 0x0000555555e0a27a in bfd_close (abfd=0x555556b9f8a0) at src/bfd/opncls.c:814
#12 0x000055555595a9d3 in gdb_bfd_close_or_warn (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:626
#13 0x000055555595ad29 in gdb_bfd_unref (abfd=0x555556b9f8a0) at src/gdb/gdb_bfd.c:715
#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573
#15 0x0000555555ae955a in std::_Sp_counted_ptr<objfile*, (__gnu_cxx::_Lock_policy)2>::_M_dispose (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:377
#16 0x000055555572b7c8 in std::_Sp_counted_base<(__gnu_cxx::_Lock_policy)2>::_M_release (this=0x555556c20db0) at /usr/include/c++/9/bits/shared_ptr_base.h:155
#17 0x00005555557263c3 in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::~__shared_count (this=0x555556bf0588, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:730
#18 0x0000555555ae745e in std::__shared_ptr<objfile, (__gnu_cxx::_Lock_policy)2>::~__shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr_base.h:1169
#19 0x0000555555ae747e in std::shared_ptr<objfile>::~shared_ptr (this=0x555556bf0580, __in_chrg=<optimized out>) at /usr/include/c++/9/bits/shared_ptr.h:103
#20 0x0000555555b1c1dc in __gnu_cxx::new_allocator<std::_List_node<std::shared_ptr<objfile> > >::destroy<std::shared_ptr<objfile> > (this=0x5555564cdd60, __p=0x555556bf0580) at /usr/include/c++/9/ext/new_allocator.h:153
#21 0x0000555555b1bb1d in std::allocator_traits<std::allocator<std::_List_node<std::shared_ptr<objfile> > > >::destroy<std::shared_ptr<objfile> > (__a=..., __p=0x555556bf0580) at /usr/include/c++/9/bits/alloc_traits.h:497
#22 0x0000555555b1b73e in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::_M_erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/stl_list.h:1921
#23 0x0000555555b1afeb in std::__cxx11::list<std::shared_ptr<objfile>, std::allocator<std::shared_ptr<objfile> > >::erase (this=0x5555564cdd60, __position=std::shared_ptr<objfile> (expired, weak count 1) = {get() = 0x555556515540}) at /usr/include/c++/9/bits/list.tcc:158
#24 0x0000555555b19576 in program_space::remove_objfile (this=0x5555564cdd20, objfile=0x555556515540) at src/gdb/progspace.c:210
#25 0x0000555555ae4502 in objfile::unlink (this=0x555556515540) at src/gdb/objfiles.c:487
#26 0x0000555555ae5a12 in objfile_purge_solibs () at src/gdb/objfiles.c:875
#27 0x0000555555c09686 in no_shared_libraries (ignored=0x0, from_tty=1) at src/gdb/solib.c:1236
#28 0x00005555559e3f5f in detach_command (args=0x0, from_tty=1) at src/gdb/infcmd.c:2769
So frame #28 already detached the remote process, and then we're
purging the shared libraries. GDB had opened remote shared libraries
via the target: sysroot, so it tries closing them. GDBserver is
tearing down already, so remote communication breaks down and we close
the remote target and throw TARGET_CLOSE_ERROR.
Note frame #14:
#14 0x0000555555ae4730 in objfile::~objfile (this=0x555556515540, __in_chrg=<optimized out>) at src/gdb/objfiles.c:573
That's a dtor, thus noexcept. That's the reason for the
std::terminate.
Stepping back a bit, why do we still have open remote files if we've
managed to detach already, and, we're debugging with "target remote"?
The reason is that commit 408f66864a1a823591b26420410c982174c239a2
makes detach_command hold a reference to the target, so the remote
target won't be finally closed until frame #28 returns. It's closing
the target that invalidates target file I/O handles.
This commit fixes the issue by not relying on target_close to
invalidate the target file I/O handles, instead invalidate them
immediately in remote_unpush_target. So when GDB purges the solibs,
and we end up in target_fileio_close (frame #7 above), there's nothing
to do, and we don't try to talk with the remote target anymore.
The regression isn't seen when testing with
--target_board=native-gdbserver, because that does "set sysroot" to
disable the "target:" sysroot, for test run speed reasons. So this
commit adds a testcase that explicitly tests detach with "set sysroot
target:".
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
PR gdb/28080
* remote.c (remote_unpush_target): Invalidate file I/O target
handles.
* target.c (fileio_handles_invalidate_target): Make extern.
* target.h (fileio_handles_invalidate_target): Declare.
gdb/testsuite/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
PR gdb/28080
* gdb.base/detach-sysroot-target.exp: New.
* gdb.base/detach-sysroot-target.c: New.
Reported-By: Jonah Graham <jonah@kichwacoders.com>
Change-Id: I851234910172f42a1b30e731161376c344d2727d
|
|
At the moment some check-read1 timeouts are handled like this in
gdb.base/info-macros.exp:
...
gdb_test_multiple_with_read1_timeout_factor 10 "$test" $testname {
-re "$r1$r2$r3" {
pass $testname
}
-re ".*#define TWO.*\r\n$gdb_prompt" {
fail $testname
}
-re ".*#define THREE.*\r\n$gdb_prompt" {
fail $testname
}
-re ".*#define FOUR.*\r\n$gdb_prompt" {
fail $testname
}
}
...
which is not ideal.
We could use gdb_test_lines, but it currently doesn't support verifying
the absence of regexps, which is done using the clauses above calling fail.
Fix this by using gdb_test_lines and adding a -re-not syntax to
gdb_test_lines, such that we can do:
...
gdb_test_lines $test $testname $r1.*$r2 \
-re-not "#define TWO" \
-re-not "#define THREE" \
-re-not "#define FOUR"
...
Tested on x86_64-linux, whith make targets check and check-read1.
Also observed that check-read1 execution time is reduced from 6m35s to 13s.
gdb/testsuite/ChangeLog:
2021-07-06 Tom de Vries <tdevries@suse.de>
* gdb.base/info-macros.exp: Replace use of
gdb_test_multiple_with_read1_timeout_factor with gdb_test_lines.
(gdb_test_multiple_with_read1_timeout_factor): Remove.
* lib/gdb.exp (gdb_test_lines): Add handling or -re-not <regexp>.
|
|
Now that the GDB 11 branch has been created, we can
bump the version number.
gdb/ChangeLog:
GDB 11 branch created (4b51505e33441c6165e7789fa2b6d21930242927):
* version.in: Bump version to 12.0.50.DATE-git.
gdb/testsuite/ChangeLog:
* gdb.base/default.exp: Change $_gdb_major to 12.
|
|
Currently, on GNU/Linux, if you try to access memory and you have a
running thread selected, GDB fails the memory accesses, like:
(gdb) c&
Continuing.
(gdb) p global_var
Cannot access memory at address 0x555555558010
Or:
(gdb) b main
Breakpoint 2 at 0x55555555524d: file access-mem-running.c, line 59.
Warning:
Cannot insert breakpoint 2.
Cannot access memory at address 0x55555555524d
This patch removes this limitation. It teaches the native Linux
target to read/write memory even if the target is running. And it
does this without temporarily stopping threads. We now get:
(gdb) c&
Continuing.
(gdb) p global_var
$1 = 123
(gdb) b main
Breakpoint 2 at 0x555555555259: file access-mem-running.c, line 62.
(The scenarios above work correctly with current GDBserver, because
GDBserver temporarily stops all threads in the process whenever GDB
wants to access memory (see prepare_to_access_memory /
done_accessing_memory). Freezing the whole process makes sense when
we need to be sure that we have a consistent view of memory and don't
race with the inferior changing it at the same time as GDB is
accessing it. But I think that's a too-heavy hammer for the default
behavior. I think that ideally, whether to stop all threads or not
should be policy decided by gdb core, probably best implemented by
exposing something like gdbserver's prepare_to_access_memory /
done_accessing_memory to gdb core.)
Currently, if we're accessing (reading/writing) just a few bytes, then
the Linux native backend does not try accessing memory via
/proc/<pid>/mem and goes straight to ptrace
PTRACE_PEEKTEXT/PTRACE_POKETEXT. However, ptrace always fails when
the ptracee is running. So the first step is to prefer
/proc/<pid>/mem even for small accesses. Without further changes
however, that may cause a performance regression, due to constantly
opening and closing /proc/<pid>/mem for each memory access. So the
next step is to keep the /proc/<pid>/mem file open across memory
accesses. If we have this, then it doesn't make sense anymore to even
have the ptrace fallback, so the patch disables it.
I've made it such that GDB only ever has one /proc/<pid>/mem file open
at any time. As long as a memory access hits the same inferior
process as the previous access, then we reuse the previously open
file. If however, we access memory of a different process, then we
close the previous file and open a new one for the new process.
If we wanted, we could keep one /proc/<pid>/mem file open per
inferior, and never close them (unless the inferior exits or execs).
However, having seen bfd patches recently about hitting too many open
file descriptors, I kept the logic to have only one file open tops.
Also, we need to handle memory accesses for processes for which we
don't have an inferior object, for when we need to detach a
fork-child, and we'd probaly want to handle caching the open file for
that scenario (no inferior for process) too, which would probably end
up meaning caching for last non-inferior process, which is very much
what I'm proposing anyhow. So always having one file open likely ends
up a smaller patch.
The next step is handling the case of GDB reading/writing memory
through a thread that is running and exits. The access should not
result in a user-visible failure if the inferior/process is still
alive.
Once we manage to open a /proc/<lwpid>/mem file, then that file is
usable for memory accesses even if the corresponding lwp exits and is
reaped. I double checked that trying to open the same
/proc/<lwpid>/mem path again fails because the lwp is really gone so
there's no /proc/<lwpid>/ entry on the filesystem anymore, but the
previously open file remains usable. It's only when the whole process
execs that we need to reopen a new file.
When the kernel destroys the whole address space, i.e., when the
process exits or execs, the reads/writes fail with 0 aka EOF, in which
case there's nothing else to do than returning a memory access
failure. Note this means that when we get an exec event, we need to
reopen the file, to access the process's new address space.
If we need to open (or reopen) the /proc/<pid>/mem file, and the LWP
we're opening it for exits before we open it and before we reap the
LWP (i.e., the LWP is zombie), the open fails with EACCES. The patch
handles this by just looking for another thread until it finds one
that we can open a /proc/<pid>/mem successfully for.
If we need to open (or reopen) the /proc/<pid>/mem file, and the LWP
we're opening has exited and we already reaped it, which is the case
if the selected thread is in THREAD_EXIT state, the open fails with
ENOENT. The patch handles this the same way as a zombie race
(EACCES), instead of checking upfront whether we're accessing a
known-exited thread, because that would result in more complicated
code, because we also need to handle accessing lwps that are not
listed in the core thread list, and it's the core thread list that
records the THREAD_EXIT state.
The patch includes two testcases:
#1 - gdb.base/access-mem-running.exp
This is the conceptually simplest - it is single-threaded, and has
GDB read and write memory while the program is running. It also
tests setting a breakpoint while the program is running, and checks
that the breakpoint is hit immediately.
#2 - gdb.threads/access-mem-running-thread-exit.exp
This one is more elaborate, as it continuously spawns short-lived
threads in order to exercise accessing memory just while threads are
exiting. It also spawns two different processes and alternates
accessing memory between the two processes to exercise the reopening
the /proc file frequently. This also ends up exercising GDB reading
from an exited thread frequently. I confirmed by putting abort()
calls in the EACCES/ENOENT paths added by the patch that we do hit
all of them frequently with the testcase. It also exits the
process's main thread (i.e., the main thread becomes zombie), to
make sure accessing memory in such a corner-case scenario works now
and in the future.
The tests fail on GNU/Linux native before the code changes, and pass
after. They pass against current GDBserver, again because GDBserver
supports memory access even if all threads are running, by
transparently pausing the whole process.
gdb/ChangeLog:
yyyy-mm-dd Pedro Alves <pedro@palves.net>
PR mi/15729
PR gdb/13463
* linux-nat.c (linux_nat_target::detach): Close the
/proc/<pid>/mem file if it was open for this process.
(linux_handle_extended_wait) <PTRACE_EVENT_EXEC>: Close the
/proc/<pid>/mem file if it was open for this process.
(linux_nat_target::mourn_inferior): Close the /proc/<pid>/mem file
if it was open for this process.
(linux_nat_target::xfer_partial): Adjust. Do not fall back to
inf_ptrace_target::xfer_partial for memory accesses.
(last_proc_mem_file): New.
(maybe_close_proc_mem_file): New.
(linux_proc_xfer_memory_partial_pid): New, with bits factored out
from linux_proc_xfer_partial.
(linux_proc_xfer_partial): Delete.
(linux_proc_xfer_memory_partial): New.
gdb/testsuite/ChangeLog
yyyy-mm-dd Pedro Alves <pedro@palves.net>
PR mi/15729
PR gdb/13463
* gdb.base/access-mem-running.c: New.
* gdb.base/access-mem-running.exp: New.
* gdb.threads/access-mem-running-thread-exit.c: New.
* gdb.threads/access-mem-running-thread-exit.exp: New.
Change-Id: Ib3c082528872662a3fc0ca9b31c34d4876c874c9
|
|
Currently the 'info sources' command lists all of the known source
files together, regardless of their source, e.g. here is a session
debugging a test application that makes use of a shared library:
(gdb) info sources
Source files for which symbols have been read in:
/tmp/info-sources/test.c, /usr/include/stdc-predef.h,
/tmp/info-sources/header.h, /tmp/info-sources/helper.c
Source files for which symbols will be read in on demand:
(gdb)
In this commit I change the format of the 'info sources' results so
that the results are grouped by the object file that uses that source
file. Here's the same session with the new output format:
(gdb) info sources
/tmp/info-sources/test.x:
/tmp/info-sources/test.c, /usr/include/stdc-predef.h,
/tmp/info-sources/header.h
/lib64/ld-linux-x86-64.so.2:
(Objfile has no debug information.)
system-supplied DSO at 0x7ffff7fcf000:
(Objfile has no debug information.)
/tmp/info-sources/libhelper.so:
/tmp/info-sources/helper.c, /usr/include/stdc-predef.h,
/tmp/info-sources/header.h
/lib64/libc.so.6:
(Objfile has no debug information.)
(gdb)
Notice that in the new output some source files are repeated,
e.g. /tmp/info-sources/header.h, as multiple objfiles use this source
file.
Further, some object files are tagged with the message '(Objfile has
no debug information.)', it is also possible to see the message '(Full
debug information has not yet been read for this file.)', which is
printed when some symtabs within an objfile have not yet been
expanded.
All of the existing regular expression based filtering still works.
An original version of this patch added the new format as an option to
'info sources', however, it was felt that the new layout was so much
better than the old style that GDB should just switch to the new
result format completely.
gdb/ChangeLog:
* NEWS: Mention changes to 'info sources'.
* symtab.c (info_sources_filter::print): Delete.
(struct output_source_filename_data) <print_header>: Delete
declaration. <printed_filename_p>: New member function.
(output_source_filename_data::print_header): Delete.
(info_sources_worker): Update group-by-objfile style output to
make it CLI suitable, simplify non-group-by-objfile now this is
only used from the MI.
(info_sources_command): Make group-by-objfile be the default for
CLI info sources command.
* symtab.h (struct info_sources_filter) <print>: Delete.
gdb/doc/ChangeLog:
* gdb.texinfo (Symbols): Document new output format for 'info
sources'.
gdb/testsuite/ChangeLog:
* gdb.base/info_sources_2-header.h: New file.
* gdb.base/info_sources_2-lib.c: New file.
* gdb.base/info_sources_2-test.c: New file.
* gdb.base/info_sources_2.exp: New file.
|
|
When running test-case gdb.base/info-macros.exp, I run into:
...
PASS: gdb.base/info-macros.exp: info macro --
PASS: gdb.base/info-macros.exp: info macro --
DUPLICATE: gdb.base/info-macros.exp: info macro --
PASS: gdb.base/info-macros.exp: info macro --
...
These messages come from gdb_test calls using the following commands:
- "info macro --"
- "info macro -- "
- "info macro -- ".
Apparantly the test names get stripped of trailing whitespace, and the first
two end up identical.
Fix this by explicitly specifying an <EOL> after the trailing whitespace in
the test name, such that we have:
...
PASS: gdb.base/info-macros.exp: info macro --
PASS: gdb.base/info-macros.exp: info macro -- <EOL>
PASS: gdb.base/info-macros.exp: info macro -- <EOL>
...
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-06-24 Tom de Vries <tdevries@suse.de>
* gdb.base/info-macros.exp: Add <EOL> after trailing whitespace in
test names.
|
|
I found the following duplicates in gdb.base/argv0-symlink.exp:
...
DUPLICATE: gdb.base/argv0-symlink.exp: set print repeats 10000
DUPLICATE: gdb.base/argv0-symlink.exp: set print elements 10000
...
Fix these by using with_test_prefix "file symlink" / "dir symlink".
Tested on x86_64-linux.
gdb/testsuite/ChangeLog:
2021-06-24 Tom de Vries <tdevries@suse.de>
* gdb.base/argv0-symlink.exp: Use with_test_prefix.
|
|
On Ubuntu 20.04, when the debug info package for libc is not installed,
I get:
FAIL: gdb.base/info-types-c++.exp: info types
FAIL: gdb.base/info-types-c.exp: info types
The reason is that the output of info types is exactly:
(gdb) info types
All defined types:
File /home/smarchi/src/binutils-gdb/gdb/testsuite/gdb.base/info-types.c:
52: typedef enum {...} anon_enum_t;
45: typedef struct {...} anon_struct_t;
68: typedef union {...} anon_union_t;
28: typedef struct baz_t baz;
31: typedef struct baz_t * baz_ptr;
21: struct baz_t;
double
33: enum enum_t;
float
int
38: typedef enum enum_t my_enum_t;
17: typedef float my_float_t;
16: typedef int my_int_t;
54: typedef enum {...} nested_anon_enum_t;
47: typedef struct {...} nested_anon_struct_t;
70: typedef union {...} nested_anon_union_t;
30: typedef struct baz_t nested_baz;
29: typedef struct baz_t nested_baz_t;
39: typedef enum enum_t nested_enum_t;
19: typedef float nested_float_t;
18: typedef int nested_int_t;
62: typedef union union_t nested_union_t;
56: union union_t;
unsigned int
(gdb)
The lines we expect in the test contain an empty line at the end:
...
"62:\[\t \]+typedef union union_t nested_union_t;" \
"56:\[\t \]+union union_t;" \
"--optional" "\[\t \]+unsigned int" \
""]
This is written with the supposition that other files will be listed, so
an empty line will be included to separate the symbols from this file
from the next one. This empty line is not included when info-types.c is
the only file listed.
Fix this by rewriting gdb_test_lines to accept a single, plain tcl multiline
regexp, such that we can write:
...
"62:\[\t \]+typedef union union_t nested_union_t;" \
"56:\[\t \]+union union_t;(" \
"\[\t \]+unsigned int)?" \
"($|\r\n.*)"]
...
Tested affected test-cases:
- gdb.base/info-types-c.exp
- gdb.base/info-types-c++.exp
- gdb.base/info-macros.exp
- gdb.cp/cplusfuncs.exp
on x86_64-linux (openSUSE Leap 15.2), both with check and check-read1.
Also tested the first two with gcc-4.8.
Also tested on ubuntu 18.04.
gdb/testsuite/ChangeLog:
2021-06-23 Tom de Vries <tdevries@suse.de>
* lib/gdb.exp (gdb_test_lines): Rewrite to accept single
multiline tcl regexp.
* gdb.base/info-types.exp.tcl: Update. Make empty line at end of
regexp optional.
* gdb.base/info-macros.exp: Update.
* gdb.cp/cplusfuncs.exp: Update.
|
|
This test tests passing arguments made of exactly two single-quotes
('') or a single newline character through the --args argument of GDB.
For some reason, GDB adds some extra single quotes when transmitting the
arguments to GDBserver. This produces some FAILs when testing with the
native-extended-gdbserver board:
FAIL: gdb.base/args.exp: argv[2] for one empty (with single quotes)
FAIL: gdb.base/args.exp: argv[2] for two empty (with single quotes)
FAIL: gdb.base/args.exp: argv[3] for two empty (with single quotes)
FAIL: gdb.base/args.exp: argv[2] for one newline
FAIL: gdb.base/args.exp: argv[2] for two newlines
FAIL: gdb.base/args.exp: argv[3] for two newlines
This is documented as PR 27989. Add some appropriate KFAILs.
gdb/testsuite/ChangeLog:
* gdb.base/args.exp: Check target, KFAIL if remote.
(args_test): Add parameter and use it.
Change-Id: I49225d1c7df7ebaba480ebdd596df80f8fbf62f0
|
|
Some test names end with a parenthesis, we don't want that:
https://sourceware.org/gdb/wiki/GDBTestcaseCookbook#Do_not_use_.22tail_parentheses.22_on_test_messages
Fix that.
gdb/testsuite/ChangeLog:
* gdb.base/args.exp: Remove trailing parenthesis in test names.
Change-Id: I0306ea202bae3a4ed5bf0bd65e0ab5ed5de52fe1
|
|
All tests in this file append to GDBFLAGS instead of overwriting it,
except the last two. I noticed because when testing with the
native-extended-remote board, it removes the "set sysroot" argument, and
it causes the test to be very long to run, due to big glibc debug info
being read through the remote target.
I think this oddity is due to a race condition between these two
commits:
[1] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=c22261528c50f7760dd6a2e29314662b377eebb4
[2] https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=6b8ce727297b1e40738e50f83a75881b290fe6a6
The first one added the two tests. The second one changes the test to
append to GDBFLAGS instead of overwriting it. But the second one was
probably written before the first one was it, so missed the new tests.
Change those two tests to be like the others.
gdb/testsuite/ChangeLog:
* gdb.base/args.exp: Use $old_gdbflags in all tests.
Change-Id: I531276125ecb70e80f52adbd320ebb85b0c8eba0
|
|
Use save_vars instead of manually saving/restoring. This ensures that
if anything throws an error, GDBFLAGS will be correctly restored.
Remove the global GDBFLAGS declaration at the top, it's not necessary.
gdb/testsuite/ChangeLog:
* gdb.base/args.exp: Use save_vars.
Change-Id: I3a45e4fc1635ec0212de2415040f91eecaf4a057
|