Before this patch there was only one call: can_hardware_single_step. Its
implementation was a check on breakpoint_reinsert_addr if NULL it assumed
that the target could hardware single step.
This patch prepares for the case where this is not true anymore.
In order to improve software single stepping in GDBServer the
breakpoint_reinsert_addr operation of targets that had a very simple
software implementation used only for stepping over thread creation events
will be removed.
This will create a case where a target does not support hardware single
step and has the operation breakpoint_reinsert_addr set to NULL, thus
can_hardware_single_step needs to be implemented another way.
A new target operation supports_hardware_single_step is introduced and is
to return true if the target does support such a feature, support for the
feature is manually hardcoded.
Note that the hardware single step support was enabled as per the current
behavior, I did not check if tile for example really has ptrace singlestep
support but since the current implementation assumed it had, I kept it
that way.
No regressions on Ubuntu 14.04 on ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }
Compilation tested on: aarch64,arm,bfind,crisv32,m32r,ppc,s390,tic6x,tile,
xtensa.
Not tested : sh.
gdb/gdbserver/ChangeLog:
* linux-aarch64-low.c (aarch64_supports_hardware_single_step):
New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-arm-low.c (arm_supports_hardware_single_step): New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-bfin-low.c (bfin_supports_hardware_single_step): New function.
(struct linux_target_ops) <bfin_supports_hardware_single_step>:
Initialize.
* linux-crisv32-low.c (cris_supports_hardware_single_step):
New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-low.c (can_hardware_single_step): Use
supports_hardware_single_step.
(can_software_single_step): New function.
(start_step_over): Call can_software_single_step.
(linux_supports_hardware_single_step): New function.
(struct target_ops) <supports_software_single_step>: Initialize.
* linux-low.h (struct linux_target_ops)
<supports_hardware_single_step>: Initialize.
* linux-m32r-low.c (m32r_supports_hardware_single_step): New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-ppc-low.c (ppc_supports_hardware_single_step): New function.
(struct linux_target_ops) <supports_hardware_single_step> Initialize.
* linux-s390-low.c (s390_supports_hardware_single_step): New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-sh-low.c (sh_supports_hardware_single_step): New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-tic6x-low.c (tic6x_supports_hardware_single_step): New function.
(struct linux_target_ops) <tic6x_supports_hardware_single_step>:
Initialize.
* linux-tile-low.c (tile_supports_hardware_single_step): New function.
(struct linux_target_ops) <tile_supports_hardware_single_step>:
Initialize.
* linux-x86-low.c (x86_supports_hardware_single_step) New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* linux-xtensa-low.c (xtensa_supports_hardware_single_step):
New function.
(struct linux_target_ops) <supports_hardware_single_step>: Initialize.
* target.h (struct target_ops): <supports_software_single_step>:
New field.
(target_supports_software_single_step): New macro.
Without this patch, when doing a software single step, with for example
a conditional breakpoint, gdbserver would wrongly avance the pc of
breakpoint_len and skips an instruction.
This is due to gdbserver assuming that it's hardware single stepping.
When it resumes from the breakpoint address it expects the trap to be
caused by ptrace and if it's rather caused by a software breakpoint
it assumes this is a permanent breakpoint and that it needs to skip
over it.
However when software single stepping, this breakpoint is legitimate as
it's the reinsert breakpoint gdbserver has put in place to break at
the next instruction. Thus gdbserver wrongly advances the pc and skips
an instruction.
This patch fixes this behavior so that gdbserver checks if it is a
reinsert breakpoint from software single stepping. If it is it won't
advance the pc. And if there's no reinsert breakpoint there we assume
then that it's a permanent breakpoint and advance the pc.
Here's a commented log of what would happen before and after the fix on
gdbserver :
/* Here there is a conditional breakpoint at 0x10428 that needs to be
stepped over. */
Need step over [LWP 11204]? yes, found breakpoint at 0x10428
...
/* e7f001f0 is a breakpoint instruction on arm
Here gdbserver writes the software breakpoint we would like to hit
*/
Writing e7f001f0 to 0x0001042c in process 11204
...
Resuming lwp 11220 (continue, signal 0, stop not expected)
pending reinsert at 0x10428
stop pc is 00010428
continue from pc 0x10428
...
/* Here gdbserver hit the software breakpoint that was in place
for the step over */
stop pc is 0001042c
pc is 0x1042c
step-over for LWP 11220.11220 executed software breakpoint
Finished step over.
Could not find fast tracepoint jump at 0x10428 in list (reinserting).
/* Here gdbserver writes back the original instruction */
Writing e50b3008 to 0x0001042c in process 11220
Step-over finished.
Need step over [LWP 11220]? No
/* Here because gdbserver assumes this is a permenant breakpoint it advances
the pc of breakpoint_len, in this case 4 bytes, so we have just skipped
the instruction that was written back here :
Writing e50b3008 to 0x0001042c in process 11220
*/
stop pc is 00010430
pc is 0x10430
Need step over [LWP 11220]? No, no breakpoint found at 0x10430
Proceeding, no step-over needed
proceed_one_lwp: lwp 11220
stop pc is 00010430
This patch fixes this situation and we get the right behavior :
Writing e50b3008 to 0x0001042c in process 11245
Hit a gdbserver breakpoint.
Hit a gdbserver breakpoint.
Step-over finished.
proceeding all threads.
Need step over [LWP 11245]? No
stop pc is 0001042c
pc is 0x1042c
Need step over [LWP 11245]? No, no breakpoint found at 0x1042c
Proceeding, no step-over needed
proceed_one_lwp: lwp 11245
stop pc is 0001042c
pc is 0x1042c
Resuming lwp 11245 (continue, signal 0, stop not expected)
stop pc is 0001042c
continue from pc 0x1042c
It also works if the value at 0x0001042c is a permanent breakpoint.
If so gdbserver will finish the step over, remove the reinserted breakpoint,
resume at that location and on the next SIGTRAP gdbserver will trigger
the advance PC condition as reinsert_breakpoint_inserted_here will be false.
I also tested this against bp-permanent.exp on arm (with a work in progress
software single step patchset) without any regressions.
It's also tested against x86 bp-permanent.exp without any regression.
So both software and hardware single step are tested.
No regressions on Ubuntu 14.04 on ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_wait_1): Fix pc advance condition.
* mem-break.c (reinsert_breakpoint_inserted_here): New function.
* mem-break.h (reinsert_breakpoint_inserted_here): New declaration.
When manually stepping over a permanent breakpoint on ARM we need to fetch the
right breakpoint size based on the current instruction set used.
Since this is not encoded in the stop_pc, the instruction mode needs to be
fetched from the CPSR register.
This is done by introducing a new target operation called :
breakpoint_kind_from_current_state.
For other targets that do not need this, breakpoint_kind_from_pc is used.
No regressions, tested on ubuntu 14.04 ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }
gdb/gdbserver/ChangeLog:
* linux-arm-low.c (arm_is_thumb_mode): New function.
(arm_breakpoint_at): Use arm_is_thumb_mode.
(arm_breakpoint_kind_from_current_state): New function.
(struct linux_target_ops) <breakpoint_kind_from_current_state>:
Initialize.
* linux-low.c (linux_wait_1): Call breakpoint_kind_from_current_state.
(linux_breakpoint_kind_from_current_state): New function.
(struct target_ops <breakpoint_kind_from_current_state>: Initialize.
* linux-low.h (struct linux_target_ops)
<breakpoint_kind_from_current_state>: New field.
* target.h (struct target_ops): Likewise.
(target_breakpoint_kind_from_current_state): New macro.
Running killed-outside.exp in with "maint set target-non-stop on"
hangs currently. This test has the inferior process die with a
SIGKILL while stopped. gdbserver gets a SIGCHLD and reacts by
retrieveing the SIGKILL events out of waitpid. But because the
process is not resumed from GDB's perspective, the event is left
pending. When GDB resumes the process afterwards, the process is not
really resumed because it already has the event pending. But nothing
wakes up the event loop to consume the event.
Handle this in the same way nat/linux-nat.c:linux_nat_resume handles
this.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_resume): Wake up the event loop before
returning.
Testing with "maint set target-non-stop on" causes regressions in
tests that rely on TARGET_WAITKIND_NO_RESUMED, which isn't modelled on
the RSP. In real all-stop, gdbserver detects the situation and
reporst error to GDB, and so the tests (e.g.,
gdb.threads/no-unwaited-for-left.exp) at fail quickly. But with
"maint set target-non-stop on", GDB instead hangs forever waiting for
a stop reply that never comes, and so the tests take longer to time
out.
This adds a new "N" stop reply packet that maps 1-1 to
TARGET_WAITKIND_NO_RESUMED.
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
PR 14618
* NEWS (New remote packets): Mention the N stop reply.
* remote.c (remote_protocol_features): Add "no-resumed" entry.
(remote_query_supported): Report no-resumed+ support.
(remote_parse_stop_reply): Handle 'N'.
(process_stop_reply): Handle TARGET_WAITKIND_NO_RESUMED.
(remote_wait_as): Handle 'N' / TARGET_WAITKIND_NO_RESUMED.
(_initialize_remote): Register "set/show remote
no-resumed-stop-reply" commands.
gdb/doc/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
PR 14618
* gdb.texinfo (Stop Reply Packets): Document the N stop reply.
(Remote Configuration): Add the "set/show remote
no-resumed-stop-reply" to the available settings table.
(General Query Packets): Document the "no-resumed" qSupported
feature.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
PR 14618
* linux-low.c (linux_wait_1): If the last resumed thread is gone,
report TARGET_WAITKIND_NO_RESUMED.
* remote-utils.c (prepare_resume_reply): Handle
TARGET_WAITKIND_NO_RESUMED.
* server.c (report_no_resumed): New global.
(handle_query) <qSupported>: Handle "no-resumed+". Report
"no-resumed+" support.
(resume): When the target reports TARGET_WAITKIND_NO_RESUMED, only
return error if the client doesn't support no-resumed events.
(push_stop_notification): New function.
(handle_target_event): Use it. Report TARGET_WAITKIND_NO_RESUMED
events if the client supports them.
gdb/testsuite/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.threads/no-unwaited-for-left.exp: Remove setup_kfail calls.
killed-outside.exp regresses with "maint set target-non-stop on". The
logs show:
(gdb) continue
Continuing.
infrun: clear_proceed_status_thread (Thread 9028.9028)
infrun: proceed (addr=0xffffffffffffffff, signal=GDB_SIGNAL_DEFAULT)
infrun: proceed: resuming Thread 9028.9028
Sending packet: $Z0,3615a03966,1#4b... Notification received: Stop:X9;process:2344
Packet received: E01
Sending packet: $Z0,3615a13970,1#47...Packet received: E01
Sending packet: $Z0,3615a14891,1#4a...Packet received: E01
infrun: resume (step=0, signal=GDB_SIGNAL_0), trap_expected=0, current thread [Thread 9028.9028] at 0x4005e4
Sending packet: $vCont;c:p2344.2344#1a...Packet received: E.target not running.
Sending packet: $qXfer:threads:read::0,fff#03...Packet received: l<threads>\n</threads>\n
Sending packet: $vStopped#55...Packet received: OK
Unexpected vCont reply in non-stop mode: E.target not running.
(gdb) remote_async_inferior_event_handler
infrun: target_wait (-1.0.0, status) =
infrun: 9028.0.0 [process 9028],
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
infrun: clear_step_over_info
infrun: stop_all_threads
remote_thread_exit_events(1)
Note the "Unexpected vCont reply" error.
I traced it to a problem in status_pending_p_callback. It resumes an
LWP when it shouldn't.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (thread_still_has_status_pending_p): Don't check
vCont;t here.
(lwp_resumed): New function.
(status_pending_p_callback): Return early if the LWP is not
supposed to be resumed.
When testing with "maint set target-non-stop on", a few
threading-related tests expose an issue that requires new RSP packets.
Say there are 3 threads running, 1-3. If GDB tries to stop thread 1,
2 and 3, and then waits for their stops, but meanwhile say, thread 2
exits, GDB hangs forever waiting for a stop for thread 2 that won't
ever happen.
This patch fixes the issue by adding support for thread exit events to
the protocol. However, we don't want these always enabled, as they're
useless most of the time, and would slow down remote debugging. So I
made it so that GDB can enable/disable them, and then made gdb do that
around the cases that need it, which currently is only
infrun.c:stop_all_threads.
In turn, if we have thread exit events, then the extra "thread x
exited" traffic slows down attach-many-short-lived-threads.exp enough
that gdb has trouble keeping up with new threads that are spawned
while gdb tries to stop existing ones. To fix that I added support
for the counterpart thread created events too. Enabling those when we
try to stop threads ensures that new threads never get a chance to
themselves start new threads, killing the race.
gdb/doc/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Remote Configuration): List "set/show remote
thread-events" command in configuration table.
(Stop Reply Packets): Document "T05 create" stop
reason and 'w' stop reply.
(General Query Packets): Document QThreadEvents packet. Document
QThreadEvents qSupported feature.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Assert that the LWP's
waitstatus is TARGET_WAITKIND_IGNORE. If GDB wants to hear about
thread create events, leave the new child's status pending.
(linux_low_filter_event): If GDB wants to hear about thread exit
events, leave the LWP marked dead and don't delete it.
(linux_wait_for_event_filtered): Don't check for thread exit.
(filter_exit_event): New function.
(linux_wait_1): Use it, when returning an exit event.
(linux_resume_one_lwp_throw): Assert that the LWP's
waitstatus is TARGET_WAITKIND_IGNORE.
* remote-utils.c (prepare_resume_reply): Handle
TARGET_WAITKIND_THREAD_CREATED and TARGET_WAITKIND_THREAD_EXITED.
* server.c (report_thread_events): New global.
(handle_general_set): Handle QThreadEvents.
(handle_query) <qSupported>: Handle and report QThreadEvents+;
(handle_target_event): Handle TARGET_WAITKIND_THREAD_CREATED and
TARGET_WAITKIND_THREAD_EXITED.
* server.h (report_thread_events): Declare.
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* NEWS (New commands): Mention "set/show remote thread-events"
commands.
(New remote packets): Mention thread created/exited stop reasons
and QThreadEvents packet.
* infrun.c (disable_thread_events): New function.
(stop_all_threads): Disable/enable thread create/exit events.
Handle TARGET_WAITKIND_THREAD_EXITED.
(handle_inferior_event_1): Handle TARGET_WAITKIND_THREAD_CREATED
and TARGET_WAITKIND_THREAD_EXITED.
* remote.c (remove_child_of_pending_fork): Also remove threads of
threads that have TARGET_WAITKIND_THREAD_EXITED events.
(remote_parse_stop_reply): Handle "create" magic register. Handle
'w' stop reply.
(initialize_remote): Install remote_thread_events as
to_thread_events target hook.
(remote_thread_events): New function.
* target-delegates.c: Regenerate.
* target.c (target_thread_events): New function.
* target.h (struct target_ops) <to_thread_events>: New field.
(target_thread_events): Declare.
* target/waitstatus.c (target_waitstatus_to_string): Handle
TARGET_WAITKIND_THREAD_CREATED and TARGET_WAITKIND_THREAD_EXITED.
* target/waitstatus.h (enum target_waitkind)
<TARGET_WAITKIND_THREAD_CREATED, TARGET_WAITKIND_THREAD_EXITED):
New values.
Running attach-many-short-lived-threads.exp with the extended-remote
board with "maint set target-non-stop on" times out -- the attach
never completes. Enabling infrun debug logs, we see that GDB is stuck
stopping all threads:
infrun: target_wait (-1.0.0, status) =
infrun: 1639.22213.0 [Thread 1639.22213],
infrun: status->kind = stopped, signal = GDB_SIGNAL_0
infrun: Thread 1639.22260 not executing
infrun: Thread 1639.22256 not executing
infrun: Thread 1639.22258 not executing
infrun: Thread 1639.22257 not executing
infrun: Thread 1639.22259 not executing
infrun: Thread 1639.22255 not executing
infrun: Thread 1639.22253 executing, already stopping
infrun: Thread 1639.22251 executing, already stopping
infrun: Thread 1639.22252 executing, already stopping
infrun: Thread 1639.22250 executing, already stopping
infrun: Thread 1639.22254 executing, already stopping
infrun: Thread 1639.22247 executing, already stopping
infrun: Thread 1639.22213 not executing
infrun: Thread 1639.22207 not executing
infrun: Thread 1639.22201 not executing
infrun: Thread 1639.22219 not executing
infrun: Thread 1639.1639 not executing
** HANG HERE **
GDB is waiting for the stop replies of any of those "already stopping"
threads. Take 22253 for example. On the gdbserver logs we see:
...
resume_stop request for LWP 22253
stopping LWP 22253
Sending sigstop to lwp 22253
linux_resume done
...
and:
my_waitpid (-1, 0x40000001)
my_waitpid (-1, 0x80000001): status(3057f), 22253
LWFE: waitpid(-1, ...) returned 22253, ERRNO-OK
LLW: waitpid 22253 received Trace/breakpoint trap (stopped)
pc is 0x3615ef4ce1
HEW: Got clone event from LWP 22253, new child is LWP 22259
but from here on, we never see any other event for LWP 22253. In
particular, we never see the expected SIGSTOP (from "Sending sigstop"
above). The issue is that linux_resume_stopped_resumed_lwps never
re-resumes the 22253 after the clone event.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (resume_stopped_resumed_lwps): Don't check whether
the thread's last_resume_kind was resume_stop.
With "maint set target-non-stop on", the attach tests occasionally
crash gdbserver.
Basically, gdb attaches with vAttach;PID, and then shortly after reads
the xml target description for that process, to figure out the
process' architecture. On the gdbserver side, the target description
is only filled in when the first process/thread in the thread group
reports its initial PTRACE_ATTACH SIGSTOP. So if GDB is fast enough,
it can read the target description _before_ that initial stop, and
then gdbserver dies dereferencing a NULL tdesc pointer.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_attach): In non-stop mode, wait for one stop
before returning.
This patch adds support for thread names in the remote protocol, and
updates gdb/gdbserver to use it. The information is added to the XML
description sent in response to the qXfer:threads:read packet.
gdb/ChangeLog:
* linux-nat.c (linux_nat_thread_name): Replace implementation by call
to linux_proc_tid_get_name.
* nat/linux-procfs.c (linux_proc_tid_get_name): New function,
implementation inspired by linux_nat_thread_name.
* nat/linux-procfs.h (linux_proc_tid_get_name): New declaration.
* remote.c (struct private_thread_info) <name>: New field.
(free_private_thread_info): Free name field.
(remote_thread_name): New function.
(thread_item_t) <name>: New field.
(clear_threads_listing_context): Free name field.
(start_thread): Get name xml attribute.
(thread_attributes): Add "name" attribute.
(remote_update_thread_list): Copy name field.
(init_remote_ops): Assign remote_thread_name callback.
* target.h (target_thread_name): Update comment.
* NEWS: Mention remote thread name support.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_target_ops): Use linux_proc_tid_get_name.
* server.c (handle_qxfer_threads_worker): Refactor to include thread
name in reply.
* target.h (struct target_ops) <thread_name>: New field.
(target_thread_name): New macro.
gdb/doc/ChangeLog:
* gdb.texinfo (Thread List Format): Mention thread names.
The target_process_qsupported method is called for each qSupported
feature that the common code does not recognize. The only current
implementation, for x86 Linux (x86_linux_process_qsupported), assumes
that it either is called with the "xmlRegisters=i386" feature, or that
it is isn't called at all, indicating the connected GDB predates x86
XML descriptions.
That's a bad assumption however. If GDB sends in a new/unknown (to
core gdbserver) feature after "xmlRegisters=i386", say, something like
qSupported:xmlRegisters=i386;UnknownFeature+, then when
target_process_qsupported is called for "UnknownFeature+",
x86_linux_process_qsupported clears the 'use_xml' global and calls
x86_linux_update_xmltarget, and gdbserver ends up _not_ reporting a
XML description...
This commit changes the target_process_qsupported API to instead pass
down a vector of unprocessed qSupported features in one go.
(There's an early call to target_process_qsupported(NULL) that
indicates "starting qSupported processing". There's no matching call
to mark the end of processing, though. I first fixed this by passing
(char *)-1 to indicate that, and adjusted the x86 backend to only
clear 'use_xml' when qSupported processing starts, and then only call
x86_linux_update_xmltarget() when (char *)-1 was passed. However, I
wasn't that happy with the hack and came up this alternative version.)
gdb/gdbserver/ChangeLog:
2015-11-19 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_process_qsupported): Change prototype.
Adjust.
* linux-low.h (struct linux_target_ops) <process_qsupported>:
Change prototype.
* linux-x86-low.c (x86_linux_process_qsupported): Change prototype
and adjust to loop over all features.
* server.c (handle_query) <qSupported>: Adjust to call
target_process_qsupported once, passing it a vector of unprocessed
features.
* target.h (struct target_ops) <process_qsupported>: Change
prototype.
(target_process_qsupported): Adjust.
Fixes:
../../../src/gdb/gdbserver/linux-low.c: In function ‘int linux_low_read_btrace(btrace_target_info*, buffer*, int)’:
../../../src/gdb/gdbserver/linux-low.c:6827:48: error: invalid conversion from ‘int’ to ‘btrace_read_type’ [-fpermissive]
err = linux_read_btrace (&btrace, tinfo, type);
^
In file included from ../../../src/gdb/gdbserver/linux-low.c:98:0:
../../../src/gdb/gdbserver/../nat/linux-btrace.h:116:26: error: initializing argument 3 of ‘btrace_error linux_read_btrace(btrace_data*, btrace_target_info*, btrace_read_type)’ [-fpermissive]
extern enum btrace_error linux_read_btrace (struct btrace_data *btrace,
^
The cyclic dependency the comment talks about is no longer relevant:
https://sourceware.org/ml/gdb-patches/2015-10/msg00643.html
gdb/gdbserver/ChangeLog:
2015-10-29 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_low_read_btrace): Change type of 'type'
parameter.
* server.c (handle_qxfer_btrace): Change type of 'type'
local.
* target.h (struct target_ops) <read_btrace>: Change type of
'type' parameter. Update comment.
gdb/ChangeLog:
* nat/linux-nat.h (__SIGRTMIN): Move here from gdbserver/linux-low.c.
gdb/gdbserver/ChangeLog:
* linux-low.c (__SIGRTMIN): Move to nat/linux-nat.h.
gdb/ChangeLog:
* common/gdb_wait.h (W_STOPCODE): Define, moved here from
gdbserver/linux-low.c.
(WSETSTOP): Simplify.
gdb/gdbserver/ChangeLog:
* linux-low.c (W_STOPCODE): Moved to common/gdb_wait.h.
This patch moves default_breakpoint_kind_from_pc to target.c and creates a macro
so that all targets can easily use it.
This allows the breakpoint_kind_from_pc operation to be left unimplemented in
targets that do not need it.
This is preparation to fix the win32/nto/spu build that was broken by this
patch: https://sourceware.org/ml/gdb-patches/2015-10/msg00369.html
No regression on Ubuntu 14.04 x86-64 with gdbserver-{native-extended}
gdb/gdbserver/ChangeLog:
* linux-low.c (default_breakpoint_kind_from_pc): Move to target.c.
* mem-break.c (set_breakpoint_at): Use target_breakpoint_kind_from_pc.
* target.c (default_breakpoint_kind_from_pc): Moved from linux-low.c
* target.h (target_breakpoint_kind_from_pc): New macro.
This patch fixes a regression introduced by :
https://sourceware.org/ml/gdb-patches/2015-10/msg00369.html
Tests : gdb.trace/trace-break.exp and gdb.trace/trace-mt.exp would fail on x86
with gdbserver-{native,extended}.
Before this patch, the breakpoint kind set by GDB with a Z packet and the one
set in the case of a tracepoint would be inconsistent on targets that did not
implement breakpoint_kind_from_pc. On x86 for example a breakpoint set by GDB
would have a kind of 1 but a breakpoint set by a tracepoint would have a kind of
0.
This created a missmatch when trying to insert a tracepoint and a breakpoint at
the same location. One of the two breakpoints would be removed with debug
message : "Inconsistent breakpoint kind".
This patch fixes the issue by changing the default 0 breakpoint kind to be
the size of the breakpoint according to sw_breakpoint_from_kind.
The default breakpoint kind must be the breakpoint length to keep consistency
between breakpoints set via GDB and the ones set internally by GDBServer.
No regression on Ubuntu 14.04 x86-64 with gdbserver-{native-extended}
gdb/gdbserver/ChangeLog:
* linux-low.c (default_breakpoint_kind_from_pc): New function.
(linux_breakpoint_kind_from_pc): Use default_breakpoint_kind_from_pc for
the default breakpoint kind.
There's two ways to set breakpoints in GDBServer.
- GDBServer setting its own breakpoints, through API set_breakpoint_at.
- GDBServer setting breakpoints according to the information in Z
packets, through API set_gdb_breakpoint.
Before this patch the breakpoint kinds were a concept unique to GDB and Z
packets, as GDBServer never had to set different kinds of breakpoint on its
own.
This patch teaches GDBServer to handle breakpoint kinds for its own
breakpoints. It generalizes the breakpoint kind as per Z packets to
represent different kinds of breakpoints directly set by GDBServer also.
GDBServer now querys breakpoint_kind_from_pc to know what breakpoint kind to
set on its own.
As the kind is now a differentiating factor equivalent to size for the
breakpoint struct and that it's size can be queried using
sw_breakpoint_from_kind, the size field has been replaced with the kind field.
All references to size are now replaced by kind or a call to bp_size that wraps
sw_breakpoing_from_kind and returns the size of the breakpoint in memory.
To fetch the software breakpoint data bp_opcode is called and wraps the
sw_breakpoint_from_kind call.
No regressions on Ubuntu 14.04 on ARMv7 and x86.
With gdbserver-{native,extended} / { -marm -mthumb }
gdb/gdbserver/ChangeLog:
* linux-low.c (initialize_low): Ajdust for breakpoint global variables
removal.
* mem-break.c : Remove breakpoint_data/breakpoint_len global variables.
(struct raw_breakpoint) <size>: Remove.
(struct raw_breakpoint) <kind>: Add.
(bp_size): New function.
(bp_opcode): Likewise.
(find_raw_breakpoint_at): Adjust for kind.
(insert_memory_breakpoint): Adjust for kind call bp_size,bp_opcode.
(remove_memory_breakpoint): Adjust for kind call bp_size.
(set_raw_breakpoint_at): Adjust for kind.
(set_breakpoint): Likewise.
(set_breakpoint_at): Call breakpoint_kind_from_pc.
(delete_raw_breakpoint): Adjust for kind.
(delete_breakpoint): Likewise.
(find_gdb_breakpoint): Likewise.
(set_gdb_breakpoint_1): Likewise.
(set_gdb_breakpoint): Likewise.
(delete_gdb_breakpoint_1): Likewise.
(delete_gdb_breakpoint): Likewise.
(uninsert_raw_breakpoint): Likewise.
(reinsert_raw_breakpoint): Likewise.
(set_breakpoint_data): Remove.
(validate_inserted_breakpoint): Adjust for kind call bp_size,bp_opcode.
(check_mem_read): Adjust for kind call bp_size.
(check_mem_write): Adjust for kind call bp_size,bp_opcode.
(clone_one_breakpoint): Adjust for kind.
* mem-break.h (set_gdb_breakpoint): Likewise.
(delete_gdb_breakpoint): Likewise.
* server.c (process_serial_event): Likewise.
This patch is in preparation for software breakpoints on ARM linux. It
refactors breakpoint and breakpoint_len into breakpoint_kind_from_pc and
sw_breakpoint_from kind to prepare the case where we have multiple types of
breakpoints.
Kind is the type of breakpoint (hardware or software) to be inserted, usually it
is the lenght of the software breakpoint but can be something else depending on
the target.
This patch introduces the linux_target_ops breakpoint_kind_from_pc and
sw_breakpoint_from_kind.
breakpoint_kind_from_pc returns the breakpoint kind and adjusts the PC to the
real memory location in case a flag was present in the PC. E.g the instruction
mode on ARM.
sw_breakpoint_from_kind returns the software breakpoint for this kind as a
string of bytes, the length of the breakpoint is adjusted for the breakpoint's
size in memory.
For targets that have only one kind of breakpoint, the default value 0 is
returned by linux_breakpoint_kind_from_pc so that not all targets need to
implement the breakpoint_kind_from_pc operation.
No regressions, tested on Ubuntu 14.04 on ARMv7 and x86
With gdbserver-{native,extended} / { -marm -mthumb }
Also since the target_ops have been changed compilation was tested on
affected archs namely : aarch64, arm, bfin, cris, crisv32, m32r,
m68k, mips, nios2, ppc, s390, sparc, tic6x, tile, x86, steins.
Not tested : sh
gdb/gdbserver/ChangeLog:
* linux-aarch64-low.c (aarch64_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-arm-low.c (arm_breakpoint_kind_from_pc): New function.
(arm_sw_breakpoint_from_kind): New function.
* linux-bfin-low.c (bfin_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-cris-low.c (cris_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-crisv32-low.c (cris_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-low.c (linux_wait_1): Call breakpoint_kind_from_pc
and sw_breakpoint_from_kind to increment the pc.
(linux_breakpoint_kind_from_pc): New function.
(linux_sw_breakpoint_from_kind): New function.
(struct target_ops) <sw_breakpoint_from_kind>: Initialize field.
(initialize_low): Call breakpoint_kind_from_pc and
sw_breakpoint_from_kind to replace breakpoint_data/len.
* linux-low.h (struct linux_target_ops) <breakpoint_kind_from_pc>:
New field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Likewise.
* linux-m32r-low.c (m32r_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-m68k-low.c (m68k_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-mips-low.c (mips_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-nios2-low.c (nios2_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-ppc-low.c (ppc_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-s390-low.c (s390_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-sh-low.c (sh_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-sparc-low.c (sparc_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-tic6x-low.c (tic6x_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-tile-low.c (tile_sw_breakpoint_from_kind): New function.
* linux-x86-low.c (x86_sw_breakpoint_from_kind): New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
* linux-xtensa-low.c (xtensa_sw_breakpoint_from_kind) New function.
(struct linux_target_ops) <breakpoint>: Remove.
(struct linux_target_ops) <breakpoint_len>: Remove.
(struct linux_target_ops) <breakpoint_kind_from_pc>: Initialize field.
(struct linux_target_ops) <sw_breakpoint_from_kind>: Initialize field.
In my patch https://sourceware.org/ml/gdb-patches/2015-04/msg01110.html
a new target_ops hook supports_conditional_breakpoints was added to
disable conditional breakpoints if target doesn't have hardware single
step. This patch is to generalize this hook from
supports_conditional_breakpoints to supports_hardware_single_step,
so that the following patch can use it.
gdb/gdbserver:
2015-09-15 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_supports_conditional_breakpoints): Rename
it to ...
(linux_supports_hardware_single_step): ... New function.
(linux_target_ops): Update.
* lynx-low.c (lynx_target_ops): Set field
supports_hardware_single_step to target_can_do_hardware_single_step.
* nto-low.c (nto_target_ops): Likewise.
* spu-low.c (spu_target_ops): Likewise.
* win32-low.c (win32_target_ops): Likewise.
* target.c (target_can_do_hardware_single_step): New function.
* target.h (struct target_ops) <supports_conditional_breakpoints>:
Remove. <supports_hardware_single_step>: New field.
(target_supports_conditional_breakpoints): Remove.
(target_supports_hardware_single_step): New macro.
(target_can_do_hardware_single_step): Declare.
* server.c (handle_query): Use target_supports_hardware_single_step
instead of target_supports_conditional_breakpoints.
This patch implements support for exec events on extended-remote Linux
targets. Follow-exec-mode and rerun behave as expected. Catchpoints and
test updates are implemented in subsequent patches.
This patch was derived from a patch posted last October:
https://sourceware.org/ml/gdb-patches/2014-10/msg00877.html.
It was originally based on some work done by Luis Machado in 2013.
IMPLEMENTATION
----------------
Exec events are enabled via ptrace options.
When an exec event is detected by gdbserver, the existing process
data, along with all its associated lwp and thread data, is deleted
and replaced by data for a new single-threaded process. The new
process data is initialized with the appropriate parts of the state
of the execing process. This approach takes care of several potential
pitfalls, including:
* deleting the data for an execing non-leader thread before any
wait/sigsuspend occurs
* correctly initializing the architecture of the execed process
We then report the exec event using a new RSP stop reason, "exec".
When GDB receives an "exec" event, it saves the status in the event
structure's target_waitstatus field, like what is done for remote fork
events. Because the original and execed programs may have different
architectures, we skip parsing the section of the stop reply packet
that contains register data. The register data will be retrieved
later after the inferior's architecture has been set up by
infrun.c:follow_exec.
At that point the exec event is handled by the existing event handling
in GDB. However, a few changes were necessary so that
infrun.c:follow_exec could accommodate the remote target.
* Where follow-exec-mode "new" is handled, we now call
add_inferior_with_spaces instead of add_inferior with separate calls
to set up the program and address spaces. The motivation for this
is that add_inferior_with_spaces also sets up the initial architecture
for the inferior, which is needed later by target_find_description
when it calls target_gdbarch.
* We call a new target function, target_follow_exec. This function
allows us to store the execd_pathname in the inferior, instead of
using the static string remote_exec_file from remote.c. The static
string didn't work for follow-exec-mode "new", since once you switched
to the execed program, the original remote exec-file was lost. The
execd_pathname is now stored in the inferior's program space as a
REGISTRY field. All of the requisite mechanisms for this are
defined in remote.c.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_mourn): Static declaration.
(linux_arch_setup): Move in front of
handle_extended_wait.
(linux_arch_setup_thread): New function.
(handle_extended_wait): Handle exec events. Call
linux_arch_setup_thread. Make event_lwp argument a
pointer-to-a-pointer.
(check_zombie_leaders): Do not check stopped threads.
(linux_low_ptrace_options): Add PTRACE_O_TRACEEXEC.
(linux_low_filter_event): Add lwp and thread for exec'ing
non-leader thread if leader thread has been deleted.
Refactor code into linux_arch_setup_thread and call it.
Pass child lwp pointer by reference to handle_extended_wait.
(linux_wait_for_event_filtered): Update comment.
(linux_wait_1): Prevent clobbering exec event status.
(linux_supports_exec_events): New function.
(linux_target_ops) <supports_exec_events>: Initialize new member.
* lynx-low.c (lynx_target_ops) <supports_exec_events>: Initialize
new member.
* remote-utils.c (prepare_resume_reply): New stop reason 'exec'.
* server.c (report_exec_events): New global variable.
(handle_query): Handle qSupported query for exec-events feature.
(captured_main): Initialize report_exec_events.
* server.h (report_exec_events): Declare new global variable.
* target.h (struct target_ops) <supports_exec_events>: New
member.
(target_supports_exec_events): New macro.
* win32-low.c (win32_target_ops) <supports_exec_events>:
Initialize new member.
gdb/ChangeLog:
* infrun.c (follow_exec): Use process-style ptid for
exec message. Call add_inferior_with_spaces and
target_follow_exec.
* nat/linux-ptrace.c (linux_supports_traceexec): New function.
* nat/linux-ptrace.h (linux_supports_traceexec): Declare.
* remote.c (remote_pspace_data): New static variable.
(remote_pspace_data_cleanup): New function.
(get_remote_exec_file): New function.
(set_remote_exec_file_1): New function.
(set_remote_exec_file): New function.
(show_remote_exec_file): New function.
(remote_exec_file): Delete static variable.
(anonymous enum) <PACKET_exec_event_feature> New
enumeration constant.
(remote_protocol_features): Add entry for exec-events feature.
(remote_query_supported): Add client side of qSupported query
for exec-events feature.
(remote_follow_exec): New function.
(remote_parse_stop_reply): Handle 'exec' stop reason.
(extended_remote_run, extended_remote_create_inferior): Call
get_remote_exec_file and set_remote_exec_file_1.
(init_extended_remote_ops) <to_follow_exec>: Initialize new
member.
(_initialize_remote): Call
register_program_space_data_with_cleanup. Call
add_packet_config_cmd for remote exec-events feature.
Modify call to add_setshow_string_noescape_cmd for exec-file
to use new functions set_remote_exec_file and
show_remote_exec_file.
* target-debug.h, target-delegates.c: Regenerated.
* target.c (target_follow_exec): New function.
* target.h (struct target_ops) <to_follow_exec>: New member.
(target_follow_exec): Declare new function.
For the BTS recording format, we sometimes get a FROM->TO record where the
FROM address lies in the kernel and the TO address lies in user space at
whatever address the user process was resumed.
GDB has a heuristic to filter out such records based on looking at the most
significant bit in the PC. This works fine for 64-bit systems but it doesn't
always work for 32-bit systems. Libraries that are loaded at fairly high
addresses might be mistaken for kernel code and branches inside the library
are filtered out.
Change the heuristic to (again heuristically) try to determine the lowest
address in kernel space. Any PC that is smaller than that should be in
user space.
On today's systems, there should be a symbol "_text" at that address.
Read /proc/kallsyms and search for that symbol.
It is not guaranteed that /proc/kallsyms is readable on all systems. On
64-bit systems, we fall back to check the most significant bit. On 32-bit
systems, we refrain from filtering out addresses.
The filtering should really be done by the kernel. And it soon will be:
https://lkml.org/lkml/2015/8/31/212.
gdb/
* nat/linux-btrace.h (struct btrace_target_info) <ptr_bits>: Remove.
* nat/linux-btrace.c: Include filestuff.h and inttypes.h.
Remove include of sys/utsname.h.
(linux_determine_kernel_ptr_bits): Remove.
(linux_determine_kernel_start): New.
(perf_event_is_kernel_addr): Remove tinfo argument. Update users.
Update check.
(perf_event_skip_bts_record): Remove tinfo argument. Update users.
(linux_enable_bts, linux_enable_pt): Remove tinfo->ptr_bits
initialization.
* x86-linux-nat.c (x86_linux_enable_btrace): Remove ptr_bits
assignment.
gdbserver/
* linux-low.c (linux_low_enable_btrace): Remove.
(linux_target_ops): Replace linux_low_enable_btrace with
linux_enable_btrace.
The Linux target and gdbserver now check the siginfo si_code
reported on a SIGTRAP to detect whether the trap indicates
a software breakpoint was hit.
Unfortunately, on Cell/B.E., the kernel uses an si_code value
of TRAP_BRKPT when a SW breakpoint was hit in PowerPC code,
but a si_code value of SI_KERNEL when a SW breakpoint was
hit in SPU code.
This patch updates Linux target and gdbserver to accept both
si_code values to indicate SW breakpoint on PowerPC.
ChangeLog:
* nat/linux-ptrace.h (GDB_ARCH_TRAP_BRKPT): Replace by ...
(GDB_ARCH_IS_TRAP_BRKPT): ... this. Add __powerpc__ case.
* linux-nat.c (check_stopped_by_breakpoint): Use
GDB_ARCH_IS_TRAP_BRKPT instead of GDB_ARCH_TRAP_BRKPT.
gdbserver/ChangeLog:
* linux-low.c (check_stopped_by_breakpoint): Use
GDB_ARCH_IS_TRAP_BRKPT instead of GDB_ARCH_TRAP_BRKPT.
In all-stop mode, if the current thread disappears while stopping all
threads, gdbserver calls set_desired_thread(0) ['0' means "I want the
continue thread"] which just picks the first thread in the list.
This looks like a dangerous thing to do. GDBserver continues
processing whatever it was doing, but to the wrong thread. If
debugging more than one process, we may even pick the wrong process.
Instead, GDBserver should detect the situation and bail out of
whatever is was doing.
The backends used to pay attention to the set 'cont_thread' (the Hc
thread, used in the old way to resume threads, before vCont), but all
such 'cont_thread' checks have been eliminated meanwhile. The
remaining implicit dependencies that I found on there being a selected
thread in the backends are in the Ctrl-C handling, which some backends
use as thread to send a signal to. Even that seems to me to be better
handled by always using the first thread in the list or by using the
signal_pid PID.
In order to make this a systematic approach, I'm making
set_desired_thread never fallback to a random thread, and instead end
up with current_thread == NULL, like already done in non-stop mode.
Then I updated all callers to handle the situation.
I stumbled on this while fixing other bugs exposed by
gdb.threads/fork-plus-threads.exp test. The problems I saw were fixed
in a different way, but in any case, I think the potential for
problems is more or less obvious, and the resulting code looks a bit
less magical to me.
Tested on x86-64 Fedora 20, w/ native-extended-gdbserver board.
gdb/gdbserver/ChangeLog:
2015-08-21 Pedro Alves <palves@redhat.com>
* linux-low.c (wait_for_sigstop): Always switch to no thread
selected if the previously current thread dies.
* lynx-low.c (lynx_request_interrupt): Use the first thread's
process instead of the current thread's.
* remote-utils.c (input_interrupt): Don't check if there's no
current thread.
* server.c (gdb_read_memory, gdb_write_memory): If setting the
current thread to the general thread fails, error out.
(handle_qxfer_auxv, handle_qxfer_libraries)
(handle_qxfer_libraries_svr4, handle_qxfer_siginfo)
(handle_qxfer_spu, handle_qxfer_statictrace, handle_qxfer_fdpic)
(handle_query): Check if there's a thread selected instead of
checking whether there's any thread in the thread list.
(handle_qxfer_threads, handle_qxfer_btrace)
(handle_qxfer_btrace_conf): Don't error out early if there's no
thread in the thread list.
(handle_v_cont, myresume): Don't set the current thread to the
continue thread.
(process_serial_event) <Hg handling>: Also set thread_id if the
previous general thread is still alive.
(process_serial_event) <g/G handling>: If setting the current
thread to the general thread fails, error out.
* spu-low.c (spu_resume, spu_request_interrupt): Use the first
thread's lwp instead of the current thread's.
* target.c (set_desired_thread): If the desired thread was not
found, leave the current thread pointing to NULL. Return an int
(boolean) indicating success.
* target.h (set_desired_thread): Change return type to int.
This tag allows debugging of MIPS position independent executables
and provides access to shared library information.
gdb/gdbserver/
* linux-low.c (get_r_debug): Handle DT_MIPS_RLD_MAP_REL.
gdb/
* solib-svr4.c (read_program_header): Add base_addr argument to
report the runtime address of the segment.
(find_program_interpreter): Update read_program_header call to pass
a NULL pointer for the new argument.
(scan_dyntag): Add ptr_addr argument to report the runtime address
of the tag payload.
(scan_dyntag_auxv): Likewise and use thew new base_addr argument of
read_program_header to get the base address of the dynamic segment.
(elf_locate_base): Update uses of scan_dyntag, scan_dyntag_auxv and
read_program_header.
(elf_locate_base): Scan for and handle DT_MIPS_RLD_MAP_REL.
While hacking on the fix for PR threads/18600 (Threads left stopped
after fork+thread spawn), I once saw its test (fork-plus-threads.exp)
FAIL against gdbserver because move_out_of_jump_pad_callback has a
gdb_breakpoint_here call, and the caller isn't making sure the current
thread points to the right thread. In the case I saw, the current
thread pointed to the wrong process, so gdb_breakpoint_here returned
the wrong answer. Unfortunately I didn't save logs. Still, seems
obvious enough and it should fix a potential occasional racy FAIL.
Tested on x86_64 Fedora 20.
gdb/gdbserver/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* linux-low.c (move_out_of_jump_pad_callback): Temporarily switch
the current thread.
Running gdbserver --debug under Valgrind shows:
==4803== Invalid read of size 4
==4803== at 0x432B62: linux_write_memory (linux-low.c:5320)
==4803== by 0x4143F7: write_inferior_memory (target.c:83)
==4803== by 0x415895: remove_memory_breakpoint (mem-break.c:362)
==4803== by 0x432EF5: linux_remove_point (linux-low.c:5460)
==4803== by 0x416319: delete_raw_breakpoint (mem-break.c:802)
==4803== by 0x4163F3: release_breakpoint (mem-break.c:842)
==4803== by 0x416477: delete_breakpoint_1 (mem-break.c:869)
==4803== by 0x4164EF: delete_breakpoint (mem-break.c:891)
==4803== by 0x416843: delete_gdb_breakpoint_1 (mem-break.c:1069)
==4803== by 0x4168D8: delete_gdb_breakpoint (mem-break.c:1098)
==4803== by 0x4134E3: process_serial_event (server.c:4051)
==4803== by 0x4138E4: handle_serial_event (server.c:4196)
==4803== Address 0x4c6b930 is 0 bytes inside a block of size 1 alloc'd
==4803== at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==4803== by 0x4240C6: xmalloc (common-utils.c:43)
==4803== by 0x41439C: write_inferior_memory (target.c:80)
==4803== by 0x415895: remove_memory_breakpoint (mem-break.c:362)
==4803== by 0x432EF5: linux_remove_point (linux-low.c:5460)
==4803== by 0x416319: delete_raw_breakpoint (mem-break.c:802)
==4803== by 0x4163F3: release_breakpoint (mem-break.c:842)
==4803== by 0x416477: delete_breakpoint_1 (mem-break.c:869)
==4803== by 0x4164EF: delete_breakpoint (mem-break.c:891)
==4803== by 0x416843: delete_gdb_breakpoint_1 (mem-break.c:1069)
==4803== by 0x4168D8: delete_gdb_breakpoint (mem-break.c:1098)
==4803== by 0x4134E3: process_serial_event (server.c:4051)
==4803==
And:
==7272== Conditional jump or move depends on uninitialised value(s)
==7272== at 0x3615E48361: vfprintf (vfprintf.c:1634)
==7272== by 0x414E89: debug_vprintf (debug.c:60)
==7272== by 0x42800A: debug_printf (common-debug.c:35)
==7272== by 0x43937B: my_waitpid (linux-waitpid.c:149)
==7272== by 0x42D740: linux_wait_for_event_filtered (linux-low.c:2441)
==7272== by 0x42DADA: linux_wait_for_event (linux-low.c:2552)
==7272== by 0x42E165: linux_wait_1 (linux-low.c:2860)
==7272== by 0x42F5D8: linux_wait (linux-low.c:3453)
==7272== by 0x4144A4: mywait (target.c:107)
==7272== by 0x413969: handle_target_event (server.c:4214)
==7272== by 0x41A1A6: handle_file_event (event-loop.c:429)
==7272== by 0x41996D: process_event (event-loop.c:184)
gdb/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* nat/linux-waitpid.c (my_waitpid): Only print *status if waitpid
returned > 0.
gdb/gdbserver/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_write_memory): Rewrite debug output to avoid
reading beyond the passed in buffer length.
Ref: https://sourceware.org/ml/gdb-patches/2015-07/msg00868.html
This adds a test that has a multithreaded program have several threads
continuously fork, while another thread continuously steps over a
breakpoint.
This exposes several intertwined issues, which this patch addresses:
- When we're stopping and suspending threads, some thread may fork,
and we missed setting its suspend count to 1, like we do when a new
clone/thread is detected. When we next unsuspend threads, the fork
child's suspend count goes below 0, which is bogus and fails an
assertion.
- If a step-over is cancelled because a signal arrives, but then gdb
is not interested in the signal, we pass the signal straight back
to the inferior. However, we miss that we need to re-increment the
suspend counts of all other threads that had been paused for the
step-over. As a result, other threads indefinitely end up stuck
stopped.
- If a detach request comes in just while gdbserver is handling a
step-over (in the test at hand, this is GDB detaching the fork
child), gdbserver internal errors in stabilize_thread's helpers,
which assert that all thread's suspend counts are 0 (otherwise we
wouldn't be able to move threads out of the jump pads). The
suspend counts aren't 0 while a step-over is in progress, because
all threads but the one stepping past the breakpoint must remain
paused until the step-over finishes and the breakpoint can be
reinserted.
- Occasionally, we see "BAD - reinserting but not stepping." being
output (from within linux_resume_one_lwp_throw). That was because
GDB pokes memory while gdbserver is busy with a step-over, and that
suspends threads, and then re-resumes them with proceed_one_lwp,
which missed another reason to tell linux_resume_one_lwp that the
thread should be set back to stepping.
- In a couple places, we were resuming threads that are meant to be
suspended. E.g., when a vCont;c/s request for thread B comes in
just while gdbserver is stepping thread A past a breakpoint. The
resume for thread B must be deferred until the step-over finishes.
- The test runs with both "set detach-on-fork" on and off. When off,
it exercises the case of GDB detaching the fork child explicitly.
When on, it exercises the case of gdb resuming the child
explicitly. In the "off" case, gdb seems to exponentially become
slower as new inferiors are created. This is _very_ noticeable as
with only 100 inferiors gdb is crawling already, which makes the
test take quite a bit to run. For that reason, I've disabled the
"off" variant for now.
gdb/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* target/waitstatus.h (enum target_stop_reason)
<TARGET_STOPPED_BY_SINGLE_STEP>: New value.
gdb/gdbserver/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Set the fork child's suspend
count if stopping and suspending threads.
(check_stopped_by_breakpoint): If stopped by trace, set the LWP's
stop reason to TARGET_STOPPED_BY_SINGLE_STEP.
(linux_detach): Complete an ongoing step-over.
(lwp_suspended_inc, lwp_suspended_decr): New functions. Use
throughout.
(resume_stopped_resumed_lwps): Don't resume a suspended thread.
(linux_wait_1): If passing a signal to the inferior after
finishing a step-over, unsuspend and re-resume all lwps. If we
see a single-step event but the thread should be continuing, don't
pass the trap to gdb.
(stuck_in_jump_pad_callback, move_out_of_jump_pad_callback): Use
internal_error instead of gdb_assert.
(enqueue_pending_signal): New function.
(check_ptrace_stopped_lwp_gone): Add debug output.
(start_step_over): Use internal_error instead of gdb_assert.
(complete_ongoing_step_over): New function.
(linux_resume_one_thread): Don't resume a suspended thread.
(proceed_one_lwp): If the LWP is stepping over a breakpoint, reset
it stepping.
gdb/testsuite/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* gdb.threads/forking-threads-plus-breakpoint.exp: New file.
* gdb.threads/forking-threads-plus-breakpoint.c: New file.
The tail end of linux_wait_1 isn't expecting that the select_event_lwp
machinery can pick a whole-process exit event to report to GDB. When
that happens, both gdb and gdbserver end up quite confused:
...
(gdb)
[Thread 24971.24971] #1 stopped.
0x0000003615a011f0 in ?? ()
c&
Continuing.
(gdb) [New Thread 24971.24981]
[New Thread 24983.24983]
[New Thread 24971.24982]
[Thread 24983.24983] #3 stopped.
0x0000003615ebc7cc in __libc_fork () at ../nptl/sysdeps/unix/sysv/linux/fork.c:130
130 pid = ARCH_FORK ();
[New Thread 24984.24984]
Error in re-setting breakpoint -16: PC register is not available
Error in re-setting breakpoint -17: PC register is not available
Error in re-setting breakpoint -18: PC register is not available
Error in re-setting breakpoint -19: PC register is not available
Error in re-setting breakpoint -24: PC register is not available
Error in re-setting breakpoint -25: PC register is not available
Error in re-setting breakpoint -26: PC register is not available
Error in re-setting breakpoint -27: PC register is not available
Error in re-setting breakpoint -28: PC register is not available
Error in re-setting breakpoint -29: PC register is not available
Error in re-setting breakpoint -30: PC register is not available
PC register is not available
(gdb)
gdb/gdbserver/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* linux-low.c (add_lwp): Set waitstatus to TARGET_WAITKIND_IGNORE.
(linux_thread_alive): Use lwp_is_marked_dead.
(extended_event_reported): Delete.
(linux_wait_1): Check if waitstatus is TARGET_WAITKIND_IGNORE
instead of extended_event_reported.
(mark_lwp_dead): Don't set the 'dead' flag. Store the waitstatus
as well.
(lwp_is_marked_dead): New function.
(lwp_running): Use lwp_is_marked_dead.
* linux-low.h: Delete 'dead' field, and update 'waitstatus's
comment.
The "extended event with waitstatus" debug output is unreachable, as
it is guarded by "if (!report_to_gdb)". If extended_event_reported is
true, then so is report_to_gdb. Move it to where we print why we're
reporting an event to GDB.
Also, the debug output currently tries to print the wrong struct
target_waitstatus.
gdb/gdbserver/ChangeLog:
2015-08-06 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_wait_1): Move fork event output out of the
!report_to_gdb check. Pass event_child->waitstatus to
target_waitstatus_to_string instead of ourstatus.
This patch moves variable have_ptrace_getregset from linux-x86-low.c
to linux-low.c, so that arm can use it too.
gdb/gdbserver:
2015-08-04 Yao Qi <yao.qi@linaro.org>
* linux-x86-low.c (have_ptrace_getregset): Move it to ...
* linux-low.c: ... here.
* linux-low.h (have_ptrace_getregset): Declare it.
Running gdb.threads/fork-plus-threads.exp against gdbserver in
extended-remote mode, even though the test passes, we still see broken
behavior:
(gdb) PASS: gdb.threads/fork-plus-threads.exp: set detach-on-fork off
continue &
Continuing.
(gdb) PASS: gdb.threads/fork-plus-threads.exp: continue &
[New Thread 28092.28092]
[Thread 28092.28092] #2 stopped.
[New Thread 28094.28094]
[Inferior 2 (process 28092) exited normally]
[New Thread 28094.28105]
[New Thread 28094.28109]
...
[Thread 28174.28174] #18 stopped.
[New Thread 28185.28185]
[Inferior 10 (process 28174) exited normally]
[New Thread 28185.28196]
[Thread 28185.28185] #20 stopped.
Cannot remove breakpoints because program is no longer writable.
Further execution is probably impossible.
[Inferior 11 (process 28185) exited normally]
[Inferior 1 (process 28091) exited normally]
PASS: gdb.threads/fork-plus-threads.exp: reached breakpoint
info threads
No threads.
(gdb) PASS: gdb.threads/fork-plus-threads.exp: no threads left
info inferiors
Num Description Executable
* 1 <null> /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.threads/fork-plus-threads
(gdb) PASS: gdb.threads/fork-plus-threads.exp: only inferior 1 left
All the "[Thread FOO] #NN stopped." above are bogus, as well as the
"Cannot remove breakpoints because program is no longer writable.",
which is a consequence.
The problem is that when we intercept a fork event, we should report
the event for the parent, only, and leave the child stopped, but not
report its stop event. GDB later decides whether to follow the parent
or the child. But because handle_extended_wait does not set the
child's last_status.kind to TARGET_WAITKIND_STOPPED, a
stop_all_threads/unstop_all_lwps sequence (e.g., from trying to access
memory) by mistake ends up queueing a SIGSTOP on the child, resuming
it, and then when that SIGSTOP is intercepted, because the LWP has
last_resume_kind set to resume_stop, gdbserver reports the stop to
GDB, as GDB_SIGNAL_0:
...
>>>> entering unstop_all_lwps
unstopping all lwps
proceed_one_lwp: lwp 1600
client wants LWP to remain 1600 stopped
proceed_one_lwp: lwp 1828
Client wants LWP 1828 to stop. Making sure it has a SIGSTOP pending
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sending sigstop to lwp 1828
pc is 0x3615ebc7cc
Resuming lwp 1828 (continue, signal 0, stop expected)
continue from pc 0x3615ebc7cc
unstop_all_lwps done
sigchld_handler
<<<< exiting unstop_all_lwps
handling possible target event
>>>> entering linux_wait_1
linux_wait_1: [<all threads>]
my_waitpid (-1, 0x40000001)
my_waitpid (-1, 0x1): status(137f), 1828
LWFE: waitpid(-1, ...) returned 1828, ERRNO-OK
LLW: waitpid 1828 received Stopped (signal) (stopped)
pc is 0x3615ebc7cc
Expected stop.
LLW: resume_stop SIGSTOP caught for LWP 1828.1828.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
linux_wait_1 ret = LWP 1828.1828, 1, 0
<<<< exiting linux_wait_1
Writing resume reply for LWP 1828.1828:1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Tested on x86_64 Fedora 20, extended-remote.
gdb/gdbserver/ChangeLog:
2015-07-30 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Set the child's last
reported status to TARGET_WAITKIND_STOPPED.
As the result of the previous patch, new_inferior is no longer used.
This patch is to remove it.
gdb/gdbserver:
2015-07-24 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_create_inferior): Remove setting to
proc->priv->new_inferior.
(linux_attach): Likewise.
(linux_low_filter_event): Likewise.
* linux-low.h (struct process_info_private) <new_inferior>: Remove.
Nowadays, when --wrapper is used, GDBserver skips extra traps/stops
in the wrapper program, and stops at the first instruction of the
program to be debugged. However, GDBserver created target description
in the first stop of inferior, and the executable of the inferior
is the wrapper program rather than the program to be debugged. In
this way, the target description can be wrong if the architectures
of wrapper program and program to be debugged are different. This
is shown by some fails in gdb.server/wrapper.exp on buildbot.
We are testing i686-linux GDB (Fedora-i686) on an x86_64-linux box
(fedora-x86-64-4) in buildbot, such configuration causes fails in
gdb.server/wrapper.exp like this:
spawn /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/../../gdb/gdbserver/gdbserver --once --wrapper env TEST=1 -- :2346 /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/outputs/gdb.server/wrapper/wrapper
Process /home/gdb-buildbot-2/fedora-x86-64-4/fedora-i686/build/gdb/testsuite/outputs/gdb.server/wrapper/wrapper created; pid = 8795
Can't debug 64-bit process with 32-bit GDBserver
Exiting
target remote localhost:2346
localhost:2346: Connection timed out.
(gdb) FAIL: gdb.server/wrapper.exp: setting breakpoint at marker
See https://sourceware.org/ml/gdb-testers/2015-q3/msg01541.html
In this case, program to be debugged ("wrapper") is 32-bit but wrapper
program ("/usr/bin/env") is 64-bit, so GDBserver gets the 64-bit
target description instead of 32-bit.
The root cause of this problem is that GDBserver creates target
description too early, and the rationale of fix could be creating
target description once the GDBserver skips extra traps and inferior
stops at the first instruction of the program we want to debug. IOW,
when GDBserver skips extra traps, the inferior's tdesc is NULL, and
mywait and its callees shouldn't use inferior's tdesc, so in this
patch, we skip code that requires register access, see changes in
linux_resume_one_lwp_throw and need_step_over_p.
In linux_low_filter_event, if target description isn't initialised and
GDBserver attached the process, we create target description immediately,
because GDBserver don't have to skip extra traps for attach, IOW, it
makes no sense to use --attach and --wrapper together. Otherwise, the
process is launched by GDBserver, we keep the status pending, and return.
After GDBserver skipped extra traps in start_inferior, we call a
target_ops hook arch_setup to initialise target description there.
gdb/gdbserver:
2015-07-24 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_arch_setup): New function.
(linux_low_filter_event): If proc->tdesc is NULL and
proc->attached is true, call the_low_target.arch_setup.
Otherwise, keep status pending, and return.
(linux_resume_one_lwp_throw): Don't call get_pc if
thread->while_stepping isn't NULL. Don't call
get_thread_regcache if proc->tdesc is NULL.
(need_step_over_p): Return 0 if proc->tdesc is NULL.
(linux_target_ops): Install arch_setup.
* server.c (start_inferior): Call the_target->arch_setup.
* target.h (struct target_ops) <arch_setup>: New field.
(target_arch_setup): New marco.
* lynx-low.c (lynx_target_ops): Update.
* nto-low.c (nto_target_ops): Update.
* spu-low.c (spu_target_ops): Update.
* win32-low.c (win32_target_ops): Update.
Nowadays, we set proc->priv->new_inferior to 1 inside linux_add_process,
and new_inferior is used as a flag to initialise target description later.
linux_add_process is used for the three cases, fork/vfork event
(handle_extended_wait), run the program (linux_create_inferior), and
attach to the process (linux_attach). In the first case, the child's
target description is copied from parent's, so we don't need to initialise
target description again later, which means we don't need to set
proc->priv->new_inferior to 1 in this case. For the rest of two cases,
we need this flag.
This patch move the code setting proc->priv->new_inferior to 1 inside
linux_add_process to linux_create_inferior and linux_attach. No
functionality is changed.
gdb/gdbserver:
2015-07-24 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_add_process): Don't set
proc->priv->new_inferior.
(linux_create_inferior): Set proc->priv->new_inferior to 1.
(linux_attach): Likewise.
Producer part of the new "build-id" XML attribute.
gdb/ChangeLog
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
Jan Kratochvil <jan.kratochvil@redhat.com>
gdbserver build-id attribute generator.
* features/library-list-svr4.dtd (library-list-svr4): New
'build-id' attribute.
gdb/doc/ChangeLog
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
Jan Kratochvil <jan.kratochvil@redhat.com>
gdbserver build-id attribute generator.
* gdb.texinfo (Library List Format for SVR4 Targets): Add
'build-id' in description, example, new attribute in dtd.
gdb/gdbserver/ChangeLog
2015-07-15 Aleksandar Ristovski <aristovski@qnx.com
Jan Kratochvil <jan.kratochvil@redhat.com>
gdbserver build-id attribute generator.
* linux-low.c (nat/linux-maps.h, search.h, rsp-low.h): Include.
(ElfXX_Ehdr, ElfXX_Phdr, ElfXX_Nhdr): New.
(ELFXX_FLD, ELFXX_SIZEOF, ELFXX_ROUNDUP, BUILD_ID_INVALID): New.
(find_phdr): New.
(get_dynamic): Use find_pdhr to traverse program headers.
(struct mapping_entry, mapping_entry_s, free_mapping_entry_vec)
(compare_mapping_entry_range, struct find_memory_region_callback_data)
(read_build_id, find_memory_region_callback, lrfind_mapping_entry)
(get_hex_build_id): New.
(linux_qxfer_libraries_svr4): Add optional build-id attribute
to reply XML document.
If the process disappears (e.g., killed with "kill -9" from the shell)
while it was stopped under GDBserver's control, and the GDBserver
tries to kill it, GDBserver asserts:
(gdb) shell kill -9 23084
(gdb) kill
...
Killing process(es): 23084
/home/pedro/gdb/mygit/src/gdb/gdbserver/linux-low.c:972: A problem internal to GDBserver has been detected.
kill_wait_lwp: Assertion `res > 0' failed.
...
gdb/gdbserver/ChangeLog:
2015-07-14 Pedro Alves <palves@redhat.com>
* linux-low.c (kill_wait_lwp): Don't assert if waitpid fails.
Instead, ignore ECHILD, and throw an error for other errnos.
Adds a new command "record btrace pt" to configure the kernel to use
Intel(R) Processor Trace instead of Branch Trace Strore.
The "record btrace" command chooses the tracing format automatically.
Intel(R) Processor Trace support requires Linux 4.1 and libipt.
gdb/
* NEWS: Announce new commands "record btrace pt" and "record pt".
Announce new options "set|show record btrace pt buffer-size".
* btrace.c: Include "rsp-low.h".
Include "inttypes.h".
(btrace_add_pc): Add forward declaration.
(pt_reclassify_insn, ftrace_add_pt, btrace_pt_readmem_callback)
(pt_translate_cpu_vendor, btrace_finalize_ftrace_pt)
(btrace_compute_ftrace_pt): New.
(btrace_compute_ftrace): Support BTRACE_FORMAT_PT.
(check_xml_btrace_version): Update version check.
(parse_xml_raw, parse_xml_btrace_pt_config_cpu)
(parse_xml_btrace_pt_raw, parse_xml_btrace_pt)
(btrace_pt_config_cpu_attributes, btrace_pt_config_children)
(btrace_pt_children): New.
(btrace_children): Add support for "pt".
(parse_xml_btrace_conf_pt, btrace_conf_pt_attributes): New.
(btrace_conf_children): Add support for "pt".
* btrace.h: Include "intel-pt.h".
(btrace_pt_error): New.
* common/btrace-common.c (btrace_format_string, btrace_data_fini)
(btrace_data_empty): Support BTRACE_FORMAT_PT.
* common/btrace-common.h (btrace_format): Add BTRACE_FORMAT_PT.
(struct btrace_config_pt): New.
(struct btrace_config)<pt>: New.
(struct btrace_data_pt_config, struct btrace_data_pt): New.
(struct btrace_data)<pt>: New.
* features/btrace-conf.dtd (btrace-conf)<pt>: New.
(pt): New.
* features/btrace.dtd (btrace)<pt>: New.
(pt, pt-config, cpu): New.
* nat/linux-btrace.c (perf_event_read, perf_event_read_all)
(perf_event_pt_event_type, kernel_supports_pt)
(linux_supports_pt): New.
(linux_supports_btrace): Support BTRACE_FORMAT_PT.
(linux_enable_bts): Free tinfo on error.
(linux_enable_pt): New.
(linux_enable_btrace): Support BTRACE_FORMAT_PT.
(linux_disable_pt): New.
(linux_disable_btrace): Support BTRACE_FORMAT_PT.
(linux_fill_btrace_pt_config, linux_read_pt): New.
(linux_read_btrace): Support BTRACE_FORMAT_PT.
* nat/linux-btrace.h (struct btrace_tinfo_pt): New.
(struct btrace_target_info)<pt>: New.
* record-btrace.c (set_record_btrace_pt_cmdlist)
(show_record_btrace_pt_cmdlist): New.
(record_btrace_print_pt_conf): New.
(record_btrace_print_conf): Support BTRACE_FORMAT_PT.
(btrace_ui_out_decode_error): Support BTRACE_FORMAT_PT.
(cmd_record_btrace_pt_start): New.
(cmd_record_btrace_start): Support BTRACE_FORMAT_PT.
(cmd_set_record_btrace_pt, cmd_show_record_btrace_pt): New.
(_initialize_record_btrace): Add new commands.
* remote.c (PACKET_Qbtrace_pt, PACKET_Qbtrace_conf_pt_size): New.
(remote_protocol_features): Add "Qbtrace:pt".
Add "Qbtrace-conf:pt:size".
(remote_supports_btrace): Support BTRACE_FORMAT_PT.
(btrace_sync_conf): Support PACKET_Qbtrace_conf_pt_size.
(remote_enable_btrace): Support BTRACE_FORMAT_PT.
(_initialize_remote): Add new commands.
gdbserver/
* linux-low.c: Include "rsp-low.h"
(linux_low_encode_pt_config, linux_low_encode_raw): New.
(linux_low_read_btrace): Support BTRACE_FORMAT_PT.
(linux_low_btrace_conf): Support BTRACE_FORMAT_PT.
(handle_btrace_enable_pt): New.
(handle_btrace_general_set): Support "pt".
(handle_btrace_conf_general_set): Support "pt:size".
doc/
* gdb.texinfo (Process Record and Replay): Spell out that variables
and registers are not available during btrace replay.
Describe the new "record btrace pt" command.
Describe the new "set|show record btrace pt buffer-size" options.
(General Query Packets): Describe the new Qbtrace:pt and
Qbtrace-conf:pt:size packets.
Expand "bts" to "Branch Trace Store".
Update the branch trace DTD.
This commit implements the "vFile:setfs" packet in gdbserver.
gdb/gdbserver/ChangeLog:
* target.h (struct target_ops) <multifs_open>: New field.
<multifs_unlink>: Likewise.
<multifs_readlink>: Likewise.
* linux-low.c (nat/linux-namespaces.h): New include.
(linux_target_ops): Initialize the_target->multifs_open,
the_target->multifs_unlink and the_target->multifs_readlink.
* hostio.h (hostio_handle_new_gdb_connection): New declaration.
* hostio.c (hostio_fs_pid): New static variable.
(hostio_handle_new_gdb_connection): New function.
(handle_setfs): Likewise.
(handle_open): Use the_target->multifs_open as appropriate.
(handle_unlink): Use the_target->multifs_unlink as appropriate.
(handle_readlink): Use the_target->multifs_readlink as
appropriate.
(handle_vFile): Handle vFile:setfs packets.
* server.c (handle_query): Call hostio_handle_new_gdb_connection
after target_handle_new_gdb_connection.
This patch fixes some intermittent test failures in
gdb.base/foll-vfork.exp where a vfork child would be (incorrectly)
resumed when handling the vfork event. In this case the result
was a subsequent event reported to the client side as a SIGTRAP
delivered to the as-yet-unknown child thread.
The new thread was resumed (incorrectly) in linux-low.c when
resume_stopped_resumed_lwps was called from
linux_wait_for_event_filtered after the vfork event had been
handled in handle_extended_wait.
Gdbserver/linux-low.c's add_thread function creates threads with
last_resume_kind == resume_continue by default. This field is
used by resume_stopped_resumed_lwps to decide whether to perform
the resume:
static void
resume_stopped_resumed_lwps (struct inferior_list_entry *entry) {
struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
if (lp->stopped
&& !lp->status_pending_p
&& thread->last_resume_kind != resume_stop
&& thread->last_status.kind == TARGET_WAITKIND_IGNORE)
{
So the fix is to make sure to set thread->last_resume_kind to
resume_stop. Here we do that for new fork children in
gdbserver/linux-low.c:handle_extended_wait.
In addition, it seemed prudent to initialize lwp_info.status_pending_p
for the new fork child. I also rearranged the initialization code
so that all of the lwp_info initialization was together, rather than
intermixed with thread_info and process_info initialization.
Tested native, native-gdbserver, native-extended-gdbserver on
x86_64 GNU/Linux.
gdb/gdbserver/
* linux-low.c (handle_extended_wait): Initialize
thread_info.last_resume_kind for new fork children.
This patch implements follow-fork for vfork on extended-remote Linux targets.
The implementation follows the native implementation as much as possible.
Most of the work is done on the GDB side in the existing code now in
infrun.c. GDBserver just has to report the events and do a little
bookkeeping.
Implementation includes:
* enabling VFORK events by adding ptrace options for VFORK and VFORK_DONE
to linux-low.c:linux_low_ptrace_options.
* handling VFORK and VFORK_DONE events in linux-low.c:handle_extended_wait
and reporting them to GDB.
* including VFORK and VFORK_DONE events in the predicate
linux-low.c:extended_event_reported.
* adding support for VFORK and VFORK_DONE events in RSP by adding stop
reasons "vfork" and "vforkdone" to the 'T' Stop Reply Packet in both
gdbserver/remote-utils.c and gdb/remote.c.
Tested on x64 Ubuntu Lucid, native, remote, extended-remote.
gdb/gdbserver/ChangeLog:
* linux-low.c (handle_extended_wait): Handle PTRACE_EVENT_FORK and
PTRACE_EVENT_VFORK_DONE.
(linux_low_ptrace_options, extended_event_reported): Add vfork
events.
* remote-utils.c (prepare_resume_reply): New stop reasons "vfork"
and "vforkdone" for RSP 'T' Stop Reply Packet.
* server.h (report_vfork_events): Declare
global variable.
gdb/ChangeLog:
* remote.c (remove_vfork_event_p): New function.
(remote_follow_fork): Add vfork event type to event checking.
(remote_parse_stop_reply): New stop reasons "vfork" and
"vforkdone" for RSP 'T' Stop Reply Packet.
This patch implements the architecture-specific pieces of follow-fork
for remote and extended-remote Linux targets, which in the current
implementation copyies the parent's debug register state into the new
child's data structures. This is required for x86, arm, aarch64, and
mips.
This follows the native implementation as closely as possible by
implementing a new linux_target_ops function 'new_fork', which is
analogous to 'linux_nat_new_fork' in linux-nat.c. In gdbserver, the debug
registers are stored in the process list, instead of an
architecture-specific list, so the function arguments are process_info
pointers instead of an lwp_info and a pid as in the native implementation.
In the MIPS implementation the debug register mirror is stored differently
from x86, ARM, and aarch64, so instead of doing a simple structure assignment
I had to clone the list of watchpoint structures.
Tested using gdb.threads/watchpoint-fork.exp on x86, and ran manual tests
on a MIPS board and an ARM board. Aarch64 hasn't been tested.
gdb/gdbserver/ChangeLog:
* linux-aarch64-low.c (aarch64_linux_new_fork): New function.
(the_low_target) <new_fork>: Initialize new member.
* linux-arm-low.c (arm_new_fork): New function.
(the_low_target) <new_fork>: Initialize new member.
* linux-low.c (handle_extended_wait): Call new target function
new_fork.
* linux-low.h (struct linux_target_ops) <new_fork>: New member.
* linux-mips-low.c (mips_add_watchpoint): New function
extracted from mips_insert_point.
(the_low_target) <new_fork>: Initialize new member.
(mips_linux_new_fork): New function.
(mips_insert_point): Call mips_add_watchpoint.
* linux-x86-low.c (x86_linux_new_fork): New function.
(the_low_target) <new_fork>: Initialize new member.
This patch implements basic support for follow-fork and detach-on-fork on
extended-remote Linux targets. Only 'fork' is supported in this patch;
'vfork' support is added n a subsequent patch. This patch depends on
the previous patches in the patch series.
Sufficient extended-remote functionality has been implemented here to pass
gdb.base/multi-forks.exp, as well as gdb.base/foll-fork.exp with the
catchpoint tests commented out. Some other fork tests fail with this
patch because it doesn't provide the architecture support needed for
watchpoint inheritance or fork catchpoints.
The implementation follows the same general structure as for the native
implementation as much as possible.
This implementation includes:
* enabling fork events in linux-low.c in initialize_low and
linux_enable_extended_features
* handling fork events in gdbserver/linux-low.c:handle_extended_wait
- when a fork event occurs in gdbserver, we must do the full creation
of the new process, thread, lwp, and breakpoint lists. This is
required whether or not the new child is destined to be
detached-on-fork, because GDB will make target calls that require all
the structures. In particular we need the breakpoint lists in order
to remove the breakpoints from a detaching child. If we are not
detaching the child we will need all these structures anyway.
- as part of this event handling we store the target_waitstatus in a new
member of the parent lwp_info structure, 'waitstatus'. This
is used to store extended event information for reporting to GDB.
- handle_extended_wait is given a return value, denoting whether the
handled event should be reported to GDB. Previously it had only
handled clone events, which were never reported.
* using a new predicate in gdbserver to control handling of the fork event
(and eventually all extended events) in linux_wait_1. The predicate,
extended_event_reported, checks a target_waitstatus.kind for an
extended ptrace event.
* implementing a new RSP 'T' Stop Reply Packet stop reason: "fork", in
gdbserver/remote-utils.c and remote.c.
* implementing new target and RSP support for target_follow_fork with
target extended-remote. (The RSP components were actually defined in
patch 1, but they see their first use here).
- remote target routine remote_follow_fork, which just sends the 'D;pid'
detach packet to detach the new fork child cleanly. We can't just
call target_detach because the data structures for the forked child
have not been allocated on the host side.
Tested on x64 Ubuntu Lucid, native, remote, extended-remote.
gdb/gdbserver/ChangeLog:
* linux-low.c (handle_extended_wait): Implement return value,
rename argument 'event_child' to 'event_lwp', handle
PTRACE_EVENT_FORK, call internal_error for unrecognized event.
(linux_low_ptrace_options): New function.
(linux_low_filter_event): Call linux_low_ptrace_options,
use different argument fo linux_enable_event_reporting,
use return value from handle_extended_wait.
(extended_event_reported): New function.
(linux_wait_1): Call extended_event_reported and set
status to report fork events.
(linux_write_memory): Add pid to debug message.
(reset_lwp_ptrace_options_callback): New function.
(linux_handle_new_gdb_connection): New function.
(linux_target_ops): Initialize new structure member.
* linux-low.h (struct lwp_info) <waitstatus>: New member.
* lynx-low.c: Initialize new structure member.
* remote-utils.c (prepare_resume_reply): Implement stop reason
"fork" for "T" stop message.
* server.c (handle_query): Call handle_new_gdb_connection.
* server.h (report_fork_events): Declare global flag.
* target.h (struct target_ops) <handle_new_gdb_connection>:
New member.
(target_handle_new_gdb_connection): New macro.
* win32-low.c: Initialize new structure member.
gdb/ChangeLog:
* linux-nat.c (linux_nat_ptrace_options): New function.
(linux_init_ptrace, wait_lwp, linux_nat_filter_event):
Call linux_nat_ptrace_options and use different argument to
linux_enable_event_reporting.
(_initialize_linux_nat): Delete call to
linux_ptrace_set_additional_flags.
* nat/linux-ptrace.c (current_ptrace_options): Rename to
supported_ptrace_options.
(additional_flags): Delete variable.
(linux_check_ptrace_features): Use supported_ptrace_options.
(linux_test_for_tracesysgood, linux_test_for_tracefork):
Likewise, and remove additional_flags check.
(linux_enable_event_reporting): Change 'attached' argument to
'options'. Use supported_ptrace_options.
(ptrace_supports_feature): Change comment. Use
supported_ptrace_options.
(linux_ptrace_set_additional_flags): Delete function.
* nat/linux-ptrace.h (linux_ptrace_set_additional_flags):
Delete function prototype.
* remote.c (remote_fork_event_p): New function.
(remote_detach_pid): New function.
(remote_detach_1): Call remote_detach_pid, don't mourn inferior
if doing detach-on-fork.
(remote_follow_fork): New function.
(remote_parse_stop_reply): Handle new "T" stop reason "fork".
(remote_pid_to_str): Print "process" strings for pid/0/0 ptids.
(init_extended_remote_ops): Initialize to_follow_fork.
This patch implements a mechanism for GDB to determine whether fork
events are supported in gdbserver. This is a preparatory patch for
remote fork and exec event support.
Two new RSP packets are defined to represent fork and vfork event
support. These packets are used just like PACKET_multiprocess_feature
to denote whether the corresponding event is supported. GDB sends
fork-events+ and vfork-events+ to gdbserver to inquire about fork
event support. If the response enables these packets, then GDB
knows that gdbserver supports the corresponding events and will
enable them.
Target functions used to query for support are included along with
each new packet.
In order for gdbserver to know whether the events are supported at the
point where the qSupported packet arrives, the code in nat/linux-ptrace.c
had to be reorganized. Previously it would test for fork/exec event
support, then enable the events using the pid of the inferior. When the
qSupported packet arrives there may not be an inferior. So the mechanism
was split into two parts: a function that checks whether the events are
supported, called when gdbserver starts up, and another that enables the
events when the inferior stops for the first time.
Another gdbserver change was to add some global variables similar to
multi_process, one per new packet. These are used to control whether
the corresponding fork events are enabled. If GDB does not inquire
about the event support in the qSupported packet, then gdbserver will
not set these "report the event" flags. If the flags are not set, the
events are ignored like they were in the past. Thus, gdbserver will
never send fork event notification to an older GDB that doesn't
recognize fork events.
Tested on Ubuntu x64, native/remote/extended-remote, and as part of
subsequent patches in the series.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_supports_fork_events): New function.
(linux_supports_vfork_events): New function.
(linux_target_ops): Initialize new structure members.
(initialize_low): Call linux_check_ptrace_features.
* lynx-low.c (lynx_target_ops): Initialize new structure
members.
* server.c (report_fork_events, report_vfork_events):
New global flags.
(handle_query): Add new features to qSupported packet and
response.
(captured_main): Initialize new global variables.
* target.h (struct target_ops) <supports_fork_events>:
New member.
<supports_vfork_events>: New member.
(target_supports_fork_events): New macro.
(target_supports_vfork_events): New macro.
* win32-low.c (win32_target_ops): Initialize new structure
members.
gdb/ChangeLog:
* nat/linux-ptrace.c (linux_check_ptrace_features): Change
from static to extern.
* nat/linux-ptrace.h (linux_check_ptrace_features): Declare.
* remote.c (anonymous enum): <PACKET_fork_event_feature,
* PACKET_vfork_event_feature>: New enumeration constants.
(remote_protocol_features): Add table entries for new packets.
(remote_query_supported): Add new feature queries to qSupported
packet.
(_initialize_remote): Exempt new packets from the requirement
to have 'set remote' commands.
GDBserver steps over breakpoint if the condition is false, but if target
doesn't support hardware single step, the step over is very simple, if
not incorrect, in linux-arm-low.c:
/* We only place breakpoints in empty marker functions, and thread locking
is outside of the function. So rather than importing software single-step,
we can just run until exit. */
static CORE_ADDR
arm_reinsert_addr (void)
{
struct regcache *regcache = get_thread_regcache (current_thread, 1);
unsigned long pc;
collect_register_by_name (regcache, "lr", &pc);
return pc;
}
and linux-mips-low.c does the same. GDBserver sets a breakpoint at the
return address of the current function, resume and wait the program hits
the breakpoint in order to achieve "breakpoint step over". What if
program hits other user breakponits during this "step over"?
It is worse if the arm/thumb interworking is considered. Nowadays,
GDBserver arm backend unconditionally inserts arm breakpoint,
/* Define an ARM-mode breakpoint; we only set breakpoints in the C
library, which is most likely to be ARM. If the kernel supports
clone events, we will never insert a breakpoint, so even a Thumb
C library will work; so will mixing EABI/non-EABI gdbserver and
application. */
(const unsigned char *) &arm_breakpoint,
(const unsigned char *) &arm_eabi_breakpoint,
note that the comments are no longer valid as C library can be compiled
in thumb mode.
When GDBserver steps over a breakpoint in arm mode function, which
returns to thumb mode, GDBserver will insert arm mode breakpoint by
mistake and the program will crash. GDBserver alone is unable to
determine the arm/thumb mode given a PC address. See how GDB does
it in arm-tdep.c:arm_pc_is_thumb.
After thinking about how to teach GDBserver inserting right breakpoint
(arm or thumb) for a while, I reconsider it from a different direction
that it may be unreasonable to run target-side conditional breakpoint for
targets without hardware single step. Pedro also pointed this out here
https://sourceware.org/ml/gdb-patches/2015-04/msg00337.html
This patch is to add a new target_ops hook
supports_conditional_breakpoints, and only reply
";ConditionalBreakpoints+" if it is true. On linux targets,
supports_conditional_breakpoints returns true if target has hardware
single step, on other targets, (win32, lynx, nto, spu), set it to NULL,
because conditional breakpoint is a linux-specific feature.
gdb/gdbserver:
2015-05-08 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_supports_conditional_breakpoints): New
function.
(linux_target_ops): Install new target method.
* lynx-low.c (lynx_target_ops): Install NULL hook for
supports_conditional_breakpoints.
* nto-low.c (nto_target_ops): Likewise.
* spu-low.c (spu_target_ops): Likewise.
* win32-low.c (win32_target_ops): Likewise.
* server.c (handle_query): Check
target_supports_conditional_breakpoints.
* target.h (struct target_ops) <supports_conditional_breakpoints>:
New field.
(target_supports_conditional_breakpoints): New macro.
Hi,
I see the following error on arm linux gdbserver,
continue^M
Continuing.^M
../../../binutils-gdb/gdb/gdbserver/linux-arm-low.c:458: A problem internal to GDBserver has been detected.^M
raw_bkpt_type_to_arm_hwbp_type: unhandled raw type^M
Remote connection closed^M
(gdb) FAIL: gdb.base/cond-eval-mode.exp: hbreak: continue
After we make GDBserver handling Zx/zx packet idempotent,
[PATCH 3/3] [GDBserver] Make Zx/zx packet handling idempotent.
https://sourceware.org/ml/gdb-patches/2014-04/msg00480.html
> Now removal/insertion of all kinds of breakpoints/watchpoints, either
> internal, or from GDB, always go through the target methods.
GDBserver handles all kinds of breakpoints/watchpoints through target
methods. However, some target backends, such as arm, don't support Z0
packet but need software breakpoint to do breakpoint stepping over in
linux-low.c:start_step_over,
if (can_hardware_single_step ())
{
step = 1;
}
else
{
CORE_ADDR raddr = (*the_low_target.breakpoint_reinsert_addr) ();
set_reinsert_breakpoint (raddr);
step = 0;
}
a software breakpoint is requested to the backend, and the error is
triggered. This problem should affect targets having
breakpoint_reinsert_addr hooked.
Instead of handling memory breakpoint in these affected linux backend,
this patch handles memory breakpoint in linux_{insert,remove}_point,
that, if memory breakpoint is requested, call
{insert,remove}_memory_breakpoint respectively. Then, it becomes
unnecessary to handle memory breakpoint for linux x86 backend, so
this patch removes the code there.
This patch is tested with GDBserver on x86_64-linux and arm-linux
(-marm, -mthumb). Note that there are still some fails in
gdb.base/cond-eval-mode.exp with -mthumb, because GDBserver doesn't
know how to select the correct breakpoint instruction according to
the arm-or-thumb-mode of requested address. This is a separate
issue, anyway.
gdb/gdbserver:
2015-04-09 Yao Qi <yao.qi@linaro.org>
* linux-low.c (linux_insert_point): Call
insert_memory_breakpoint if TYPE is raw_bkpt_type_sw.
(linux_remove_point): Call remove_memory_breakpoint if type is
raw_bkpt_type_sw.
* linux-x86-low.c (x86_insert_point): Don't call
insert_memory_breakpoint.
(x86_remove_point): Don't call remove_memory_breakpoint.
This adds/tweaks a few debug logs I found useful recently.
gdb/gdbserver/ChangeLog:
2015-03-24 Pedro Alves <palves@redhat.com>
* linux-low.c (check_stopped_by_breakpoint): Tweak debug log
output. Also dump TRAP_TRACE.
(linux_low_filter_event): In debug output, distinguish a
resume_stop SIGSTOP from a delayed SIGSTOP.
gdb/ChangeLog:
2015-03-24 Pedro Alves <palves@redhat.com>
* linux-nat.c (linux_nat_resume): Output debug logs before trying
to resume the event lwp. Use the lwp's ptid instead of the passed
in (maybe wildcard) ptid.
(stop_wait_callback): Tweak debug log output.
(check_stopped_by_breakpoint): Tweak debug log output. Also dump
TRAP_TRACE.
(linux_nat_filter_event): In debug output, distinguish a
resume_stop SIGSTOP from a delayed SIGSTOP. Output debug logs
before trying to resume the lwp.
This commit moves the code to handle lwp_info.arch_private for
Linux x86 into a new shared file, nat/x86-linux.c.
gdb/ChangeLog:
* nat/x86-linux.h: New file.
* nat/x86-linux.c: Likewise.
* Makefile.in (HFILES_NO_SRCDIR): Add nat/x86-linux.h.
(x86-linux.o): New rule.
* config/i386/linux.mh (NATDEPFILES): Add x86-linux.o.
* config/i386/linux64.mh (NATDEPFILES): Likewise.
* nat/linux-nat.h (struct arch_lwp_info): New forward declaration.
(lwp_set_arch_private_info): New declaration.
(lwp_arch_private_info): Likewise.
* linux-nat.c (lwp_set_arch_private_info): New function.
(lwp_arch_private_info): Likewise.
* x86-linux-nat.c: Include nat/x86-linux.h.
(arch_lwp_info): Removed structure.
(update_debug_registers_callback):
Use lwp_set_debug_registers_changed.
(x86_linux_prepare_to_resume): Use lwp_debug_registers_changed
and lwp_set_debug_registers_changed.
(x86_linux_new_thread): Use lwp_set_debug_registers_changed.
gdb/gdbserver/ChangeLog:
* Makefile.in (x86-linux.o): New rule.
* configure.srv: Add x86-linux.o to relevant targets.
* linux-low.c (lwp_set_arch_private_info): New function.
(lwp_arch_private_info): Likewise.
* linux-x86-low.c: Include nat/x86-linux.h.
(arch_lwp_info): Removed structure.
(update_debug_registers_callback):
Use lwp_set_debug_registers_changed.
(x86_linux_prepare_to_resume): Use lwp_debug_registers_changed
and lwp_set_debug_registers_changed.
(x86_linux_new_thread): Use lwp_set_debug_registers_changed.
This commit changes the signature of linux_target_ops.new_thread in
gdbserver to match that used in GDB's equivalent.
gdb/gdbserver/ChangeLog:
* linux-low.h (linux_target_ops) <new_thread>: Changed signature.
* linux-arm-low.c (arm_new_thread): Likewise.
* linux-aarch64-low.c (aarch64_linux_new_thread): Likewise.
* linux-mips-low.c (mips_linux_new_thread): Likewise.
* linux-x86-low.c (x86_linux_new_thread): Likewise.
* linux-low.c (add_lwp): Update the_low_target.new_thread call.
This commit introduces three accessors that shared Linux code can
use to access fields of struct lwp_info. The GDB and gdbserver
Linux x86 code is modified to use them.
gdb/ChangeLog:
* nat/linux-nat.h (ptid_of_lwp): New declaration.
(lwp_is_stopped): Likewise.
(lwp_stop_reason): Likewise.
* linux-nat.c (ptid_of_lwp): New function.
(lwp_is_stopped): Likewise.
(lwp_is_stopped_by_watchpoint): Likewise.
* x86-linux-nat.c (update_debug_registers_callback):
Use lwp_is_stopped.
(x86_linux_prepare_to_resume): Use ptid_of_lwp and
lwp_stop_reason.
gdb/gdbserver/ChangeLog:
* linux-low.c (ptid_of_lwp): New function.
(lwp_is_stopped): Likewise.
(lwp_stop_reason): Likewise.
* linux-x86-low.c (update_debug_registers_callback):
Use lwp_is_stopped.
(x86_linux_prepare_to_resume): Use ptid_of_lwp and
lwp_stop_reason.
This commit introduces a new function, iterate_over_lwps, that
shared Linux code can use to call a function for each LWP that
matches certain criteria. This function already existed in GDB
and was in use by GDB's various low-level Linux x86 debug register
setters. An equivalent was written for gdbserver and gdbserver's
low-level Linux x86 debug register setters were modified to use
it.
gdb/ChangeLog:
* linux-nat.h: Include nat/linux-nat.h.
(iterate_over_lwps): Move declaration to nat/linux-nat.h.
* nat/linux-nat.h (struct lwp_info): New forward declaration.
(iterate_over_lwps_ftype): New typedef.
(iterate_over_lwps): New declaration.
* linux-nat.h (iterate_over_lwps): Update comment. Use
iterate_over_lwps_ftype. Update callback return value check.
gdb/gdbserver/ChangeLog:
* linux-low.h: Include nat/linux-nat.h.
* linux-low.c (iterate_over_lwps_args): New structure.
(iterate_over_lwps_filter): New function.
(iterate_over_lwps): Likewise.
* linux-x86-low.c (update_debug_registers_callback):
Update signature to what iterate_over_lwps expects.
Remove PID check that iterate_over_lwps now performs.
(x86_dr_low_set_addr): Use iterate_over_lwps.
(x86_dr_low_set_control): Likewise.
This commit introduces a new function, current_lwp_ptid, that
shared Linux code can use to obtain the ptid of the current
lightweight process.
gdb/ChangeLog:
* nat/linux-nat.h (current_lwp_ptid): New declaration.
* linux-nat.c (current_lwp_ptid): New function.
* x86-linux-nat.c: Include nat/linux-nat.h.
(x86_linux_dr_get_addr): Use current_lwp_ptid.
(x86_linux_dr_get_control): Likewise.
(x86_linux_dr_get_status): Likewise.
(x86_linux_dr_set_control): Likewise.
(x86_linux_dr_set_addr): Likewise.
gdb/gdbserver/ChangeLog:
* linux-low.c (current_lwp_ptid): New function.
* linux-x86-low.c: Include nat/linux-nat.h.
(x86_dr_low_get_addr): Use current_lwp_ptid.
(x86_dr_low_get_control): Likewise.
(x86_dr_low_get_status): Likewise.
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.
The previous change added an assertion that is catching yet another
bug in count_events_callback/select_event_lwp_callback:
(gdb)
PASS: gdb.mi/mi-nonstop.exp: interrupted
mi_expect_interrupt: expecting: \*stopped,(reason="signal-received",signal-name="0",signal-meaning="Signal 0"|reason="signal-received",signal-name="SIGINT",signal-meaning="Interrupt")[^
]*
/home/pedro/gdb/mygit/src/gdb/gdbserver/linux-low.c:2329: A problem internal to GDBserver has been detected.
select_event_lwp: Assertion `num_events > 0' failed.
=thread-group-exited,id="i1"
Certainly select_event_lwp_callback should always at least find one
event, as it's only called because an event triggered (though we may
have more than one: the point of the function is randomly picking
one).
An LWP that GDB previously asked to continue/step (thus is resumed)
and gets a vCont;t request ends up with last_resume_kind ==
resume_stop. These functions in gdbserver used to filter out events
that weren't going to be reported to GDB; I think the last_resume_kind
kind check used to make sense at that point, but it no longer does.
gdb/gdbserver/ChangeLog:
2015-03-19 Pedro Alves <palves@redhat.com>
* linux-low.c (count_events_callback, select_event_lwp_callback):
No longer check whether the thread has resume_stop as last resume
kind.
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.
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.
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.
This patch adjusts gdbserver's Linux backend to tell gdbserver core
(and ultimately GDB) whether a trap was caused by a breakpoint.
It teaches the backend to get that information out of the si_code of
the SIGTRAP siginfo.
gdb/gdbserver/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* linux-low.c (check_stopped_by_breakpoint) [USE_SIGTRAP_SIGINFO]:
Decide whether a breakpoint triggered based on the SIGTRAP's
siginfo.si_code.
(thread_still_has_status_pending_p) [USE_SIGTRAP_SIGINFO]: Don't check whether a
breakpoint is inserted if relying on SIGTRAP's siginfo.si_code.
(linux_low_filter_event): Check for breakpoints before checking
watchpoints.
(linux_wait_1): Don't re-increment the PC if relying on SIGTRAP's
siginfo.si_code.
(linux_stopped_by_sw_breakpoint)
(linux_supports_stopped_by_sw_breakpoint)
(linux_stopped_by_hw_breakpoint)
(linux_supports_stopped_by_hw_breakpoint): New functions.
(linux_target_ops): Install new target methods.
The heuristic for filtering out kernel addressess in BTS trace checks the
most significant bit in each address. This works fine for 32-bit and 64-bit
mode.
For 32-bit compatibility mode, i.e. a 32-bit inferior running on 64-bit
host, we need to check bit 63 (or any bit bigger than 31), not bit 31.
Use the machine field in struct utsname provided by a uname call to
determine whether we are running on a 64-bit host.
Thanks to Jan Kratochvil for reporting the issue.
gdb/
* nat/linux-btrace.c: Include sys/utsname.h.
(linux_determine_kernel_ptr_bits): New.
(linux_enable_bts): Call linux_determine_kernel_ptr_bits.
* x86-linux-nat.c (x86_linux_enable_btrace): Do not overwrite non-zero
ptr_bits.
gdbserver/
* linux-low.c (linux_low_enable_btrace): Do not overwrite non-zero
ptr_bits.
This patch renames symbols that happen to have names which are
reserved keywords in C++.
Most of this was generated with Tromey's cxx-conversion.el script.
Some places where later hand massaged a bit, to fix formatting, etc.
And this was rebased several times meanwhile, along with re-running
the script, so re-running the script from scratch probably does not
result in the exact same output. I don't think that matters anyway.
gdb/
2015-02-27 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
Rename symbols whose names are reserved C++ keywords throughout.
gdb/gdbserver/
2015-02-27 Tom Tromey <tromey@redhat.com>
Pedro Alves <palves@redhat.com>
Rename symbols whose names are reserved C++ keywords throughout.
.decr_pc_after_break is never higher than .breakpoint_len, so use
.breakpoint_len directly. Based on idea from Yao here:
https://sourceware.org/ml/gdb-patches/2015-02/msg00689.html
gdb/gdbserver/ChangeLog:
2015-02-26 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_wait_1): When incrementing the PC past a
program breakpoint always use the_low_target.breakpoint_len as
increment, rather than the maximum between that and
the_low_target.decr_pc_after_break.
I'm going to add an alternate mechanism of breakpoint trap
identification to 'check_stopped_by_breakpoint' that does not rely on
checking the instruction at PC. The mechanism currently used to tell
whether we're stepping over a permanent breakpoint doesn't fit in that
new method. This patch redoes the whole logic in a different way that
works with both old and new methods, in essence moving the "stepped
permanent breakpoint" detection "one level up". It makes lower level
check_stopped_by_breakpoint always the adjust the PC, and then has
linux_wait_1 advance the PC past the breakpoint if necessary. This
ends up being better also because this now handles
non-decr_pc_after_break targets too. Before, such targets would get
stuck forever reexecuting the breakpoint instruction.
Tested on x86_64 Fedora 20.
gdb/gdbserver/ChangeLog:
2015-02-23 Pedro Alves <palves@redhat.com>
* linux-low.c (check_stopped_by_breakpoint): Don't check if the
thread was doing a step-over; always adjust the PC if
we stepped over a permanent breakpoint.
(linux_wait_1): If we stepped over breakpoint that was on top of a
permanent breakpoint, manually advance the PC past it.
Another fix I'm working made schedlock.exp fail with gdbserver
frequently. Looking deeper, it turns out to be a pre-existing bug.
status_pending_p_callback is filtering out LWPs incorrectly. The
result is that that sometimes status_pending_p_callback returns a
pending event for an LWP that isn't expected, and then GDBserver gets
very confused.
E.g,. when doing a step-over, linux_wait_for_event is called with a
particular LWP's ptid, meaning events for all other LWPs should be
left pending, but here we see it retuning an event for some other LWP:
linux_wait_1: [<all threads>]
step_over_bkpt set [LWP 29577.29577], doing a blocking wait <--------
my_waitpid (-1, 0x40000001)
my_waitpid (-1, 0x80000001): status(57f), 0
LWFE: waitpid(-1, ...) returned 0, ERRNO-OK
pc is 0x4007a0
src/gdb/gdbserver/linux-low.c:2587: A problem internal to GDBserver has been detected.
linux_wait_1: got event for 29581 <--------
Remote connection closed
(gdb) FAIL: gdb.threads/schedlock.exp: continue to breakpoint: return to loop (initial)
delete breakpoints
Tested on x86_64 Fedora 20.
gdb/gdbserver/ChangeLog:
2015-02-20 Pedro Alves <palves@redhat.com>
* linux-low.c (status_pending_p_callback): Use ptid_match.
When gdb creates a dummy frame to execute a function in the inferior,
the process may generate a SIGSEGV, SIGTRAP or SIGILL because the stack
is non executable. If the signal handler set in gdb has option print
or stop enabled for these signals gdb handles this correctly.
However, in the case of noprint and nostop the signal is short-circuited
and the inferior process is sent the signal directly. This causes the
inferior to crash because of gdb.
This patch adds a check for SIGSEGV, SIGTRAP or SIGILL so that these
signals are sent to gdb rather than short-circuited in the inferior.
gdb then handles them properly and the inferior process does not
crash.
This patch also fixes the same behavior in gdbserver.
Also added a small testcase to test the issue called catch-gdb-caused-signals.
This applies to Linux only, tested on Linux.
gdb/ChangeLog:
PR breakpoints/16812
* linux-nat.c (linux_nat_filter_event): Report SIGTRAP,SIGILL,SIGSEGV.
* nat/linux-ptrace.c (linux_wstatus_maybe_breakpoint): Add.
* nat/linux-ptrace.h: Add linux_wstatus_maybe_breakpoint.
gdb/gdbserver/ChangeLog:
PR breakpoints/16812
* linux-low.c (wstatus_maybe_breakpoint): Remove.
(linux_low_filter_event): Update wstatus_maybe_breakpoint name.
(linux_wait_1): Report SIGTRAP,SIGILL,SIGSEGV.
gdb/testsuite/ChangeLog:
PR breakpoints/16812
* gdb.base/catch-gdb-caused-signals.c: New file.
* gdb.base/catch-gdb-caused-signals.exp: New file.
Allow the size of the branch trace ring buffer to be defined by the
user. The specified buffer size will be used when BTS tracing is
enabled for new threads.
The obtained buffer size may differ from the requested size. The
actual buffer size for the current thread is shown in the "info record"
command.
Bigger buffers mean longer traces, but also longer processing time.
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
* btrace.c (parse_xml_btrace_conf_bts): Add size.
(btrace_conf_bts_attributes): New.
(btrace_conf_children): Add attributes.
* common/btrace-common.h (btrace_config_bts): New.
(btrace_config)<bts>: New.
(btrace_config): Update comment.
* nat/linux-btrace.c (linux_enable_btrace, linux_enable_bts):
Use config.
* features/btrace-conf.dtd: Increment version. Add size
attribute to bts element.
* record-btrace.c (set_record_btrace_bts_cmdlist,
show_record_btrace_bts_cmdlist): New.
(record_btrace_adjust_size, record_btrace_print_bts_conf,
record_btrace_print_conf, cmd_set_record_btrace_bts,
cmd_show_record_btrace_bts): New.
(record_btrace_info): Call record_btrace_print_conf.
(_initialize_record_btrace): Add commands.
* remote.c: Add PACKET_Qbtrace_conf_bts_size enum.
(remote_protocol_features): Add Qbtrace-conf:bts:size packet.
(btrace_sync_conf): Synchronize bts size.
(_initialize_remote): Add Qbtrace-conf:bts:size packet.
* NEWS: Announce new commands and new packets.
doc/
* gdb.texinfo (Branch Trace Configuration Format): Add size.
(Process Record and Replay): Describe new set|show commands.
(General Query Packets): Describe Qbtrace-conf:bts:size packet.
testsuite/
* gdb.btrace/buffer-size: New.
gdbserver/
* linux-low.c (linux_low_btrace_conf): Print size.
* server.c (handle_btrace_conf_general_set): New.
(hanle_general_set): Call handle_btrace_conf_general_set.
(handle_query): Report Qbtrace-conf:bts:size as supported.
Add a struct to describe the branch trace configuration and use it for
enabling branch tracing.
The user will be able to set configuration fields for each tracing format
to be used for new threads.
The actual configuration that is active for a given thread will be shown
in the "info record" command.
At the moment, the configuration struct only contains a format field
that is set to the only available format.
The format is the only configuration option that can not be set via set
commands. It is given as argument to the "record btrace" command when
starting recording.
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
* Makefile.in (XMLFILES): Add btrace-conf.dtd.
* x86-linux-nat.c (x86_linux_enable_btrace): Update parameters.
(x86_linux_btrace_conf): New.
(x86_linux_create_target): Initialize to_btrace_conf.
* nat/linux-btrace.c (linux_enable_btrace): Update parameters.
Check format. Split into this and ...
(linux_enable_bts): ... this.
(linux_btrace_conf): New.
(perf_event_skip_record): Renamed into ...
(perf_event_skip_bts_record): ... this. Updated users.
(linux_disable_btrace): Split into this and ...
(linux_disable_bts): ... this.
(linux_read_btrace): Check format.
* nat/linux-btrace.h (linux_enable_btrace): Update parameters.
(linux_btrace_conf): New.
(btrace_target_info)<ptid>: Moved.
(btrace_target_info)<conf>: New.
(btrace_target_info): Split into this and ...
(btrace_tinfo_bts): ... this. Updated users.
* btrace.c (btrace_enable): Update parameters.
(btrace_conf, parse_xml_btrace_conf_bts, parse_xml_btrace_conf)
(btrace_conf_children, btrace_conf_attributes)
(btrace_conf_elements): New.
* btrace.h (btrace_enable): Update parameters.
(btrace_conf, parse_xml_btrace_conf): New.
* common/btrace-common.h (btrace_config): New.
* feature/btrace-conf.dtd: New.
* record-btrace.c (record_btrace_conf): New.
(record_btrace_cmdlist): New.
(record_btrace_enable_warn, record_btrace_open): Pass
&record_btrace_conf.
(record_btrace_info): Print recording format.
(cmd_record_btrace_bts_start): New.
(cmd_record_btrace_start): Call cmd_record_btrace_bts_start.
(_initialize_record_btrace): Add "record btrace bts" subcommand.
Add "record bts" alias command.
* remote.c (remote_state)<btrace_config>: New.
(remote_btrace_reset, PACKET_qXfer_btrace_conf): New.
(remote_protocol_features): Add qXfer:btrace-conf:read.
(remote_open_1): Call remote_btrace_reset.
(remote_xfer_partial): Handle TARGET_OBJECT_BTRACE_CONF.
(btrace_target_info)<conf>: New.
(btrace_sync_conf, btrace_read_config): New.
(remote_enable_btrace): Update parameters. Call btrace_sync_conf and
btrace_read_conf.
(remote_btrace_conf): New.
(init_remote_ops): Initialize to_btrace_conf.
(_initialize_remote): Add qXfer:btrace-conf packet.
* target.c (target_enable_btrace): Update parameters.
(target_btrace_conf): New.
* target.h (target_enable_btrace): Update parameters.
(target_btrace_conf): New.
(target_object)<TARGET_OBJECT_BTRACE_CONF>: New.
(target_ops)<to_enable_btrace>: Update parameters and comment.
(target_ops)<to_btrace_conf>: New.
* target-delegates: Regenerate.
* target-debug.h (target_debug_print_const_struct_btrace_config_p)
(target_debug_print_const_struct_btrace_target_info_p): New.
NEWS: Announce new command and new packet.
doc/
* gdb.texinfo (Process Record and Replay): Describe the "record
btrace bts" command.
(General Query Packets): Describe qXfer:btrace-conf:read packet.
(Branch Trace Configuration Format): New.
gdbserver/
* linux-low.c (linux_low_enable_btrace): Update parameters.
(linux_low_btrace_conf): New.
(linux_target_ops)<to_btrace_conf>: Initialize.
* server.c (current_btrace_conf): New.
(handle_btrace_enable): Rename to ...
(handle_btrace_enable_bts): ... this. Pass ¤t_btrace_conf
to target_enable_btrace. Update comment. Update users.
(handle_qxfer_btrace_conf): New.
(qxfer_packets): Add btrace-conf entry.
(handle_query): Report qXfer:btrace-conf:read as supported packet.
* target.h (target_ops)<enable_btrace>: Update parameters and comment.
(target_ops)<read_btrace_conf>: New.
(target_enable_btrace): Update parameters.
(target_read_btrace_conf): New.
testsuite/
* gdb.btrace/delta.exp: Update "info record" output.
* gdb.btrace/enable.exp: Update "info record" output.
* gdb.btrace/finish.exp: Update "info record" output.
* gdb.btrace/instruction_history.exp: Update "info record" output.
* gdb.btrace/next.exp: Update "info record" output.
* gdb.btrace/nexti.exp: Update "info record" output.
* gdb.btrace/step.exp: Update "info record" output.
* gdb.btrace/stepi.exp: Update "info record" output.
* gdb.btrace/nohist.exp: Update "info record" output.
Add a structure to hold the branch trace data and an enum to describe
the format of that data. So far, only BTS is supported. Also added
a NONE format to indicate that no branch trace data is available.
This will make it easier to support different branch trace formats in
the future.
2015-02-09 Markus Metzger <markus.t.metzger@intel.com>
* Makefile.in (SFILES): Add common/btrace-common.c.
(COMMON_OBS): Add common/btrace-common.o.
(btrace-common.o): Add build rules.
* btrace.c (parse_xml_btrace): Update parameters.
(parse_xml_btrace_block): Set format field.
(btrace_add_pc, btrace_fetch): Use struct btrace_data.
(do_btrace_data_cleanup, make_cleanup_btrace_data): New.
(btrace_compute_ftrace): Split into this and...
(btrace_compute_ftrace_bts): ...this.
(btrace_stitch_trace): Split into this and...
(btrace_stitch_bts): ...this.
* btrace.h (parse_xml_btrace): Update parameters.
(make_cleanup_btrace_data): New.
* common/btrace-common.c: New.
* common/btrace-common.h: Include common-defs.h.
(btrace_block_s): Update comment.
(btrace_format): New.
(btrace_format_string): New.
(btrace_data_bts): New.
(btrace_data): New.
(btrace_data_init, btrace_data_fini, btrace_data_empty): New.
* remote.c (remote_read_btrace): Update parameters.
* target.c (target_read_btrace): Update parameters.
* target.h (target_read_btrace): Update parameters.
(target_ops)<to_read_btrace>: Update parameters.
* x86-linux-nat.c (x86_linux_read_btrace): Update parameters.
* target-delegates.c: Regenerate.
* target-debug (target_debug_print_struct_btrace_data_p): New.
* nat/linux-btrace.c (linux_read_btrace): Split into this and...
(linux_read_bts): ...this.
* nat/linux-btrace.h (linux_read_btrace): Update parameters.
gdbserver/
* Makefile.in (SFILES): Add common/btrace-common.c.
(OBS): Add common/btrace-common.o.
(btrace-common.o): Add build rules.
* linux-low: Include btrace-common.h.
(linux_low_read_btrace): Use struct btrace_data. Call
btrace_data_init and btrace_data_fini.
Since the starvation avoidance series
(https://sourceware.org/ml/gdb-patches/2014-12/msg00631.html), both
GDB and GDBserver pull all events out of ptrace before deciding which
event to process.
There's one problem with that though. Because we resume new threads
immediately when we see a PTRACE_EVENT_CLONE event, if the program
constantly spawns threads fast enough, new threads can spawn threads
faster we can pull events out of the kernel, and thus we'd get stuck
in an infinite loop, never returning any event to the core to process.
I occasionally see this happen with the
attach-many-short-lived-threads.exp test against gdbserver.
The fix is to delay resuming new threads until we've pulled out all
events out of the kernel.
On native, we already have the resume_stopped_resumed_lwps function
that knows to resume LWPs that are stopped with no event to report to
the core. So the patch just adds another use. GDBserver didn't have
the equivalent yet, so the patch adds one.
Tested on x86_64 Fedora 20, native and gdbserver (remote and
extended-remote).
gdb/gdbserver/ChangeLog:
2015-02-04 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Don't resume LWPs here.
(resume_stopped_resumed_lwps): New function.
(linux_wait_for_event_filtered): Use it.
gdb/ChangeLog:
2015-02-04 Pedro Alves <palves@redhat.com>
* linux-nat.c (handle_extended_wait): Don't resume LWPs here.
(wait_lwp): Don't call wait_lwp if linux_handle_extended_wait
returns true.
(resume_stopped_resumed_lwps): Don't check whether the thread is
marked as executing.
(linux_nat_wait_1): Use resume_stopped_resumed_lwps.
This patch moves the shared code present on
gdb/linux-nat.c:linux_nat_create_inferior and
gdb/gdbserver/linux-low.c:linux_create_inferior to
nat/linux-personality.c. This code is responsible for disabling
address space randomization based on user setting, and using
<sys/personality.h> to do that. I decided to put the prototype of the
maybe_disable_address_space_randomization on nat/linux-osdata.h
because it seemed the best place to put it.
I regression-tested this patch on Fedora 20 x86_64, and found no
regressions.
gdb/ChangeLog
2015-01-15 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (HFILES_NO_SRCDIR): Add nat/linux-personality.h.
(linux-personality.o): New rule.
* common/common-defs.h: Include <stdint.h>.
* config/aarch64/linux.mh (NATDEPFILES): Include
linux-personality.o.
* config/alpha/alpha-linux.mh (NATDEPFILES): Likewise.
* config/arm/linux.mh (NATDEPFILES): Likewise.
* config/i386/linux64.mh (NATDEPFILES): Likewise.
* config/i386/linux.mh (NATDEPFILES): Likewise.
* config/ia64/linux.mh (NATDEPFILES): Likewise.
* config/m32r/linux.mh (NATDEPFILES): Likewise.
* config/m68k/linux.mh (NATDEPFILES): Likewise.
* config/mips/linux.mh (NATDEPFILES): Likewise.
* config/pa/linux.mh (NATDEPFILES): Likewise.
* config/powerpc/linux.mh (NATDEPFILES): Likewise.
* config/powerpc/ppc64-linux.mh (NATDEPFILES): Likewise.
* config/powerpc/spu-linux.mh (NATDEPFILES): Likewise.
* config/s390/linux.mh (NATDEPFILES): Likewise.
* config/sparc/linux64.mh (NATDEPFILES): Likewise.
* config/sparc/linux.mh (NATDEPFILES): Likewise.
* config/tilegx/linux.mh (NATDEPFILES): Likewise.
* config/xtensa/linux.mh (NATDEPFILES): Likewise.
* defs.h: Remove #include <stdint.h> (moved to
common/common-defs.h).
* linux-nat.c: Include nat/linux-personality.h. Remove #include
<sys/personality.h>; do not define ADDR_NO_RANDOMIZE (moved to
nat/linux-personality.c).
(linux_nat_create_inferior): Remove code to disable address space
randomization (moved to nat/linux-personality.c). Create cleanup
to disable address space randomization.
* nat/linux-personality.c: New file.
* nat/linux-personality.h: Likewise.
gdb/gdbserver/ChangeLog
2015-01-15 Sergio Durigan Junior <sergiodj@redhat.com>
* Makefile.in (SFILES): Add linux-personality.c.
(linux-personality.o): New rule.
* configure.srv (srv_linux_obj): Add linux-personality.o to the
list of objects to be built.
* linux-low.c: Include nat/linux-personality.h.
(linux_create_inferior): Remove code to disable address space
randomization (moved to ../nat/linux-personality.c). Create
cleanup to disable address space randomization.
This patch applies the same starvation avoidance improvements of the
previous patch to the Linux gdbserver side.
Without this, the test added by the following commit
(gdb.threads/non-stop-fair-events.exp) always fails with time outs.
gdb/gdbserver/
2015-01-09 Pedro Alves <palves@redhat.com>
* linux-low.c (step_over_bkpt): Move higher up in the file.
(handle_extended_wait): Don't store the stop_pc here.
(get_stop_pc): Adjust comments and rename to ...
(check_stopped_by_breakpoint): ... this. Record whether the LWP
stopped for a software breakpoint or hardware breakpoint.
(thread_still_has_status_pending_p): New function.
(status_pending_p_callback): Use
thread_still_has_status_pending_p. If the event is no longer
interesting, resume the LWP.
(handle_tracepoints): Add assert.
(maybe_move_out_of_jump_pad): Remove cancel_breakpoints call.
(wstatus_maybe_breakpoint): New function.
(cancel_breakpoint): Delete function.
(check_stopped_by_watchpoint): New function, factored out from
linux_low_filter_event.
(lp_status_maybe_breakpoint): Delete function.
(linux_low_filter_event): Remove filter_ptid argument.
Leave thread group exits pending here. Store the LWP's stop PC.
Always leave events pending.
(linux_wait_for_event_filtered): Pull all events out of the
kernel, and leave them all pending.
(count_events_callback, select_event_lwp_callback): Consider all
events.
(cancel_breakpoints_callback, linux_cancel_breakpoints): Delete.
(select_event_lwp): Only give preference to the stepping LWP in
all-stop mode. Adjust comments.
(ignore_event): New function.
(linux_wait_1): Delete 'retry' label. Use ignore_event. Remove
references to cancel_breakpoints. Adjust to renames. Also give
equal priority to all LWPs that have had events in non-stop mode.
If reporting a software breakpoint event, unadjust the LWP's PC.
(linux_wait): If linux_wait_1 returned an ignored event, retry.
(stuck_in_jump_pad_callback, move_out_of_jump_pad_callback):
Adjust.
(linux_resume_one_lwp): Store the LWP's PC. Adjust.
(resume_status_pending_p): Use thread_still_has_status_pending_p.
(linux_stopped_by_watchpoint): Adjust.
(linux_target_ops): Remove reference to linux_cancel_breakpoints.
* linux-low.h (enum lwp_stop_reason): New.
(struct lwp_info) <stop_pc>: Adjust comment.
<stopped_by_watchpoint>: Delete field.
<stop_reason>: New field.
* linux-x86-low.c (x86_linux_prepare_to_resume): Adjust.
* mem-break.c (software_breakpoint_inserted_here)
(hardware_breakpoint_inserted_here): New function.
* mem-break.h (software_breakpoint_inserted_here)
(hardware_breakpoint_inserted_here): Declare.
* target.h (struct target_ops) <cancel_breakpoints>: Remove field.
(cancel_breakpoints): Delete.
* tracepoint.c (clear_installed_tracepoints, stop_tracing)
(upload_fast_traceframes): Remove references to
cancel_breakpoints.
... instead of relying on libthread_db.
I wrote a test that attaches to a program that constantly spawns
short-lived threads, which exposed several issues. This is one of
them.
On Linux, we need to attach to all threads of a process (thread group)
individually. We currently rely on libthread_db to list the threads,
but that is problematic, because libthread_db relies on reading data
structures out of the inferior (which may well be corrupted). If
threads are being created or exiting just while we try to attach, we
may trip on inconsistencies in the inferior's thread list. To work
around that, when we see a seemingly corrupt list, we currently retry
a few times:
static void
thread_db_find_new_threads_2 (ptid_t ptid, int until_no_new)
{
...
if (until_no_new)
{
/* Require 4 successive iterations which do not find any new threads.
The 4 is a heuristic: there is an inherent race here, and I have
seen that 2 iterations in a row are not always sufficient to
"capture" all threads. */
...
That heuristic may well fail, and when it does, we end up with threads
in the program that aren't under GDB's control. That's obviously bad
and results in quite mistifying failures, like e.g., the process dying
for seeminly no reason when a thread that wasn't attached trips on a
breakpoint.
There's really no reason to rely on libthread_db for this nowadays
when we have /proc mounted. In that case, which is the usual case, we
can list the LWPs from /proc/PID/task/. In fact, GDBserver is already
doing this. The patch factors out that code that knows to walk the
task/ directory out of GDBserver, and makes GDB use it too.
Like GDBserver, the patch makes GDB attach to LWPs and _not_ wait for
them to stop immediately. Instead, we just tag the LWP as having an
expected stop. Because we can only set the ptrace options when the
thread stops, we need a new flag in the lwp structure to keep track of
whether we've already set the ptrace options, just like in GDBserver.
Note that nothing issues any ptrace command to the threads between the
PTRACE_ATTACH and the stop, so this is safe (unlike one scenario
described in gdbserver's linux-low.c).
When we attach to a program that has threads exiting while we attach,
it's easy to race with a thread just exiting as we try to attach to
it, like:
#1 - get current list of threads
#2 - attach to each listed thread
#3 - ooops, attach failed, thread is already gone
As this is pretty normal, we shouldn't be issuing a scary warning in
step #3.
When #3 happens, PTRACE_ATTACH usually fails with ESRCH, but sometimes
we'll see EPERM as well. That happens when the kernel still has the
thread in its task list, but the thread is marked as dead.
Unfortunately, EPERM is ambiguous and we'll get it also on other
scenarios where the thread isn't dead, and in those cases, it's useful
to get a warning. To distiguish the cases, when we get an EPERM
failure, we open /proc/PID/status, and check the thread's state -- if
the /proc file no longer exists, or the state is "Z (Zombie)" or "X
(Dead)", we ignore the EPERM error silently; otherwise, we'll warn.
Unfortunately, there seems to be a kernel race here. Sometimes I get
EPERM, and then the /proc state still indicates "R (Running)"... If
we wait a bit and retry, we do end up seeing X or Z state, or get an
ESRCH. I thought of making GDB retry the attach a few times, but even
with a 500ms wait and 4 retries, I still see the warning sometimes. I
haven't been able to identify the kernel path that causes this yet,
but in any case, it looks like a kernel bug to me. As this just
results failure to suppress a warning that we've been printing since
about forever anyway, I'm just making the test cope with it, and issue
an XFAIL.
gdb/gdbserver/
2015-01-09 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_attach_fail_reason_string): Move to
nat/linux-ptrace.c, and rename.
(linux_attach_lwp): Update comment.
(attach_proc_task_lwp_callback): New function.
(linux_attach): Adjust to rename and use
linux_proc_attach_tgid_threads.
(linux_attach_fail_reason_string): Delete declaration.
gdb/
2015-01-09 Pedro Alves <palves@redhat.com>
* linux-nat.c (attach_proc_task_lwp_callback): New function.
(linux_nat_attach): Use linux_proc_attach_tgid_threads.
(wait_lwp, linux_nat_filter_event): If not set yet, set the lwp's
ptrace option flags.
* linux-nat.h (struct lwp_info) <must_set_ptrace_flags>: New
field.
* nat/linux-procfs.c: Include <dirent.h>.
(linux_proc_get_int): New parameter "warn". Handle it.
(linux_proc_get_tgid): Adjust.
(linux_proc_get_tracerpid): Rename to ...
(linux_proc_get_tracerpid_nowarn): ... this.
(linux_proc_pid_get_state): New function, factored out from
(linux_proc_pid_has_state): ... this. Add new parameter "warn"
and handle it.
(linux_proc_pid_is_gone): New function.
(linux_proc_pid_is_stopped): Adjust.
(linux_proc_pid_is_zombie_maybe_warn)
(linux_proc_pid_is_zombie_nowarn): New functions.
(linux_proc_pid_is_zombie): Use
linux_proc_pid_is_zombie_maybe_warn.
(linux_proc_attach_tgid_threads): New function.
* nat/linux-procfs.h (linux_proc_get_tgid): Update comment.
(linux_proc_get_tracerpid): Rename to ...
(linux_proc_get_tracerpid_nowarn): ... this, and update comment.
(linux_proc_pid_is_gone): New declaration.
(linux_proc_pid_is_zombie): Update comment.
(linux_proc_pid_is_zombie_nowarn): New declaration.
(linux_proc_attach_lwp_func): New typedef.
(linux_proc_attach_tgid_threads): New declaration.
* nat/linux-ptrace.c (linux_ptrace_attach_fail_reason): Adjust to
use nowarn functions.
(linux_ptrace_attach_fail_reason_string): Move here from
gdbserver/linux-low.c and rename.
(ptrace_supports_feature): If the current ptrace options are not
known yet, check them now, instead of asserting.
* nat/linux-ptrace.h (linux_ptrace_attach_fail_reason_string):
Declare.
This patch enhances GDB on GNU/Linux systems in the situation where
we are debugging an inferior that was created from GDB (as opposed
to attached to), by asking the kernel to kill the inferior if GDB
terminates without doing it itself.
This would typically happen when GDB encounters a problem and
crashes, or when it gets killed by an external process. This can
be observed by starting a program under GDB, and then killing
GDB with signal 9. After GDB is killed, the inferior still remains.
This patch also fixes GDBserver similarly.
This fix is conditional on the kernel supporting the PTRACE_O_EXITKILL
feature. On older kernels, the behavior remains unchanged.
gdb/ChangeLog:
* nat/linux-ptrace.h (PTRACE_O_EXITKILL): Define if not
already defined.
(linux_enable_event_reporting): Add parameter "attached".
* nat/linux-ptrace.c (linux_test_for_exitkill): New forward
declaration. New function.
(linux_check_ptrace_features): Add linux_test_for_exitkill call.
(linux_enable_event_reporting): Add new parameter "attached".
Do not call ptrace with the PTRACE_O_EXITKILL if ATTACHED is
nonzero.
* linux-nat.c (linux_init_ptrace): Add parameter "attached".
Use it. Update function description.
(linux_child_post_attach, linux_child_post_startup_inferior):
Update call to linux_enable_event_reporting.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_low_filter_event): Update call to
linux_enable_event_reporting following the addition of
a new parameter to that function.
Tested on x86_64-linux, native and native-gdbserver.
I also verified by hand that the inferior gets killed when killing
GDB in the "run" case, while the inferior remains in the "attach"
case. Same for GDBserver.
This makes gdbserver actually provide values for the TDB registers
when the inferior was stopped in a transaction. The change in
linux-low.c is needed to suppress the warning for an unavailable TDB.
The test case 's390-tdbregs.exp' passes with this patch and fails
without.
gdb/gdbserver/ChangeLog:
* linux-low.c (regsets_fetch_inferior_registers): Suppress the
warning upon ENODATA from ptrace.
* linux-s390-low.c (s390_store_tdb): New.
(s390_regsets): Add regset for NT_S390_TDB.
For GNU/Linux targets using the regsets interface, this change
supports regsets that can be read but not written. The S390 "last
break" regset is an example. So far it had been defined with
regset->set_request == PTRACE_GETREGSET, such that the respective
ptrace call does not cause any harm. Now we just skip the whole
read/modify/write sequence for regsets that do not define a
fill_function.
gdb/gdbserver/ChangeLog:
* linux-low.c (regsets_store_inferior_registers): Skip regsets
without a fill_function.
* linux-s390-low.c (s390_fill_last_break): Remove.
(s390_regsets): Set fill_function to NULL for NT_S390_LAST_BREAK.
(s390_arch_setup): Use regset's size instead of fill_function for
loop end condition.
When fetch_inferior_registers does not update all registers, this
patch assures that no stale register values remain in the register
cache. On Linux platforms using the regsets interface, when one of
the ptrace calls used for fetching the register values returns an
error, this patch also avoids copying the random data returned from
ptrace into the register cache. All unfetched registers are marked
"unavailable" instead.
gdb/gdbserver/ChangeLog:
* linux-low.c (regsets_fetch_inferior_registers): Do not invoke
the regset's store function when ptrace returned an error.
* regcache.c (get_thread_regcache): Invalidate register cache
before fetching inferior's registers.
Replace the while-loops in linux-low.c that iterate over regsets by
for-loops. This makes it clearer what is iterated over. Also, since
"continue" now moves on to the next iteration without having to
increment the regset pointer first, the code is slightly reduced.
In case of EIO the old code did not increment the regset pointer, but
iterated over the same (now disabled) regset again. This extra
iteration is now avoided.
gdb/gdbserver/ChangeLog:
* linux-low.c (regsets_fetch_inferior_registers): Rephrase
while-loop as for-loop.
(regsets_store_inferior_registers): Likewise.
There's code in linux_wait_1 that resumes all threads if the Hc thread
disappears. It's the wrong thing to do, as GDB has told GDBserver to
resume only one thread, because e.g., the user has scheduler-locking
enabled, or because GDB was stepping the program over a breakpoint.
Resuming all threads behind GDB's back can't be good in either case.
The right thing to do is to detect that that the (only) resumed thread
is gone, and let GDB know about it. The Linux backend is already
doing that nowadays, since:
commit fa96cb382c
Author: Pedro Alves <palves@redhat.com>
AuthorDate: Thu Feb 27 14:30:08 2014 +0000
Teach GDBserver's Linux backend about no unwaited-for children (TARGET_WAITKIND_NO_RESUMED).
The backend detects that all resumed threads have disappeared, and
returns TARGET_WAITKIND_NO_RESUMED to the core of GDBserver, which
then reports an error to GDB.
There's no need to frob the passed in ptid to wait for the continue
thread either -- linux_wait_for_event only returns events for resumed
threads.
The badness (of resuming threads) can actually be observed in the
testsuite, if we force-disable vCont support in GDBserver -- before
the patch, gdb.threads/no-unwaited-for-left.exp hangs if we disable
vCont:
(gdb) continue
Continuing.
FAIL: gdb.threads/no-unwaited-for-left.exp: continue to breakpoint: break-here (timeout)
... more cascading timeouts ....
After the patch, gdb.threads/no-unwaited-for-left.exp behaves the same
with or without vCont support:
(gdb) continue
Continuing.
[New Thread 32226]
[Switching to Thread 32226]
Breakpoint 2, thread_a (arg=0x0) at /home/pedro/gdb/mygit/build/../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
28 return 0; /* break-here */
(gdb) PASS: gdb.threads/no-unwaited-for-left.exp: continue to breakpoint: break-here
...
continue
Continuing.
warning: Remote failure reply: E.No unwaited-for children left.
[Thread 32222] #1 stopped.
(gdb) FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits
Overall, this is also good for getting rid of a RSP detail from the backend.
gdb/gdbserver/
2014-11-12 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_wait_1): Don't force a wait for the Hc
thread, and don't resume all threads if the Hc thread has exited.
The target->request_interrupt callback implements the handling for
ctrl-c. User types ctrl-c in GDB, GDB sends a \003 to the remote
target, and the remote targets stops the program with a SIGINT, just
like if the user typed ctrl-c in GDBserver's terminal.
The trouble is that using kill_lwp(signal_pid, SIGINT) sends the
SIGINT directly to the program's main thread. If that thread has
exited already, then that kill won't do anything.
Instead, send the SIGINT to the process group, just like GDB
does (see inf-ptrace.c:inf_ptrace_stop).
gdb.threads/leader-exit.exp is extended to cover the scenario. It
fails against GDBserver before the patch.
Tested on x86_64 Fedora 20, native and GDBserver.
gdb/gdbserver/
2014-11-12 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_request_interrupt): Always send a SIGINT to
the process group instead of to a specific LWP.
gdb/testsuite/
2014-11-12 Pedro Alves <palves@redhat.com>
* gdb.threads/leader-exit.exp: Test sending ctrl-c works after the
leader has exited.
I see the following fail on arm-none-linux-gnueabi testing,
(gdb) continue^M
Continuing.^M
^M
Program received signal SIGILL, Illegal instruction.^M
[Switching to Thread 1003]^M
handler (signo=10) at
/scratch/yqi/arm-none-linux-gnueabi/src/gdb-trunk/gdb/testsuite/gdb.threads/sigstep-threads.c:33^M
33 tgkill (getpid (), gettid (), SIGUSR1); /* step-2 */^M
(gdb) FAIL: gdb.threads/sigstep-threads.exp: continue
the cause is that GDBserver doesn't cancel the breakpoint if the stop
signal is SIGILL. The kernel used here is a little old, 2.6.x, and
doesn't translate SIGILL to SIGTRAP when program hits breakpoint
instruction (which is an illegal instruction actually). GDB and
GDBserver can translate SIGILL to SIGTRAP under certain circumstance,
so it is not a problem here. See gdbserver/linux-low.c:linux_wait_1
/* If this event was not handled before, and is not a SIGTRAP, we
report it. SIGILL and SIGSEGV are also treated as traps in case
a breakpoint is inserted at the current PC. If this target does
not support internal breakpoints at all, we also report the
SIGTRAP without further processing; it's of no concern to us. */
maybe_internal_trap
= (supports_breakpoints ()
&& (WSTOPSIG (w) == SIGTRAP
|| ((WSTOPSIG (w) == SIGILL
|| WSTOPSIG (w) == SIGSEGV)
&& (*the_low_target.breakpoint_at) (event_child->stop_pc))));
However, SIGILL and SIGSEGV is not considered when cancelling
breakpoint, which causes the fail above. That is, when GDB is doing
software single step on address ADDR, both thread A and thread B hits the
software single step breakpoint, and get SIGILL. GDB selects the event
from thread A, removes the software single step breakpoint, and resume
the program. The event (SIGILL) from thread B is reported to GDB, but
GDB doesn't regard this SIGILL as SIGTRAP, because the breakpoint on
address ADDR was removed, so GDB reports "Program received signal
SIGILL".
The patch is to allow calling cancel_breakpoint if the signal is
SIGILL and SIGSEGV. This patch fixes the fail above. Likewise, event
lwp selection should honour SIGILL and SIGSEGV too.
gdb/gdbserver:
2014-09-23 Yao Qi <yao@codesourcery.com>
* linux-low.c (lp_status_maybe_breakpoint): New function.
(linux_low_filter_event): Call lp_status_maybe_breakpoint.
(count_events_callback): Likewise.
(select_event_lwp_callback): Likewise.
(cancel_breakpoints_callback): Likewise.
This commit implements functions for identifying and extracting extended
ptrace event information from a Linux wait status. These are just
convenience functions intended to hide the ">> 16" used to extract the
event from the wait status word, replacing the hard-coded shift with a more
descriptive function call. This is preparatory work for implementation of
follow-fork and detach-on-fork for extended-remote linux targets.
gdb/ChangeLog:
* linux-nat.c (linux_handle_extended_wait): Call
linux_ptrace_get_extended_event.
(wait_lwp): Call linux_is_extended_waitstatus.
(linux_nat_filter_event): Call linux_ptrace_get_extended_event
and linux_is_extended_waitstatus.
* nat/linux-ptrace.c (linux_test_for_tracefork): Call
linux_ptrace_get_extended_event.
(linux_ptrace_get_extended_event): New function.
(linux_is_extended_waitstatus): New function.
* nat/linux-ptrace.h (linux_ptrace_get_extended_event)
(linux_is_extended_waitstatus): New declarations.
gdb/gdbserver/ChangeLog:
* linux-low.c (handle_extended_wait): Call
linux_ptrace_get_extended_event.
(get_stop_pc, get_detach_signal, linux_low_filter_event): Call
linux_is_extended_waitstatus.
---
GDB has a function named "current_inferior" and gdbserver has a global
variable named "current_inferior", but the two are not equivalent;
indeed, gdbserver does not have any real equivalent of what GDB calls
an inferior. What gdbserver's "current_inferior" is actually pointing
to is a structure describing the current thread. This commit renames
current_inferior as current_thread in gdbserver to clarify this. It
also renames the function "set_desired_inferior" to "set_desired_thread"
and renames various local variables from foo_inferior to foo_thread.
gdb/gdbserver/ChangeLog:
* inferiors.h (current_inferior): Renamed as...
(current_thread): New variable. All uses updated.
* linux-low.c (get_pc): Renamed saved_inferior as saved_thread.
(maybe_move_out_of_jump_pad): Likewise.
(cancel_breakpoint): Likewise.
(linux_low_filter_event): Likewise.
(wait_for_sigstop): Likewise.
(linux_resume_one_lwp): Likewise.
(need_step_over_p): Likewise.
(start_step_over): Likewise.
(linux_stabilize_threads): Renamed save_inferior as saved_thread.
* linux-x86-low.c (x86_linux_update_xmltarget): Likewise.
* proc-service.c (ps_lgetregs): Renamed reg_inferior as reg_thread
and save_inferior as saved_thread.
* regcache.c (get_thread_regcache): Renamed saved_inferior as
saved_thread.
(regcache_invalidate_thread): Likewise.
* remote-utils.c (prepare_resume_reply): Likewise.
* thread-db.c (thread_db_get_tls_address): Likewise.
(disable_thread_event_reporting): Likewise.
(remove_thread_event_breakpoints): Likewise.
* tracepoint.c (gdb_agent_about_to_close): Renamed save_inferior
as saved_thread.
* target.h (set_desired_inferior): Renamed as...
(set_desired_thread): New declaration. All uses updated.
* server.c (myresume): Updated comment to reference thread instead
of inferior.
(handle_serial_event): Likewise.
(handle_target_event): Likewise.
This commit downgrades a fatal error to a warning in linux_async.
linux_async is called from two different places in gdbserver:
Via target_async from handle_accept_event. The argument
is always zero, so the warning will never be printed here.
Via start_non_stop from handle_general_set. This prints
its own error message to stderr on failure, which will
be preceded by the warning if it is emitted.
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_async): Replace fatal with warning.
Tidy up and return.
(linux_start_non_stop): Return -1 if linux_async failed.
This commit moves the inclusion of errno.h to common-defs.h and
removes all other inclusions. Note that prior to this commit
server.h included errno.h protected by "#ifdef HAVE_ERRNO_H".
This protection was added with the Windows CE port, which is
currently broken. Since no other platform needs this, I have
removed the protection and the configury to support it.
gdb/
2014-08-07 Gary Benson <gbenson@redhat.com>
* common/common-defs.h: Include errno.h.
* defs.h: Do not include errno.h.
* ada-typeprint.c: Likewise.
* c-typeprint.c: Likewise.
* core-regset.c: Likewise.
* corefile.c: Likewise.
* corelow.c: Likewise.
* event-loop.c: Likewise.
* f-typeprint.c: Likewise.
* gnu-nat.c: Likewise.
* go32-nat.c: Likewise.
* i386gnu-nat.c: Likewise.
* m2-typeprint.c: Likewise.
* nat/linux-btrace.c: Likewise.
* p-typeprint.c: Likewise.
* procfs.c: Likewise.
* remote-sim.c: Likewise.
* rs6000-nat.c: Likewise.
* target.c: Likewise.
* typeprint.c: Likewise.
* ui-file.c: Likewise.
* valops.c: Likewise.
* valprint.c: Likewise.
gdb/gdbserver/
2014-08-07 Gary Benson <gbenson@redhat.com>
* configure.ac (AC_CHECK_HEADERS): Remove errno.h.
* configure: Regenerate.
* config.in: Likewise.
* server.h: Do not include errno.h.
* event-loop.c: Likewise.
* hostio-errno.c: Likewise.
* linux-low.c: Likewise.
* remote-utils.c: Likewise.
* spu-low.c: Likewise.
* utils.c: Likewise.
* gdbreplay.c: Unconditionally include errno.h.
This commit replaces a hardwired target-is-async check.
gdb/gdbserver/
2014-08-06 Gary Benson <gbenson@redhat.com>
* linux-low.c (linux_supports_non_stop): Use target_is_async_p.
Since we use tkill everywhere, using kill to try to kill each lwp
individually looks suspiciously odd. We should really be using tgkill
everywhere, but at least while we don't get there this makes us
consistent.
gdb/gdbserver/
2014-07-16 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_kill_one_lwp): Use kill_lwp, not kill.
gdb/
2014-07-16 Pedro Alves <palves@redhat.com>
* linux-nat.c (kill_callback): Use kill_lwp, not kill.
Although most compilers follow right-to-left evaluation order, the
order of evaluation of a function call's arguments is really
unspecified. target_pid_to_str or ptid_of may well clobber errno when
we get to evaluate the third argument to debug_printf.
gdb/gdbserver/
2014-07-15 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_kill_one_lwp): Save errno and work with saved
copy.
Here's an example, with the new test:
gdbserver :9999 gdb.threads/kill
gdb gdb.threads/kill
(gdb) b 52
Breakpoint 1 at 0x4007f4: file kill.c, line 52.
Continuing.
Breakpoint 1, main () at kill.c:52
52 return 0; /* set break here */
(gdb) k
Kill the program being debugged? (y or n) y
gdbserver :9999 gdb.threads/kill
Process gdb.base/watch_thread_num created; pid = 9719
Listening on port 1234
Remote debugging from host 127.0.0.1
Killing all inferiors
Segmentation fault (core dumped)
Backtrace:
(gdb) bt
#0 0x00000000004068a0 in find_inferior (list=0x66b060 <all_threads>, func=0x427637 <kill_one_lwp_callback>, arg=0x7fffffffd3fc) at src/gdb/gdbserver/inferiors.c:199
#1 0x00000000004277b6 in linux_kill (pid=15708) at src/gdb/gdbserver/linux-low.c:966
#2 0x000000000041354d in kill_inferior (pid=15708) at src/gdb/gdbserver/target.c:163
#3 0x00000000004107e9 in kill_inferior_callback (entry=0x6704f0) at src/gdb/gdbserver/server.c:2934
#4 0x0000000000406522 in for_each_inferior (list=0x66b050 <all_processes>, action=0x4107a6 <kill_inferior_callback>) at src/gdb/gdbserver/inferiors.c:57
#5 0x0000000000412377 in process_serial_event () at src/gdb/gdbserver/server.c:3767
#6 0x000000000041267c in handle_serial_event (err=0, client_data=0x0) at src/gdb/gdbserver/server.c:3880
#7 0x00000000004189ff in handle_file_event (event_file_desc=4) at src/gdb/gdbserver/event-loop.c:434
#8 0x00000000004181c6 in process_event () at src/gdb/gdbserver/event-loop.c:189
#9 0x0000000000418f45 in start_event_loop () at src/gdb/gdbserver/event-loop.c:552
#10 0x0000000000411272 in main (argc=3, argv=0x7fffffffd8d8) at src/gdb/gdbserver/server.c:3283
The problem is that linux_wait_for_event deletes lwps that have exited
(even those not passed in as lwps of interest), while the lwp/thread
list is being walked on with find_inferior. find_inferior can handle
the current iterated inferior being deleted, but not others.
When killing lwps, we don't really care about any of the pending
status handling of linux_wait_for_event. We can just waitpid the lwps
directly, which is also what GDB does (see
linux-nat.c:kill_wait_callback). This way the lwps are not deleted
while we're walking the list. They'll be deleted by linux_mourn
afterwards.
This crash triggers several times when running the testsuite against
GDBserver with the native-gdbserver board (target remote), but as GDB
can't distinguish between GDBserver crashing and "kill" being
sucessful, as in both cases the connection is closed (the 'k' packet
doesn't require a reply), and the inferior is gone, that results in no
FAIL.
The patch adds a generic test that catches the issue with
extended-remote mode (and works fine with native testing too). Here's
how it fails with the native-extended-gdbserver board without the fix:
(gdb) info threads
Id Target Id Frame
6 Thread 15367.15374 0x000000373bcbc98d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
5 Thread 15367.15373 0x000000373bcbc98d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
4 Thread 15367.15372 0x000000373bcbc98d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
3 Thread 15367.15371 0x000000373bcbc98d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
2 Thread 15367.15370 0x000000373bcbc98d in nanosleep () at ../sysdeps/unix/syscall-template.S:81
* 1 Thread 15367.15367 main () at .../gdb.threads/kill.c:52
(gdb) kill
Kill the program being debugged? (y or n) y
Remote connection closed
^^^^^^^^^^^^^^^^^^^^^^^^
(gdb) FAIL: gdb.threads/kill.exp: kill
Extended remote should remain connected after the kill.
gdb/gdbserver/
2014-07-11 Pedro Alves <palves@redhat.com>
* linux-low.c (kill_wait_lwp): New function, based on
kill_one_lwp_callback, but use my_waitpid directly.
(kill_one_lwp_callback, linux_kill): Use it.
gdb/testsuite/
2014-07-11 Pedro Alves <palves@redhat.com>
* gdb.threads/kill.c: New file.
* gdb.threads/kill.exp: New file.
This patch fixes hardware breakpoint regressions exposed by my fix for
"PR breakpoints/7143 - Watchpoint does not trigger when first set", at
https://sourceware.org/ml/gdb-patches/2014-03/msg00167.html
The testsuite caught them on Linux/x86_64, at least. gdb.sum:
gdb.sum:
FAIL: gdb.base/hbreak2.exp: next over recursive call
FAIL: gdb.base/hbreak2.exp: backtrace from factorial(5.1)
FAIL: gdb.base/hbreak2.exp: continue until exit at recursive next test
gdb.log:
(gdb) next
Program received signal SIGTRAP, Trace/breakpoint trap.
factorial (value=4) at ../../../src/gdb/testsuite/gdb.base/break.c:113
113 if (value > 1) { /* set breakpoint 7 here */
(gdb) FAIL: gdb.base/hbreak2.exp: next over recursive call
Actually, that patch just exposed a latent issue to "breakpoints
always-inserted off" mode, not really caused it. After that patch,
GDB no longer removes breakpoints at each internal event, thus making
some scenarios behave like breakpoint always-inserted on. The bug is
easy to trigger with always-inserted on.
The issue is that since the target-side breakpoint conditions support,
if the stub/server supports evaluating breakpoint conditions on the
target side, then GDB is sending duplicate Zx packets to the target
without removing them before, and GDBserver is not really expecting
that for Z packets other than Z0/z0. E.g., with "set breakpoint
always-inserted on" and "set debug remote 1":
(gdb) b main
Sending packet: $m410943,1#ff...Packet received: 48
Breakpoint 4 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z0,410943,1#48...Packet received: OK
^^^^^^^^^^^^
(gdb) b main
Note: breakpoint 4 also set at pc 0x410943.
Sending packet: $m410943,1#ff...Packet received: 48
Breakpoint 5 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z0,410943,1#48...Packet received: OK
^^^^^^^^^^^^
(gdb) b main
Note: breakpoints 4 and 5 also set at pc 0x410943.
Sending packet: $m410943,1#ff...Packet received: 48
Breakpoint 6 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z0,410943,1#48...Packet received: OK
^^^^^^^^^^^^
(gdb) del
Delete all breakpoints? (y or n) y
Sending packet: $Z0,410943,1#48...Packet received: OK
Sending packet: $Z0,410943,1#48...Packet received: OK
Sending packet: $z0,410943,1#68...Packet received: OK
And for Z1, similarly:
(gdb) hbreak main
Sending packet: $m410943,1#ff...Packet received: 48
Hardware assisted breakpoint 4 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z1,410943,1#49...Packet received: OK
^^^^^^^^^^^^
Packet Z1 (hardware-breakpoint) is supported
(gdb) hbreak main
Note: breakpoint 4 also set at pc 0x410943.
Sending packet: $m410943,1#ff...Packet received: 48
Hardware assisted breakpoint 5 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z1,410943,1#49...Packet received: OK
^^^^^^^^^^^^
(gdb) hbreak main
Note: breakpoints 4 and 5 also set at pc 0x410943.
Sending packet: $m410943,1#ff...Packet received: 48
Hardware assisted breakpoint 6 at 0x410943: file ../../../src/gdb/gdbserver/server.c, line 3028.
Sending packet: $Z1,410943,1#49...Packet received: OK
^^^^^^^^^^^^
(gdb) del
Delete all breakpoints? (y or n) y
Sending packet: $Z1,410943,1#49...Packet received: OK
^^^^^^^^^^^^
Sending packet: $Z1,410943,1#49...Packet received: OK
^^^^^^^^^^^^
Sending packet: $z1,410943,1#69...Packet received: OK
^^^^^^^^^^^^
So GDB sent a bunch of Z1 packets, and then when finally removing the
breakpoint, only one z1 packet was sent. On the GDBserver side (with
monitor set debug-hw-points 1), in the Z1 case, we see:
$ ./gdbserver :9999 ./gdbserver
Process ./gdbserver created; pid = 8629
Listening on port 9999
Remote debugging from host 127.0.0.1
insert_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=1 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
insert_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=2 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
insert_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=3 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
insert_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=4 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
insert_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=5 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
remove_watchpoint (addr=410943, len=1, type=instruction-execute):
CONTROL (DR7): 00000101 STATUS (DR6): 00000000
DR0: addr=0x410943, ref.count=4 DR1: addr=0x0, ref.count=0
DR2: addr=0x0, ref.count=0 DR3: addr=0x0, ref.count=0
That's one insert_watchpoint call for each Z1 packet, and then one
remove_watchpoint call for the z1 packet. Notice how ref.count
increased for each insert_watchpoint call, and then in the end, after
GDB told GDBserver to forget about the hardware breakpoint, GDBserver
ends with the the first debug register still with ref.count=4! IOW,
the hardware breakpoint is left armed on the target, while on the GDB
end it's gone. If the program happens to execute 0x410943 afterwards,
then the CPU traps, GDBserver reports the trap to GDB, and GDB not
having a breakpoint set at that address anymore, reports to the user a
spurious SIGTRAP.
This is exactly what is happening in the hbreak2.exp test, though in
that case, it's a shared library event that triggers a
breakpoint_re_set, when breakpoints are still inserted (because
nowadays GDB doesn't remove breakpoints while handling internal
events), and that recreates breakpoint locations, which likewise
forces breakpoint reinsertion and Zx packet resends...
That is a lot of bogus Zx duplication that should possibly be
addressed on the GDB side. GDB resends Zx packets because the way to
change the target-side condition, is to resend the breakpoint to the
server with the new condition. (That's an option in the packet: e.g.,
"Z1,410943,1;X3,220027" for "hbreak main if 0". The packets in the
examples above are shorter because the breakpoints don't have
conditions attached). GDB doesn't remove the breakpoint first before
reinserting it because that'd be bad for non-stop, as it'd open a
window where the inferior could miss the breakpoint. The conditions
actually haven't changed between the resends, but GDB isn't smart
enough to realize that.
(TBC, if the target doesn't support target-side conditions, then GDB
doesn't trigger these resends (init_bp_location calls
mark_breakpoint_location_modified, and that does nothing if condition
evaluation is on the host side. The resends are caused by the
'loc->condition_changed = condition_modified.' line.)
But, even if GDB was made smarter, GDBserver should really still
handle the resends anyway. So target-side conditions also aren't
really to blame. The documentation of the Z/z packets says:
"To avoid potential problems with duplicate packets, the operations
should be implemented in an idempotent way."
As such, we may want to fix GDB, but we should definitely fix
GDBserver. The fix is a prerequisite for target-side conditions on
hardware breakpoints anyway (and while at it, on watchpoints too).
GDBserver indeed already treats duplicate Z0 packets in an idempotent
way. mem-break.c has the concept of high-level and low-level
breakpoints, somewhat similar to GDB's split of breakpoints vs
breakpoint locations, and keeps track of multiple breakpoints
referencing the same address/location, for the case of an internal
GDBserver breakpoint or a tracepoint being set at the same address as
a GDB breakpoint. But, it only allows GDB to ever contribute one
reference to a software breakpoint location. IOW, if gdbserver sees a
Z0 packet for the same address where it already had a GDB breakpoint
set, then GDBserver won't create another high-level GDB breakpoint.
However, mem-break.c only tracks GDB Z0 breakpoints. The same logic
should apply to all kinds of Zx packets. Currently, gdbserver passes
down each duplicate Zx (other than Z0) request directly to the
target->insert_point routine. The x86 watchpoint support itself
refcounts watchpoint / hw breakpoint requests, to handle overlapping
watchpoints, and save debug registers. But that code doesn't (and
really shouldn't) handle the duplicate requests, assuming that for
each insert there will be a corresponding remove.
So the fix is to generalize mem-break.c to track all kinds of Zx
breakpoints, and filter out duplicates. As mentioned, this ends up
adding support for target-side conditions on hardware breakpoints and
watchpoints too (though GDB itself doesn't support the latter yet).
Probably the least obvious change in the patch is that it kind of
turns the breakpoint insert/remove APIs inside out. Before, the
target methods were only called for GDB breakpoints. The internal
breakpoint set/delete methods inserted memory breakpoints directly
bypassing the insert/remove target methods. That's not good when the
target should use a debug API to set software breakpoints, instead of
relying on GDBserver patching memory with breakpoint instructions, as
is the case of NTO.
Now removal/insertion of all kinds of breakpoints/watchpoints, either
internal, or from GDB, always go through the target methods. The
insert_point/remove_point methods no longer get passed a Z packet
type, but an internal/raw breakpoint type. They're also passed a
pointer to the raw breakpoint itself (note that's still opaque outside
mem-break.c), so that insert_memory_breakpoint /
remove_memory_breakpoint have access to the breakpoint's shadow
buffer. I first tried passing down a new structure based on GDB's
"struct bp_target_info" (actually with that name exactly), but then
decided against it as unnecessary complication.
As software/memory breakpoints work by poking at memory, when setting
a GDB Z0 breakpoint (but not internal breakpoints, as those can assume
the conditions are already right), we need to tell the target to
prepare to access memory (which on Linux means stop threads). If that
operation fails, we need to return error to GDB. Seeing an error, if
this is the first breakpoint of that type that GDB tries to insert,
GDB would then assume the breakpoint type is supported, but it may
actually not be. So we need to check whether the type is supported at
all before preparing to access memory. And to solve that, the patch
adds a new target->supports_z_point_type method that is called before
actually trying to insert the breakpoint.
Other than that, hopefully the change is more or less obvious.
New test added that exercises the hbreak2.exp regression in a more
direct way, without relying on a breakpoint re-set happening before
main is reached.
Tested by building GDBserver for:
aarch64-linux-gnu
arm-linux-gnueabihf
i686-pc-linux-gnu
i686-w64-mingw32
m68k-linux-gnu
mips-linux-gnu
mips-uclinux
nios2-linux-gnu
powerpc-linux-gnu
sh-linux-gnu
tilegx-unknown-linux-gnu
x86_64-redhat-linux
x86_64-w64-mingw32
And also regression tested on x86_64 Fedora 20.
gdb/gdbserver/
2014-05-20 Pedro Alves <palves@redhat.com>
* linux-aarch64-low.c (aarch64_insert_point)
(aarch64_remove_point): No longer check whether the type is
supported here. Adjust to new interface.
(the_low_target): Install aarch64_supports_z_point_type as
supports_z_point_type method.
* linux-arm-low.c (raw_bkpt_type_to_arm_hwbp_type): New function.
(arm_linux_hw_point_initialize): Take an enum raw_bkpt_type
instead of a Z packet char. Adjust.
(arm_supports_z_point_type): New function.
(arm_insert_point, arm_remove_point): Adjust to new interface.
(the_low_target): Install arm_supports_z_point_type.
* linux-crisv32-low.c (cris_supports_z_point_type): New function.
(cris_insert_point, cris_remove_point): Adjust to new interface.
Don't check whether the type is supported here.
(the_low_target): Install cris_supports_z_point_type.
* linux-low.c (linux_supports_z_point_type): New function.
(linux_insert_point, linux_remove_point): Adjust to new interface.
* linux-low.h (struct linux_target_ops) <insert_point,
remove_point>: Take an enum raw_bkpt_type instead of a char. Add
raw_breakpoint pointer parameter.
<supports_z_point_type>: New method.
* linux-mips-low.c (mips_supports_z_point_type): New function.
(mips_insert_point, mips_remove_point): Adjust to new interface.
Use mips_supports_z_point_type.
(the_low_target): Install mips_supports_z_point_type.
* linux-ppc-low.c (the_low_target): Install NULL as
supports_z_point_type method.
* linux-s390-low.c (the_low_target): Install NULL as
supports_z_point_type method.
* linux-sparc-low.c (the_low_target): Install NULL as
supports_z_point_type method.
* linux-x86-low.c (x86_supports_z_point_type): New function.
(x86_insert_point): Adjust to new insert_point interface. Use
insert_memory_breakpoint. Adjust to new
i386_low_insert_watchpoint interface.
(x86_remove_point): Adjust to remove_point interface. Use
remove_memory_breakpoint. Adjust to new
i386_low_remove_watchpoint interface.
(the_low_target): Install x86_supports_z_point_type.
* lynx-low.c (lynx_target_ops): Install NULL as
supports_z_point_type callback.
* nto-low.c (nto_supports_z_point_type): New.
(nto_insert_point, nto_remove_point): Adjust to new interface.
(nto_target_ops): Install nto_supports_z_point_type.
* mem-break.c: Adjust intro comment.
(struct raw_breakpoint) <raw_type, size>: New fields.
<inserted>: Update comment.
<shlib_disabled>: Delete field.
(enum bkpt_type) <gdb_breakpoint>: Delete value.
<gdb_breakpoint_Z0, gdb_breakpoint_Z1, gdb_breakpoint_Z2,
gdb_breakpoint_Z3, gdb_breakpoint_Z4>: New values.
(raw_bkpt_type_to_target_hw_bp_type): New function.
(find_enabled_raw_code_breakpoint_at): New function.
(find_raw_breakpoint_at): New type and size parameters. Use them.
(insert_memory_breakpoint): New function, based off
set_raw_breakpoint_at.
(remove_memory_breakpoint): New function.
(set_raw_breakpoint_at): Reimplement.
(set_breakpoint): New, based on set_breakpoint_at.
(set_breakpoint_at): Reimplement.
(delete_raw_breakpoint): Go through the_target->remove_point
instead of assuming memory breakpoints.
(find_gdb_breakpoint_at): Delete.
(Z_packet_to_bkpt_type, Z_packet_to_raw_bkpt_type): New functions.
(find_gdb_breakpoint): New function.
(set_gdb_breakpoint_at): Delete.
(z_type_supported): New function.
(set_gdb_breakpoint_1): New function, loosely based off
set_gdb_breakpoint_at.
(check_gdb_bp_preconditions, set_gdb_breakpoint): New functions.
(delete_gdb_breakpoint_at): Delete.
(delete_gdb_breakpoint_1): New function, loosely based off
delete_gdb_breakpoint_at.
(delete_gdb_breakpoint): New function.
(clear_gdb_breakpoint_conditions): Rename to ...
(clear_breakpoint_conditions): ... this. Don't handle a NULL
breakpoint.
(add_condition_to_breakpoint): Make static.
(add_breakpoint_condition): Take a struct breakpoint pointer
instead of an address. Adjust.
(gdb_condition_true_at_breakpoint): Rename to ...
(gdb_condition_true_at_breakpoint_z_type): ... this, and add
z_type parameter.
(gdb_condition_true_at_breakpoint): Reimplement.
(add_breakpoint_commands): Take a struct breakpoint pointer
instead of an address. Adjust.
(gdb_no_commands_at_breakpoint): Rename to ...
(gdb_no_commands_at_breakpoint_z_type): ... this. Add z_type
parameter. Return true if no breakpoint was found. Change debug
output.
(gdb_no_commands_at_breakpoint): Reimplement.
(run_breakpoint_commands): Rename to ...
(run_breakpoint_commands_z_type): ... this. Add z_type parameter,
and change return type to boolean.
(run_breakpoint_commands): New function.
(gdb_breakpoint_here): Also check for Z1 breakpoints.
(uninsert_raw_breakpoint): Don't try to reinsert a disabled
breakpoint. Go through the_target->remove_point instead of
assuming memory breakpoint.
(uninsert_breakpoints_at, uninsert_all_breakpoints): Uninsert
software and hardware breakpoints.
(reinsert_raw_breakpoint): Go through the_target->insert_point
instead of assuming memory breakpoint.
(reinsert_breakpoints_at, reinsert_all_breakpoints): Reinsert
software and hardware breakpoints.
(check_breakpoints, breakpoint_here, breakpoint_inserted_here):
Check both software and hardware breakpoints.
(validate_inserted_breakpoint): Assert the breakpoint is a
software breakpoint. Set the inserted flag to -1 instead of
setting shlib_disabled.
(delete_disabled_breakpoints): Adjust.
(validate_breakpoints): Only validate software breakpoints.
Adjust to inserted flag change.
(check_mem_read, check_mem_write): Skip breakpoint types other
than software breakpoints. Adjust to inserted flag change.
* mem-break.h (enum raw_bkpt_type): New enum.
(raw_breakpoint, struct process_info): Forward declare.
(Z_packet_to_target_hw_bp_type): Delete declaration.
(raw_bkpt_type_to_target_hw_bp_type, Z_packet_to_raw_bkpt_type)
(set_gdb_breakpoint, delete_gdb_breakpoint)
(clear_breakpoint_conditions): New declarations.
(set_gdb_breakpoint_at, clear_gdb_breakpoint_conditions): Delete.
(breakpoint_inserted_here): Update comment.
(add_breakpoint_condition, add_breakpoint_commands): Replace
address parameter with a breakpoint pointer parameter.
(gdb_breakpoint_here): Update comment.
(delete_gdb_breakpoint_at): Delete.
(insert_memory_breakpoint, remove_memory_breakpoint): Declare.
* server.c (process_point_options): Take a struct breakpoint
pointer instead of an address. Adjust.
(process_serial_event) <Z/z packets>: Use set_gdb_breakpoint and
delete_gdb_breakpoint.
* spu-low.c (spu_target_ops): Install NULL as
supports_z_point_type method.
* target.h: Include mem-break.h.
(struct target_ops) <prepare_to_access_memory>: Update comment.
<supports_z_point_type>: New field.
<insert_point, remove_point>: Take an enum raw_bkpt_type argument
instead of a char. Also take a raw breakpoint pointer.
* win32-arm-low.c (the_low_target): Install NULL as
supports_z_point_type.
* win32-i386-low.c (i386_supports_z_point_type): New function.
(i386_insert_point, i386_remove_point): Adjust to new interface.
(the_low_target): Install i386_supports_z_point_type.
* win32-low.c (win32_supports_z_point_type): New function.
(win32_insert_point, win32_remove_point): Adjust to new interface.
(win32_target_ops): Install win32_supports_z_point_type.
* win32-low.h (struct win32_target_ops):
<supports_z_point_type>: New method.
<insert_point, remove_point>: Take an enum raw_bkpt_type argument
instead of a char. Also take a raw breakpoint pointer.
gdb/testsuite/
2014-05-20 Pedro Alves <palves@redhat.com>
* gdb.base/break-idempotent.c: New file.
* gdb.base/break-idempotent.exp: New file.
On Linux, we need to explicitly ptrace attach to all lwps of a
process. Because GDB might not be connected yet when an attach is
requested, and thus it may not be possible to activate thread_db, as
that requires access to symbols (IOW, gdbserver --attach), a while ago
we make linux_attach loop over the lwps as listed by /proc/PID/task to
find the lwps to attach to.
linux_attach_lwp_1 has:
...
if (initial)
/* If lwp is the tgid, we handle adding existing threads later.
Otherwise we just add lwp without bothering about any other
threads. */
ptid = ptid_build (lwpid, lwpid, 0);
else
{
/* Note that extracting the pid from the current inferior is
safe, since we're always called in the context of the same
process as this new thread. */
int pid = pid_of (current_inferior);
ptid = ptid_build (pid, lwpid, 0);
}
That "safe" comment referred to linux_attach_lwp being called by
thread-db.c. But this was clearly missed when a new call to
linux_attach_lwp_1 was added to linux_attach. As a result,
current_inferior will be set to some random process, and non-initial
lwps of the second inferior get assigned the pid of the wrong
inferior. E.g., in the case of attaching to two inferiors, for the
second inferior (and so on), non-initial lwps of the second inferior
get assigned the pid of the first inferior. This doesn't trigger on
the first inferior, when current_inferior is NULL, add_thread switches
the current inferior to the newly added thread.
Rather than making linux_attach switch current_inferior temporarily
(thus avoiding further reliance on global state), or making
linux_attach_lwp_1 get the tgid from /proc, which add extra syscalls,
and will be wrong in case of the user having originally attached
directly to a non-tgid lwp, and then that lwp spawning new clones (the
ptid.pid field of further new clones should be the same as the
original lwp's pid, which is not the tgid), we note that callers of
linux_attach_lwp/linux_attach_lwp_1 always have the right pid handy
already, so they can pass it down along with the lwpid.
The only other reason for the "initial" parameter is to error out
instead of warn in case of attach failure, when we're first attaching
to a process. There are only three callers of
linux_attach_lwp/linux_attach_lwp_1, and each wants to print a
different warn/error string, so we can just move the error/warn out of
linux_attach_lwp_1 to the callers, thus getting rid of the "initial"
parameter.
There really nothing gdbserver-specific about attaching to two
threaded processes, so this adds a new test under gdb.multi/. The
test passes cleanly against the native GNU/Linux target, but
fails/triggers the bug against GDBserver (before the patch), with the
native-extended-remote board (as plain remote doesn't support
multi-process).
Tested on x86_64 Fedora 17, with the native-extended-gdbserver board.
gdb/gdbserver/
2014-04-25 Pedro Alves <palves@redhat.com>
PR server/16255
* linux-low.c (linux_attach_fail_reason_string): New function.
(linux_attach_lwp): Delete.
(linux_attach_lwp_1): Rename to ...
(linux_attach_lwp): ... this. Take a ptid instead of a pid as
argument. Remove "initial" parameter. Return int instead of
void. Don't error or warn here.
(linux_attach): Adjust to call linux_attach_lwp. Call error on
failure to attach to the tgid. Call warning when failing to
attach to an lwp.
* linux-low.h (linux_attach_lwp): Take a ptid instead of a pid as
argument. Remove "initial" parameter. Return int instead of
void. Don't error or warn here.
(linux_attach_fail_reason_string): New declaration.
* thread-db.c (attach_thread): Adjust to linux_attach_lwp's
interface change. Use linux_attach_fail_reason_string.
gdb/
2014-04-25 Pedro Alves <palves@redhat.com>
PR server/16255
* common/linux-ptrace.c (linux_ptrace_attach_warnings): Rename to ...
(linux_ptrace_attach_fail_reason): ... this. Remove "warning: "
and newline from built string.
* common/linux-ptrace.h (linux_ptrace_attach_warnings): Rename to ...
(linux_ptrace_attach_fail_reason): ... this.
* linux-nat.c (linux_nat_attach): Adjust to use
linux_ptrace_attach_fail_reason.
gdb/testsuite/
2014-04-25 Simon Marchi <simon.marchi@ericsson.com>
Pedro Alves <palves@redhat.com>
PR server/16255
* gdb.multi/multi-attach.c: New file.
* gdb.multi/multi-attach.exp: New file.
sh-linux-gnu-gcc (...) src/gdb/gdbserver/linux-low.c
.../src/gdb/gdbserver/linux-low.c: In function 'linux_read_loadmap':
.../src/gdb/gdbserver/linux-low.c:5284:13: error: 'struct lwp_info' has no member named 'entry'
make[1]: *** [linux-low.o] Error 1
gdb/gdbserver/
2014-04-09 Pedro Alves <palves@redhat.com>
* linux-low.c (linux_read_loadmap): Pass current_inferior directly
to lwpid_of.
GDBserver currently hangs forever in waitpid if the leader thread
exits before other threads, or if all resumed threads exit - e.g.,
next over a thread exit with sched-locking on. This is exposed by
leader-exit.exp. leader-exit.exp is part of a series of tests for a
set of related problems. See
<http://www.sourceware.org/ml/gdb-patches/2011-10/msg00704.html>:
"
To recap, on the Linux kernel, ptrace/waitpid don't allow reaping the
leader thread until all other threads in the group are reaped. When
the leader exits, it goes zombie, but waitpid will not return an exit
status until the other threads are gone. This is presently exercised
by the gdb.threads/leader-exit.exp test. The fix for that test, in
linux-nat.c:wait_lwp, handles the case where we see the leader gone
when we're stopping all threads to report an event to some other
thread to the core.
(...)
The latter bit about not blocking if there no resumed threads in the
process also applies to some other thread exiting, not just the main
thread. E.g., this test starts a thread, and runs to a breakpoint in
that thread:
...
(gdb) c
Continuing.
[New Thread 0x7ffff75a4700 (LWP 23397)]
[Switching to Thread 0x7ffff75a4700 (LWP 23397)]
Breakpoint 2, thread_a (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
28 return 0; /* break-here */
(gdb) info threads
* 2 Thread 0x7ffff75a4700 (LWP 23397) thread_a (arg=0x0) at ../../../src/gdb/testsuite/gdb.threads/no-unwaited-for-left.c:28
1 Thread 0x7ffff7fcb720 (LWP 23391) 0x00007ffff7bc606d in pthread_join (threadid=140737343276800, thread_return=0x0) at pthread_join.c:89
The thread will exit as soon as we resume it. But if we only resume
that thread, leaving the rest of the threads stopped:
(gdb) set scheduler-locking on
(gdb) c
Continuing.
^C^C^C^C^C^C^C^C
"
This patch fixes the issues by implementing TARGET_WAITKIND_NO_RESUMED
on GDBserver, similarly to what the patch above did for native
Linux GDB.
gdb.threads/leader-exit.exp now passes.
gdb.threads/no-unwaited-for-left.exp now at least errors out instead
of hanging:
continue
Continuing.
warning: Remote failure reply: E.No unwaited-for children left.
[Thread 15454] #1 stopped.
0x00000034cf408e60 in pthread_join (threadid=140737353922368, thread_return=0x0) at pthread_join.c:93
93 lll_wait_tid (pd->tid);
(gdb) FAIL: gdb.threads/no-unwaited-for-left.exp: continue stops when the main thread exits
The gdb.threads/non-ldr-exc-*.exp tests are skipped because GDBserver
unfortunately doesn't support fork/exec yet, but I'm confident this
fixes the related issues.
I'm leaving modeling TARGET_WAITKIND_NO_RESUMED in the RSP for a
separate pass.
(BTW, in case of error in response to a vCont, it would be better for
GDB to query the target for the current thread, or re-select one,
instead of assuming current inferior_ptid is still the selected
thread.)
This implementation is a little different from GDB's, because I'm
avoiding bringing in more of this broken use of waitpid(PID) into
GDBserver. Specifically, this avoids waitpid(PID) when stopping all
threads. There's really no need for wait_for_sigstop to wait for each
LWP in turn. Instead, with some refactoring, we make it reuse
linux_wait_for_event.
gdb/gdbserver/
2014-02-27 Pedro Alves <palves@redhat.com>
PR 12702
* inferiors.h (A_I_NEXT, ALL_INFERIORS_TYPE, ALL_PROCESSES): New
macros.
* linux-low.c (delete_lwp, handle_extended_wait): Add debug
output.
(last_thread_of_process_p): Take a PID argument instead of a
thread pointer.
(linux_wait_for_lwp): Delete.
(num_lwps, check_zombie_leaders, not_stopped_callback): New
functions.
(linux_low_filter_event): New function, party factored out from
linux_wait_for_event.
(linux_wait_for_event): Rename to ...
(linux_wait_for_event_filtered): ... this. Add new filter ptid
argument. Partly rewrite. Always use waitpid(-1, WNOHANG) and
sigsuspend. Check for zombie leaders.
(linux_wait_for_event): Reimplement as wrapper around
linux_wait_for_event_filtered.
(linux_wait_1): Handle TARGET_WAITKIND_NO_RESUMED. Assume that if
a normal or signal exit is seen, it's the whole process exiting.
(wait_for_sigstop): No longer a for_each_inferior callback.
Rewrite on top of linux_wait_for_event_filtered.
(stop_all_lwps): Call wait_for_sigstop directly.
* server.c (resume, handle_target_event): Handle
TARGET_WAITKIND_NO_RESUMED.
* gdbthread.h (add_thread): Change result type to struct thread_info *.
* inferiors.c (add_thread): Change result type to struct thread_info *.
All callers updated.
(add_lwp): Call add_thread here instead of in callers.
All callers updated.
* linux-low.h (get_lwp_thread): Rewrite.
(struct lwp_info): New member "thread".
This speeds up gdbserver attach in non-stop mode because now get_lwp_thread
doesn't do a linear search for the corresponding thread_info object.
* dll.c (clear_dlls): Replace accessing list implemention details
with API function.
* gdbthread.h (get_first_thread): Declare.
* inferiors.c (for_each_inferior_with_data): New function.
(get_first_thread): New function.
(find_thread_ptid): Simplify.
(get_first_inferior): New function.
(clear_list): Delete.
(one_inferior_p): New function.
(clear_inferior_list): New function.
(clear_inferiors): Update.
* inferiors.h (for_each_inferior_with_data): Declare.
(clear_inferior_list): Declare.
(one_inferior_p): Declare.
(get_first_inferior): Declare.
* linux-low.c (linux_wait_for_event): Replace accessing list
implemention details with API function.
* server.c (target_running): Ditto.
(accumulate_file_name_length): New function.
(emit_dll_description): New function.
(handle_qxfer_libraries): Replace accessing list implemention
details with API function.
(handle_qxfer_threads_worker): New function.
(handle_qxfer_threads_proper): Replace accessing list implemention
details with API function.
(handle_query): Ditto.
(visit_actioned_threads_callback_ftype): New typedef.
(visit_actioned_threads_data): New struct.
(visit_actioned_threads): Rewrite to be find_inferior callback.
(resume): Call find_inferior.
(handle_status): Replace accessing list implemention
details with API function.
(process_serial_event): Replace accessing list implemention details
with API function.
* target.c (set_desired_inferior): Replace accessing list implemention
details with API function.
* tracepoint.c (same_process_p): New function.
(gdb_agent_about_to_close): Replace accessing list implemention
details with API function.
* win32-low.c (child_delete_thread): Replace accessing list
implemention details with API function.
(match_dll_by_basename): New function.
(dll_is_loaded_by_basename): New function.
(win32_ensure_ntdll_loaded): Replace accessing list implemention
details call to dll_is_loaded_by_basename.
Read branch trace data incrementally and extend the current trace rather than
discarding it and reading the entire trace buffer each time.
If the branch trace buffer overflowed, we can't extend the current trace so we
discard it and start anew by reading the entire branch trace buffer.
2014-01-16 Markus Metzger <markus.t.metzger@intel.com>
* common/linux-btrace.c (perf_event_read_bts, linux_read_btrace):
Support delta reads.
(linux_disable_btrace): Change return type.
* common/linux-btrace.h (linux_read_btrace): Change parameters
and return type to allow error reporting. Update users.
(linux_disable_btrace): Change return type. Update users.
* common/btrace-common.h (btrace_read_type) <BTRACE_READ_DELTA>:
New.
(btrace_error): New.
(btrace_block) <begin>: Comment on BEGIN == 0.
* btrace.c (btrace_compute_ftrace): Start from the end of
the current trace.
(btrace_stitch_trace, btrace_clear_history): New.
(btrace_fetch): Read delta trace, return if replaying.
(btrace_clear): Move clear history code to btrace_clear_history.
(parse_xml_btrace): Throw an error if parsing failed.
* target.h (struct target_ops) <to_read_btrace>: Change parameters
and return type to allow error reporting.
(target_read_btrace): Change parameters and return type to allow
error reporting.
* target.c (target_read_btrace): Update.
* remote.c (remote_read_btrace): Support delta reads. Pass
errors on.
* NEWS: Announce it.
gdbserver/
* target.h (target_ops) <read_btrace>: Change parameters and
return type to allow error reporting.
* server.c (handle_qxfer_btrace): Support delta reads. Pass
trace reading errors on.
* linux-low.c (linux_low_read_btrace): Pass trace reading
errors on.
(linux_low_disable_btrace): New.
This patch is purely mechanical. It removes gdb_stat.h and changes
the code to use sys/stat.h.
2013-11-18 Tom Tromey <tromey@redhat.com>
* common/gdb_stat.h: Remove.
* ada-lang.c: Use sys/stat.h, not gdb_stat.h.
* common/filestuff.c: Use sys/stat.h, not gdb_stat.h.
* common/linux-osdata.c: Use sys/stat.h, not gdb_stat.h.
* corefile.c: Use sys/stat.h, not gdb_stat.h.
* ctf.c: Use sys/stat.h, not gdb_stat.h.
* darwin-nat.c: Use sys/stat.h, not gdb_stat.h.
* dbxread.c: Use sys/stat.h, not gdb_stat.h.
* dwarf2read.c: Use sys/stat.h, not gdb_stat.h.
* exec.c: Use sys/stat.h, not gdb_stat.h.
* gdbserver/linux-low.c: Use sys/stat.h, not gdb_stat.h.
* gdbserver/remote-utils.c: Use sys/stat.h, not gdb_stat.h.
* inf-child.c: Use sys/stat.h, not gdb_stat.h.
* jit.c: Use sys/stat.h, not gdb_stat.h.
* linux-nat.c: Use sys/stat.h, not gdb_stat.h.
* m68klinux-nat.c: Use sys/stat.h, not gdb_stat.h.
* main.c: Use sys/stat.h, not gdb_stat.h.
* mdebugread.c: Use sys/stat.h, not gdb_stat.h.
* mi/mi-cmd-env.c: Use sys/stat.h, not gdb_stat.h.
* nto-tdep.c: Use sys/stat.h, not gdb_stat.h.
* objfiles.c: Use sys/stat.h, not gdb_stat.h.
* procfs.c: Use sys/stat.h, not gdb_stat.h.
* remote-fileio.c: Use sys/stat.h, not gdb_stat.h.
* remote-mips.c: Use sys/stat.h, not gdb_stat.h.
* remote.c: Use sys/stat.h, not gdb_stat.h.
* rs6000-nat.c: Use sys/stat.h, not gdb_stat.h.
* sol-thread.c: Use sys/stat.h, not gdb_stat.h.
* solib-spu.c: Use sys/stat.h, not gdb_stat.h.
* source.c: Use sys/stat.h, not gdb_stat.h.
* symfile.c: Use sys/stat.h, not gdb_stat.h.
* symmisc.c: Use sys/stat.h, not gdb_stat.h.
* symtab.c: Use sys/stat.h, not gdb_stat.h.
* top.c: Use sys/stat.h, not gdb_stat.h.
* xcoffread.c: Use sys/stat.h, not gdb_stat.h.
to PTRACE_TYPE_ARG3.
* linux-low.c: Rename all occurrences of PTRACE_ARG3_TYPE
to PTRACE_TYPE_ARG3 and PTRACE_ARG4_TYPE to
PTRACE_TYPE_ARG4.
* linux-low.h (PTRACE_ARG3_TYPE): Rename to PTRACE_TYPE_ARG3.
(PTRACE_ARG4_TYPE): Rename to PTRACE_TYPE_ARG4.
With the pathmax gnulib module in place, we can use PATH_MAX
consistently throughout, instead of the current mixbag of PATH_MAX and
MAXPATHLEN uses. It's no longer necessary to include sys/param.h
(supposedly, I can't check all ports touched here) for MAXPATHLEN.
Don't remove sys/param.h from GDB's configure.ac, as later tests in
the file use HAVE_SYS_PARAM_H checks.
Tested on x86_64 Fedora 17.
Also cross-built for --host=i686-w64-mingw32, and --host=i586-pc-msdosdjgpp.
gdb/
2013-07-01 Pedro Alves <palves@redhat.com>
* defs.h: Include "pathmax.h".
* utils.c: Don't include sys/param.h.
(gdb_realpath): Remove code that checks for MAXPATHLEN.
* solib-ia64-hpux.c (ia64_hpux_handle_load_event): Use PATH_MAX
instead of MAXPATHLEN.
* solib-sunos.c: Don't include sys/param.h.
* xcoffread.c: Don't include sys/param.h.
* bsd-kvm.c: Don't include sys/param.h.
* darwin-nat.c: Don't include sys/param.h.
(darwin_pid_to_exec_file): Use PATH_MAX instead of MAXPATHLEN.
* darwin-nat-info.c: Don't include sys/param.h.
* fbsd-nat.c (fbsd_pid_to_exec_file): Use PATH_MAX instead of
MAXPATHLEN.
* i386obsd-nat.c: Don't include sys/param.h.
* inf-child.c: Don't include sys/param.h.
(inf_child_fileio_readlink): Use PATH_MAX instead of MAXPATHLEN.
* linux-fork.c: Don't include sys/param.h.
(fork_save_infrun_state): Use PATH_MAX instead of MAXPATHLEN.
* linux-nat.c: Don't include sys/param.h.
(linux_child_pid_to_exec_file, linux_proc_pending_signals)
(linux_proc_pending_signals): Use PATH_MAX instead of MAXPATHLEN.
* m68klinux-nat.c: Don't include sys/param.h.
* nbsd-nat.c: Don't include sys/param.h.
(nbsd_pid_to_exec_file): Use PATH_MAX instead of MAXPATHLEN.
* ppc-linux-nat.c: Don't include sys/param.h.
* rs6000-nat.c: Don't include sys/param.h.
* spu-linux-nat.c. Don't include sys/param.h.
* windows-nat.c: Don't include sys/param.h.
* xtensa-linux-nat.c: Don't include sys/param.h.
* config/i386/nm-fbsd.h: Don't include sys/param.h.
gdb/gdbserver/
2013-07-01 Pedro Alves <palves@redhat.com>
* server.h: Include "pathmax.h".
* linux-low.c: Don't include sys/param.h.
(linux_pid_exe_is_elf_64_file): Use PATH_MAX instead of
MAXPATHLEN.
* win32-low.c: Don't include sys/param.h.
(win32_create_inferior): Use PATH_MAX instead of MAXPATHLEN.
There's no need for every arch to pre-allocate disabled_regsets.
Chances are the array won't be used.
(I have a hunch that with some more work we could dispense with
initialize_regsets_info.)
Tested on x86_64 Fedora 17 w/ -lmcheck.
gdb/gdbserver/
2013-06-11 Pedro Alves <palves@redhat.com>
* linux-low.c (regset_disabled, disable_regset): New functions.
(regsets_fetch_inferior_registers)
(regsets_store_inferior_registers): Use them.
(initialize_regsets_info); Don't allocate the disabled_regsets
array here.
* linux-low.h (struct regsets_info) <disabled_regsets>: Extend
comment.
This fixes the regression reported at
<http://sourceware.org/ml/gdb-patches/2013-06/msg00185.html>.
GDBserver was reaching:
static int
regsets_fetch_inferior_registers (struct regsets_info *regsets_info,
struct regcache *regcache)
{
struct regset_info *regset;
int saw_general_regs = 0;
int pid;
struct iovec iov;
regset = regsets_info->regsets;
pid = lwpid_of (get_thread_lwp (current_inferior));
while (regset->size >= 0)
{
void *buf, *data;
int nt_type, res;
if (regset->size == 0
|| regsets_info->disabled_regsets[regset - regsets_info->regsets])
{
>>>>>>> regset ++; <<<<<<< HERE
continue;
}
Because info->disabled_regsets[] was not being initialized, and that
causes all sorts of wrong.
gdb/gdbserver/
2013-06-11 Pedro Alves <palves@redhat.com>
* linux-low.c (initialize_regsets_info): Use xcalloc instead of
xmalloc.
This patch makes GDBserver support multi-process + biarch.
Currently, if you're debugging more than one process at once with a
single gdbserver (in extended-remote mode), then all processes must
have the same architecture (e.g., 64-bit vs 32-bit). Otherwise, you
see this:
Added inferior 2
[Switching to inferior 2 [<null>] (<noexec>)]
Reading symbols from /home/pedro/gdb/tests/main32...done.
Temporary breakpoint 2 at 0x4004cf: main. (2 locations)
Starting program: /home/pedro/gdb/tests/main32
warning: Selected architecture i386 is not compatible with reported target architecture i386:x86-64
warning: Architecture rejected target-supplied description
Remote 'g' packet reply is too long: 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000090cfffff0000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000b042f7460000000000020000230000002b0000002b0000002b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007f03000000000000ffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801f00003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
... etc, etc ...
Even though the process was running a 32-bit program, GDBserver sent
back to GDB a register set in 64-bit layout.
A patch (http://sourceware.org/ml/gdb-patches/2012-11/msg00228.html) a
while ago made GDB track a target_gdbarch per inferior, and as
consequence, fetch a target description per-inferior. This patch is
the GDBserver counterpart, that makes GDBserver keep track of each
process'es XML target description and register layout. So in the
example above, GDBserver will send the correct register set in 32-bit
layout to GDB.
A new "struct target_desc" object (tdesc for short) is added, that
holds the target description and register layout information about
each process. Each `struct process_info' holds a pointer to a target
description. The regcache also gains a pointer to a target
description, mainly for convenience, and parallel with GDB (and
possible future support for programs that flip processor modes).
The low target's arch_setup routines are responsible for setting the
process'es correct tdesc. This isn't that much different to how
things were done before, except that instead of detecting the inferior
process'es architecture and calling the corresponding
init_registers_FOO routine, which would change the regcache layout
globals and recreate the threads' regcaches, the regcache.c globals
are gone, and the init_registers_$BAR routines now each initialize a
separate global struct target_desc object (one for each arch variant
GDBserver supports), and so all the init_registers_$BAR routines that
are built into GDBserver are called early at GDBserver startup time
(similarly to how GDB handles its built-in target descriptions), and
then the arch_setup routine is responsible for making
process_info->tdesc point to one of these target description globals.
The regcache module is all parameterized to get the regcache's layout
from the tdesc object instead of the old register_bytes, etc. globals.
The threads' regcaches are now created lazily. The old scheme where
we created each of them when we added a new thread doesn't work
anymore, because we add the main thread/lwp before we see it stop for
the first time, and it is only when we see the thread stop for the
first time that we have a chance of determining the inferior's
architecture (through the_low_target.arch_setup). Therefore when we
add the main thread we don't know which architecture/tdesc its
regcache should have.
This patch makes the gdb.multi/multi-arch.exp test now pass against
(extended-remote) GDBserver. It currently fails, without this patch.
The IPA also uses the regcache, so it gains a new global struct
target_desc pointer, which points at the description of the process it
is loaded in.
Re. the linux-low.c & friends changes. Since the register map
etc. may differ between processes (64-bit vs 32-bit) etc., the
linux_target_ops num_regs, regmap and regset_bitmap data fields are no
longer sufficient. A new method is added in their place that returns
a pointer to a new struct that includes all info linux-low.c needs to
access registers of the current inferior.
The patch/discussion that originally introduced
linux-low.c:disabled_regsets mentions that the disabled_regsets set
may be different per mode (in a biarch setup), and indeed that is
cleared whenever we start a new (first) inferior, so that global is
moved as well behind the new `struct regs_info'.
On the x86 side:
I simply replaced the i387-fp.c:num_xmm_registers global with a check
for 64-bit or 32-bit process, which is equivalent to how the global
was set. This avoided coming up with some more general mechanism that
would work for all targets that use this module (GNU/Linux, Windows,
etc.).
Tested:
GNU/Linux IA64
GNU/Linux MIPS64
GNU/Linux PowerPC (Fedora 16)
GNU/Linux s390x (Fedora 16)
GNU/Linux sparc64 (Debian)
GNU/Linux x86_64, -m64 and -m32 (Fedora 17)
Cross built, and smoke tested:
i686-w64-mingw32, under Wine.
GNU/Linux TI C6x, by Yao Qi.
Cross built but otherwise not tested:
aarch64-linux-gnu
arm-linux-gnu
m68k-linux
nios2-linux-gnu
sh-linux-gnu
spu
tilegx-unknown-linux-gnu
Completely untested:
GNU/Linux Blackfin
GNU/Linux CRIS
GNU/Linux CRISv32
GNU/Linux TI Xtensa
GNU/Linux M32R
LynxOS
QNX NTO
gdb/gdbserver/
2013-06-07 Pedro Alves <palves@redhat.com>
* Makefile.in (OBS): Add tdesc.o.
(IPA_OBJS): Add tdesc-ipa.o.
(tdesc-ipa.o): New rule.
* ax.c (gdb_eval_agent_expr): Adjust register_size call to new
interface.
* linux-low.c (new_inferior): Delete.
(disabled_regsets, num_regsets): Delete.
(linux_add_process): Adjust to set the new per-process
new_inferior flag.
(linux_detach_one_lwp): Adjust to call regcache_invalidate_thread.
(linux_wait_for_lwp): Adjust. Only call arch_setup if the event
was a stop. When calling arch_setup, switch the current inferior
to the thread that got an event.
(linux_resume_one_lwp): Adjust to call regcache_invalidate_thread.
(regsets_fetch_inferior_registers)
(regsets_store_inferior_registers): New regsets_info parameter.
Adjust to use it.
(linux_register_in_regsets): New regs_info parameter. Adjust to
use it.
(register_addr, fetch_register, store_register): New usrregs_info
parameter. Adjust to use it.
(usr_fetch_inferior_registers, usr_store_inferior_registers): New
parameter regs_info. Adjust to use it.
(linux_fetch_registers): Get the current inferior's regs_info, and
adjust to use it.
(linux_store_registers): Ditto.
[HAVE_LINUX_REGSETS] (initialize_regsets_info): New.
(initialize_low): Don't initialize the target_regsets here. Call
initialize_low_arch.
* linux-low.h (target_regsets): Delete declaration.
(struct regsets_info): New.
(struct usrregs_info): New.
(struct regs_info): New.
(struct process_info_private) <new_inferior>: New field.
(struct linux_target_ops): Delete the num_regs, regmap, and
regset_bitmap fields. New field regs_info.
[HAVE_LINUX_REGSETS] (initialize_regsets_info): Declare.
* i387-fp.c (num_xmm_registers): Delete.
(i387_cache_to_fsave, i387_fsave_to_cache): Adjust find_regno
calls to new interface.
(i387_cache_to_fxsave, i387_cache_to_xsave, i387_fxsave_to_cache)
(i387_xsave_to_cache): Adjust find_regno calls to new interface.
Infer the number of xmm registers from the regcache's target
description.
* i387-fp.h (num_xmm_registers): Delete.
* inferiors.c (add_thread): Don't install the thread's regcache
here.
* proc-service.c (gregset_info): Fetch the current inferior's
regs_info. Adjust to use it.
* regcache.c: Include tdesc.h.
(register_bytes, reg_defs, num_registers)
(gdbserver_expedite_regs): Delete.
(get_thread_regcache): If the thread doesn't have a regcache yet,
create one, instead of aborting gdbserver.
(regcache_invalidate_one): Rename to ...
(regcache_invalidate_thread): ... this.
(regcache_invalidate_one): New.
(regcache_invalidate): Only invalidate registers of the current
process.
(init_register_cache): Add target_desc parameter, and use it.
(new_register_cache): Ditto. Assert the target description has a
non zero registers_size.
(regcache_cpy): Add assertions. Adjust.
(realloc_register_cache, set_register_cache): Delete.
(registers_to_string, registers_from_string): Adjust.
(find_register_by_name, find_regno, find_register_by_number)
(register_cache_size): Add target_desc parameter, and use it.
(free_register_cache_thread, free_register_cache_thread_one)
(regcache_release, register_cache_size): New.
(register_size): Add target_desc parameter, and use it.
(register_data, supply_register, supply_register_zeroed)
(supply_regblock, supply_register_by_name, collect_register)
(collect_register_as_string, collect_register_by_name): Adjust.
* regcache.h (struct target_desc): Forward declare.
(struct regcache) <tdesc>: New field.
(init_register_cache, new_register_cache): Add target_desc
parameter.
(regcache_invalidate_thread): Declare.
(regcache_invalidate_one): Delete declaration.
(regcache_release): Declare.
(find_register_by_number, register_cache_size, register_size)
(find_regno): Add target_desc parameter.
(gdbserver_expedite_regs, gdbserver_xmltarget): Delete
declarations.
* remote-utils.c: Include tdesc.h.
(outreg, prepare_resume_reply): Adjust.
* server.c: Include tdesc.h.
(gdbserver_xmltarget): Delete declaration.
(get_features_xml, process_serial_event): Adjust.
* server.h [IN_PROCESS_AGENT] (struct target_desc): Forward
declare.
(struct process_info) <tdesc>: New field.
(ipa_tdesc): Declare.
* tdesc.c: New file.
* tdesc.h: New file.
* tracepoint.c: Include tdesc.h.
[IN_PROCESS_AGENT] (ipa_tdesc): Define.
(get_context_regcache): Adjust to pass ipa_tdesc down.
(do_action_at_tracepoint): Adjust to get the register cache size
from the context regcache's description.
(traceframe_walk_blocks): Adjust to get the register cache size
from the current trace frame's description.
(traceframe_get_pc): Adjust to get current trace frame's
description and pass it down.
(gdb_collect): Adjust to get the register cache size from the
IPA's description.
* linux-amd64-ipa.c (tdesc_amd64_linux): Declare.
(gdbserver_xmltarget): Delete.
(initialize_low_tracepoint): Set the ipa's target description.
* linux-i386-ipa.c (tdesc_i386_linux): Declare.
(initialize_low_tracepoint): Set the ipa's target description.
* linux-x86-low.c: Include tdesc.h.
[__x86_64__] (is_64bit_tdesc): New.
(ps_get_thread_area, x86_get_thread_area): Use it.
(i386_cannot_store_register): Rename to ...
(x86_cannot_store_register): ... this. Use is_64bit_tdesc.
(i386_cannot_fetch_register): Rename to ...
(x86_cannot_fetch_register): ... this. Use is_64bit_tdesc.
(x86_fill_gregset, x86_store_gregset): Adjust register_size calls
to new interface.
(target_regsets): Rename to ...
(x86_regsets): ... this.
(x86_get_pc, x86_set_pc): Adjust register_size calls to new
interface.
(x86_siginfo_fixup): Use is_64bit_tdesc.
[__x86_64__] (tdesc_amd64_linux, tdesc_amd64_avx_linux)
(tdesc_x32_avx_linux, tdesc_x32_linux)
(tdesc_i386_linux, tdesc_i386_mmx_linux, tdesc_i386_avx_linux):
Declare.
(x86_linux_update_xmltarget): Delete.
(I386_LINUX_XSAVE_XCR0_OFFSET): Define.
(have_ptrace_getfpxregs, have_ptrace_getregset): New.
(AMD64_LINUX_USER64_CS): New.
(x86_linux_read_description): New, based on
x86_linux_update_xmltarget.
(same_process_callback): New.
(x86_arch_setup_process_callback): New.
(x86_linux_update_xmltarget): New.
(x86_regsets_info): New.
(amd64_linux_regs_info): New.
(i386_linux_usrregs_info): New.
(i386_linux_regs_info): New.
(x86_linux_regs_info): New.
(x86_arch_setup): Reimplement.
(x86_install_fast_tracepoint_jump_pad): Use is_64bit_tdesc.
(x86_emit_ops): Ditto.
(the_low_target): Adjust. Install x86_linux_regs_info,
x86_cannot_fetch_register, and x86_cannot_store_register.
(initialize_low_arch): New.
* linux-ia64-low.c (tdesc_ia64): Declare.
(ia64_fetch_register): Adjust.
(ia64_usrregs_info, regs_info): New globals.
(ia64_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-sparc-low.c (tdesc_sparc64): Declare.
(sparc_fill_gregset_to_stack, sparc_store_gregset_from_stack):
Adjust.
(sparc_arch_setup): New function.
(sparc_regsets_info, sparc_usrregs_info, regs_info): New globals.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-ppc-low.c (tdesc_powerpc_32l, tdesc_powerpc_altivec32l)
(tdesc_powerpc_cell32l, tdesc_powerpc_vsx32l)
(tdesc_powerpc_isa205_32l, tdesc_powerpc_isa205_altivec32l)
(tdesc_powerpc_isa205_vsx32l, tdesc_powerpc_e500l)
(tdesc_powerpc_64l, tdesc_powerpc_altivec64l)
(tdesc_powerpc_cell64l, tdesc_powerpc_vsx64l)
(tdesc_powerpc_isa205_64l, tdesc_powerpc_isa205_altivec64l)
(tdesc_powerpc_isa205_vsx64l): Declare.
(ppc_cannot_store_register, ppc_collect_ptrace_register)
(ppc_supply_ptrace_register, parse_spufs_run, ppc_get_pc)
(ppc_set_pc, ppc_get_hwcap): Adjust.
(ppc_usrregs_info): Forward declare.
(!__powerpc64__) ppc_regmap_adjusted: New global.
(ppc_arch_setup): Adjust to the current process'es target
description.
(ppc_fill_vsxregset, ppc_store_vsxregset, ppc_fill_vrregset)
(ppc_store_vrregset, ppc_fill_evrregset, ppc_store_evrregse)
(ppc_store_evrregset): Adjust.
(target_regsets): Rename to ...
(ppc_regsets): ... this, and make static.
(ppc_usrregs_info, ppc_regsets_info, regs_info): New globals.
(ppc_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-s390-low.c (tdesc_s390_linux32, tdesc_s390_linux32v1)
(tdesc_s390_linux32v2, tdesc_s390_linux64, tdesc_s390_linux64v1)
(tdesc_s390_linux64v2, tdesc_s390x_linux64, tdesc_s390x_linux64v1)
(tdesc_s390x_linux64v2): Declare.
(s390_collect_ptrace_register, s390_supply_ptrace_register)
(s390_fill_gregset, s390_store_last_break): Adjust.
(target_regsets): Rename to ...
(s390_regsets): ... this, and make static.
(s390_get_pc, s390_set_pc): Adjust.
(s390_get_hwcap): New target_desc parameter, and use it.
[__s390x__] (have_hwcap_s390_high_gprs): New global.
(s390_arch_setup): Adjust to set the current process'es target
description. Don't adjust the regmap.
(s390_usrregs_info, s390_regsets_info, regs_info): New globals.
[__s390x__] (s390_usrregs_info_3264, s390_regsets_info_3264)
(regs_info_3264): New globals.
(s390_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-mips-low.c (tdesc_mips_linux, tdesc_mips_dsp_linux)
(tdesc_mips64_linux, tdesc_mips64_dsp_linux): Declare.
[__mips64] (init_registers_mips_linux)
(init_registers_mips_dsp_linux): Delete defines.
[__mips64] (tdesc_mips_linux, tdesc_mips_dsp_linux): New defines.
(have_dsp): New global.
(mips_read_description): New, based on mips_arch_setup.
(mips_arch_setup): Reimplement.
(get_usrregs_info): New function.
(mips_cannot_fetch_register, mips_cannot_store_register)
(mips_get_pc, mips_set_pc, mips_fill_gregset, mips_store_gregset)
(mips_fill_fpregset, mips_store_fpregset): Adjust.
(target_regsets): Rename to ...
(mips_regsets): ... this, and make static.
(mips_regsets_info, mips_dsp_usrregs_info, mips_usrregs_info)
(dsp_regs_info, regs_info): New globals.
(mips_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-arm-low.c (tdesc_arm, tdesc_arm_with_iwmmxt)
(tdesc_arm_with_vfpv2, tdesc_arm_with_vfpv3, tdesc_arm_with_neon):
Declare.
(arm_fill_vfpregset, arm_store_vfpregset): Adjust.
(arm_read_description): New, with bits factored from
arm_arch_setup.
(arm_arch_setup): Reimplement.
(target_regsets): Rename to ...
(arm_regsets): ... this, and make static.
(arm_regsets_info, arm_usrregs_info, regs_info): New globals.
(arm_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-m68k-low.c (tdesc_m68k): Declare.
(target_regsets): Rename to ...
(m68k_regsets): ... this, and make static.
(m68k_regsets_info, m68k_usrregs_info, regs_info): New globals.
(m68k_regs_info): New function.
(m68k_arch_setup): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-sh-low.c (tdesc_sharch): Declare.
(target_regsets): Rename to ...
(sh_regsets): ... this, and make static.
(sh_regsets_info, sh_usrregs_info, regs_info): New globals.
(sh_regs_info, sh_arch_setup): New functions.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-bfin-low.c (tdesc_bfin): Declare.
(bfin_arch_setup): New function.
(bfin_usrregs_info, regs_info): New globals.
(bfin_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-cris-low.c (tdesc_cris): Declare.
(cris_arch_setup): New function.
(cris_usrregs_info, regs_info): New globals.
(cris_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-cris-low.c (tdesc_crisv32): Declare.
(cris_arch_setup): New function.
(cris_regsets_info, cris_usrregs_info, regs_info): New globals.
(cris_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-m32r-low.c (tdesc_m32r): Declare.
(m32r_arch_setup): New function.
(m32r_usrregs_info, regs_info): New globals.
(m32r_regs_info): Adjust.
(initialize_low_arch): New function.
* linux-tic6x-low.c (tdesc_tic6x_c64xp_linux)
(tdesc_tic6x_c64x_linux, tdesc_tic6x_c62x_linux): Declare.
(tic6x_usrregs_info): Forward declare.
(tic6x_read_description): New function, based on ...
(tic6x_arch_setup): ... this. Reimplement.
(target_regsets): Rename to ...
(tic6x_regsets): ... this, and make static.
(tic6x_regsets_info, tic6x_usrregs_info, regs_info): New globals.
(tic6x_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-xtensa-low.c (tdesc_xtensa): Declare.
(xtensa_fill_gregset, xtensa_store_gregset): Adjust.
(target_regsets): Rename to ...
(xtensa_regsets): ... this, and make static.
(xtensa_regsets_info, xtensa_usrregs_info, regs_info): New
globals.
(xtensa_arch_setup, xtensa_regs_info): New functions.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-nios2-low.c (tdesc_nios2_linux): Declare.
(nios2_arch_setup): Set the current process'es tdesc.
(target_regsets): Rename to ...
(nios2_regsets): ... this.
(nios2_regsets_info, nios2_usrregs_info, regs_info): New globals.
(nios2_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-aarch64-low.c (tdesc_aarch64): Declare.
(aarch64_arch_setup): Set the current process'es tdesc.
(target_regsets): Rename to ...
(aarch64_regsets): ... this.
(aarch64_regsets_info, aarch64_usrregs_info, regs_info): New globals.
(aarch64_regs_info): New function.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* linux-tile-low.c (tdesc_tilegx, tdesc_tilegx32): Declare
globals.
(target_regsets): Rename to ...
(tile_regsets): ... this.
(tile_regsets_info, tile_usrregs_info, regs_info): New globals.
(tile_regs_info): New function.
(tile_arch_setup): Set the current process'es tdesc.
(the_low_target): Adjust.
(initialize_low_arch): New function.
* spu-low.c (tdesc_spu): Declare.
(spu_create_inferior, spu_attach): Set the new process'es tdesc.
* win32-arm-low.c (tdesc_arm): Declare.
(arm_arch_setup): New function.
(the_low_target): Install arm_arch_setup instead of
init_registers_arm.
* win32-i386-low.c (tdesc_i386, tdesc_amd64): Declare.
(init_windows_x86): Rename to ...
(i386_arch_setup): ... this. Set `win32_tdesc'.
(the_low_target): Adjust.
* win32-low.c (win32_tdesc): New global.
(child_add_thread): Don't create the thread cache here.
(do_initial_child_stuff): Set the new process'es tdesc.
* win32-low.h (struct target_desc): Forward declare.
(win32_tdesc): Declare.
* lynx-i386-low.c (tdesc_i386): Declare global.
(lynx_i386_arch_setup): Set `lynx_tdesc'.
* lynx-low.c (lynx_tdesc): New global.
(lynx_add_process): Set the new process'es tdesc.
* lynx-low.h (struct target_desc): Forward declare.
(lynx_tdesc): Declare global.
* lynx-ppc-low.c (tdesc_powerpc_32): Declare global.
(lynx_ppc_arch_setup): Set `lynx_tdesc'.
* nto-low.c (nto_tdesc): New global.
(do_attach): Set the new process'es tdesc.
* nto-low.h (struct target_desc): Forward declare.
(nto_tdesc): Declare.
* nto-x86-low.c (tdesc_i386): Declare.
(nto_x86_arch_setup): Set `nto_tdesc'.
gdb/
2013-06-07 Pedro Alves <palves@redhat.com>
* regformats/regdat.sh: Output #include tdesc.h. Make globals
static. Output a global target description pointer.
(init_registers_${name}): Adjust to initialize a
target description structure.
This patch adds support for range stepping to GDBserver, teaching it
about vCont;r.
It'd be easy to enable this for all hardware single-step targets
without needing the linux_target_ops hook, however, at least PPC needs
special care, due to the fact that PPC atomic sequences can't be
hardware single-stepped through, a thing which GDBserver doesn't know
about. So this leaves the support limited to x86/x86_64.
gdb/
2013-05-23 Pedro Alves <palves@redhat.com>
* NEWS: Mention GDBserver range stepping support.
gdb/gdbserver/
2013-05-23 Yao Qi <yao@codesourcery.com>
Pedro Alves <palves@redhat.com>
* linux-low.c (lwp_in_step_range): New function.
(linux_wait_1): If the thread was range stepping and stopped
outside the stepping range, report the stop to GDB. Otherwise,
continue stepping. Add range stepping debug output.
(linux_set_resume_request): Copy the step range from the resume
request to the lwp.
(linux_supports_range_stepping): New.
(linux_target_ops) <supports_range_stepping>: Set to
linux_supports_range_stepping.
* linux-low.h (struct linux_target_ops)
<supports_range_stepping>: New field.
(struct lwp_info) <step_range_start, step_range_end>: New fields.
* linux-x86-low.c (x86_supports_range_stepping): New.
(the_low_target) <supports_range_stepping>: Set to
x86_supports_range_stepping.
* server.c (handle_v_cont): Handle 'r' action.
(handle_v_requests): Append ";r" if the target supports range
stepping.
* target.h (struct thread_resume) <step_range_start,
step_range_end>: New fields.
(struct target_ops) <supports_range_stepping>:
New field.
(target_supports_range_stepping): New macro.
PT_DATA_ADDR and PT_TEXT_END_ADDR. Update comments.
(linux_read_offsets): Remove PT_TEXT_ADDR, PT_DATA_ADDR and
PT_TEXT_END_ADDR guards. Update comments.
(linux_target_op) <read_offsets>: Conditionally define to
linux_read_offsets if the target is UCLIBC and if it defines
PT_TEXT_ADDR, PT_DATA_ADDR and PT_TEXT_END_ADDR.
Oleg Nesterov told me that the Linux kernel copies the parent's ptrace
options to fork/clone children, so there's no need for GDB to do that
manually.
I was actually a bit surprised, since I thought the ptracer had to
always set the ptrace options itself, and GDB is indeed calling
PTRACE_SETOPTIONS for each new fork child, if it'll stay attached.
Looking at the history of that code, I found that is was actually I
who added that set-ptrace-options-in-children bit, back in
http://sourceware.org/ml/gdb-patches/2009-05/msg00656.html. But,
honestly, I don't recall why I needed that. I think I may have just
blindly believed it was necessary.
I then looked back at the history of all the PTRACE_SETOPTIONS code we
have, and found that gdb never did copy the ptrace options before my
patch. But, when gdbserver learnt to use PTRACE_EVENT_CLONE, at
http://sourceware.org/ml/gdb-patches/2007-10/msg00547.html, it was
made to do 'ptrace (PTRACE_SETOPTIONS, new_pid, 0,
PTRACE_O_TRACECLONE)' for all new clones. Hmmm. But, GDB itself
never did that, so it can't really ever have been necessary, I
believe, otherwise GDB should have been doing it too.
(GDBserver doesn't support following forks, and so naturally doesn't
do any PTRACE_SETOPTIONS on fork children.)
So this patch removes the -I believe- unnecessary ptrace syscalls.
Tested on x86_64 Fedora 17, native/gdbserver, and on x86_64 RHEL5
native/gdbserver (Linux 2.6.18, I think a ptrace-on-utrace kernel).
No regressions.
gdb/
2013-03-22 Pedro Alves <palves@redhat.com>
* linux-nat.c (linux_child_follow_fork): Don't call
linux_enable_event_reporting.
(linux_handle_extended_wait): Don't call
linux_enable_event_reporting.
gdb/gdbserver/
2013-03-22 Pedro Alves <palves@redhat.com>
* linux-low.c (handle_extended_wait): Don't call
linux_enable_event_reporting.
This fixes the followin error when HAVE_LINUX_BTRACE is not defined:
linux-low.c:5943: error: excess elements in struct initializer
linux-low.c:5943: error: (near initialization for 'linux_target_ops')
gdb/gdbserver/ChangeLog:
* linux-low.c (linux_target_ops) [!HAVE_LINUX_BTRACE]:
Remove extraneous NULL element.
We define the following packets:
Qbtrace:bts enable branch tracing for the current thread
returns "OK" or "Enn"
Qbtrace:off disable branch tracing for the current thread
returns "OK" or "Enn"
qXfer:btrace:read read the full branch trace data for the current thread
gdb/
* target.h (enum target_object): Add TARGET_OBJECT_BTRACE.
* remote.c: Include btrace.h.
(struct btrace_target_info): New struct.
(remote_supports_btrace): New function.
(send_Qbtrace): New function.
(remote_enable_btrace): New function.
(remote_disable_btrace): New function.
(remote_teardown_btrace): New function.
(remote_read_btrace): New function.
(init_remote_ops): Add btrace ops.
(enum <unnamed>): Add btrace packets.
(struct protocol_feature remote_protocol_features[]): Add btrace packets.
(_initialize_remote): Add packet configuration for branch tracing.
gdbserver/
* target.h (struct target_ops): Add btrace ops.
(target_supports_btrace): New macro.
(target_enable_btrace): New macro.
(target_disable_btrace): New macro.
(target_read_btrace): New macro.
* gdbthread.h (struct thread_info): Add btrace field.
* server.c: Include btrace-common.h.
(handle_btrace_general_set): New function.
(handle_btrace_enable): New function.
(handle_btrace_disable): New function.
(handle_general_set): Call handle_btrace_general_set.
(handle_qxfer_btrace): New function.
(struct qxfer qxfer_packets[]): Add btrace entry.
* inferiors.c (remove_thread): Disable btrace.
* linux-low: Include linux-btrace.h.
(linux_low_enable_btrace): New function.
(linux_low_read_btrace): New function.
(linux_target_ops): Add btrace ops.
* configure.srv (i[34567]86-*-linux*): Add linux-btrace.o.
Add srv_linux_btrace=yes.
(x86_64-*-linux*): Add linux-btrace.o.
Add srv_linux_btrace=yes.
* configure.ac: Define HAVE_LINUX_BTRACE.
* config.in: Regenerated.
* configure: Regenerated.
PROBLEM:
The function linux_write_memory () in linux-low.c allocates a buffer
on the stack to hold a copy of the data to be written.
register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *)
alloca (count * sizeof (PTRACE_XFER_TYPE));
"count" is the number of bytes to be written, rounded up to the
nearest multiple of sizeof (PTRACE_XFER_TYPE) and allowing for not
being an aligned address. The function later uses
buffer[0] = ptrace (PTRACE_PEEKTEXT, pid,
(PTRACE_ARG3_TYPE) (uintptr_t) addr, 0);
The problem is that this function can be called to write zero bytes on
an aligned address, for example when receiving an X packet of length 0
(used to test if 8-bit write is supported). Under these circumstances,
count can be zero.
Since in this case, buffer[0] may never have been allocated, the stack
is corrupted and gdbserver may crash.
SOLUTION:
Writing zero bytes should always succeed. The patch below returns
successfully early if the length is zero, so avoiding the stack
corruption.
Verified on the ARC GDB 7.5.1 port.
2013-03-07 Jeremy Bennett <jeremy.bennett@embecosm.com>
PR server/15236
* linux-low.c (linux_write_memory): Return early success if LEN is
zero.
Two modifications:
1. The addition of 2013 to the copyright year range for every file;
2. The use of a single year range, instead of potentially multiple
year ranges, as approved by the FSF.
ARI fixes: move gdb_wait and gdb_stat headers to common subdirectory.
* gdb_stat.h: Delete. Moved to common directory.
* common/gdb_stat.h: New file.
* gdb_wait.h: Delete. Moved to common directory.
* common/gdb_wait.h: New file.
* Makefile.in (H_FILES_NO_SRC): Adapt to new header
location.
* contrib/ari/gdb_ari.sh (wait.h rule): Adapt to new gdb_wait.h
location.
(stat.h rule): Adapt to new gdb_stat.h location.
* common/linux-osdata.c: Include "gdb_stat.h" header instead of
<sys/stat.h> header.
* common/linux-ptrace.c: Include "gdb_wait.h" header instead of
<sys/wait.h> header.
gdbserver ChangeLog entry:
2012-11-15 Pierre Muller <muller@sourceware.org>
* configure.ac (AC_CHECK_HEADERS): Add wait.h header.
* config.in: Regenerate.
* configure: Regenerate.
* linux-low.c: Use "gdb_stat.h" header instead of <sys/stat.h> header.
Use "gdb_wait.h" header instead of <sys/wait.h> header.
* lynx-low.c: Use "gdb_wait.h" header instead of <sys/wait.h> header.
* remote-utils.c: Use "gdb_stat.h" header instead of <sys/stat.h>
header.
* server.c: Remove HAVE_WAIT_H conditional. Use "gdb_wait.h" header
instead of <sys/wait.h> header.
* spu-low.c: Use "gdb_wait.h" header instead of <sys/wait.h> header.
* solib-svr4.c (svr4_current_sos): New comment on
svr4_current_sos_via_xfer_libraries fall back.
gdb/gdbserver/
* linux-low.c (linux_qxfer_libraries_svr4): Return -1 if R_DEBUG is -1.
gdb/testsuite/
* gdb.server/solib-list-lib.c: New file.
* gdb.server/solib-list-main.c: New file.
* gdb.server/solib-list.exp: New file.
* linux-low (__UCLIBC__ && !(__UCLIBC_HAS_MMU__ || __ARCH_HAS_MMU__)):
Include asm/ptrace.h.
(PT_TEXT_ADDR, PT_DATA_ADDR, PT_TEXT_END_ADDR): Define only if not
already defined.
Pedro Alves <palves@redhat.com>
* linux-low.c (enum stopping_threads_kind): New.
(stopping_threads): Change type to `enum stopping_threads_kind'.
(handle_extended_wait): If stopping and suspending threads, leave
the new_lwp suspended too.
(linux_wait_for_event): Adjust.
(stop_all_lwps): Set `stopping_threads' to
STOPPING_AND_SUSPENDING_THREADS or STOPPING_THREADS depending on
whether we're suspending threads or just stopping them. Assert no
recursion happens.