2016-01-01 05:33:14 +01:00
|
|
|
# Copyright 2013-2016 Free Software Foundation, Inc.
|
2013-07-17 11:44:26 +02:00
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or modify
|
|
|
|
# it under the terms of the GNU General Public License as published by
|
|
|
|
# the Free Software Foundation; either version 3 of the License, or
|
|
|
|
# (at your option) any later version.
|
|
|
|
#
|
|
|
|
# This program is distributed in the hope that it will be useful,
|
|
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
# GNU General Public License for more details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License
|
|
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
|
|
# Test adding and removing a symbol file dynamically:
|
|
|
|
# 1) Run to gdb_add_symbol_file in $srcfile.
|
|
|
|
# 2) Set a pending breakpoint at bar in $srcfile3.
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 3) Load the library's symbols using 'add-symbol-file'.
|
2013-07-17 11:44:26 +02:00
|
|
|
# 4) 'info files' must display ${lib_basename}.
|
|
|
|
# 5) Continue to bar in $srcfile3.
|
|
|
|
# 6) Set a breakpoint at foo in $srcfile3.
|
|
|
|
# 7) Continue to foo in $srcfile3.
|
|
|
|
# 8) Set a breakpoint at gdb_remove_symbol_file.
|
|
|
|
# 9) Continue to gdb_remove_symbol_file in $srcfile.
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 10) Remove the library's symbols using 'remove-symbol-file'.
|
2013-07-17 11:44:26 +02:00
|
|
|
# 11) 'info files' must not display ${lib_basename}, anymore.
|
|
|
|
# 12) Check that the breakpoints at foo and bar are pending.
|
|
|
|
# 13) Check that the execution can continue without error.
|
Stale breakpoint instructions, spurious SIGTRAPS.
Without the code portion of the patch, we get these failures:
FAIL: gdb.base/break-unload-file.exp: always-inserted on: break: continue
FAIL: gdb.base/break-unload-file.exp: always-inserted on: hbreak: continue
FAIL: gdb.base/sym-file.exp: stale bkpts: continue to breakpoint: end here
They all looks like random SIGTRAPs:
continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000400541 in foo () at ../../../src/gdb/testsuite/gdb.base/break-unload-file.c:21
21 }
(gdb) FAIL: gdb.base/break-unload-file.exp: always-inserted on: break: continue
(This is a regression caused by the remove-symbol-file command
series.)
break-unload-file.exp is about having breakpoints inserted, and then
doing "file". I caught this while writing a test that does "file
PROGRAM", while PROGRAM was already loaded, which internally does
"file" first, because I wanted to force a breakpoint_re_set, but the
test is more explicit in case GDB ever optimizes out that re-set.
The problem is that unloading the file with "file" ends up in
disable_breakpoints_in_freed_objfile, which marks all breakpoint
locations of the objfile as both shlib_disabled, _and_ clears the
inserted flag, without actually removing the breakpoints from the
inferior. Now, usually, in all-stop, breakpoints will already be
removed from the inferior before the user can issue the "file"
command, but, with non-stop, or breakpoints always-inserted on mode,
breakpoints stay inserted even while the user has the prompt. In the
latter case, then, if we let the program continue, and it executes the
address where we had previously set the breakpoint, it'll actually
execute the breakpoint instruction that we left behind...
Now, one issue is that the intent of
disable_breakpoints_in_freed_objfile is really to handle the unloading
of OBJF_USERLOADED objfiles. These are objfiles that were added with
add-symbol-file and that are removed with remove-symbol-file.
"add-symbol-file"'s docs in the manual clearly say these commands are
used to let GDB know about dynamically loaded code:
You would use this command when @var{filename} has been dynamically
loaded (by some other means) into the program that is running.
Similarly, the online help says:
(gdb) help add-symbol-file
Load symbols from FILE, assuming FILE has been dynamically loaded.
So it makes sense to, like when shared libraries are unloaded through
the generic solib machinery, mark the breakpoint locations as
shlib_disabled. But, the "file" command is not about dynamically
loaded code, it's about the main program. So the patch makes
disable_breakpoints_in_freed_objfile skip all objfiles but
OBJF_USERLOADED ones, thus skipping the main objfile.
Then, the reason that disable_breakpoints_in_freed_objfile was
clearing the inserted flag isn't clear, but likely to avoid breakpoint
removal errors, assuming remove-symbol-file was called after the
dynamic object was already unmapped from the inferior. In that case,
it'd okay to simply clear the inserted flag, but not so if the user
for example does remove-symbol-file to remove the library because he
made a mistake in the library's address, and wants to re-do
add-symbol-file with the correct address.
To address all that, I propose an alternative implementation, that
handles both cases. The patch includes changes to sym-file.exp to
cover them.
This implementation leaves the inserted flag alone, and handles
breakpoint insertion/removal failure gracefully when the locations are
in OBJF_USERLOADED objfiles, just like we handle insertion/removal
failure gracefully for locations in shared libraries.
To try to make sure we aren't patching back stale shadow memory
contents into the inferior, in case the program mapped a different
library at the same address where we had the breakpoint, without the
user having had a chance of remove-symbol-file'ing before, this adds a
new memory_validate_breakpoint function that checks if the breakpoint
instruction is still in memory. ppc_linux_memory_remove_breakpoint
does this unconditionally for all memory breakpoints, and questions
whether memory_remove_breakpoint should be changed to do this for all
breakpoints. Possibly yes, though I'm not certain, hence this
baby-steps patch.
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/
2014-04-23 Pedro Alves <palves@redhat.com>
* breakpoint.c (insert_bp_location): Tolerate errors if the
breakpoint is set in a user-loaded objfile.
(remove_breakpoint_1): Likewise. Also tolerate errors if the
location is marked shlib_disabled. If the breakpoint is set in a
user-loaded objfile is a GDB-side memory breakpoint, validate it
before uninsertion. (disable_breakpoints_in_freed_objfile): Skip
non-OBJF_USERLOADED objfiles. Don't clear the location's inserted
flag.
* mem-break.c (memory_validate_breakpoint): New function.
* objfiles.c (userloaded_objfile_contains_address_p): New
function.
* objfiles.h (userloaded_objfile_contains_address_p): Declare.
* target.h (memory_validate_breakpoint): New declaration.
gdb/testsuite/
2014-04-23 Pedro Alves <palves@redhat.com>
* gdb.base/break-unload-file.c: New file.
* gdb.base/break-unload-file.exp: New file.
* gdb.base/sym-file-lib.c (baz): New function.
* gdb.base/sym-file-loader.c (struct segment) <mapped_size>: New
field.
(load): Store the segment's mapped size.
(unload): New function.
(unload_shlib): New function.
* gdb.base/sym-file-loader.h (unload_shlib): New declaration.
* gdb.base/sym-file-main.c (main): Unload, and reload the library,
set a breakpoint at baz, and call it.
* gdb.base/sym-file.exp: New tests for stale breakpoint
instructions.
2014-04-23 00:19:19 +02:00
|
|
|
# 14) Regression test for a stale breakpoints bug.
|
2013-07-17 11:44:26 +02:00
|
|
|
|
|
|
|
if {![is_elf_target]} {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if [skip_shlib_tests] {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
set target_size TARGET_UNKNOWN
|
|
|
|
if {[is_lp64_target]} {
|
|
|
|
set target_size TARGET_LP64
|
|
|
|
} elseif {[is_ilp32_target]} {
|
|
|
|
set target_size TARGET_ILP32
|
|
|
|
} else {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
set main_basename sym-file-main
|
|
|
|
set loader_basename sym-file-loader
|
|
|
|
set lib_basename sym-file-lib
|
|
|
|
|
|
|
|
standard_testfile $main_basename.c $loader_basename.c $lib_basename.c
|
|
|
|
|
|
|
|
set libsrc "${srcdir}/${subdir}/${srcfile3}"
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
set lib_so [standard_output_file ${lib_basename}.so]
|
|
|
|
set lib_syms [shlib_symbol_file ${lib_so}]
|
|
|
|
set lib_dlopen [shlib_target_file ${lib_basename}.so]
|
|
|
|
|
2013-07-17 11:44:26 +02:00
|
|
|
set exec_opts [list debug "additional_flags= -I$srcdir/../../include/ -D$target_size\
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
-DSHLIB_NAME\\=\"$lib_dlopen\""]
|
2013-07-17 11:44:26 +02:00
|
|
|
|
|
|
|
if [get_compiler_info] {
|
|
|
|
return -1
|
|
|
|
}
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
if {[gdb_compile_shlib $libsrc $lib_so {debug}] != ""} {
|
2013-07-17 11:44:26 +02:00
|
|
|
untested ${testfile}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if {[prepare_for_testing $testfile $binfile "$srcfile $srcfile2" $exec_opts]} {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
gdb_load_shlibs ${lib_so}
|
|
|
|
|
|
|
|
if ![runto_main] then {
|
|
|
|
fail "Can't run to main"
|
|
|
|
return
|
2013-07-17 11:44:26 +02:00
|
|
|
}
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 1) Run to gdb_add_symbol_file in $srcfile for adding the library's
|
|
|
|
# symbols.
|
|
|
|
gdb_breakpoint gdb_add_symbol_file
|
|
|
|
gdb_continue_to_breakpoint gdb_add_symbol_file
|
|
|
|
|
2013-07-17 11:44:26 +02:00
|
|
|
# 2) Set a pending breakpoint at bar in $srcfile3.
|
|
|
|
set result [gdb_breakpoint bar allow-pending]
|
|
|
|
if {!$result} then {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 3) Add the library's symbols using 'add-symbol-file'.
|
|
|
|
set result [gdb_test "add-symbol-file ${lib_syms} addr" \
|
|
|
|
"Reading symbols from .*${lib_syms}\\.\\.\\.done\\." \
|
2014-04-15 13:49:51 +02:00
|
|
|
"add-symbol-file ${lib_basename}.so addr" \
|
2013-07-17 11:44:26 +02:00
|
|
|
"add symbol table from file \".*${lib_basename}\\.so\"\
|
|
|
|
at.*\\(y or n\\) " \
|
|
|
|
"y"]
|
|
|
|
if {$result != 0} then {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# 4) 'info files' must display $srcfile3.
|
|
|
|
gdb_test "info files" \
|
|
|
|
"^(?=(.*${lib_basename})).*" \
|
|
|
|
"info files must display ${lib_basename}"
|
|
|
|
|
|
|
|
# 5) Continue to bar in $srcfile3 to ensure that the breakpoint
|
|
|
|
# was bound correctly after adding $shilb_name.
|
|
|
|
set lnum_bar [gdb_get_line_number "break at bar" $srcfile3]
|
|
|
|
gdb_continue_to_breakpoint bar ".*${lib_basename}\\.c:$lnum_bar.*"
|
|
|
|
|
|
|
|
# 6) Set a breakpoint at foo in $srcfile3.
|
|
|
|
set result [gdb_breakpoint foo]
|
|
|
|
if {!$result} then {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# 7) Continue to foo in $srcfile3 to ensure that the breakpoint
|
|
|
|
# was bound correctly.
|
|
|
|
set lnum_foo [gdb_get_line_number "break at foo" $srcfile3]
|
|
|
|
gdb_continue_to_breakpoint foo ".*${lib_basename}\\.c:$lnum_foo.*"
|
|
|
|
|
|
|
|
# 8) Set a breakpoint at gdb_remove_symbol_file in $srcfile for
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# removing the library's symbols.
|
2013-07-17 11:44:26 +02:00
|
|
|
set result [gdb_breakpoint gdb_remove_symbol_file]
|
|
|
|
if {!$result} then {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# 9) Continue to gdb_remove_symbol_file in $srcfile.
|
|
|
|
gdb_continue_to_breakpoint gdb_remove_symbol_file
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 10) Remove the library's symbols using 'remove-symbol-file'.
|
2013-07-17 11:44:26 +02:00
|
|
|
set result [gdb_test "remove-symbol-file -a addr" \
|
|
|
|
""\
|
|
|
|
"remove-symbol-file -a addr" \
|
|
|
|
"Remove symbol table from file \".*${lib_basename}\\.so\"\\?\
|
|
|
|
.*\\(y or n\\) " \
|
|
|
|
"y"]
|
|
|
|
if {$result != 0} then {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
# 11) 'info files' must not display ${lib_basename}, anymore.
|
|
|
|
gdb_test "info files" \
|
|
|
|
"^(?!(.*${lib_basename})).*" \
|
|
|
|
"info files must not display ${lib_basename}"
|
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
# 12) Check that the breakpoints at foo and bar are pending after
|
|
|
|
# removing the library's symbols.
|
|
|
|
gdb_test "info breakpoints 3" \
|
2013-07-17 11:44:26 +02:00
|
|
|
".*PENDING.*" \
|
2014-04-15 13:49:51 +02:00
|
|
|
"breakpoint at foo is pending"
|
2013-07-17 11:44:26 +02:00
|
|
|
|
Make sym-file.exp work with remote targets and hosts.
The main issue here is that this test passes the host's absolute path
to the library to load to the "dlopen"-like routine, which doesn't
work when either the target or the host are remote, unless a shared
filesystem has been set up.
Tests that dynamically load a library solve this by dlopen'ing by
basename, and setting rpath to $ORIGIN. See gdb_compile.
This test doesn't use dlopen, but instead uses its own simple elf
loader. The fix is to pass this loader the library basename, and
teach it to look up the library by basename in the executable's
directory as well, i.e., assuming/emulating RPATH=$ORIGIN.
Tested on x86_64 Fedora 17, native and gdbserver.
I looked around in the web to figure out Linux's /proc/self/exe
equivalents in other ELF OSs. I think I covered all relevant, but if
not, I think it'll be simple enough to add more. (Note the test is
skipped on non-ELF targets.)
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/testsuite/
2014-04-15 Pedro Alves <palves@redhat.com>
* gdb.base/sym-file-loader.c: Include <limits.h>.
(SELF_LINK): New define.
(get_origin): New function.
(load_shlib): Use it.
* gdb.base/sym-file.exp: Don't early return if the target is
remote. Use runto_main, and issue fail is that fails. Use
gdb_load_shlibs.
(shlib_name): Delete.
(lib_so, lib_syms, lib_dlopen): New globals. Use them throughout.
2014-04-14 18:23:55 +02:00
|
|
|
gdb_test "info breakpoints 4" \
|
2013-07-17 11:44:26 +02:00
|
|
|
".*PENDING.*" \
|
2014-04-15 13:49:51 +02:00
|
|
|
"breakpoint at bar is pending"
|
2013-07-17 11:44:26 +02:00
|
|
|
|
|
|
|
# 13) Check that the execution can continue without error.
|
Stale breakpoint instructions, spurious SIGTRAPS.
Without the code portion of the patch, we get these failures:
FAIL: gdb.base/break-unload-file.exp: always-inserted on: break: continue
FAIL: gdb.base/break-unload-file.exp: always-inserted on: hbreak: continue
FAIL: gdb.base/sym-file.exp: stale bkpts: continue to breakpoint: end here
They all looks like random SIGTRAPs:
continue
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000000000400541 in foo () at ../../../src/gdb/testsuite/gdb.base/break-unload-file.c:21
21 }
(gdb) FAIL: gdb.base/break-unload-file.exp: always-inserted on: break: continue
(This is a regression caused by the remove-symbol-file command
series.)
break-unload-file.exp is about having breakpoints inserted, and then
doing "file". I caught this while writing a test that does "file
PROGRAM", while PROGRAM was already loaded, which internally does
"file" first, because I wanted to force a breakpoint_re_set, but the
test is more explicit in case GDB ever optimizes out that re-set.
The problem is that unloading the file with "file" ends up in
disable_breakpoints_in_freed_objfile, which marks all breakpoint
locations of the objfile as both shlib_disabled, _and_ clears the
inserted flag, without actually removing the breakpoints from the
inferior. Now, usually, in all-stop, breakpoints will already be
removed from the inferior before the user can issue the "file"
command, but, with non-stop, or breakpoints always-inserted on mode,
breakpoints stay inserted even while the user has the prompt. In the
latter case, then, if we let the program continue, and it executes the
address where we had previously set the breakpoint, it'll actually
execute the breakpoint instruction that we left behind...
Now, one issue is that the intent of
disable_breakpoints_in_freed_objfile is really to handle the unloading
of OBJF_USERLOADED objfiles. These are objfiles that were added with
add-symbol-file and that are removed with remove-symbol-file.
"add-symbol-file"'s docs in the manual clearly say these commands are
used to let GDB know about dynamically loaded code:
You would use this command when @var{filename} has been dynamically
loaded (by some other means) into the program that is running.
Similarly, the online help says:
(gdb) help add-symbol-file
Load symbols from FILE, assuming FILE has been dynamically loaded.
So it makes sense to, like when shared libraries are unloaded through
the generic solib machinery, mark the breakpoint locations as
shlib_disabled. But, the "file" command is not about dynamically
loaded code, it's about the main program. So the patch makes
disable_breakpoints_in_freed_objfile skip all objfiles but
OBJF_USERLOADED ones, thus skipping the main objfile.
Then, the reason that disable_breakpoints_in_freed_objfile was
clearing the inserted flag isn't clear, but likely to avoid breakpoint
removal errors, assuming remove-symbol-file was called after the
dynamic object was already unmapped from the inferior. In that case,
it'd okay to simply clear the inserted flag, but not so if the user
for example does remove-symbol-file to remove the library because he
made a mistake in the library's address, and wants to re-do
add-symbol-file with the correct address.
To address all that, I propose an alternative implementation, that
handles both cases. The patch includes changes to sym-file.exp to
cover them.
This implementation leaves the inserted flag alone, and handles
breakpoint insertion/removal failure gracefully when the locations are
in OBJF_USERLOADED objfiles, just like we handle insertion/removal
failure gracefully for locations in shared libraries.
To try to make sure we aren't patching back stale shadow memory
contents into the inferior, in case the program mapped a different
library at the same address where we had the breakpoint, without the
user having had a chance of remove-symbol-file'ing before, this adds a
new memory_validate_breakpoint function that checks if the breakpoint
instruction is still in memory. ppc_linux_memory_remove_breakpoint
does this unconditionally for all memory breakpoints, and questions
whether memory_remove_breakpoint should be changed to do this for all
breakpoints. Possibly yes, though I'm not certain, hence this
baby-steps patch.
Tested on x86_64 Fedora 17, native and gdbserver.
gdb/
2014-04-23 Pedro Alves <palves@redhat.com>
* breakpoint.c (insert_bp_location): Tolerate errors if the
breakpoint is set in a user-loaded objfile.
(remove_breakpoint_1): Likewise. Also tolerate errors if the
location is marked shlib_disabled. If the breakpoint is set in a
user-loaded objfile is a GDB-side memory breakpoint, validate it
before uninsertion. (disable_breakpoints_in_freed_objfile): Skip
non-OBJF_USERLOADED objfiles. Don't clear the location's inserted
flag.
* mem-break.c (memory_validate_breakpoint): New function.
* objfiles.c (userloaded_objfile_contains_address_p): New
function.
* objfiles.h (userloaded_objfile_contains_address_p): Declare.
* target.h (memory_validate_breakpoint): New declaration.
gdb/testsuite/
2014-04-23 Pedro Alves <palves@redhat.com>
* gdb.base/break-unload-file.c: New file.
* gdb.base/break-unload-file.exp: New file.
* gdb.base/sym-file-lib.c (baz): New function.
* gdb.base/sym-file-loader.c (struct segment) <mapped_size>: New
field.
(load): Store the segment's mapped size.
(unload): New function.
(unload_shlib): New function.
* gdb.base/sym-file-loader.h (unload_shlib): New declaration.
* gdb.base/sym-file-main.c (main): Unload, and reload the library,
set a breakpoint at baz, and call it.
* gdb.base/sym-file.exp: New tests for stale breakpoint
instructions.
2014-04-23 00:19:19 +02:00
|
|
|
set lnum_reload [gdb_get_line_number "reload lib here"]
|
|
|
|
gdb_breakpoint $lnum_reload
|
|
|
|
gdb_continue_to_breakpoint reload ".*${srcfile}:$lnum_reload.*"
|
|
|
|
|
|
|
|
# 14) Regression test for a stale breakpoints bug. Check whether
|
|
|
|
# unloading symbols manually without the program actually unloading
|
|
|
|
# the library, when breakpoints are inserted doesn't leave stale
|
|
|
|
# breakpoints behind.
|
|
|
|
with_test_prefix "stale bkpts" {
|
|
|
|
# Force breakpoints always inserted.
|
|
|
|
gdb_test_no_output "set breakpoint always-inserted on"
|
|
|
|
|
|
|
|
# Get past the library reload.
|
|
|
|
gdb_continue_to_breakpoint gdb_add_symbol_file
|
|
|
|
|
|
|
|
# Load the library's symbols.
|
|
|
|
gdb_test "add-symbol-file ${lib_syms} addr" \
|
|
|
|
"Reading symbols from .*${lib_syms}\\.\\.\\.done\\." \
|
|
|
|
"add-symbol-file ${lib_basename}.so addr" \
|
|
|
|
"add symbol table from file \".*${lib_syms}\"\
|
|
|
|
at.*\\(y or n\\) " \
|
|
|
|
"y"
|
|
|
|
|
|
|
|
# Set a breakpoint at baz, in the library.
|
|
|
|
gdb_breakpoint baz
|
|
|
|
|
|
|
|
gdb_test "info breakpoints 7" ".*y.*0x.*in baz.*" \
|
|
|
|
"breakpoint at baz is resolved"
|
|
|
|
|
|
|
|
# Unload symbols manually without the program actually unloading
|
|
|
|
# the library.
|
|
|
|
gdb_test "remove-symbol-file -a addr" \
|
|
|
|
"" \
|
|
|
|
"remove-symbol-file -a addr" \
|
|
|
|
"Remove symbol table from file \".*${lib_basename}\\.so\"\\?\
|
|
|
|
.*\\(y or n\\) " \
|
|
|
|
"y"
|
|
|
|
|
|
|
|
gdb_test "info breakpoints 7" ".*PENDING.*" \
|
|
|
|
"breakpoint at baz is pending"
|
|
|
|
|
|
|
|
# Check that execution can continue without error. If GDB leaves
|
|
|
|
# breakpoints behind, we'll get back a spurious SIGTRAP.
|
|
|
|
set lnum_end [gdb_get_line_number "end here"]
|
|
|
|
gdb_breakpoint $lnum_end
|
|
|
|
gdb_continue_to_breakpoint "end here" ".*end here.*"
|
|
|
|
}
|