On GNU/Linux, this test sometimes FAILs like this:
(gdb) run
Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.threads/killed
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
ptrace: No such process.
(gdb)
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
FAIL: gdb.threads/killed.exp: run program to completion (timeout)
Note the suspicious "No such process" line (that's errno==ESRCH).
Adding debug output we see:
linux_nat_wait: [process -1], [TARGET_WNOHANG]
LLW: enter
LNW: waitpid(-1, ...) returned 18465, ERRNO-OK
LLW: waitpid 18465 received Stopped (signal) (stopped)
LNW: waitpid(-1, ...) returned 18461, ERRNO-OK
LLW: waitpid 18461 received Trace/breakpoint trap (stopped)
LLW: Handling extended status 0x03057f
LHEW: Got clone event from LWP 18461, new child is LWP 18465
LNW: waitpid(-1, ...) returned 0, ERRNO-OK
RSRL: resuming stopped-resumed LWP LWP 18465 at 0x3b36af4b51: step=0
RSRL: resuming stopped-resumed LWP LWP 18461 at 0x3b36af4b51: step=0
sigchld
ptrace: No such process.
(gdb) linux_nat_wait: [process -1], [TARGET_WNOHANG]
LLW: enter
LNW: waitpid(-1, ...) returned 18465, ERRNO-OK
LLW: waitpid 18465 received Killed (terminated)
LLW: LWP 18465 exited.
LNW: waitpid(-1, ...) returned 18461, No child processes
LLW: waitpid 18461 received Killed (terminated)
Process 18461 exited
LNW: waitpid(-1, ...) returned -1, No child processes
LLW: exit
sigchld
infrun: target_wait (-1, status) =
infrun: 18461 [process 18461],
infrun: status->kind = signalled, signal = GDB_SIGNAL_KILL
infrun: TARGET_WAITKIND_SIGNALLED
Program terminated with signal SIGKILL, Killed.
The program no longer exists.
infrun: stop_waiting
FAIL: gdb.threads/killed.exp: run program to completion (timeout)
The issue is that here:
RSRL: resuming stopped-resumed LWP LWP 18465 at 0x3b36af4b51: step=0
RSRL: resuming stopped-resumed LWP LWP 18461 at 0x3b36af4b51: step=0
The first line shows we had just resumed LWP 18465, which does:
void *
child_func (void *dummy)
{
kill (pid, SIGKILL);
exit (1);
}
So if the kernel manages to schedule that thread fast enough, the
process may be killed before GDB has a chance to resume LWP 18461.
GDBserver has code at the tail end of linux_resume_one_lwp to cope
with this:
~~~
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, lwpid_of (thread),
(PTRACE_TYPE_ARG3) 0,
/* Coerce to a uintptr_t first to avoid potential gcc warning
of coercing an 8 byte integer to a 4 byte pointer. */
(PTRACE_TYPE_ARG4) (uintptr_t) signal);
current_thread = saved_thread;
if (errno)
{
/* ESRCH from ptrace either means that the thread was already
running (an error) or that it is gone (a race condition). If
it's gone, we will get a notification the next time we wait,
so we can ignore the error. We could differentiate these
two, but it's tricky without waiting; the thread still exists
as a zombie, so sending it signal 0 would succeed. So just
ignore ESRCH. */
if (errno == ESRCH)
return;
perror_with_name ("ptrace");
}
~~~
However, that's not a complete fix, because between starting to handle
the resume request and getting that PTRACE_CONTINUE, we run other
ptrace calls that can also fail with ESRCH, and that end up throwing
an error (with perror_with_name).
In the case above, I indeed sometimes see resume_stopped_resumed_lwps
fail in the registers read:
resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
{
...
CORE_ADDR pc = regcache_read_pc (regcache);
Or e.g., in 32-bit mode, i386_linux_resume has several calls that can
throw too.
Whether to ignore ptrace errors or not depends on context that is only
available somewhere up the call chain. So the fix is to let ptrace
errors throw as they do today, and wrap the resume request in a
TRY/CATCH that swallows it iff the lwp that we were trying to resume
is no longer ptrace-stopped.
gdb/gdbserver/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_resume_one_lwp): Rename to ...
(linux_resume_one_lwp_throw): ... this. Don't handle ESRCH here,
instead call perror_with_name.
(check_ptrace_stopped_lwp_gone): New function.
(linux_resume_one_lwp): Reimplement as wrapper around
linux_resume_one_lwp_throw that swallows errors if the LWP is
gone.
gdb/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-nat.c (linux_resume_one_lwp): Rename to ...
(linux_resume_one_lwp_throw): ... this. Don't handle ESRCH here,
instead call perror_with_name.
(check_ptrace_stopped_lwp_gone): New function.
(linux_resume_one_lwp): Reimplement as wrapper around
linux_resume_one_lwp_throw that swallows errors if the LWP is
gone.
(resume_stopped_resumed_lwps): Try register reads in TRY/CATCH and
swallows errors if the LWP is gone. Use
linux_resume_one_lwp_throw instead of linux_resume_one_lwp.
Wanting to make sure the new continue-pending-status.exp test tests
both cases of threads 2 and 3 reporting an event, I added counters to
the test, to make it FAIL if events for both threads aren't seen.
Assuming a well behaved backend, and given a reasonable number of
iterations, it should PASS.
However, running that against GNU/Linux gdbserver, I found that
surprisingly, that FAILed. GDBserver always reported the breakpoint
hit for the same thread.
Turns out that I broke gdbserver's thread event randomization
recently, with git commit 582511be ([gdbserver] linux-low.c: better
starvation avoidance, handle non-stop mode too). In that commit I
missed that the thread structure also has a status_pending_p field...
The end result was that count_events_callback always returns 0, and
then if no thread is stepping, select_event_lwp always returns the
event thread. IOW, no randomization is happening at all. Quite
curious how all the other changes in that patch were sufficient to fix
non-stop-fair-events.exp anyway even with that broken.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/gdbserver/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-low.c (count_events_callback, select_event_lwp_callback):
Use the lwp's status_pending_p field, not the thread's.
gdb/testsuite/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* gdb.threads/continue-pending-status.exp (saw_thread_2)
(saw_thread_3): New globals.
(top level): Increment them when an event for the corresponding
thread is seen.
(no thread starvation): New test.
If the linux_nat_resume's short-circuits the resume because the
current thread has a pending status, and, a thread with a higher
number was previously stopped for a breakpoint, GDB internal errors,
like:
/home/pedro/gdb/mygit/src/gdb/linux-nat.c:2590: internal-error: status_callback: Assertion `lp->status != 0' failed.
Fix this by make status_callback bail out earlier. GDBserver is
already doing the same.
New test added that exercises this.
gdb/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-nat.c (status_callback): Return early if the LWP has no
status pending.
gdb/testsuite/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* gdb.threads/continue-pending-status.c: New file.
* gdb.threads/continue-pending-status.exp: New file.
This function (in both GDB and GDBserver) used to consider only
SIGTRAP/breakpoint events, but that's no longer the case nowadays.
gdb/gdbserver/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-low.c (select_event_lwp_callback): Update comments to
no longer mention SIGTRAP.
gdb/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-nat.c (select_event_lwp_callback): Update comment to no
longer mention SIGTRAP.
Unwind info in system dlls uses almost all possible codes, contrary to unwind
info generated by gcc. A few issues have been discovered: incorrect handling
of SAVE_NONVOL opcodes and incorrect in prologue range checks. Furthermore I
added comments not to forget what has been investigated.
gdb/ChangeLog:
* amd64-windows-tdep.c (amd64_windows_find_unwind_info): Move
redirection code to ...
(amd64_windows_frame_decode_insns): ... Here. Fix in prologue
checks. Fix SAVE_NONVOL operations. Add debug code and comments.
This commit makes support for the "vFile:fstat" packet be detected
by probing rather than using qSupported, for consistency with the
other vFile: packets.
gdb/ChangeLog:
(remote_protocol_features): Remove the "vFile:fstat" feature.
(remote_hostio_fstat): Probe for "vFile:fstat" support.
gdb/doc/ChangeLog:
* gdb.texinfo (General Query Packets): Remove documentation
for now-removed vFile:fstat qSupported features.
gdb/gdbserver/ChangeLog:
* server.c (handle_query): Do not report vFile:fstat as supported.
Hi,
This patch is to support catch syscall on aarch64 linux. We
implement gdbarch method get_syscall_number for aarch64-linux,
and add aarch64-linux.xml file, which looks straightforward, however
the changes to test case doesn't.
First of all, we enable catch-syscall.exp on aarch64-linux target,
but skip the multi_arch testing on current stage. I plan to touch
multi arch debugging on aarch64-linux later.
Then, when I run catch-syscall.exp on aarch64-linux, gcc errors that
SYS_pipe isn't defined. We find that aarch64 kernel only has pipe2
syscall and libc already convert pipe to pipe2. As a result, I change
catch-syscall.c to use SYS_pipe if it is defined, otherwise use
SYS_pipe2 instead. The vector all_syscalls in catch-syscall.exp can't
be pre-determined, so I add a new proc setup_all_syscalls to fill it,
according to the availability of SYS_pipe.
Regression tested on {x86_64, aarch64}-linux x {native, gdbserver}.
gdb:
2015-03-18 Yao Qi <yao.qi@linaro.org>
PR tdep/18107
* aarch64-linux-tdep.c: Include xml-syscall.h
(aarch64_linux_get_syscall_number): New function.
(aarch64_linux_init_abi): Call
set_gdbarch_get_syscall_number.
* syscalls/aarch64-linux.xml: New file.
gdb/testsuite:
2015-03-18 Yao Qi <yao.qi@linaro.org>
PR tdep/18107
* gdb.base/catch-syscall.c [!SYS_pipe] (pipe2_syscall): New
variable.
* gdb.base/catch-syscall.exp: Don't skip it on
aarch64*-*-linux* target. Remove elements in all_syscalls.
(test_catch_syscall_multi_arch): Skip it on aarch64*-linux*
target.
(setup_all_syscalls): New proc.
Forward declarations of struct stat break the Windows build.
This commit removes a forward declaration of struct stat and
includes sys/stat.h directly instead.
gdb/ChangeLog:
PR gdb/18131
* common/common-remote-fileio.h (sys/stat.h): New include.
(stuct stat): Remove forward declaration.
Without this, not all registers were present in the core generated by
gcore. For example, running 'gcore' on a program without examining
the vector registers (SSE or AVX) would store all the vector registers
as zeros because they were not pulled into the regcache. Running
'info vector' before 'gcore' would store the correct values in the
core since it populated the regcache. For Linux processes, a similar
operation is achieved by having the thread iterator callback invoke
target_fetch_registers on each thread before its corresponding
register notes are dumped.
gdb/ChangeLog:
* fbsd-tdep.c (fbsd_make_corefile_notes): Fetch all target registers
before writing core register notes.
Fixes linking an --enable-build-with-cxx build on mingw:
../readline/terminal.c:278: undefined reference to `tgetnum'
../readline/terminal.c:297: undefined reference to `tgetnum'
../readline/libreadline.a(terminal.o): In function `get_term_capabilities':
../readline/terminal.c:427: undefined reference to `tgetstr'
../readline/libreadline.a(terminal.o): In function `_rl_init_terminal_io':
[etc.]
gdb/ChangeLog:
2015-03-16 Yuanhui Zhang <asmwarrior@gmail.com>
Pedro Alves <palves@redhat.com>
* gdb_curses.h (tgetnum): Mark with EXTERN_C.
* stub-termcap.c (tgetent, tgetnum, tgetflag, tgetstr, tputs)
(tgoto): Wrap with extern "C".
src/gdb/stub-termcap.c: In function 'int tputs(char*, int, int (*)())':
src/gdb/stub-termcap.c:67:22: error: too many arguments to function
outfun (*string++);
^
gdb/ChangeLog:
2015-03-16 Pedro Alves <palves@redhat.com>
Yuanhui Zhang <asmwarrior@gmail.com>
* stub-termcap.c (tputs): Change prototype.
Building mingw GDB with --enable-build-with-cxx shows:
../../binutils-gdb/gdb/windows-nat.c: At global scope:
../../binutils-gdb/gdb/windows-nat.c:192:1: error: conflicting declaration 'typedef struct thread_info_struct thread_info'
thread_info;
^
In file included from ../../binutils-gdb/gdb/windows-nat.c:52:0:
../../binutils-gdb/gdb/gdbthread.h:160:8: error: 'struct thread_info' has a previous declaration as 'struct thread_info'
struct thread_info
^
Simply rename the structure to avoid the conflict.
gdb/ChangeLog:
2015-03-16 Yuanhui Zhang <asmwarrior@gmail.com>
Pedro Alves <palves@redhat.com>
* windows-nat.c (struct thread_info_struct): Rename to ...
(struct windows_thread_info_struct): ... this.
(thread_info): Rename to ...
(windows_thread_info): ... this.
All users updated.
gdb/ChangeLog
2015-03-14 Jan Kratochvil <jan.kratochvil@redhat.com>
Pedro Alves <palves@redhat.com>
* NEWS: New Removed targets and native configurations.
IIUC it is a pre-requisite for IPv6 support, some UNICes do not support
getaddrinfo required for IPv6. But coincidentally such UNICes are no longer
really supported by GDB. Therefore it was concluded we can remove all such
UNICes and then we can implement IPv6 easily with getaddrinfo.
In mail
Re: getaddrinfo available on all GDB hosts? [Re: [PATCH v2] Add IPv6 support for remote TCP connections]
Message-ID: <20140211034157.GG5485@adacore.com>
https://sourceware.org/ml/gdb-patches/2014-02/msg00333.html
Joel said:
So I chose HP-UX first for this patch.
gdb/ChangeLog
2014-10-16 Jan Kratochvil <jan.kratochvil@redhat.com>
Remove HPUX.
* Makefile.in (ALL_64_TARGET_OBS): Remove ia64-hpux-tdep.o.
(ALL_TARGET_OBS): Remove hppa-hpux-tdep.o, solib-som.o and solib-pa64.o.
(HFILES_NO_SRCDIR): Remove solib-som.h, inf-ttrace.h, solib-pa64.h and
ia64-hpux-tdep.h, solib-ia64-hpux.h.
(ALLDEPFILES): Remove hppa-hpux-tdep.c, hppa-hpux-nat.c,
ia64-hpux-nat.c, ia64-hpux-tdep.c, somread.c and solib-som.c.
* config/djgpp/fnchange.lst: Remove hppa-hpux-nat.c and
hppa-hpux-tdep.c.
* config/ia64/hpux.mh: Remove file.
* config/pa/hpux.mh: Remove file.
* configure: Rebuilt.
* configure.ac (dlgetmodinfo, somread.o): Remove.
* configure.host (hppa*-*-hpux*, ia64-*-hpux*): Make them obsolete.
(ia64-*-hpux*): Remove its float format exception.
* configure.tgt (hppa*-*-hpux*, ia64-*-hpux*): Make them obsolete.
* hppa-hpux-nat.c: Remove file.
* hppa-hpux-tdep.c: Remove file.
* hppa-tdep.c (struct hppa_unwind_info, struct hppa_objfile_private):
Move them here from hppa-tdep.h
(hppa_objfile_priv_data, hppa_init_objfile_priv_data): Make it static.
(hppa_frame_prev_register_helper): Remove HPPA_FLAGS_REGNUM exception.
* hppa-tdep.h (struct hppa_unwind_info, struct hppa_objfile_private):
Move them to hppa-tdep.c.
(hppa_objfile_priv_data, hppa_init_objfile_priv_data): Remove
declarations.
* ia64-hpux-nat.c: Remove file.
* ia64-hpux-tdep.c: Remove file.
* ia64-hpux-tdep.h: Remove file.
* inf-ttrace.c: Remove file.
* inf-ttrace.h: Remove file.
* solib-ia64-hpux.c: Remove file.
* solib-ia64-hpux.h: Remove file.
* solib-pa64.c: Remove file.
* solib-pa64.h: Remove file.
* solib-som.c: Remove file.
* solib-som.h: Remove file.
* somread.c: Remove file.
Use kinfo_getvmmap from libutil on FreeBSD to enumerate memory
regions in a running process instead of /proc/<pid>/map. FreeBSD systems
do not mount procfs by default, but kinfo_getvmmap uses a sysctl that
is always available.
Skip memory regions for devices as well as regions an application has
requested to not be dumped via the MAP_NOCORE flag to mmap or
MADV_NOCORE advice to madvise.
gdb/ChangeLog:
* configure.ac: AC_CHECK_LIB(util, kinfo_getvmmap).
* configure: Regenerate.
* config.in: Regenerate.
* fbsd-nat.c [!HAVE_KINFO_GETVMMAP] (fbsd_read_mapping): Don't
define.
(fbsd_find_memory_regions): Use kinfo_getvmmap to
enumerate memory regions if present.
- Do not leave operators at end-of-line.
- Fix block indentation in if-else chain.
gdb/ChangeLog:
* amd64fbsd-tdep.c (amd64fbsd_sigtramp_p): Style fixes.
* i386fbsd-tdep.c: Fix style in various gdb_static_assert
expressions.
(i386fbsd_sigtramp_p): Likewise.
This commit creates the "set/show sysroot" commands using
add_setshow_optional_filename_cmd to allow the sysroot to
be restored to empty after being set.
gdb/ChangeLog:
* solib.c (_initialize_solib): Make "set/show sysroot" use
add_setshow_optional_filename_cmd so it can be restored to
empty after being set.
This commits cleans up the gdb/breakpoint.c file and moves everything
that is related to the 'catch syscall' command to the new file
gdb/break-catch-syscall.c. This is just code movement, and the only
new part is the adjustment needed on 'catching_syscall_number' to use
the new 'breakpoint_find_if' function insted of relying on the
ALL_BREAKPOINTS macro.
Tested by running the 'gdb.base/catch-syscall.exp' testcase.
gdb/ChangeLog:
2015-03-11 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (SFILES): New source break-catch-syscall.c.
(COMMON_OBS): New object break-catch-syscall.o.
* break-catch-syscall.c: New file.
* breakpoint.c: Remove inclusion of "xml-syscall.h".
(syscall_catchpoint_p): Move declaration to break-catch-syscall.c
(struct syscall_catchpoint): Likewise.
(dtor_catch_syscall): Likewise.
(catch_syscall_inferior_data): Likewise.
(struct catch_syscall_inferior_data): Likewise.
(get_catch_syscall_inferior_data): Likewise.
(catch_syscall_inferior_data_cleanup): Likewise.
(insert_catch_syscall): Likewise.
(remove_catch_syscall): Likewise.
(breakpoint_hit_catch_syscall): Likewise.
(print_it_catch_syscall): Likewise.
(print_one_catch_syscall): Likewise.
(print_mention_catch_syscall): Likewise.
(print_recreate_catch_syscall): Likewise.
(catch_syscall_breakpoint_ops): Likewise.
(syscall_catchpoint_p): Likewise.
(create_syscall_event_catchpoint): Likewise.
(catch_syscall_split_args): Likewise.
(catch_syscall_command_1): Likewise.
(is_syscall_catchpoint_enabled): Likewise.
(catch_syscall_enabled): Likewise.
(catching_syscall_number): Likewise.
(catch_syscall_completer): Likewise.
(clear_syscall_counts): Likewise.
(initialize_breakpoint_ops): Move initialization of syscall
catchpoints to break-catch-syscall.c.
(_initialize_breakpoint): Move code related to syscall catchpoints
to break-catch-syscall.c.
This commit implements the 'breakpoint_find_if' function, which allows
code external to gdb/breakpoint.c to iterate through the list of
'struct breakpoint *'. This is needed in order to create the
'gdb/break-catch-syscall.c' file, because one of its functions
(catching_syscall_number) needs to do this iteration.
My first thought was to share the ALL_BREAKPOINTS* macros on
gdb/breakpoint.h, but they use a global variable local to
gdb/breakpoint.c, and I did not want to share that variable. So, in
order to keep the minimal separation, I decided to implement this
way of iterating through the existing 'struct breakpoint *'.
This function was based on BFD's bfd_sections_find_if. If the
user-provided function returns 0, the iteration proceeds. Otherwise,
the iteration stops and the function returns the 'struct breakpoint *'
that is being processed. This means that the return value of this
function can be either NULL or a pointer to a 'struct breakpoint'.
gdb/ChangeLog:
2015-03-11 Sergio Durigan Junior <sergiodj@redhat.com>
* breakpoint.c (breakpoint_find_if): New function.
* breakpoint.h (breakpoint_find_if): New prototype.
This commit adds a new packet "vFile:fstat:" to the remote protocol
that can be used by to retrieve information about files that have
been previously opened using vFile:open. vFile:fstat: support is
added to GDB, and remote_bfd_iovec_stat is implemented using it. If
vFile:fstat: is not supported by the remote GDB creates a dummy result
by zeroing the supplied stat structure and setting its st_size field
to INT_MAX. This mimics GDB's previous behaviour, with the exception
that GDB did not previously zero the structure so all other fields
would have been returned unchanged, which is to say very likely
populated with random values from the stack.
gdb/ChangeLog:
* remote-fileio.h (remote_fileio_to_host_stat): New declaration.
* remote-fileio.c (remote_fileio_to_host_uint): New function.
(remote_fileio_to_host_ulong): Likewise.
(remote_fileio_to_host_mode): Likewise.
(remote_fileio_to_host_time): Likewise.
(remote_fileio_to_host_stat): Likewise.
* remote.c (PACKET_vFile_fstat): New enum value.
(remote_protocol_features): Register the "vFile:fstat" feature.
(remote_hostio_fstat): New function.
(remote_bfd_iovec_stat): Use the above.
(_initialize_remote): Register new "set/show remote
hostio-fstat-packet" command.
* symfile.c (separate_debug_file_exists): Update comment.
* NEWS: Announce new vFile:fstat packet.
gdb/doc/ChangeLog:
* gdb.texinfo (Remote Configuration): Document the
"set/show remote hostio-fstat-packet" command.
(General Query Packets): Document the vFile:fstat
qSupported features.
(Host I/O Packets): Document the vFile:fstat packet.
Re-registering a command will delete previous commands of the same name,
running the destroyer for the command object. The Guile destroyer
incorrectly tried to xfree the name and other strings, which is invalid
as they are on the GC heap.
gdb/ChangeLog:
* guile/scm-cmd.c (cmdscm_destroyer): Don't xfree the name and
other strings, as these are on the GC'd heap, and will be
collected along with the smob.
gdb/ChangeLog:
* guile/guile.c (_initialize_guile): Disable automatic
finalization, if Guile offers us that possibility.
* guile/guile.c (call_initialize_gdb_module):
* guile/scm-safe-call.c (gdbscm_with_catch): Arrange to run
finalizers in appropriate places.
* config.in (HAVE_GUILE_MANUAL_FINALIZATION): New definition.
* configure.ac (AC_TRY_LIBGUILE): Add a check for
scm_set_automatic_finalization_enabled.
* configure: Regenerated.
Instead of analyzing the prologue and possibly coming to a wrong
conclusion, this change tries to skip the prologue with the use of
skip_prologue_using_sal. Only if that fails, the prologue analyzer is
invoked as before.
gdb/ChangeLog:
* s390-linux-tdep.c (s390_skip_prologue): Skip the prologue using
SAL, if possible.
For multi-threaded inferiors on S390 GNU/Linux targets, GDB tried to
update the PER info via ptrace() in a newly attached thread before
assuring that the thread is stopped. Depending on the timing, this
could lead to a GDB internal error. The patch defers the PER info
update until just before resuming the thread.
gdb/ChangeLog:
* s390-linux-nat.c (struct arch_lwp_info): New.
(s390_fix_watch_points): Rename to...
(s390_prepare_to_resume): ...this. Skip the PER info update
unless the watch points have changed.
(s390_refresh_per_info, s390_new_thread): New functions.
(s390_insert_watchpoint): Call s390_refresh_per_info instead of
s390_fix_watch_points.
(s390_remove_watchpoint): Likewise.
(_initialize_s390_nat): Reflect renaming of s390_fix_watch_points.
Register s390_prepare_to_resume.
This reverts 366c75fc.
We don't actually need to access the object through
"struct sockaddr *", so we don't need the union:
https://sourceware.org/ml/gdb-patches/2015-03/msg00213.html
gdb/ChangeLog:
2015-03-09 Pedro Alves <palves@redhat.com>
Revert:
2015-03-07 Pedro Alves <palves@redhat.com>
* common/gdb_socket.h: New file.
* ser-tcp.c: Include gdb_socket.h. Don't include netinet/in.h nor
sys/socket.h.
(net_open): Use union gdb_sockaddr_u.
gdb/gdbserver/ChangeLog:
2015-03-09 Pedro Alves <palves@redhat.com>
Revert:
2015-03-07 Pedro Alves <palves@redhat.com>
* gdbreplay.c: No longer include <netinet/in.h>, <sys/socket.h>,
or <winsock2.h> here. Instead include "gdb_socket.h".
(remote_open): Use union gdb_sockaddr_u.
* remote-utils.c: No longer include <netinet/in.h>, <sys/socket.h>
or <winsock2.h> here. Instead include "gdb_socket.h".
(handle_accept_event, remote_prepare): Use union gdb_sockaddr_u.
* tracepoint.c: Include "gdb_socket.h" instead of <sys/socket.h>
or <sys/un.h>.
(init_named_socket, gdb_agent_helper_thread): Use union
gdb_sockaddr_u.
Whoops, these are C specific, but I somehow missed the warnings before:
cc1plus: warning: command line option ‘-Wmissing-prototypes’ is valid for C/ObjC but not for C++ [enabled by default]
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++ [enabled by default]
cc1plus: warning: command line option ‘-Wmissing-parameter-type’ is valid for C/ObjC but not for C++ [enabled by default]
cc1plus: warning: command line option ‘-Wold-style-declaration’ is valid for C/ObjC but not for C++ [enabled by default]
cc1plus: warning: command line option ‘-Wold-style-definition’ is valid for C/ObjC but not for C++ [enabled by default]
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* configure.ac (build_warnings): Move -Wmissing-prototypes
-Wdeclaration-after-statement -Wmissing-parameter-type
-Wold-style-declaration -Wold-style-definition to the C-specific
set.
* configure: Regenerate.
gdb/gdbserver/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* configure.ac (build_warnings): Move
-Wdeclaration-after-statement to the C-specific set.
* configure: Regenerate.
Building gdbserver in C++ mode shows:
gdb/gdbserver/tracepoint.c: In function ‘void* gdb_agent_helper_thread(void*)’:
gdb/gdbserver/tracepoint.c:7190:47: error: cannot convert ‘sockaddr_un*’ to ‘sockaddr*’ for argument ‘2’ to ‘int accept(int, sockaddr*, socklen_t*)’
fd = accept (listen_fd, &sockaddr, &tmp);
A few places in the tree already have an explicit cast to struct
sockaddr *, but that's a strict aliasing violation. Instead of
propagating invalid code, fix this by using a union instead.
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* common/gdb_socket.h: New file.
* ser-tcp.c: Include gdb_socket.h. Don't include netinet/in.h nor
sys/socket.h.
(net_open): Use union gdb_sockaddr_u.
gdb/gdbserver/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* gdbreplay.c: No longer include <netinet/in.h>, <sys/socket.h>,
or <winsock2.h> here. Instead include "gdb_socket.h".
(remote_open): Use union gdb_sockaddr_u.
* remote-utils.c: No longer include <netinet/in.h>, <sys/socket.h>
or <winsock2.h> here. Instead include "gdb_socket.h".
(handle_accept_event, remote_prepare): Use union gdb_sockaddr_u.
* tracepoint.c: Include "gdb_socket.h" instead of <sys/socket.h>
or <sys/un.h>.
(init_named_socket, gdb_agent_helper_thread): Use union
gdb_sockaddr_u.
Although the current TRY/CATCH implementation works in C++ mode too,
it relies on setjmp/longjmp, and longjmp bypasses calling the
destructors of objects on the stack, which is obviously bad for C++.
This patch fixes this by makes TRY/CATCH use real try/catch in C++
mode behind the scenes. The way this is done allows RAII and cleanups
to coexist while we phase out cleanups, instead of requiring a flag
day.
This patch is not strictly necessary until we require a C++ compiler
and start actually using RAII, though I'm all for baby steps, and it
shows my proposed way forward. Putting it in now, allows for easier
experimentation and exposure of potential problems with real C++
exceptions.
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* common/common-exceptions.c [!__cplusplus] (enum catcher_state)
(exceptions_state_mc_action_iter)
(exceptions_state_mc_action_iter_1, exceptions_state_mc_catch):
Don't define.
[__cplusplus] (try_scope_depth): New global.
[__cplusplus] (exception_try_scope_entry)
(exception_try_scope_exit, gdb_exception_sliced_copy)
(exception_rethrow): New functions.
(throw_exception): In C++ mode, throw
gdb_exception_RETURN_MASK_QUIT for RETURN_QUIT and
gdb_exception_RETURN_MASK_ERROR for RETURN_ERROR.
(throw_it): In C++ mode, use try_scope_depth.
* common/common-exceptions.h [!__cplusplus]
(exceptions_state_mc_action_iter)
(exceptions_state_mc_action_iter_1, exceptions_state_mc_catch):
Don't declare.
[__cplusplus] (exception_try_scope_entry)
(exception_try_scope_exit, exception_rethrow): Declare.
[__cplusplus] (struct exception_try_scope): New struct.
[__cplusplus] (TRY, CATCH, END_CATCH): Reimplement on top of real
C++ exceptions.
(struct gdb_exception_RETURN_MASK_ALL)
(struct gdb_exception_RETURN_MASK_ERROR)
(struct gdb_exception_RETURN_MASK_QUIT): New types.
After the previous patch, this is the last remaining use of a volatile
struct gdb_exception. Kill it, as it's troublesome for C++: we can't
assign volatile <-> non-volatile without copy constructors /
assignment operators that do that, which I'd rather avoid.
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* main.c (handle_command_errors): Remove volatile qualifier from
parameter.
All these were caught by actually making TRY/CATCH use try/catch
behind the scenes, which then resulted in the build failing (on x86_64
Fedora 20) because there was code between the try and catch blocks.
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* breakpoint.c (save_breakpoints): Adjust to avoid code between
TRY and CATCH.
* gdbtypes.c (safe_parse_type): Remove empty line.
(types_deeply_equal):
* guile/scm-frame.c (gdbscm_frame_name):
* linux-thread-db.c (find_new_threads_once):
* python/py-breakpoint.c (bppy_get_commands):
* record-btrace.c (record_btrace_insert_breakpoint)
(record_btrace_remove_breakpoint, record_btrace_start_replaying)
(record_btrace_start_replaying): Adjust to avoid code between TRY
and CATCH.
This patch splits the TRY_CATCH macro into three, so that we go from
this:
~~~
volatile gdb_exception ex;
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
}
if (ex.reason < 0)
{
}
~~~
to this:
~~~
TRY
{
}
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
~~~
Thus, we'll be getting rid of the local volatile exception object, and
declaring the caught exception in the catch block.
This allows reimplementing TRY/CATCH in terms of C++ exceptions when
building in C++ mode, while still allowing to build GDB in C mode
(using setjmp/longjmp), as a transition step.
TBC, after this patch, is it _not_ valid to have code between the TRY
and the CATCH blocks, like:
TRY
{
}
// some code here.
CATCH (ex, RETURN_MASK_ERROR)
{
}
END_CATCH
Just like it isn't valid to do that with C++'s native try/catch.
By switching to creating the exception object inside the CATCH block
scope, we can get rid of all the explicitly allocated volatile
exception objects all over the tree, and map the CATCH block more
directly to C++'s catch blocks.
The majority of the TRY_CATCH -> TRY+CATCH+END_CATCH conversion was
done with a script, rerun from scratch at every rebase, no manual
editing involved. After the mechanical conversion, a few places
needed manual intervention, to fix preexisting cases where we were
using the exception object outside of the TRY_CATCH block, and cases
where we were using "else" after a 'if (ex.reason) < 0)' [a CATCH
after this patch]. The result was folded into this patch so that GDB
still builds at each incremental step.
END_CATCH is necessary for two reasons:
First, because we name the exception object in the CATCH block, which
requires creating a scope, which in turn must be closed somewhere.
Declaring the exception variable in the initializer field of a for
block, like:
#define CATCH(EXCEPTION, mask) \
for (struct gdb_exception EXCEPTION; \
exceptions_state_mc_catch (&EXCEPTION, MASK); \
EXCEPTION = exception_none)
would avoid needing END_CATCH, but alas, in C mode, we build with C90,
which doesn't allow mixed declarations and code.
Second, because when TRY/CATCH are wired to real C++ try/catch, as
long as we need to handle cleanup chains, even if there's no CATCH
block that wants to catch the exception, we need for stop at every
frame in the unwind chain and run cleanups, then rethrow. That will
be done in END_CATCH.
After we require C++, we'll still need TRY/CATCH/END_CATCH until
cleanups are completely phased out -- TRY/CATCH in C++ mode will
save/restore the current cleanup chain, like in C mode, and END_CATCH
catches otherwise uncaugh exceptions, runs cleanups and rethrows, so
that C++ cleanups and exceptions can coexist.
IMO, this still makes the TRY/CATCH code look a bit more like a
newcomer would expect, so IMO worth it even if we weren't considering
C++.
gdb/ChangeLog.
2015-03-07 Pedro Alves <palves@redhat.com>
* common/common-exceptions.c (struct catcher) <exception>: No
longer a pointer to volatile exception. Now an exception value.
<mask>: Delete field.
(exceptions_state_mc_init): Remove all parameters. Adjust.
(exceptions_state_mc): No longer pop the catcher here.
(exceptions_state_mc_catch): New function.
(throw_exception): Adjust.
* common/common-exceptions.h (exceptions_state_mc_init): Remove
all parameters.
(exceptions_state_mc_catch): Declare.
(TRY_CATCH): Rename to ...
(TRY): ... this. Remove EXCEPTION and MASK parameters.
(CATCH, END_CATCH): New.
All callers adjusted.
gdb/gdbserver/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
Adjust all callers of TRY_CATCH to use TRY/CATCH/END_CATCH
instead.
More preparation for running the TRY_CATCH->TRY/CATCH conversion
script.
gdb/ChangeLog:
2015-03-07 Tom Tromey <tromey@redhat.com>
* top.c (quit_force): Inline and delete DO_TRY, DO_PRINT_EX.
This normalizes some exception catch blocks that check for ex.reason
to look like this:
~~~
volatile gdb_exception ex;
TRY_CATCH (ex, RETURN_MASK_ALL)
{
...
}
if (ex.reason < 0)
{
...
}
~~~
This is a preparation step for running a script that converts all
TRY_CATCH uses to look like this instead:
~~~
TRY
{
...
}
CATCH (ex, RETURN_MASK_ALL)
{
...
}
END_CATCH
~~~
The motivation for that change is being able to reimplent TRY/CATCH in
terms of C++ try/catch.
This commit makes it so that:
- no condition other than ex.reason < 0 is checked in the if
predicate
- there's no "else" block to check whether no exception was caught
- there's no code between the TRY_CATCH (TRY) block and the
'if (ex.reason < 0)' block (CATCH).
- the exception object is no longer referred to outside the if/catch
block. Note the local volatile exception objects that are
currently defined inside functions that use TRY_CATCH will
disappear. In cases it's more convenient to still refer to the
exception outside the catch block, a new non-volatile local is
added and copy to that object is made within the catch block.
The following patches should make this all clearer.
gdb/ChangeLog:
2015-03-07 Pedro Alves <palves@redhat.com>
* amd64-tdep.c (amd64_frame_cache, amd64_sigtramp_frame_cache)
(amd64_epilogue_frame_cache): Normal exception handling code.
* break-catch-throw.c (check_status_exception_catchpoint)
(re_set_exception_catchpoint): Ditto.
* cli/cli-interp.c (safe_execute_command):
* cli/cli-script.c (script_from_file): Ditto.
* compile/compile-c-symbols.c (generate_c_for_for_one_variable):
Ditto.
* compile/compile-object-run.c (compile_object_run): Ditto.
* cp-abi.c (baseclass_offset): Ditto.
* cp-valprint.c (cp_print_value): Ditto.
* exceptions.c (catch_exceptions_with_msg):
* frame-unwind.c (frame_unwind_try_unwinder): Ditto.
* frame.c (get_frame_address_in_block_if_available): Ditto.
* i386-tdep.c (i386_frame_cache, i386_epilogue_frame_cache)
(i386_sigtramp_frame_cache): Ditto.
* infcmd.c (post_create_inferior): Ditto.
* linespec.c (parse_linespec, find_linespec_symbols):
* p-valprint.c (pascal_object_print_value): Ditto.
* parse.c (parse_expression_for_completion): Ditto.
* python/py-finishbreakpoint.c (bpfinishpy_init): Ditto.
* remote.c (remote_get_noisy_reply): Ditto.
* s390-linux-tdep.c (s390_frame_unwind_cache): Ditto.
* solib-svr4.c (solib_svr4_r_map): Ditto.
This commit introduces a new inline common function "startswith"
which takes two string arguments and returns nonzero if the first
string starts with the second. It also updates the 295 places
where this logic was written out longhand to use the new function.
gdb/ChangeLog:
* common/common-utils.h (startswith): New inline function.
All places where this logic was used updated to use the above.
When we find out that a breakpoint is set on top of a program
breakpoint, we mark it as "permanent". E.g.,:
...
if (bp_loc_is_permanent (loc))
{
loc->inserted = 1;
loc->permanent = 1;
}
...
Note we didn't fill in the breakpoint's shadow (shadow_len remains 0).
In case the target claims support for evaluating breakpoint
conditions, GDB sometimes reinserts breakpoints that are already
inserted (to update the conditions on the target side). Since GDB
doesn't know whether the target supports evaluating conditions _of_
software breakpoints (vs hardware breakpoints, etc.) until it actually
tries it, if the target doesn't actually support z0 breakpoints, GDB
ends up reinserting a GDB-managed software/memory breakpoint
(mem-break.c).
And that is the case that is buggy: breakpoints that are marked
inserted contribute their shadows (if any) to the memory returned by
target_read_memory, to mask out breakpoints. Permanent breakpoints
are always marked as inserted. So if the permanent breakpoint doesn't
have a shadow yet in its shadow buffer, but we set shadow_len before
calling target_read_memory, then the still clear shadow_contents
buffer will be used by the breakpoint masking code... And then from
there on, the permanent breakpoint has a broken shadow buffer, and
thus any memory read out of that address will read bogus code, and
many random bad things fall out from that.
The fix is just to set shadow_len at the same time shadow_contents is
set, not one before and another after...
Fixes all gdb.base/bp-permanent.exp FAILs on PPC64 GNU/Linux gdbserver
and probably any other gdbserver port that doesn't do z0 breakpoints.
gdb/ChangeLog:
2015-03-05 Pedro Alves <palves@redhat.com>
PR gdb/18002
* mem-break.c (default_memory_insert_breakpoint): Set shadow_len
after reading the breakpoint's shadow memory.
record-btrace was the only target making use of this, and it no longer
uses it.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* target.h (struct target_ops) <to_decr_pc_after_break>: Delete.
(target_decr_pc_after_break): Delete declaration.
* target.c (default_target_decr_pc_after_break)
(target_decr_pc_after_break): Delete.
* linux-nat.c (check_stopped_by_breakpoint, linux_nat_wait_1): Use
gdbarch_decr_pc_after_break instead of target_decr_pc_after_break.
* linux-thread-db.c (check_event): Likewise.
* infrun.c (adjust_pc_after_break): Likewise.
* darwin-nat.c (cancel_breakpoint): Likewise.
* aix-thread.c (aix_thread_wait): Likewise.
* target-delegates.c: Regenerate.
This patch adjusts the native Linux target backend to tell the core
whether a trap was caused by a breakpoint.
It teaches the target to get that information out of the si_code of
the SIGTRAP siginfo.
Tested on x86-64 Fedora 20, s390 RHEL 7, and PPC64 Fedora 18. An
earlier version was tested on ARM Fedora 21.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* linux-nat.c (save_sigtrap): Check for breakpoints before
checking watchpoints.
(status_callback) [USE_SIGTRAP_SIGINFO]: Don't check whether a
breakpoint is inserted if relying on SIGTRAP's siginfo.si_code.
(check_stopped_by_breakpoint) [USE_SIGTRAP_SIGINFO]: Decide whether
a breakpoint triggered based on the SIGTRAP's siginfo.si_code.
(linux_nat_stopped_by_sw_breakpoint)
(linux_nat_supports_stopped_by_sw_breakpoint)
(linux_nat_stopped_by_hw_breakpoint)
(linux_nat_supports_stopped_by_hw_breakpoint): New functions.
(linux_nat_wait_1): Don't re-increment the PC if relying on
SIGTRAP's siginfo->si_code.
(linux_nat_add_target): Install new target methods.
* linux-thread-db.c (check_event): Don't account for breakpoint PC
offset if the target already adjusted the PC.
* nat/linux-ptrace.h (USE_SIGTRAP_SIGINFO): New.
(GDB_ARCH_TRAP_BRKPT): New.
(TRAP_HWBKPT): Define if not already defined.
This adjusts target remote to tell the core whether a trap was caused
by a breakpoint.
To that end, the patch teaches GDB about new RSP stop reasons "T05
swbreak" and "T05 hwbreak", that remote targets report back to GDB,
similarly to how "T05 watch" indicates a stop caused by a watchpoint.
Because targets that can report these events are expected to
themselves adjust the PC after a software breakpoint, these new stop
reasons must only be reported if the stub is talking to a GDB that
understands them. Because of that, the use of the new stop reasons
needs to be handshaked on initial connection, using the qSupported
mechanism. GDB simply sends "swbreak+" in its qSupports query, and
the stub reports back "swbreak+" too.
Because these new stop reasons are required to fix a fundamental
non-stop mode problem, this commit extends the remote non-stop intro
section in the manual, documenting the events as required.
To be clear, GDB will still cope with remote targets that don't
support these new stop reasons; it will behave just like today.
Tested on x86-64 Fedora 20, native and gdbserver.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* NEWS: Mention the new "swbreak" and "hwbreak" stop reasons.
* remote.c (struct remote_state) <remote_stopped_by_watchpoint_p>:
Delete field.
<stop_reason>: New field.
(PACKET_swbreak_feature, PACKET_hwbreak_feature): New enum values.
(packet_set_cmd_state): New function.
(remote_protocol_features): Register the "swbreak" and "hwbreak"
features.
(remote_query_supported): If not disabled with the corresponding
"set remote foo-packet" command, report support for the swbreak
and hwbreak features.
(struct stop_reply) <remote_stopped_by_watchpoint_p>: Delete
field.
<stop_reason>: New field.
(remote_parse_stop_reply): Handle "swbreak" and "hwbreak".
(remote_wait_as): Adjust.
(remote_stopped_by_sw_breakpoint)
(remote_supports_stopped_by_sw_breakpoint)
(remote_stopped_by_hw_breakpoint)
(remote_supports_stopped_by_hw_breakpoint): New functions.
(remote_stopped_by_watchpoint): New function.
(init_remote_ops): Install them.
(_initialize_remote): Register new "set/show remote
swbreak-feature-packet" and "set/show remote
swbreak-feature-packet" commands.
gdb/doc/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Remote Configuration): Document the "set/show
remote swbreak-feature-packet" and "set/show remote
hwbreak-feature-packet" commands.
(Packets) <Z0>: Add cross link to the "swbreak" stop reason's
decription.
(Stop Reply Packets): Document the swbreak and hwbreak stop
reasons.
(General Query Packets): Document the swbreak and hwbreak
qSupported features.
(Remote Non-Stop): Explain that swbreak and hwbreak are required.
This adjusts the record targets to tell the core whether a trap was
caused by a breakpoint. Targets that can do this should report
breakpoint traps with the PC already adjusted, so this removes the
re-incrementing record-full was doing.
These targets need to be adjusted before process_stratum targets
beneath are, otherwise target_supports_stopped_by_sw_breakpoint,
etc. would fall through to the target beneath while
recording/replaying, and the core would get confused.
Tested on x86-64 Fedora 20, native and gdbserver.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* btrace.h: Include target/waitstatus.h.
(struct btrace_thread_info) <stop_reason>: New field.
* record-btrace.c (record_btrace_step_thread): Use
record_check_stopped_by_breakpoint instead of breakpoint_here_p.
(record_btrace_decr_pc_after_break): Delete.
(record_btrace_stopped_by_sw_breakpoint)
(record_btrace_supports_stopped_by_sw_breakpoint)
(record_btrace_stopped_by_hw_breakpoint)
(record_btrace_supports_stopped_by_hw_breakpoint): New functions.
(init_record_btrace_ops): Install them.
* record-full.c (record_full_hw_watchpoint): Delete and replace
with ...
(record_full_stop_reason): ... this throughout.
(record_full_exec_insn): Adjust.
(record_full_wait_1): Adjust. No longer re-increment the PC.
(record_full_wait_1): Adjust. Use
record_check_stopped_by_breakpoint instead of breakpoint_here_p.
(record_full_stopped_by_watchpoint): Adjust.
(record_full_stopped_by_sw_breakpoint)
(record_full_supports_stopped_by_sw_breakpoint)
(record_full_supports_stopped_by_sw_breakpoint)
(record_full_stopped_by_hw_breakpoint)
(record_full_supports_stopped_by_hw_breakpoint): New functions.
(init_record_full_ops, init_record_full_core_ops): Install them.
* record.c (record_check_stopped_by_breakpoint): New function.
* record.h: Include target/waitstatus.h.
(record_check_stopped_by_breakpoint): New declaration.
The moribund locations heuristics are problematic. This patch teaches
GDB about targets that can reliably tell whether a trap was caused by
a software or hardware breakpoint, and thus don't need moribund
locations, thus bypassing all the problems that mechanism has.
The non-stop-fair-events.exp test is frequently failing currently.
E.g., see https://sourceware.org/ml/gdb-testers/2015-q1/msg03148.html.
The root cause is a fundamental problem with moribund locations. For
example, the stepped_breakpoint logic added by af48d08f breaks in this
case (which is what happens with that test):
- Step thread A, no breakpoint is set at PC.
- The kernel doesn't schedule thread A yet.
- Insert breakpoint at A's PC, for some reason (e.g., a step-resume
breakpoint for thread B).
- Kernel finally schedules thread A.
- thread A's stepped_breakpoint flag is not set, even though it now
stepped a breakpoint instruction.
- adjust_pc_after_break gets the PC wrong, because PC == PREV_PC, but
stepped_breakpoint is not set.
We needed the stepped_breakpoint logic to workaround moribund
locations, because otherwise adjust_pc_after_break could apply an
adjustment when it shouldn't just because there _used_ to be a
breakpoint at PC (a moribund breakpoint location). For example, on
x86, that's wrong if the thread really hasn't executed an int3, but
instead executed some other 1-byte long instruction. Getting the PC
adjustment wrong of course leads to the inferior executing the wrong
instruction.
Other problems with moribund locations are:
- if a true SIGTRAP happens to be raised when the program is
executing the PC that used to have a breakpoint, GDB will assume
that is a trap for a breakpoint that has recently been removed, and
thus we miss reporting the random signal to the user.
- to minimize that, we get rid of moribund location after a while.
That while is defined as just a certain number of events being
processed. That number of events sometimes passes by before a
delayed breakpoint is processed, and GDB confuses the trap for a
random signal, thus reporting the random trap. Once the user
resumes the thread, the program crashes because the PC was not
adjusted...
The fix for all this is to bite the bullet and get rid of heuristics
and instead rely on the target knowing accurately what caused the
SIGTRAP. The target/kernel/stub is in the best position to know what
that, because it can e.g. consult priviledged CPU flags GDB has no
access to, or by knowing which exception vector entry was called when
the instruction trapped, etc. Most debug APIs I've seen to date
report breakpoint hits as a distinct event in some fashion. For
example, on the Linux kernel, whether a breakpoint was executed is
exposed to userspace in the si_code field of the SIGTRAP's siginfo.
On Windows, the debug API reports a EXCEPTION_BREAKPOINT exception
code.
We needed to keep around deleted breakpoints in an on-the-side list
(the moribund locations) for two main reasons:
- Know that a SIGTRAP actually is a delayed event for a hit of a
breakpoint that was removed before the event was processed, and
thus should not be reported as a random signal.
- So we still do the decr_pc_after_break adjustment in that case, so
that the thread is resumed at the correct address.
In the new model, if GDB processes an event the target tells is a
breakpoint trap, and GDB doesn't find the corresponding breakpoint in
its breakpoint tables, it means that event is a delayed event for a
breakpoint that has since been removed, and thus the event should be
ignored.
For the decr_pc_after_after issue, it ends up being much simpler that
on targets that can reliably tell whether a breakpoint trapped, for
the breakpoint trap to present the PC already adjusted. Proper
multi-threading support already implies that targets needs to be doing
decr_pc_after_break adjustment themselves, otherwise for example, in
all-stop if two threads hit a breakpoint simultaneously, and the user
does "info threads", he'll see the non-event thread that hit the
breakpoint stopped at the wrong PC.
This way (target adjusts) also ends up eliminating the need for some
awkward re-incrementing of the PC in the record-full and Linux targets
that we do today, and the need for the target_decr_pc_after_break
hook.
If the target always adjusts, then there's a case where GDB needs to
re-increment the PC. Say, on x86, an "int3" instruction that was
explicitly written in the program traps. In this case, GDB should
report a random SIGTRAP signal to the user, with the PC pointing at
the instruction past the int3, just like if GDB was not debugging the
program. The user may well decide to pass the SIGTRAP to the program
because the program being debugged has a SIGTRAP handler that handles
its own breakpoints, and expects the PC to be unadjusted.
Tested on x86-64 Fedora 20.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* breakpoint.c (need_moribund_for_location_type): New function.
(bpstat_stop_status): Don't skipping checking moribund locations
of breakpoint types which the target tell caused a stop.
(program_breakpoint_here_p): New function, factored out from ...
(bp_loc_is_permanent): ... this.
(update_global_location_list): Don't create a moribund location if
the target supports reporting stops of the type of the removed
breakpoint.
* breakpoint.h (program_breakpoint_here_p): New declaration.
* infrun.c (adjust_pc_after_break): Return early if the target has
already adjusted the PC. Add comments.
(handle_signal_stop): If nothing explains a signal, and the target
tells us the stop was caused by a software breakpoint, check if
there's a breakpoint instruction in the memory. If so, adjust the
PC before presenting the stop to the user. Otherwise, ignore the
trap. If nothing explains a signal, and the target tells us the
stop was caused by a hardware breakpoint, ignore the trap.
* target.h (struct target_ops) <to_stopped_by_sw_breakpoint,
to_supports_stopped_by_sw_breakpoint, to_stopped_by_hw_breakpoint,
to_supports_stopped_by_hw_breakpoint>: New fields.
(target_stopped_by_sw_breakpoint)
(target_supports_stopped_by_sw_breakpoint)
(target_stopped_by_hw_breakpoint)
(target_supports_stopped_by_hw_breakpoint): Define.
* target-delegates.c: Regenerate.
This Linuxism has made its way into infrun.c, in the follow-fork code:
inferior_ptid = ptid_build (child_pid, child_pid, 0);
The OS-specific code should fill in the LWPID, TID parts with the
appropriate values, if any, and the core code should not be peeking at
the components of the ptids.
gdb/
2015-03-04 Pedro Alves <palves@redhat.com>
* infrun.c (follow_fork_inferior): Use the whole of the
inferior_ptid and pending_follow.related_pid ptids instead of
building ptids from the process components. Adjust verbose output
to use target_pid_to_str.
* linux-nat.c (linux_child_follow_fork): Use the whole of the
inferior_ptid and pending_follow.related_pid ptids instead of
building ptids from the process components.