Say GDB wants to access the inferior process's memory. The current
remote general thread is 3, but GDB's switched to thread 2. Because
both threads are of the same process, GDB skips making the remote
thread be thread 2 as well (sending an Hg packet) before accessing
memory (remote.c:set_general_process). However, if thread 3 has
exited meanwhile, thread 3 no longer exists on the server and
gdbserver points current_thread to NULL. The result is the memory
access fails, even through the process still exists.
Fix this by making prepare_to_access memory select the thread to
access memory through.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* mem-break.c (check_gdb_bp_preconditions): Remove current_thread
check.
(set_gdb_breakpoint): If prepare_to_access_memory fails, set *ERR
to -1.
* target.c (struct thread_search): New structure.
(thread_search_callback): New function.
(prev_general_thread): New global.
(prepare_to_access_memory, done_accessing_memory): New functions.
* target.h (prepare_to_access_memory, done_accessing_memory):
Replace macros with function declarations.
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.
Running the testsuite against gdbserver with "maint set target-non-stop on"
stumbled on a set of problems. See code comments for details.
This handles my concerns expressed in PR14618.
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
PR 14618
* infrun.c (handle_no_resumed): New function.
(handle_inferior_event_1) <TARGET_WAITKIND_NO_RESUMED>: Defer to
handle_no_resumed.
The range-stepping tests fail with "maint set target-non-stop on" mode
because exec_cmd_expect_vCont_count doesn't know that in non-stop
mode, vCont's reply is simply "OK".
gdb/testsuite/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* lib/range-stepping-support.exp (exec_cmd_expect_vCont_count):
Handle non-stop mode vCont replies.
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.
Testing with the extended-remote board with "maint set target-non-stop
on" shows a dprintf-non-stop.exp regression. The issue is simply that
the test is expecting output that is only valid for the native target:
native:
[process 8676] #1 stopped.
remote:
[Thread 8900.8900] #1 stopped.
In order to expose this without "maint set target-non-stop on", this
restarts gdb with non-stop mode already enabled.
gdb/testsuite/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.base/dprintf-non-stop.exp: Use build_executable instead of
prepare_for_testing. Start gdb with "set non-stop on" appended to
GDBFLAGS. Lax expected stop output.
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.
There's currently no non-stop equivalent of the all-stop ^C (\003)
"packet" that GDB sends when a ctrl-c is pressed while a foreground
command is active. There's vCont;t, but that's defined to cause a
"signal 0" stop.
This fixes many tests that type ^C, when testing with extended-remote
with "maint set target-non-stop on". E.g.:
Continuing.
talk to me baby
PASS: gdb.base/interrupt.exp: process is alive
a
a
PASS: gdb.base/interrupt.exp: child process ate our char
^C
[Thread 22730.22730] #1 stopped.
0x0000003615ee6650 in __read_nocancel () at ../sysdeps/unix/syscall-template.S:81
81 T_PSEUDO (SYSCALL_SYMBOL, SYSCALL_NAME, SYSCALL_NARGS)
(gdb) FAIL: gdb.base/interrupt.exp: send_gdb control C
p func1 ()
gdb/
2015-11-30 Pedro Alves <palves@redhat.com>
* NEWS (New remote packets): Mention vCtrlC.
* remote.c (PACKET_vCtrlC): New enum value.
(async_remote_interrupt): Call target_interrupt instead of
target_stop.
(remote_interrupt_as): Remove 'ptid' parameter.
(remote_interrupt_ns): New function.
(remote_stop): Adjust.
(remote_interrupt): If the target is in non-stop mode, try
interrupting with vCtrlC.
(initialize_remote): Install set remote ctrl-c packet.
gdb/doc/
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Bootstrapping): Add "interrupting remote targets"
anchor.
(Packets): Document vCtrlC.
gdb/gdbserver/
2015-11-30 Pedro Alves <palves@redhat.com>
* server.c (handle_v_requests): Handle vCtrlC.
Running local-watch-wrong-thread.exp with "maint set target-non-stop
on" exposes that gdb/remote.c only records whether the target stopped
for a breakpoint/watchpoint plus the watchpoint data address *for the
last reported remote event*. But in non-stop mode, we need to keep
that info per-thread, as each thread can end up with its own
last-status pending.
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* remote.c (struct remote_state) <remote_watch_data_address,
stop_reason>: Delete fields.
(struct private_thread_info) <stop_reason, watch_data_address>:
New fields.
(resume_clear_thread_private_info): New function.
(append_pending_thread_resumptions): Call it.
(remote_resume): Clear all threads' private info.
(process_stop_reply): Adjust.
(remote_wait_as): Don't reference remote_state's stop_reason
field.
(remote_stopped_by_sw_breakpoint)
(remote_stopped_by_hw_breakpoint, remote_stopped_by_watchpoint)
(remote_stopped_data_address): Adjust to refer get data from the
current thread.
This fixes a gdbserver crash when running
gdb.threads/non-ldr-exc-1.exp with "maint set target-non-stop on".
The problem is that qSymbol is called when gdbserver has
current_thread == NULL.
gdb/gdbserver/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdbthread.h (find_any_thread_of_pid): Declare.
* inferiors.c (thread_of_pid, find_any_thread_of_pid): New
functions.
* server.c (handle_query): If current_thread is NULL, look for
another thread of the selected process.
When running with "maint set target-non-stop on", and in all-stop
mode, nothing is stopping all threads after attaching. vAttach in
non-stop can leave all threads running and GDB has to explicitly pause
them.
This is not visible with the native target, as in that case, attach
always stops all threads (the core re-resumes them in case of
"attach&").
In addition, it's not defined which thread manages to report the
initial attach stop, so always pick the lowest one (otherwise
multi-attach.exp regresses).
gdb/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* infcmd.c (attach_post_wait): If the target is always in non-stop
mode, and the UI is in all-stop mode, stop all threads and pick
the one with lowest number as current.
This is the first pass at implementing support for all-stop mode
running against the remote target using the non-stop variant of the
protocol.
The trickiest part here is the initial connection setup/synching. We
need to fetch all inferiors' target descriptions etc. before stopping
threads, because stop_all_threads needs to read the threads' registers
(to record each thread's stop_pc). But OTOH, the initial inferior
setup (target_post_attach, post_create_inferior, etc.), only works
correctly if the inferior is stopped... So I've split that initial
setup part from attach_command_post_wait to a separate function, and
added a "still needs setup" flag to the inferior structure. This is
similar to gdbserver/linux-low.c's handling of discovering the
process's target description). Then if on connection all threads of
the remote inferior are running, when we go about stopping them, as
soon as they stop we call setup_inferior, from within
stop_all_threads.
Also, in all-stop, we need to process all the initial stop replies to
learn about all the pending signal the threads may already be stopped
for, and pick the one to report as current. This is exposed by
gdb.threads/reconnect-signal.exp.
gdb/
2015-11-30 Pedro Alves <palves@redhat.com>
* gdbthread.h (switch_to_thread_no_regs): Declare.
* infcmd.c (setup_inferior): New function, factored out from ...
(attach_command_post_wait): ... this. Rename to ...
(attach_post_wait): ... this. Replace parameter async_exec with
attach_post_wait_mode parameter. Adjust.
(enum attach_post_wait_mode): New enum.
(struct attach_command_continuation_args): Replace 'async_exec'
field with 'mode' field.
(attach_command_continuation): Adjust.
(attach_command): Add comment. Mark the inferior as needing
setup. Adjust to use enum attach_post_wait_mode.
(notice_new_inferior): Use switch_to_thread_no_regs. Adjust to
use enum attach_post_wait_mode.
* inferior.h (setup_inferior): Declare.
(struct inferior) <needs_setup>: New field.
* infrun.c (set_last_target_status): Make extern.
(stop_all_threads): Make extern. Setup inferior, if necessary.
* infrun.h (set_last_target_status, stop_all_threads): Declare.
* remote-notif.c (remote_async_get_pending_events_handler)
(handle_notification): Replace non_stop checks with
target_is_non_stop_p() checks.
* remote.c (remote_notice_new_inferior): Remove non_stop check.
(remote_update_thread_list): Replace non_stop check with
target_is_non_stop_p() check.
(print_one_stopped_thread): New function.
(process_initial_stop_replies): New 'from_tty' parameter.
"Notice" all new live inferiors after storing initial stops as
pending status in each corresponding thread. If all-stop, stop
all threads, try picking a signalled thread as current, and print
the status of that one thread. Record the last target status.
(remote_start_remote): Replace non_stop checks with
target_is_non_stop_p() checks. Don't query for the remote current
thread of use qOffsets here. Pass from_tty to
process_initial_stop_replies.
(extended_remote_attach): Replace non_stop checks with
target_is_non_stop_p() checks.
(extended_remote_post_attach): Send qOffsets here.
(remote_vcont_resume, remote_resume, remote_stop)
(remote_interrupt, remote_parse_stop_reply, remote_wait): Replace
non_stop checks with target_is_non_stop_p() checks.
(remote_async): If target is non-stop, mark/clear the pending
events token.
* thread.c (switch_to_thread_no_regs): New function.
Testing with "maint set target-non-stop on" makes mi-nonstop.exp run
with the extended-remote board. That reveals that mi-nonstop.exp is
using the wrong predicate to check for "using remote protocol".
This is not visible today because non-stop tests all fail to run with
extended-remote board, because they spawn gdb and then do "set
non-stop on". However, with that board, gdb connects to the gdbserver
from within mi_gdb_start, and changing non-stop when already connected
doesn't work. Fix that by instead enabling non-stop mode on gdb's
command line.
gdb/testsuite/ChangeLog:
2015-11-30 Pedro Alves <palves@redhat.com>
* gdb.mi/mi-nonstop.exp: Append "set non-stop on" to GDBFLAGS
instead of issuing "-gdb-set non-stop 1" after starting gdb.
Use mi_is_target_remote instead of checking "is_remote target".
* lib/gdb.exp (gdb_is_target_remote): Rename to ...
(gdb_is_target_remote_prompt): ... this, and add 'prompt_regexp'
parameter.
(gdb_is_target_remote): Reimplement.
* lib/mi-support.exp (mi_is_target_remote): New procedure.
Before commit 3a8724032abf, DEMANGLE_COMPONENT_CAST was used for both
casts and conversion operators. We now have
DEMANGLE_COMPONENT_CONVERSION for the latter.
gdb/ChangeLog:
2014-11-28 Pedro Alves <palves@redhat.com>
* cp-name-parser.y (conversion_op): Use
DEMANGLE_COMPONENT_CONVERSION instead of DEMANGLE_COMPONENT_CAST.
This patch fixes the GDB internal error on AArch64 when running
watchpoint-fork.exp
top?bt 15
internal_error (file=file@entry=0x79d558 "../../binutils-gdb/gdb/linux-nat.c", line=line@entry=4866, fmt=0x793b20 "%s: Assertion `%s' failed.")
at ../../binutils-gdb/gdb/common/errors.c:51
#1 0x0000000000495bc4 in linux_nat_thread_address_space (t=<optimized out>, ptid=<error reading variable: Cannot access memory at address 0x1302>)
at ../../binutils-gdb/gdb/linux-nat.c:4866
#2 0x00000000005db2c8 in delegate_thread_address_space (self=<optimized out>, arg1=<error reading variable: Cannot access memory at address 0x1302>)
at ../../binutils-gdb/gdb/target-delegates.c:2447
#3 0x00000000005e8c7c in target_thread_address_space (ptid=<error reading variable: Cannot access memory at address 0x1302>)
at ../../binutils-gdb/gdb/target.c:2727
#4 0x000000000054eef8 in get_thread_arch_regcache (ptid=..., gdbarch=0xad51e0) at ../../binutils-gdb/gdb/regcache.c:529
#5 0x000000000054efcc in get_thread_regcache (ptid=...) at ../../binutils-gdb/gdb/regcache.c:546
#6 0x000000000054f120 in get_thread_regcache_for_ptid (ptid=...) at ../../binutils-gdb/gdb/regcache.c:560
#7 0x00000000004a2278 in aarch64_point_is_aligned (is_watchpoint=0, addr=34168, len=2) at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:122
#8 0x00000000004a2e68 in aarch64_handle_breakpoint (type=hw_execute, addr=34168, len=2, is_insert=0, state=0xae8880)
at ../../binutils-gdb/gdb/nat/aarch64-linux-hw-point.c:465
#9 0x000000000048edf0 in aarch64_linux_remove_hw_breakpoint (self=<optimized out>, gdbarch=<optimized out>, bp_tgt=<optimized out>)
at ../../binutils-gdb/gdb/aarch64-linux-nat.c:657
#10 0x00000000005da8dc in delegate_remove_hw_breakpoint (self=<optimized out>, arg1=<optimized out>, arg2=<optimized out>)
at ../../binutils-gdb/gdb/target-delegates.c:492
#11 0x0000000000536a24 in bkpt_remove_location (bl=<optimized out>) at ../../binutils-gdb/gdb/breakpoint.c:13065
#12 0x000000000053351c in remove_breakpoint_1 (bl=0xb3fe70, is=is@entry=mark_inserted) at ../../binutils-gdb/gdb/breakpoint.c:4026
#13 0x000000000053ccc0 in detach_breakpoints (ptid=...) at ../../binutils-gdb/gdb/breakpoint.c:3930
#14 0x00000000005a3ac0 in handle_inferior_event_1 (ecs=0x7ffffff048) at ../../binutils-gdb/gdb/infrun.c:5042
After the fork, GDB will physically remove the breakpoints from the child
process (in frame #14), but at that time, GDB doesn't create an inferior
yet for child, but inferior_ptid is set to child's ptid (in frame #13).
In aarch64_point_is_aligned, we'll get the regcache of current_lwp_ptid
to determine if the current process is 32-bit or 64-bit, so the inferior
can't be found, and the internal error is caused.
I don't find a better fix other than not checking alignment on removing
breakpoint.
gdb:
2015-11-27 Yao Qi <yao.qi@linaro.org>
* nat/aarch64-linux-hw-point.c (aarch64_dr_state_remove_one_point):
Don't assert on alignment.
(aarch64_handle_breakpoint): Only check alignment when IS_INSERT
is true.
Both ARM and AArch64 have defined some SIMD data types in arm_neon.h,
but we don't have a test case for passing them and returning them in
inferior call. This test also covers passing and returning
homogeneous short vector aggregate (defined by AArch64 ABI document)
in inferior call too.
gdb/testsuite:
* gdb.arch/arm-neon.exp: New.
* gdb.arch/arm-neon.c: New.
AArch64 AAPCS defined HFA (homogeneous floating-point aggregate)
and HVF (homogeneous short vector aggregate), bug GDB only handles the
former. In the AAPCS doc, both types are treated exactly the same
in terms of alignment and passing locations (on registers or stack).
This patch is to extend is_hfa to handle both HFA and HVA.
gdb:
2015-11-27 Yao Qi <yao.qi@linaro.org>
* aarch64-tdep.c (is_hfa): Rename to ...
(is_hfa_or_hva): ... this. Handle vector type. All callers
updated.
(aarch64_extract_return_value): Update debugging message.
(aarch64_store_return_value): Likewise.
(aarch64_return_in_memory): Update comments.
As defined in AArch64 AAPCS, short vectors are passed through V
registers, and its maximum alignment is 16-byte. This patch is
to reflect these rules in GDB. This patch fixes some fails in
gdb.base/gnu_vector.exp.
gdb:
2015-11-27 Yao Qi <yao.qi@linaro.org>
* aarch64-tdep.c (aarch64_type_align): For vector type, return
its length, but with the maximum of 16 bytes.
(is_hfa): Return zero for vector type.
(aarch64_push_dummy_call): Handle short vectors.
(aarch64_extract_return_value): Likewise.
(aarch64_store_return_value): Likewise.
Hi,
I see one fail on aarch64-linux testing,
FAIL: gdb.cp/annota2.exp: watch triggered on a.x (timeout)
because GDB prints two frames-invalid annotation but the test expects
only one.
next^M
^M
^Z^Zpost-prompt^M
^M
^Z^Zstarting^M
^M
^Z^Zframes-invalid^M
^M
^Z^Zframes-invalid^M
^M
Note I also see the fail on Debian-s390x-m64 too.
https://sourceware.org/ml/gdb-testers/2015-q4/msg07291.html
The test shouldn't only expect one frames-invalid annotation, because
there can be multiple times of stop/resume before the user visible
stop. Ulrich did something similar before
https://www.sourceware.org/ml/gdb-patches/2009-06/msg00118.html
This patch only changes ${frames_invalid} to \(${frames_invalid}\)*
in the regexp pattern.
The patch below fixes the fail on aarch64-linux.
gdb/testsuite:
2015-11-27 Yao Qi <yao.qi@linaro.org>
* gdb.cp/annota2.exp: Allow multiple occurrences of the
frames-invalid annotation.
Variable frames_invalid was defined, but wasn't used much. This patch
is to replace the literals in the regexp with ${frames_invalid}.
gdb/testsuite:
2015-11-27 Yao Qi <yao.qi@linaro.org>
* gdb.cp/annota2.exp: Use ${frames_invalid}.
I couldn't find a test that verified the thread name functionality, so I
created a new one.
A target board can define gdb,no_thread_names if it doesn't support thread
names and wants to skip the tests that uses them.
This test has been made with Linux in mind. Not all platforms use
pthread_setname_np to set the thread name, but some #ifdefs can be added
later in order to support other platforms.
Tested on x86-64 Ubuntu 14.04, native and remote.
gdb/testsuite/ChangeLog:
* gdb.threads/names.exp: New file.
* gdb.threads/names.c: New file.
* README: Mention gdb,no_thread_names.
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.
Since this code path returns a string owned by the target (we don't know how
it's allocated, could be a static read-only string), it's safer if we return
a constant string. If, for some reasons, the caller wishes to modify the
string, it should make itself a copy.
gdb/ChangeLog:
* linux-nat.c (linux_nat_thread_name): Constify return value.
* target.h (struct target_ops) <to_thread_name>: Likewise.
(target_thread_name): Likewise.
* target.c (target_thread_name): Likewise.
* target-delegates.c (debug_thread_name): Regenerate.
* python/py-infthread.c (thpy_get_name): Constify local variables.
* thread.c (print_thread_info): Likewise.
(thread_find_command): Likewise.
If GDB has been configured without libipt support, i.e. HAVE_LIBIPT is
undefined, and is running on a system that supports Intel(R) Processor Trace,
GDB will run into an internal error when trying to decode the trace.
(gdb) record btrace
(gdb) s
usage (name=0x7fffffffe954 "fib-64")
at src/fib.c:12
12 fprintf(stderr, "usage: %s <num>\n", name);
(gdb) info record
Active record target: record-btrace
Recording format: Intel(R) Processor Trace.
Buffer size: 16kB.
gdb/btrace.c:971: internal-error: Unexpected branch trace format.
A problem internal to GDB has been detected,
further debugging may prove unreliable.
Quit this debugging session? (y or n)
This requires a system with Linux kernel 4.1 or later running on a 5th
Generation Intel Core processor or later.
The issue is documented as PR 19297.
When trying to enable branch tracing, in addition to checking the target
support for the requested branch tracing format, also check whether GDB
supports. it.
gdb/
* btrace.c (btrace_enable): Check whether HAVE_LIBIPT is defined.
testsuite/
* lib/gdb.exp (skip_btrace_pt_tests): Check for a "GDB does not
support" error.
gdb/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
* NEWS: Mention that a few "info" commands now list the
corresponding items in ascending ID order.
Before:
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
3: y 1
2: y 1
1: y 1
After:
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1: y 1
2: y 1
3: y 1
gdb/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* printcmd.c (display_command): Append new display at the end of
the list.
gdb/testsuite/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* gdb.base/display.exp: Expect displays to be sorted in ascending
order. Use multi_line.
* gdb.base/solib-display.exp: Likewise.
Before:
(gdb) info checkpoints
3 process 29132 at 0x4008ad, file foo.c, line 81
2 process 29131 at 0x4008ad, file foo.c, line 81
1 process 29130 at 0x4008ad, file foo.c, line 81
* 0 Thread 0x7ffff7fc5740 (LWP 29128) (main process) at 0x4008ad, file foo.c, line 81
After:
(gdb) info checkpoints
* 0 Thread 0x7ffff7fc5740 (LWP 29128) (main process) at 0x4008ad, file foo.c, line 81
1 process 29130 at 0x4008ad, file foo.c, line 81
2 process 29131 at 0x4008ad, file foo.c, line 81
3 process 29132 at 0x4008ad, file foo.c, line 81
gdb/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* printcmd.c (display_command): Append new display at the end of
the list.
gdb/testsuite/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* gdb.base/display.exp: Expect displays to be sorted in ascending
order. Use multi_line.
* gdb.base/solib-display.exp: Likewise.
Before:
(gdb) info threads
Id Target Id Frame
3 Thread 0x7ffff77c3700 (LWP 29035) callme () at foo.c:30
2 Thread 0x7ffff7fc4700 (LWP 29034) 0x000000000040087b in child_function_2 (arg=0x0) at foo.c:60
* 1 Thread 0x7ffff7fc5740 (LWP 29030) 0x0000003b37209237 in pthread_join (threadid=140737353893632, thread_return=0x0) at pthread_join.c:92
After:
(gdb) info threads
Id Target Id Frame
* 1 Thread 0x7ffff7fc5740 (LWP 29030) 0x0000003b37209237 in pthread_join (threadid=140737353893632, thread_return=0x0) at pthread_join.c:92
2 Thread 0x7ffff7fc4700 (LWP 29034) 0x000000000040087b in child_function_2 (arg=0x0) at foo.c:60
3 Thread 0x7ffff77c3700 (LWP 29035) callme () at foo.c:30
gdb/doc/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* gdb.texinfo (Inferiors and Programs): Adjust "maint info
program-spaces" example to ascending order listing.
(Threads): Adjust "info threads" example to ascending order
listing.
(Forks): Adjust "info inferiors" example to ascending order
listing.
gdb/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* inferior.c (add_inferior_silent): Append the new inferior to the
end of the list.
* progspace.c (add_program_space): Append the new pspace to the
end of the list.
* thread.c (new_thread): Append the new thread to the end of the
list.
gdb/testsuite/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
PR 17539
* gdb.base/foll-exec-mode.exp: Adjust to GDB listing inferiors and
threads in ascending order.
* gdb.base/foll-fork.exp: Likewise.
* gdb.base/foll-vfork.exp: Likewise.
* gdb.base/multi-forks.exp: Likewise.
* gdb.mi/mi-nonstop.exp: Likewise.
* gdb.mi/mi-nsintrall.exp: Likewise.
* gdb.multi/base.exp: Likewise.
* gdb.multi/multi-arch.exp: Likewise.
* gdb.python/py-inferior.exp: Likewise.
* gdb.threads/break-while-running.exp: Likewise.
* gdb.threads/execl.exp: Likewise.
* gdb.threads/gcore-thread.exp: Likewise.
* gdb.threads/info-threads-cur-sal.exp: Likewise.
* gdb.threads/kill.exp: Likewise.
* gdb.threads/linux-dp.exp: Likewise.
* gdb.threads/multiple-step-overs.exp: Likewise.
* gdb.threads/next-bp-other-thread.exp: Likewise.
* gdb.threads/step-bg-decr-pc-switch-thread.exp: Likewise.
* gdb.threads/step-over-lands-on-breakpoint.exp: Likewise.
* gdb.threads/step-over-trips-on-watchpoint.exp: Likewise.
* gdb.threads/thread-find.exp: Likewise.
* gdb.threads/tls.exp: Likewise.
* lib/mi-support.exp (mi_reverse_list): Delete.
(mi_check_thread_states): No longer reverse list.
... like the kernel does.
gcore-thread.exp has a check to make sure the signalled thread is the
current thread after loading the core back, but that just works by
accident, because the signalled thread happened to be the last thread
on the thread list, and gdb currently iterates over threads in reverse
order.
So this fixes gcore-thread.exp once we start walking threads in
ascending number.
gdb/ChangeLog:
2015-11-24 Pedro Alves <palves@redhat.com>
* linux-tdep.c (find_stop_signal): Delete.
(struct linux_corefile_thread_data) <pid>: Remove field.
(linux_corefile_thread_callback): Rename to ...
(linux_corefile_thread): ... this. Now takes a struct
linux_corefile_thread_data pointer rather than a void pointer.
Remove thread state and thread pid checks.
(linux_make_corefile_notes): Prefer dumping the signalled thread
first. Use ALL_NON_EXITED_THREADS instead of
iterate_over_threads.
When trying to save fast tracepoints to file, gdb returns internal failure:
gdb/breakpoint.c:13446: internal-error: unhandled tracepoint type 27
A problem internal to GDB has been detected, further debugging may prove unreliable.
And no file including the fast tracepoints definition is created.
The patch also extends save-trace.exp to test saving tracepoint with a
fast tracepoint in there. Note that because this test doesn't actually
inserts the tracepoints in the program, we can run it with targets that
don't actually support fast tracepoints (or tracepoints at all).
gdb/ChangeLog:
* breakpoint.c (tracepoint_print_recreate): Fix logic error
if -> else if.
gdb/testsuite/ChangeLog:
* gdb.trace/actions.c: Include trace-common.h.
(main): Add a location for a fast tracepoint.
* gdb.trace/save-trace.exp: Set a fast tracepoint in addition to
the normal tracepoints.
(gdb_verify_tracepoints): Adjust number of expected tracepoints.
Some code is duplicated, to run the test twice with absolute and
relative paths, so I factored it out in a few procs. It uses
with_test_prefix to differentiate between test runs.
I replaced usages of "save-tracepoints" with "save tracepoint", since
the former is deprecated.
I also removed the "10.x", as it doesn't make much sense anymore. It
isn't used in general in the testsuite, and I don't think it's really
useful.
gdb/testsuite/ChangeLog:
* save-trace.exp: Factor out code to these...
(gdb_save_tracepoints): New.
(gdb_load_tracepoints): New.
(do_save_load_test): New.
The comment for the code in question says:
/* If the minimal symbol has a zero size, save it
but keep scanning backwards looking for one with
a non-zero size. A zero size may mean that the
symbol isn't an object or function (e.g. a
label), or it may just mean that the size was not
specified. */
As written, the code in question will only scan past the first symbol
of zero size. My change fixes the implementation to match the
comment.
Having this correct is important when the compiler generates several
local labels that are left in place by the linker. (I've been told
that the linker should eliminate these symbols, but I know of one
architecture for which this is not happening.)
I've created a test case called asmlabel.c. It's pretty simple:
main (int argc, char **argv)
{
asm ("L0:");
v = 0;
asm ("L1:");
v = 1; /* set L1 breakpoint here */
asm ("L2:");
v = 2; /* set L2 breakpoint here */
return 0;
}
If breakpoints are placed on the lines indicated by the comments,
this is the behavior of GDB built without my patch:
(gdb) continue
Continuing.
Breakpoint 2, L1 () at asmlabel.c:26
26 v = 1; /* set L1 breakpoint here */
Note that L1 appears as the function instead of main. This is not
what we want to happen. With my patch in place, we see the desired
behavior instead:
(gdb) continue
Continuing.
Breakpoint 2, main (argc=1, argv=0x7fffffffdb88) at asmlabel.c:26
26 v = 1; /* set L1 breakpoint here */
gdb/ChangeLog:
* minsyms.c (lookup_minimal_symbol_by_pc_section_1): Scan backwards
over all zero-sized symbols.
gdb/testsuite/ChangeLog:
* gdb.base/asmlabel.exp: New test.
* gdb.base/asmlabel.c: New test case.
One of our users reported an internal error using the "bt full"
command. In their situation, reproducing involved the following
scenario:
(gdb) frame 1
(gdb) bt full
#0 0xf7783430 in __kernel_vsyscall ()
No symbol table info available.
#1 0xf5550aeb in waitpid () at ../sysdeps/unix/syscall-template.S:81
No locals.
[...]
#6 0x0fe83139 in xxxx (arg=...)
[...some locals printed, and then...]
<S17b> =
[...]/dwarf2loc.c:364: internal-error: dwarf_expr_frame_base: Assertion
`framefunc != NULL' failed.
As shown above, the error happens while GDB is trying to print the value
of <S17b>, which is a local string internally generated by the compiler.
For that, it finds that the array lives in memory, and therefore tries
to create a struct value for it via:
case DWARF_VALUE_MEMORY:
{
CORE_ADDR address = dwarf_expr_fetch_address (ctx, 0);
[...]
retval = value_at_lazy (type, address + byte_offset);
Unfortunately for us, TYPE happens to be an array whose bounds
are dynamic. More precisely, the bounds of our arrays are described
in the debugging info as being...
<4><2c1985e>: Abbrev Number: 33 (DW_TAG_subrange_type)
<2c1985f> DW_AT_type : <0x2c1989c>
<2c19863> DW_AT_lower_bound : <0x2c19835>
<2c19867> DW_AT_upper_bound : <0x2c19841>
... which are references to a pair of local variables. For instance,
the lower bound is a reference to the following DIE
<3><2c19835>: Abbrev Number: 32 (DW_TAG_variable)
<2c19836> DW_AT_name : [...]
<2c1983a> DW_AT_type : <0x2c198b4>
<2c1983e> DW_AT_artificial : 1
<2c1983e> DW_AT_location : 2 byte block: 91 58 (DW_OP_fbreg: -40)
As a result of the above, value_at_lazy indirectly triggers
a resolution of TYPE (via value_from_contents_and_address),
which means a resolution of TYPE's bounds, and as seen in
the DW_AT_location attribute above for our bounds, computing
the bound's location requires the frame (its location expression
uses DW_OP_fbreg).
Unfortunately for us, value_at_lazy does not get passed a frame,
we've lost the relevant frame when we try to resolve the array's
bounds. Instead, resolve_dynamic_range gets calls dwarf2_evaluate_property
with NULL as the frame:
static struct type *
resolve_dynamic_range (struct type *dyn_range_type,
struct property_addr_info *addr_stack)
{
[...]
if (dwarf2_evaluate_property (prop, NULL, addr_stack, &value))
^^^^
... which then handles this by using the selected frame instead:
if (frame == NULL && has_stack_frames ())
frame = get_selected_frame (NULL);
In our case, the selected frame happens to be frame #1, which is
a frame where we have a minimal amount of debugging info, and in
particular, no debug info for the function itself. And because of that,
when we try to determine the frame's base...
static void
dwarf_expr_frame_base (void *baton, const gdb_byte **start,
size_t * length)
{
struct dwarf_expr_baton *debaton = (struct dwarf_expr_baton *) baton;
const struct block *bl = get_frame_block (debaton->frame, NULL);
[...]
framefunc = block_linkage_function (bl);
... framefunc ends up being NULL, which triggers the assert
in that same function:
gdb_assert (framefunc != NULL);
This patches avoids the issue by temporarily setting the selected_frame
before printing the locals of each frames.
This patch also adds a small testcase, which reproduces the same
issue, but with a slightly different outcome:
(gdb) bt full
#0 0x000000000040049a in opaque_routine ()
No symbol table info available.
#1 0x0000000000400532 in main () at wrong_frame_bt_full-main.c:20
my_table_size = 3
my_table = <error reading variable my_table (frame address is not available.)>
With this patch, the output becomes:
(gdb) bt full
[...]
my_table = {0, 1, 2}
gdb/ChangeLog:
* stack.c (print_frame_local_vars): Temporarily set the selected
frame to FRAME while printing the frame's local variables.
gdb/testsuite/ChangeLog:
* gdb.base/wrong_frame_bt_full-main.c: New file.
* gdb.base/wrong_frame_bt_full-opaque.c: New file.
* gdb.base/wrong_frame_bt_full.exp: New file.
This crash is observable by debugging a threaded program on LynxOS.
On the GDB side, this is what we would see:
% gdb q
(gdb) target remote machine:4444
(gdb) break q.adb:6
(gdb) cont
[gdb hits breakpoint]
(gdb) cont
Remote connection closed <<<--- expected: [Inferior 1 (Remote target) exited normally]
On the gdbserver side, which was launched as usual:
% gdbserver --once :4444 q
Segmentation fault (core dumped)
Ooops!
The problem happens while GDB is trying to handle the thread termination
event of the thread that hit the breakpoint. It started happening after
the following change was made:
commit 96e7a1eb6d
Date: Fri Oct 16 11:08:38 2015 -0400
Subject: gdbserver: Reset current_thread when the thread is removed.
Reset current_thread and make sure 'remove_process' is used
after all associated threads have been removed first.
More precisely:
. GDBserver receives the execution-resume order;
. lynx-low resumes it succesfully, and then relies on lynx_wait_1
to wait for the next event;
. We quickly receive one, which lynx_wait_1 analyzes to be
a "thread exit" event, and therefore does...
case SIGTHREADEXIT:
remove_thread (find_thread_ptid (new_ptid));
lynx_continue (new_ptid);
goto retry;
=> remove_thread causes current_thread to be set to NULL...
(that's the recent change mentioned above)
=> ... which causes problems during lynx_continue, because
it calls lynx_resume, which calls regcache_invalidate,
which unfortunately assumes that CURRENT_THREAD is not NULL:
void
regcache_invalidate (void)
{
/* Only update the threads of the current process. */
SEGV!--> int pid = ptid_get_pid (current_thread->entry.id);
find_inferior (&all_threads, regcache_invalidate_one, &pid);
}
Since the problem at hand is caused by trying to figure out which
inferior to reset the regcache for, and since lynx_resume actually
had that info, this patch fixes the problem by introducing a new
routine called regcache_invalidate_pid, which invalidates the cache
of the given pid; and then modifies lynx_resume use that new routine
rather than relying on regcache_invalidate to invalidate the regcache
of the expected inferior.
gdb/gdbserver/ChangeLog:
* regcache.h (regcache_invalidate_pid): Add declaration.
* regcache.c (regcache_invalidate_pid): New function, extracted
from regcache_invalidate.
(regcache_invalidate): Reimplement using regcache_invalidate_pid.
Add trivial documentation comment.
* lynx-low.c: Use regcache_invalidate_pid instead of
regcache_invalidate.
We noticed the following hang trying to run a program where one
of the subroutines we built without debugging info (opaque_routine):
$ gdb my_program
(gdb) break opaque_routine
(gdb) run
[...hangs...]
The problem comes from the fact that, at the breakpoint's address,
we have the following code:
=> 0x0000000000401994 <+4>: pop %rbp
At some point after hitting the breakpoint and stopping, GDB calls
amd64_windows_frame_decode_epilogue, which then gets stuck in the
following infinite loop:
| /* We don't care about the instruction deallocating the frame:
| if it hasn't been executed, the pc is still in the body,
| if it has been executed, the following epilog decoding will work. */
|
| /* First decode:
| - pop reg [41 58-5f] or [58-5f]. */
|
| while (1)
| {
| /* Read opcode. */
| if (target_read_memory (pc, &op, 1) != 0)
| return -1;
|
| if (op >= 0x40 && op <= 0x4f)
| {
| /* REX prefix. */
| rex = op;
|
| /* Read opcode. */
| if (target_read_memory (pc + 1, &op, 1) != 0)
| return -1;
| }
| else
| rex = 0;
|
| if (op >= 0x58 && op <= 0x5f)
| {
| /* pop reg */
| gdb_byte reg = (op & 0x0f) | ((rex & 1) << 3);
|
| cache->prev_reg_addr[amd64_windows_w2gdb_regnum[reg]] = cur_sp;
| cur_sp += 8;
| }
| else
| break;
|
| /* Allow the user to break this loop. This shouldn't happen as the
| number of consecutive pop should be small. */
| QUIT;
| }
Nothing in that loop updates PC, and therefore, because the instruction
we stopped at is a "pop", we keep looping forever doing the same thing
over and over!
This patch fixes the issue by advancing PC to the beginning of
the next instruction if the current one is a "pop reg" instruction.
gdb/ChangeLog:
* amd64-windows-tdep.c (amd64_windows_frame_decode_epilogue):
Increment PC in while loop skipping "pop reg" instructions.
The following issue has been observed on arm-android, trying to step
over the following line of code:
Put_Line (">>> " & Integer'Image (Message (I)));
Below is a copy of the GDB transcript:
(gdb) cont
Breakpoint 1, q.dump (message=...) at q.adb:11
11 Put_Line (">>> " & Integer'Image (Message (I)));
(gdb) next
0x00016000 in system.concat_2.str_concat_2 ()
The expected behavior for the "next" command is to step over
the call to Put_Line and stop at line 12:
(gdb) next
12 I := I + 1;
What happens during the next step is that the code for line 11
above make a call to system.concat_2.str_concat_2 (to implement
the '&' string concatenation operator) before making the call
to Put_Line. While stepping, GDB stops eventually stops at the
first instruction of that function, and fails to detect that
it's a function call from where we were before, and so decides
to stop stepping.
And the reason why it fails to detect that we landed inside a function
call is because it fails to unwind from that function:
(gdb) bt
#0 0x00016000 in system.concat_2.str_concat_2 ()
#1 0x0001bc74 in ?? ()
Debugging GDB, I found that GDB decides to use the ARM unwind info
for that function, which contains the following data:
0x16000 <system__concat_2__str_concat_2>: 0x80acb0b0
Compact model index: 0
0xac pop {r4, r5, r6, r7, r8, r14}
0xb0 finish
0xb0 finish
But, in fact, using that data is wrong, in this case, because
it mentions a pop of 6 registers, and therefore hints at a frame
size of 24 bytes. The problem is that, because we're at the first
instruction of the function, the 6 registers haven't been pushed
to the stack yet. In other words, using the ARM unwind entry above,
GDB is tricked into thinking that the frame size is 24 bytes, and
that the return address (r14) is available on the stack.
One visible manifestation of this issue can been seen by looking
at the value of the stack pointer, and the frame's base address:
(gdb) p /x $sp
$2 = 0xbee427b0
(gdb) info frame
Stack level 0, frame at 0xbee427c8:
^^^^^^^^^^
||||||||||
The frame's base address should be equal to the value of the stack
pointer at entry. And you eventually get the correct frame address,
as well as the correct backtrace if you just single-step one additional
instruction, past the push:
(gdb) x /i $pc
=> 0x16000 <system__concat_2__str_concat_2>:
push {r4, r5, r6, r7, r8, lr}
(gdb) stepi
(gdb) bt
#0 0x00016004 in system.concat_2.str_concat_2 ()
#1 0x00012b6c in q.dump (message=...) at q.adb:11
#2 0x00012c3c in q () at q.adb:19
Digging further, I found that GDB tries to use the ARM unwind info
only when sure that it is relevant, as explained in the following
comment:
/* The ARM exception table does not describe unwind information
for arbitrary PC values, but is guaranteed to be correct only
at call sites. We have to decide here whether we want to use
ARM exception table information for this frame, or fall back [...]
There is one case where it decides that the info is relevant,
described in the following comment:
/* We also assume exception information is valid if we're currently
blocked in a system call. The system library is supposed to
ensure this, so that e.g. pthread cancellation works.
For that, it just parses the instruction at the address it believes
to be the point of call, and matches it against an "svc" instruction.
For instance, for a non-thumb instruction, it is at...
get_frame_pc (this_frame) - 4
... and the code checking looks like the following.
if (safe_read_memory_integer (get_frame_pc (this_frame) - 4, 4,
byte_order_for_code, &insn)
&& (insn & 0x0f000000) == 0x0f000000 /* svc */)
exc_valid = 1;
However, the reason why this doesn't work in our case is that
because we are at the first instruction of a function in the innermost
frame. That frame can't possibly be making a call, and therefore
be stuck on a system call.
What the code above ends up doing is checking the instruction
just before the start of our function, which in our case is not
even an actual instruction, but unlucky for us, happens to match
the pattern it is looking for, thus leading GDB to improperly
trust the ARM unwinding data.
gdb/ChangeLog:
* arm-tdep.c (arm_exidx_unwind_sniffer): Do not check for a frame
stuck on a system call if the given frame is the innermost frame.
See the comment added in configure.ac for more details behind
this change.
gdb/gdbserver/ChangeLog:
* configure.ac: Do not call AC_CHECK_TYPES for Elf32_auxv_t
and Elf64_auxv_t if the target is Android.
Using the gdb.ada/var_rec_arr.exp test, where the program declares
an array of variant records...
type Record_Type (I : Small_Type := 0) is record
S : String (1 .. I);
end record;
type Array_Type is array (Integer range <>) of Record_Type;
... and then a variable A1 of type Array_Type, the following command
ocassionally trigger an internal error trying to allocate more memory
than we have left:
(gdb) ptype a1(1)
[...]/utils.c:1089: internal-error: virtual memory exhausted.
A problem internal to GDB has been detected,
[...]
What happens is that recent versions of GNAT are able to generate
DWARF expressions for type Record_Type, and therefore the record's
DW_AT_byte_size is not a constant, which unfortunately breaks
an assumption made by dwarf2read.c:read_structure_type when it does:
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
TYPE_LENGTH (type) = DW_UNSND (attr);
}
As a result of this, when ada_evaluate_subexp tries to create
a value_zero for a1(1) while processing the OP_FUNCALL operator
as part of evaluating the subscripting operation in no-side-effect
mode, we try to allocate a value with a bogus size, potentially
triggering the out-of-memory internal error.
This patch avoids this issue by setting the length to zero in
this case. Until we decide to start supporting dynamic type
lengths in GDB's type struct, and it's not clear yet that
this is worth the effort (see added comment), that's probably
the best we can do.
gdb/ChangeLog:
* dwarf2read.c (read_structure_type): Set the type's length
to zero if it has a DW_AT_byte_size attribute which is not
a constant.
gdb/testsuite/ChangeLog:
* testsuite/gdb.ada/var_rec_arr.exp: Add "ptype a1(1)" test.