This patch fixes imbalanced lwp_suspend/unsuspend calls caused by the
premature choosing of another event for fairness.
select_event_lwp would switch the event before a call to
unsuspend_all_lwps, thus it would be called with the wrong event.
This caused an assertion failure: unsuspend LWP xx, suspended=-1 when
testing gdb.threads/non-stop-fair-events.exp with ARM range stepping in
GDBServer.
This patch moves the switch of event after the unsuspend/unstop calls.
No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-native.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_wait_1): Move event switch after unsuspend_lwps.
GLIBC BZ#20311 [1] proc_service.h install patch also remove 'const'
attributes from ps_get_thread_area and comment #15 discuss why to remove
the const attribute (basically since it a callback with the struct
ps_prochandle owned by the client it should be able to modify it if
it the case).
On default build this is not the issue and current g++ does not trigger
any issue with this mismatch declaration. However, on some bootstrap
build configuration where gdbserver is build with gcc instead this
triggers:
error: conflicting types for 'ps_get_thread_area'
This patch fixes it by syncing the declaration with GLIBC.
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=20311
gdb/ChangeLog:
2016-08-25 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* aarch64-linux-nat.c (ps_get_thread_area): Remove const from
struct ps_prochandle.
* amd64-linux-nat.c (ps_get_thread_area): Likewise.
* arm-linux-nat.c (ps_get_thread_area): Likewise.
* gdb_proc_service.h (ps_get_thread_area): Likewise.
* i386-linux-nat.c (ps_get_thread_area): Likewise.
* m68klinux-nat.c (ps_get_thread_area): Likewise.
* mips-linux-nat.c (ps_get_thread_area): Likewise.
* nat/aarch64-linux.c (aarch64_ps_get_thread_area): Likewise.
* nat/aarch64-linux.h (aarch64_ps_get_thread_area): Likewise.
* xtensa-linux-nat.c (ps_get_thread_area): Likewise.
gdb/gdbserver/ChangeLog:
2016-08-25 Adhemerval Zanella <adhemerval.zanella@linaro.org>
PR server/20491
* gdb_proc_service.h (ps_get_thread_area): Remove const from struct
ps_prochandle.
* linux-aarch64-low.c (ps_get_thread_area): Likewise.
* linux-arm-low.c (ps_get_thread_area): Likewise.
* linux-crisv32-low.c (ps_get_thread_area): Likewise.
* linux-m68k-low.c (ps_get_thread_area): Likewise.
* linux-mips-low.c (ps_get_thread_area): Likewise.
* linux-nios2-low.c (ps_get_thread_area): Likewise.
* linux-tic6x-low.c (ps_get_thread_area): Likewise.
* linux-x86-low.c (ps_get_thread_area): Likewise.
* linux-xtensa-low.c (ps_get_thread_area): Likewise.
Running fast tracepoint tests on x32 exposes a latent bug in the agent
bytecode jitting. There's a code path that forgets to emit the call
opcode... Whoops. Fixes a bunch of gdb.trace/trace-condition.exp
FAILs, like:
(gdb)
continue
Continuing.
Thread 1 "trace-condition" received signal SIGSEGV, Segmentation fault.
0x7ffec016 in ?? ()
(gdb) FAIL: gdb.trace/trace-condition.exp: ftrace: $rip == *set_point: advance through tracing
gdb/gdbserver/ChangeLog:
2016-08-19 Pedro Alves <palves@redhat.com>
* linux-x86-low.c (amd64_emit_call): Emit missing call opcode.
We're casting through unsigned long to write a 64-bit immediate
operand of movabs (the comment said movl, but that was incorrect).
The problem is that unsigned long is 32-bit on x32, so we were writing
fewer bytes than necessary.
Fix this by using an 8 byte memcpy like in other similar places in the
function.
gdb/gdbserver/ChangeLog:
2016-08-19 Pedro Alves <palves@redhat.com>
* linux-x86-low.c (amd64_install_fast_tracepoint_jump_pad): Fix
comment. Use memcpy instead of casting through unsigned long.
MAP_32BIT is ignored on x32, meaning the jump pad can end up somewhere
between 2GB and 4GB, too far away from the executable for 5-byte
relative jumps (JMP rel32). So on x32, try explicitly placing the
jump pad near the middle of the available address space.
gdb/gdbserver/ChangeLog:
2016-08-19 Pedro Alves <palves@redhat.com>
* linux-amd64-ipa.c (alloc_jump_pad_buffer) [__ILP32__]: Try
allocating around 0x80000000.
Building GDB for x32 fails building the IPA, with:
.../src/gdb/gdbserver/linux-amd64-ipa.c: In function ‘const target_desc* get_ipa_tdesc(int)’:
.../src/gdb/gdbserver/linux-amd64-ipa.c:182:14: error: ‘tdesc_amd64_avx_linux’ was not declared in this scope
return tdesc_amd64_avx_linux;
^
.../src/gdb/gdbserver/linux-amd64-ipa.c:184:14: error: ‘tdesc_amd64_mpx_linux’ was not declared in this scope
return tdesc_amd64_mpx_linux;
^
.../src/gdb/gdbserver/linux-amd64-ipa.c:186:14: error: ‘tdesc_amd64_avx_mpx_linux’ was not declared in this scope
return tdesc_amd64_avx_mpx_linux;
^
[...]
The problem is that the IPA is trying to use the 64-bit descriptions,
when it should be using the x32 ones.
gdb/gdbserver/ChangeLog:
2016-08-19 Pedro Alves <palves@redhat.com>
PR gdb/20415
* Makefile.in (x32-linux-ipa.o, x32-avx-linux-ipa.o)
(x32-avx512-linux-ipa.o): New rules.
* configure.ac (x86_64-*-linux*): New x32 check.
* configure.srv (ipa_x32_linux_regobj): New.
(x86_64-*-linux*): Use $ipa_x32_linux_regobj if building for x32.
* linux-amd64-ipa.c (get_ipa_tdesc) [__ILP32__]: Return x32
descriptions.
(initialize_low_tracepoint) [__ILP32__]: Initialize x32
descriptions.
* configure: Regenerate.
gdb's (or gdbserver's) own signal handling should not interfere with
the signal dispositions their spawned children inherit. However, it
currently does. For example, some paths in gdb cause SIGPIPE to be
set to SIG_IGN, and as consequence, the child starts with SIGPIPE to
set to SIG_IGN too, even though gdb was started with SIGPIPE set to
SIG_DFL.
This is because the exec family of functions does not reset the signal
disposition of signals that are set to SIG_IGN:
http://pubs.opengroup.org/onlinepubs/7908799/xsh/execve.html
Signals set to the default action (SIG_DFL) in the calling process
image are set to the default action in the new process
image. Signals set to be ignored (SIG_IGN) by the calling process
image are set to be ignored by the new process image. Signals set to
be caught by the calling process image are set to the default action
in the new process image (see <signal.h>).
And neither does it reset signal masks or flags.
In order to be transparent, when spawning new child processes to debug
(with "run", etc.), reset signal actions and mask back to what was
originally inherited from gdb/gdbserver's parent, just before execing
the target program to debug.
gdb/ChangeLog:
2016-08-09 Pedro Alves <palves@redhat.com>
PR gdb/18653
* Makefile.in (SFILES): Add
common/signals-state-save-restore.c.
(HFILES_NO_SRCDIR): Add common/signals-state-save-restore.h.
(COMMON_OBS): Add signals-state-save-restore.o.
(signals-state-save-restore.o): New rule.
* configure: Regenerate.
* fork-child.c: Include "signals-state-save-restore.h".
(fork_inferior): Call restore_original_signals_state.
* main.c: Include "signals-state-save-restore.h".
(captured_main): Call save_original_signals_state.
* common/common.m4: Add sigaction to AC_CHECK_FUNCS checks.
* common/signals-state-save-restore.c: New file.
* common/signals-state-save-restore.h: New file.
gdb/gdbserver/ChangeLog:
2016-08-09 Pedro Alves <palves@redhat.com>
PR gdb/18653
* Makefile.in (OBS): Add signals-state-save-restore.o.
(signals-state-save-restore.o): New rule.
* config.in: Regenerate.
* configure: Regenerate.
* linux-low.c: Include "signals-state-save-restore.h".
(linux_create_inferior): Call
restore_original_signals_state.
* server.c: Include "dispositions-save-restore.h".
(captured_main): Call save_original_signals_state.
gdb/testsuite/ChangeLog:
2016-08-09 Pedro Alves <palves@redhat.com>
PR gdb/18653
* gdb.base/signals-state-child.c: New file.
* gdb.base/signals-state-child.exp: New file.
* gdb.gdb/selftest.exp (do_steps_and_nexts): Add new pattern.
We build by default with a C++ compiler, but "configure --help" still
says "--enable-build-with-cxx", which hints that it is by default
disabled. Update the --help text.
gdb/ChangeLog:
2016-08-05 Pedro Alves <palves@redhat.com>
* build-with-cxx.m4: Change help string to be in terms of
--disable-build-with-cxx.
* configure: Regenerate.
gdb/gdbserver/ChangeLog:
2016-08-05 Pedro Alves <palves@redhat.com>
* configure: Regenerate.
When I run process-dies-while-detaching.exp with GDBserver, I see many
warnings printed by GDBserver,
ptrace(regsets_fetch_inferior_registers) PID=26183: No such process
ptrace(regsets_fetch_inferior_registers) PID=26183: No such process
ptrace(regsets_fetch_inferior_registers) PID=26184: No such process
ptrace(regsets_fetch_inferior_registers) PID=26184: No such process
regsets_fetch_inferior_registers is called when GDBserver resumes each
lwp.
#2 0x0000000000428260 in regsets_fetch_inferior_registers (regsets_info=0x4690d0 <aarch64_regsets_info>, regcache=0x31832020)
at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:5412
#3 0x00000000004070e8 in get_thread_regcache (thread=0x31832940, fetch=fetch@entry=1) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/regcache.c:58
#4 0x0000000000429c40 in linux_resume_one_lwp_throw (info=<optimized out>, signal=0, step=0, lwp=0x31832830)
at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4463
#5 linux_resume_one_lwp (lwp=0x31832830, step=<optimized out>, signal=<optimized out>, info=<optimized out>)
at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4573
The is the case that threads are disappeared when GDB/GDBserver resumes
them. We check errno for ESRCH, and don't print error messages, like
what we are doing in regsets_store_inferior_registers.
gdb/gdbserver:
2016-08-04 Yao Qi <yao.qi@linaro.org>
* linux-low.c (regsets_fetch_inferior_registers): Check
errno is ESRCH or not.
As a result of this commit,
9b4c5f878f
(Remove support for thread events without PTRACE_EVENT_CLONE in GDBServer.)
the last usage of td_ta_event_addr td_ta_set_event and
td_ta_event_getmsg were removed. They are no longer used. This patch
is to remove them.
gdb/gdbserver:
2016-08-02 Yao Qi <yao.qi@linaro.org>
* thread-db.c (struct thread_db) <td_ta_event_getmsg_p>: Remove.
<td_ta_set_event_p, td_ta_event_addr_p>: Remove.
(thread_db_load_search): Update.
(try_thread_db_load_1): Don't look for td_ta_event_addr,
td_ta_set_event and td_ta_event_getmsg.
Debugging an x32 process with an x32 gdbserver always results in:
(gdb) c
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0xf7de9600 in _dl_debug_state () from target:/libx32/ld-linux-x32.so.2
(gdb)
Looking at the remote debug logs reveals the problem, here:
Packet received: T05swbreak:;06:a0d4ffff00000000;07:b8d3ffff00000000;10:0096def701000000;thread:p7d7a.7d7a;core:1;
^^^^^^^^^^^^^^^^
The underlined value is the expedited value of RIP (in little endian).
But notice that 01 in 0x01f7de9600, while gdb says the program stopped
at 0xf7de9600. 0x01ffffffff is over 32 bits, which indicates that
something wen't wrong somewhere in gdbserver.
The problem turns out to be in gdbserver's x86_get_pc / x86_set_pc
routines, where "unsigned long" is used assuming that it can fit a
64-bit value, while unsigned long is actually 32-bit on x32. The
result is that collect_register_by_name / supply_register_by_name end
up reading/writing random bytes off the stack.
Fix this by using explicit uint64_t instead of unsigned long.
For consistency, use uint32_t instead of unsigned int in the 32-bit
paths.
gdb/gdbserver/ChangeLog:
2016-07-26 Pedro Alves <palves@redhat.com>
PR server/20414
* linux-x86-low.c (x86_get_pc, x86_set_pc): Use uint64_t instead
of unsigned long for 64-bit registers and use uint32_t instead of
unsigned int for 32-bit registers.
Building an x32 gdb trips on a static assertion:
In file included from .../src/gdb/common/common-defs.h:71:0,
from .../src/gdb/nat/amd64-linux-siginfo.c:21:
.../src/gdb/common/gdb_assert.h:26:66: error: size of array ‘never_defined_just_used_for_checking’ is negative
extern int never_defined_just_used_for_checking[(expr) ? 1 : -1]
^
.../src/gdb/nat/amd64-linux-siginfo.c:113:1: note: in expansion of macro ‘gdb_static_assert’
gdb_static_assert (sizeof (nat_siginfo_t) == sizeof (siginfo_t));
^
The problem is that the way nat_siginfo_t is defined, it can only
match the host's siginfo_t object when gdb is built as a 64-bit
program.
Several bits of nat_siginfo_t are off:
- nat_siginfo_t's _pad field's definition is:
int _pad[((128 / sizeof (int)) - 4)];
while /usr/include/bits/siginfo.h has:
# define __SI_MAX_SIZE 128
# if __WORDSIZE == 64
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 4)
# else
# define __SI_PAD_SIZE ((__SI_MAX_SIZE / sizeof (int)) - 3)
# endif
and __WORDSIZE == 32 for x32. This is what causes the size of
nat_siginfo_t to be wrong and the assertion to fail.
- the nat_clock_t type is incorrect for 64-bit. We have this:
/* For native 64-bit, clock_t in _sigchld is 64bit aligned at 4 bytes. */
typedef long __attribute__ ((__aligned__ (4))) nat_clock_t;
however, /usr/include/bits/siginfo.h has:
# if defined __x86_64__ && __WORDSIZE == 32
/* si_utime and si_stime must be 4 byte aligned for x32 to match the
kernel. We align siginfo_t to 8 bytes so that si_utime and si_stime
are actually aligned to 8 bytes since their offsets are multiple of
8 bytes. */
typedef __clock_t __attribute__ ((__aligned__ (4))) __sigchld_clock_t;
# define __SI_ALIGNMENT __attribute__ ((__aligned__ (8)))
# else
typedef __clock_t __sigchld_clock_t;
# define __SI_ALIGNMENT
# endif
So we're currently forcing 4-byte alignment on clock_t, when it
should only be so for x32, not 64-bit.
The fix:
- Leaves nat_siginfo_t strictly for the 64-bit ABI.
- Adds a new typedef for the siginfo type that ptrace uses
(ptrace_siginfo_t). An x32 gdb always gets/sets an x32 siginfo_t
type with PTRACE_GETSIGINFO/PTRACE_SETSIGINFO.
- Uses this new ptrace_siginfo_t type instead of nat_siginfo_t as the
intermediate conversion type.
gdb/ChangeLog:
2016-07-26 Pedro Alves <palves@redhat.com>
* amd64-linux-nat.c (amd64_linux_siginfo_fixup): Rename 'native'
parameter to 'ptrace'.
* nat/amd64-linux-siginfo.c (GDB_SI_SIZE): New define.
(nat_uptr_t): New an unsigned long.
(nat_clock_t): Remove attribute __aligned__.
(struct nat_timeval): Delete.
(nat_siginfo_t): Remove attribute __aligned__.
(ptrace_siginfo_t): Define.
(compat_siginfo_from_siginfo, siginfo_from_compat_siginfo)
(compat_x32_siginfo_from_siginfo)
(siginfo_from_compat_x32_siginfo): Make 'from' parameter const.
Convert through a ptrace_siginfo_t instead of a nat_siginfo_t.
Remove casts.
(amd64_linux_siginfo_fixup_common): Rename 'native' parameter to
'ptrace'. Remove static assertions.
(top level): New static assertions.
gdb/gdbserver/ChangeLog:
2016-07-26 Pedro Alves <palves@redhat.com>
* linux-x86-low.c (x86_siginfo_fixup): Rename 'native' parameter
to 'ptrace'.
GDBserver with software single step should be able to claim supporting
vCont s and S actions, so that GDB knows the remote target can do
single step. It doesn't matter to GDB that the single step in the
remote target is done via hardware or software.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* server.c (handle_v_requests): Support s and S actions
if target_supports_software_single_step return true.
This patch is to teach GDBserver using software single step to handle
vCont;s. Simply speaking, if the thread's resume request is resume_step,
install reinsert breakpoint at the next pcs when GDBserver is about to
resume threads. These reinsert breakpoints of a thread are removed,
when GDBserver gets an event from that thread and reports it back to
GDB.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* linux-low.c (resume_stopped_resumed_lwps): If resume request
is resume_step, call maybe_hw_step.
(linux_wait_1): Stop all threads, remove reinsert breakpoints,
and unstop them.
(linux_resume_one_lwp_throw): Don't assert the thread has reinsert
breakpoints or not.
(proceed_one_lwp): If resume request is resume_step, install
reinsert breakpoints and call maybe_hw_step.
Nowadays, we only enqueue signal when we leave thread pending in
linux_resume_one_thread. If lwp->resume->sig isn't zero (GDB wants
to resume with signal), we pass lwp->resume->sig to
linux_resume_one_lwp.
In order to reduce the difference between resuming thread with signal
and proceeding thread with signal, when we resume thread, we can
enqueue signal too, and proceed thread. The signal will be consumed in
linux_resume_one_lwp_throw from lwp->pending_signals.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* linux-low.c (proceed_one_lwp): Declare.
(linux_resume_one_thread): Remove local variable 'step'.
Lift code enqueue signal. Call proceed_one_lwp instead of
linux_resume_one_lwp.
install_software_single_step_breakpoints has parameter lwp, but still
need to switch to current_thread. In order to simplify its caller,
we do the current_thread save/restore inside install_software_single_step_breakpoints.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* gdbthread.h (make_cleanup_restore_current_thread): Declare.
* inferiors.c (do_restore_current_thread_cleanup): New function.
(make_cleanup_restore_current_thread): Likewise.
* linux-low.c (install_software_single_step_breakpoints): Call
make_cleanup_restore_current_thread. Switch current_thread to
thread.
This patch makes reinsert_breakpoint thread specific, which means we
insert and remove reinsert_breakpoint breakpoints for a specific
thread. This motivation of this change is that I'll use
reinsert_breakpoint for vCont;s on software single step target, so that
GDBserver may insert one reinsert_breakpoint for one thread doing
step-over, and insert one reinsert_breakpoint for another thread doing
vCont;s. After the operation of one thread is finished, GDBserver must
remove reinsert_breakpoint for that thread only.
On the other hand, reinsert_breakpoint is used for step-over nowadays.
GDBserver inserts reinsert_breakpoint, and wait only from the thread
doing step-over. After the step-over is done, GDBserver removes the
reinsert_breakpoint. If there is still any threads need step-over, do
the same again until all threads are finished step-over. In other words,
reinsert_breakpoint is globally thread specific, but in an implicit way.
It is natural to make it explicitly thread specific.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* mem-break.c (struct reinsert_breakpoint) <ptid>: New field.
(set_reinsert_breakpoint): New parameter ptid. Callers updated.
(clone_one_breakpoint): Likewise.
(delete_reinsert_breakpoints): Change parameter to thread.
Callers updated.
(has_reinsert_breakpoints): Likewise.
(uninsert_reinsert_breakpoints): Likewise.
(reinsert_reinsert_breakpoints): Likewise.
* mem-break.h (set_reinsert_breakpoint): Update declaration.
(delete_reinsert_breakpoints): Likewise.
(reinsert_reinsert_breakpoints): Likewise.
(uninsert_reinsert_breakpoints): Likewise.
(has_reinsert_breakpoints): Likewise.
This patch is to change the interface of clone_all_breakpoints, from
lists of breakpoints and raw_breakpoints to child thread and parent
thread. I choose child thread to pass because we need the ptid of
the child thread in the following patch.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* inferiors.c (get_thread_process): Make parameter const.
* inferiors.h (get_thread_process): Update declaration.
* mem-break.c (clone_all_breakpoints): Remove all parameters.
Add new parameters child_thread and parent_thread. Callers
updated.
* mem-break.h (clone_all_breakpoints): Update declaration.
Nowadays, there are three types of breakpoint in GDBserver,
- gdb breakpoints,
- reinsert breakpoints, used for software single step,
- other breakpoints, used for tracepoint,
but we only have one 'struct breakpoint' for all of them. Some fields
are only useful to one type of breakpoint. For example, cond_list
and command_list are only used by gdb breakpoints, while handler is
only used by other breakpoints.
This patch changes 'struct breakpoint' to a base class, which has fields
needed by all breakpoint types, also add three sub-classes to
'struct breakpoint' to these three types of breakpoints.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* mem-break.c (struct breakpoint) <cond_list>: Remove.
<command_list, handler>: Remove.
(struct gdb_breakpoint): New.
(struct other_breakpoint): New.
(struct reinsert_breakpoint): New.
(is_gdb_breakpoint): New function.
(any_persistent_commands): Update command_list if
is_gdb_breakpoint returns true.
(set_breakpoint): Create breakpoints according to their types.
(find_gdb_breakpoint): Return 'struct gdb_breakpoint *'.
(set_gdb_breakpoint_1): Likewise.
(set_gdb_breakpoint): Likewise.
(clear_breakpoint_conditions): Change parameter type to
'struct gdb_breakpoint *'.
(clear_breakpoint_commands): Likewise.
(clear_breakpoint_conditions_and_commands): Likewise.
(add_condition_to_breakpoint): Likewise.
(add_breakpoint_condition): Likewise.
(add_commands_to_breakpoint): Likewise.
(check_breakpoints): Check other_breakpoint.
(clone_one_breakpoint): Clone breakpopint according to its type.
* mem-break.h (struct gdb_breakpoint): Declare.
(set_gdb_breakpoint): Update declaration.
(clear_breakpoint_conditions_and_commands): Likewise.
(add_breakpoint_condition): Likewise.
(add_breakpoint_commands): Likewise.
* server.c (process_point_options): Change parameter type to
'struct gdb_breakpoint *'.
Nowadays, set_breakpoint_at creates breakpoint of type
other_breakpoint, but we also use set_breakpoint_at
in set_reinsert_breakpoint to create breakpoint, so that
we have to overwrite the breakpoint type like this,
bp = set_breakpoint_at (stop_at, NULL);
bp->type = reinsert_breakpoint;
which looks not very good. This patch changes set_breakpoint_at
to receive breakpoint type. Since set_breakpoint_at is
used in many places, I rename it to set_breakpoint_type_at, and wrap
it with set_breakpoint_at, and pass other_breakpoint. In this way,
we can call set_breakpoint_type_at with reinsert_breakpoint in
set_reinsert_breakpoint too, and code looks cleaner.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* mem-break.c (set_breakpoint_at): Rename it to ...
(set_breakpoint_type_at): ... it.
(set_breakpoint_at): Call set_breakpoint_type_at.
(set_reinsert_breakpoint): Call set_breakpoint_type_at.
* mem-break.h (set_breakpoint_at): Update comments.
This commit fixes detaching on Linux when some thread exits the whole
thread group (process) just while we're detaching.
On Linux, a ptracer must detach from each LWP individually, with
PTRACE_DETACH. Since PTRACE_DETACH sets the thread running free, if
one of the already-detached threads causes the whole thread group to
exit (e.g., simply calls exit), the kernel force-kills the other
threads in the group, making them zombie, just as we're still
detaching them. Since PTRACE_DETACH against a zombie thread fails
with ESRCH, and gdb/gdbserver are not expecting this, the detach fails
with an error like: "Can't detach process: No such process.".
This patch detects this detach failure as normal, and instead of
erroring out, reaps the now-dead thread.
New test included, that exercises several different scenarios that
cause GDB/GDBserver to error out when it should not.
Tested on x86-64 GNU/Linux with {unix, native-gdbserver,
native-extended-gdbserver}
Note: without the previous fix, the "single-process + continue"
variant of the new test would fail with:
(gdb) PASS: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint: switch to parent
continue
Continuing.
Warning:
Could not insert hardware watchpoint 3.
Could not insert hardware breakpoints:
You may have requested too many hardware breakpoints/watchpoints.
Command aborted.
(gdb) FAIL: gdb.threads/process-dies-while-detaching.exp: single-process: continue: watchpoint: continue
gdb/gdbserver/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Antoine Tremblay <antoine.tremblay@ericsson.com>
* linux-low.c: Change interface to take the target lwp_info
pointer directly and return void. Handle detaching from a zombie
thread.
(linux_detach_lwp_callback): New function.
(linux_detach): Detach from the leader thread after detaching from
the clone threads.
gdb/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Antoine Tremblay <antoine.tremblay@ericsson.com>
* inf-ptrace.c (inf_ptrace_detach_success): New function, factored
out from ...
(inf_ptrace_detach): ... here.
* inf-ptrace.h (inf_ptrace_detach_success): New declaration.
* linux-nat.c (get_pending_status): Rename to ...
(get_detach_signal): ... this, and return a host signal instead of
filling in a wait status.
(detach_one_lwp): New function, factored out from detach_callback
and adjusted to handle detaching from a zombie thread.
(detach_callback): Skip the leader thread.
(linux_nat_detach): No longer defer to inf_ptrace_detach to detach
the leader thread, nor build a signal string to pass down.
Instead, use target_announce_detach, detach_one_lwp and
inf_ptrace_detach_success.
gdb/testsuite/ChangeLog:
2016-07-01 Pedro Alves <palves@redhat.com>
Antoine Tremblay <antoine.tremblay@ericsson.com>
* gdb.threads/process-dies-while-detaching.c: New file.
* gdb.threads/process-dies-while-detaching.exp: New file.
In AArch64 displaced stepping and fast tracepoint, GDB/GDBserver needs
to check whether the offset can fit in the range. We are using int32_t
for offset, it is sufficient to get an offset from an instruction, but
it is not enough to get an offset from two addresses. For example,
we have a BL in shared lib which is at 0x0000002000040774, and the
scratch pad for displaced stepping is at 0x400698. The offset can't
fit in 28 bit imm. However, since we are using int32_t for offset, GDB
thinks the offset can fit it, and generate the B instruction with wrong
offset.
It fixes the following fail,
-FAIL: gdb.base/dso2dso.exp: next over call to sub2
gdb:
2016-06-28 Yao Qi <yao.qi@linaro.org>
* aarch64-tdep.c (aarch64_displaced_step_b): Use int64_t for
variable new_offset.
gdb/gdbserver:
2016-06-28 Yao Qi <yao.qi@linaro.org>
* linux-aarch64-low.c (aarch64_ftrace_insn_reloc_b): Use int64_t
for variable new_offset.
(aarch64_ftrace_insn_reloc_b_cond): Likewise.
(aarch64_ftrace_insn_reloc_cb): Likewise.
(aarch64_ftrace_insn_reloc_tb): Likewise.
(aarch64_install_fast_tracepoint_jump_pad): Likewise. Use
PRIx64 instead of PRIx32.
When I implement linux_target_ops.get_syscall_trapinfo for aarch64 and arm,
I find the second parameter sysret isn't used at all. In RSP, we don't
need syscall return value either, because GDB can figure out the return
value from registers content got by 'g' packet.
This patch is to remove them.
gdb/gdbserver:
2016-06-28 Yao Qi <yao.qi@linaro.org>
* linux-low.c (get_syscall_trapinfo): Remove parameter sysret.
Callers updated.
* linux-low.h (struct linux_target_ops) <get_syscall_trapinfo>:
Remove parameter sysno.
* linux-x86-low.c (x86_get_syscall_trapinfo): Remove parameter
sysret.
When a thread is doing step-over with reinsert breakpoint, and the
instruction executed is a syscall doing vfork, both parent and child
share the memory, so the reinsert breakpoint in the space is visible
to both of them. Also, removing the reinsert breakpoints from the
child will effectively remove them from the parent. We should
carefully manipulate reinsert breakpoints for both processes.
What we are doing here is that
- uninsert reinsert breakpoints from the parent before cloning the
breakpoint list. We use "uninsert" instead of "remove", because
we need to "reinsert" them back after vfork is done. In fact,
"uninsert" removes them from both child and parent process space.
- reinsert breakpoints in parent process are still copied to child's
breakpoint list,
- remove them from child's breakpoint list as what we did for fork,
at this point, reinsert breakpoints are removed from the child and
the parent, but they are still tracked by the parent's breakpoint
list,
- once vfork is done, "reinsert" them back to the parent,
gdb/gdbserver:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (handle_extended_wait): Call
uninsert_reinsert_breakpoints for the parent process. Remove
reinsert breakpoints from the child process. Reinsert them to
the parent process when vfork is done.
* mem-break.c (uninsert_reinsert_breakpoints): New function.
(reinsert_reinsert_breakpoints): New function.
* mem-break.h (uninsert_reinsert_breakpoints): Declare
(reinsert_reinsert_breakpoints): Declare.
When a thread is stepping over a syscall instruction with software
single step, GDBserver inserts reinsert breakpoints at the next pcs.
If the syscall call is fork, the forked child has reinsert breakpoint
in its space, and GDBserver clones parent's breakpoint list to child's.
When GDBserver resumes the child, its bp_reinsert is zero, but has
reinsert breakpoints, so the following assert is triggered if I apply
the patch extending step-over-syscall.exp.
gdb/gdbserver/linux-low.c:4292: A problem internal to GDBserver has been detected.^M
void linux_resume_one_lwp_throw(lwp_info*, int, int, siginfo_t*): Assertion `!has_reinsert_breakpoints (proc)' failed.
gdb/gdbserver:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (handle_extended_wait): If the parent is doing
step-over, remove the reinsert breakpoints from the forked child.
This patch fixes a GDBserver crash when one thread is stepping over
a syscall instruction which is exit. Step-over isn't finished due
to the exit, but GDBserver doesn't clean up the state of step-over,
so in the wait next time, GDBserver will wait on step_over_bkpt,
which is already exited, and GDBserver crashes because
'requested_child' is NULL. See gdbserver logs below,
Need step over [LWP 14858]? yes, found breakpoint at 0x2aaaaad91307^M
proceed_all_lwps: found thread 14858 needing a step-over^M
Starting step-over on LWP 14858. Stopping all threads^M
>>>> entering void stop_all_lwps(int, lwp_info*)
....
<<<< exiting void stop_all_lwps(int, lwp_info*)^M
Done stopping all threads for step-over.^M
pc is 0x2aaaaad91307^M
Writing 0f to 0x2aaaaad91307 in process 14858^M
Could not find fast tracepoint jump at 0x2aaaaad91307 in list (uninserting).^M
pending reinsert at 0x2aaaaad91307^M
step from pc 0x2aaaaad91307^M
Resuming lwp 14858 (step, signal 0, stop not expected)^M
# Start step-over for LWP 14858
>>>> entering ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)
....
LLFE: 14858 exited.
...
<<<< exiting ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)
# LWP 14858 exited
.....
>>>> entering ptid_t linux_wait_1(ptid_t, target_waitstatus*, int)^M
linux_wait_1: [<all threads>]^M
step_over_bkpt set [LWP 14858.14858], doing a blocking wait
# but step_over_bkpt is still LWP 14858, which is wrong
The fix is to finish step-over if it is ongoing, and unsuspend other
threads. Without the fix in linux-low.c, GDBserver will crash in
with running gdb.base/step-over-exit.exp.
gdb/gdbserver:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (unsuspend_all_lwps): Declare.
(linux_low_filter_event): If thread exited, call finish_step_over.
If step-over is finished, unsuspend other threads.
gdb/testsuite:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* gdb.base/step-over-exit.c: New.
* gdb.base/step-over-exit.exp: New.
This patch adds more asserts, so the incorrect or sub-optimal
reinsert breakpoints manipulations (from the tests in the following
patches) can trigger them.
gdb/gdbserver:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_resume_one_lwp_throw): Assert
has_reinsert_breakpoints returns false.
* mem-break.c (delete_disabled_breakpoints): Assert
bp type isn't reinsert_breakpoint.
This patch adds some sanity check that reinsert breakpoints must be
there when doing step-over on software single step target. The check
triggers an assert when running forking-threads-plus-breakpoint.exp
on arm-linux target,
gdb/gdbserver/linux-low.c:4714: A problem internal to GDBserver has been detected.^M
int finish_step_over(lwp_info*): Assertion `has_reinsert_breakpoints ()' failed.
the error happens when GDBserver has already resumed a thread of
process A for step-over (and wait for it hitting reinsert breakpoint),
but receives detach request for process B from GDB, which is shown in
the backtrace below,
(gdb) bt
#2 0x000228aa in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4703
#3 0x00025a50 in finish_step_over (lwp=0x12bbd98) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4749
#4 complete_ongoing_step_over () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:4760
#5 linux_detach (pid=25228) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/linux-low.c:1503
#6 0x00012bae in process_serial_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3974
#7 handle_serial_event (err=<optimized out>, client_data=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:4347
#8 0x00016d68 in handle_file_event (event_file_desc=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:429
#9 0x000173ea in process_event () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:184
#10 start_event_loop () at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/event-loop.c:547
#11 0x0000aa2c in captured_main (argv=<optimized out>, argc=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3719
#12 main (argc=<optimized out>, argv=<optimized out>) at /home/yao/SourceCode/gnu/gdb/git/gdb/gdbserver/server.c:3804
the sanity check tries to find the reinsert breakpoint from process B,
but nothing is found. It is wrong, we need to search in process A,
since we started step-over of a thread of process A.
(gdb) p lwp->thread->entry.id
$3 = {pid = 25120, lwp = 25131, tid = 0}
(gdb) p current_thread->entry.id
$4 = {pid = 25228, lwp = 25228, tid = 0}
This patch switched current_thread to the thread we are doing step-over
in finish_step_over.
gdb/gdbserver:
2016-06-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (maybe_hw_step): New function.
(linux_resume_one_lwp_throw): Call maybe_hw_step.
(finish_step_over): Switch current_thread to lwp temporarily,
and assert has_reinsert_breakpoints returns true.
(proceed_one_lwp): Call maybe_hw_step.
* mem-break.c (has_reinsert_breakpoints): New function.
* mem-break.h (has_reinsert_breakpoints): Declare.
gdb/ChangeLog:
2016-06-02 Jon Turney <jon.turney@dronecode.org.uk>
* windows-nat.c (handle_output_debug_string): Return type of
gdb_signal_from_host() is gdb_signal, not an int.
(windows_get_exec_module_filename): Add pointer casts for C++.
gdb/gdbserver/ChangeLog:
2016-06-02 Jon Turney <jon.turney@dronecode.org.uk>
* win32-low.c (win32_create_inferior): Add pointer casts for C++.
This patch is to replace find_inferior (&all_threads, unsuspend_one_lwp, NULL)
with unsuspend_all_lwps (NULL), which is shorter. They are equivalent
to each other.
gdb/gdbserver:
2016-05-17 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_stabilize_threads): Call unsuspend_all_lwps
instead of find_inferior.
This patch initialize res to zero, otherwise, it may have some garbage
bits after the *the_target->read_memory call.
gdb/gdbserver:
2016-05-05 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (get_next_pcs_read_memory_unsigned_integer):
Initialize res to zero.
Variable cpsr holds the value of cpsr register, which is 32-bit. It
is better to explicitly use uint32_t.
gdb/gdbserver:
2016-05-05 Yao Qi <yao.qi@linaro.org>
* linux-arm-low.c (arm_sigreturn_next_pc): Change type of cpsr
to uint32_t.
ChangeLog:
* spu-linux-nat.c (spu_bfd_iovec_pread): Add pointer cast for C++.
(spu_bfd_open): Likewise.
gdbserver/ChangeLog:
* spu-low.c (fetch_ppc_register): Cast PowerPC-Linux-specific value
used as first ptrace argument to PTRACE_TYPE_ARG1 for C++.
(fetch_ppc_memory_1, store_ppc_memory_1): Likewise.
I am sending this fix on behalf of Par Olsson, as a follow-up of this
one:
https://www.sourceware.org/ml/gdb-patches/2015-10/msg00196.html
This problem is exposed when enabling/disabling fast tracepoints on big
endian machines. The flag is defined as an int8_t, but is written from
gdbserver as an integer (usually 32 bits). When the agent code reads it
as an int8_t, it only considers the most significant byte, which is
always 0.
Also, we were writing 32 bits in an 8 bits field, so the write would
overflow, but since the following bytes are padding (the next field is
an uint64_t), it luckily didn't cause any issue on little endian
systems.
The fix was originally tested on ARM big endian systems, but I don't
have access to such a system. However, thanks to Marcin's PowerPC fast
tracepoint patches and gcc110 (big endian Power7) on the gcc compile
farm, I was able to reproduce the problem, test the fix and write a
test (the following patch).
gdb/gdbserver/ChangeLog:
YYYY-MM-DD Par Olsson <par.olsson@windriver.com>
* tracepoint.c (write_inferior_int8): New function.
(cmd_qtenable_disable): Write enable flag using
write_inferior_int8.
Hi,
I happen to see that field need_step_over in struct lwp_info is only
used to print a debug info. need_step_over is set in linux_wait_1
when breakpoint_here is true, however, we check breakpoint_here too in
need_step_over_p and do the step over. I think we don't need field
need_step_over, and check breakpoint_here directly in need_step_over_p.
This field was added in this patch
https://sourceware.org/ml/gdb-patches/2010-03/msg00605.html and the code
wasn't changed much since then.
This patch is to remove it.
gdb/gdbserver:
2016-04-28 Yao Qi <yao.qi@linaro.org>
* linux-low.h (struct lwp_info) <need_step_over>: Remove.
* linux-low.c (linux_wait_1): Update.
(need_step_over_p): Likewise.
When GDBserver steps over a breakpoint using software single step, it
enqueues the signal, single step and deliver the signal in the next
resume if step over is not needed. In this way, the program won't
receive the signal if the conditional breakpoint is set a branch to
self instruction, because the step over is always needed.
This patch removes the restriction that don't deliver the signal to
the inferior if we are trying to reinsert a breakpoint for software
single step and change the decision on resume vs. step-over when the
LWP has pending signals to deliver.
gdb/gdbserver:
2016-04-25 Yao Qi <yao.qi@linaro.org>
* linux-low.c (lwp_signal_can_be_delivered): Adjust.
(need_step_over_p): Return zero if the LWP has pending signals
can be delivered on software single step target.
GDBserver steps over a breakpoint while the single step breakpoint
is inserted at the same address, there are two breakpoint objects
using single raw breakpoint, which is inserted (for single step).
When step over is finished, GDBserver reinsert the breakpoint, but
it finds the raw breakpoint is already inserted, and error out
"Breakpoint already inserted at reinsert time." Even if I change the
order to delete reinsert breakpoints first (which only decreases the
refcount, but leave inserted flag unchanged), the error is still
there.
The fix is to remove the error and return instead.
gdb/gdbserver:
2016-04-25 Yao Qi <yao.qi@linaro.org>
* linux-low.c (reinsert_raw_breakpoint): If bp->inserted is true
return instead of error.
When GDBserver inserts a breakpoint, it looks for raw breakpoint, if
the raw breakpoint is found, increase its refcount, and return. This
doesn't work when it steps over a breakpoint using software single
step and the underneath instruction of breakpoint is branch to self.
When stepping over a breakpoint on ADDR using software single step,
GDBserver uninsert the breakpoint, so the corresponding raw breakpoint
RAW's 'inserted' flag is zero. Then, GDBserver insert single step
breakpoint at the same address ADDR because the instruction is branch
to self, the same raw brekapoint RAW is found, and increase the
refcount. However, the raw breakpoint is not inserted, and the
program won't stop.
gdb/gdbserver:
2016-04-25 Pedro Alves <palves@redhat.com>
Yao Qi <yao.qi@linaro.org>
* mem-break.c (set_raw_breakpoint_at): Create a raw breakpoint
object. Insert it if it is not inserted yet. Increase the
refcount and link it into the proc's raw breakpoint list.
Bits 20 ~ 23 of CPSR are reserved (RAZ, read as zero), but they are not
zero if the arm program runs on aarch64-linux. AArch64 tracer gets PSTATE
from arm 32-bit tracee as CPSR, but bits 20 ~ 23 are used in PSTATE. I
think kernel should clear these bits when it is read through ptrace, but
the fix in user space is still needed.
This patch fixes these two fails,
-FAIL: gdb.reverse/insn-reverse.exp: ext_reg_push_pop: compare registers on insn 0:vldr d7, [r11, #-12]
-FAIL: gdb.reverse/insn-reverse.exp: ext_reg_push_pop: compare registers on insn 0:vldr d7, [r7]
gdb:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* aarch32-linux-nat.c (aarch32_gp_regcache_supply): Clear CPSR
bits 20 to 23.
gdb/gdbserver:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* linux-aarch32-low.c (arm_store_gregset): Clear CPSR bits 20
to 23.
Simple exchange of mpx-avx for avx-mpx.
Other occurrences were not found.
2016-04-22 Walfred Tedeschi <walfred.tedeschi@intel.com>
gdb/gdbserver/ChangeLog:
* configure.srv (srv_amd64_xmlfiles): Exchange
i386/amd64-mpx-avx.xml for i386/amd64-avx-mpx.xml.
GDBserver doesn't deliver signal when stepping over a breakpoint even
hardware single step is used. When GDBserver started to step over
(thread creation) breakpoint for mutlit-threaded debugging in 2002 [1],
GDBserver behaves this way.
This behavior gets trouble on conditional breakpoints on branch to
self instruction like this,
0x00000000004005b6 <+29>: jmp 0x4005b6 <main+29>
and I set breakpoint
$(gdb) break branch-to-self.c:43 if counter > 3
and the variable counter will be set to 5 in SIGALRM signal handler.
Since GDBserver keeps stepping over breakpoint, the SIGALRM can never
be dequeued and delivered to the inferior, so the program can't stop.
The test can be found in gdb.base/branch-to-self.exp.
GDBserver didn't deliver signal when stepping over a breakpoint because
a tracepoint is collected twice if GDBserver does so in the following
scenario, which can be reproduced by gdb.trace/signal.exp.
- program stops at tracepoint, and tracepoint is collected,
- gdbserver starts a step-over,
- a signal arrives, step-over is canceled, and signal should be passed,
- gdbserver starts a new step-over again, pass the signal as well,
- program stops at the entry of signal handler, step-over finished,
- gdbserver proceeds,
- program returns from the signal handler, again to the tracepoint,
and thus is collected again.
The spurious collection isn't that harmful, IMO, so it should be OK
to let GDBserver deliver signal when stepping over a breakpoint.
gdb/gdbserver:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* linux-low.c (lwp_signal_can_be_delivered): Don't deliver
signal when stepping over breakpoint with software single
step.
gdb/testsuite:
2016-04-22 Yao Qi <yao.qi@linaro.org>
* gdb.trace/signal.exp: Also pass if
$tracepoint_hits($i) > $iterations.
Now that gdb/gdbserver compile as C++ programs by default, the s390
GNU/Linux build started failing with:
In file included from ../../src/gdb/common/common-defs.h:64:0,
from ../../src/gdb/defs.h:28,
from ../../src/gdb/s390-linux-nat.c:22:
../../src/gdb/s390-linux-nat.c: In function ‘void fetch_regset(regcache*, int, int, int, const regset*)’:
../../src/gdb/../include/libiberty.h:711:38: error: invalid conversion from ‘void*’ to ‘gdb_byte* {aka unsigned char*}’ [-fpermissive]
# define alloca(x) __builtin_alloca(x)
^
../../src/gdb/s390-linux-nat.c:297:19: note: in expansion of macro ‘alloca’
gdb_byte *buf = alloca (regsize);
^
etc.
gdb/ChangeLog:
2016-04-21 Pedro Alves <palves@redhat.com>
* s390-linux-nat.c (fetch_regset, store_regset, check_regset): Use
void * instead of gdb_byte *.
gdb/gdbserver/ChangeLog:
2016-04-21 Pedro Alves <palves@redhat.com>
* linux-s390-low.c (s390_collect_ptrace_register)
(s390_supply_ptrace_register, s390_get_hwcap): Use gdb_byte * and
add casts.
(s390_check_regset): Use void * instead of gdb_byte *.