We have noticed that GDB would sometimes crash trying to print
from a nested function the value of a variable declared in an
enclosing scope. This appears to be target dependent, although
that correlation might only be fortuitious. We noticed the issue
on x86_64-darwin, x86-vxworks6 and x86-solaris. The investigation
was done on Darwin.
This is a new feature that was introduced by:
commit 63e43d3aed
Date: Thu Feb 5 17:00:06 2015 +0100
DWARF: handle non-local references in nested functions
We can reproduce the problem with one of the testcases that was
added with the patch (gdb.base/nested-subp1.exp), where we have...
18 int
19 foo (int i1)
20 {
21 int
22 nested (int i2)
23 {
[...]
27 return i1 * i2; /* STOP */
28 }
... After building the example program, and running until line 27,
try printing the value of "i1":
% gdb gdb.base/nested-subp1
(gdb) break foo.c:27
(gdb) run
Breakpoint 1, nested (i2=2) at /[...]/nested-subp1.c:27
27 return i1 * i2; /* STOP */
(gdb) p i1
[1] 73090 segmentation fault ../gdb -q gdb.base/nested-subp1
Ooops!
What happens is that, because the reference is non-local, we are trying
to follow the function's static link, which does...
/* If we don't know how to compute FRAME's base address, don't give up:
maybe the frame we are looking for is upper in the stace frame. */
if (framefunc != NULL
&& SYMBOL_BLOCK_OPS (framefunc)->get_frame_base != NULL
&& (SYMBOL_BLOCK_OPS (framefunc)->get_frame_base (framefunc, frame)
== upper_frame_base))
... or, in other words, calls the get_frame_base "method" of
framefunc's struct symbol_block_ops data. This resolves to
the block_op_get_frame_base function.
Looking at the function's implementation, we see:
struct dwarf2_locexpr_baton *dlbaton;
[...]
dlbaton = SYMBOL_LOCATION_BATON (framefunc);
[...]
result = dwarf2_evaluate_loc_desc (type, frame, start, length,
dlbaton->per_cu);
^^^^^^^^^^^^^^^
Printing dlbaton->per_cu gives a value that seems fairly bogus for
a memory address (0x60). Because of it, dwarf2_evaluate_loc_desc
then crashes trying to dereference it.
What's different on Darwin compared to Linux is that the function's
frame base is encoded using the following form:
.byte 0x40 # uleb128 0x40; (DW_AT_frame_base)
.byte 0x6 # uleb128 0x6; (DW_FORM_data4)
... and so dwarf2_symbol_mark_computed ends up creating
a SYMBOL_LOCATION_BATON as a struct dwarf2_loclist_baton:
if (attr_form_is_section_offset (attr)
/* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
&& DW_UNSND (attr) < dwarf2_section_size (objfile, section))
{
struct dwarf2_loclist_baton *baton;
[...]
SYMBOL_LOCATION_BATON (sym) = baton;
However, if you look more closely at block_op_get_frame_base's
implementation, you'll notice that the function extracts the
symbol's SYMBOL_LOCATION_BATON as a dwarf2_locexpr_baton
(a DWARF _expression_ rather than a _location list_).
That's why we end up decoding the DLBATON improperly, and thus
pass a random dlbaton->per_cu when calling dwarf2_evaluate_loc_desc.
This works on x86_64-linux, because we indeed have the frame base
described using a different form:
.uleb128 0x40 # (DW_AT_frame_base)
.uleb128 0x18 # (DW_FORM_exprloc)
This patch fixes the issue by doing what we do for most (if not all)
other such methods: providing one implementation each for loc-list,
and loc-expr. Both implementations are nearly identical, so perhaps
we might later want to improve this. But this patch first tries to
fix the crash first, leaving the design issue for later.
gdb/ChangeLog:
* dwarf2loc.c (locexpr_get_frame_base): Renames
block_op_get_frame_base.
(dwarf2_block_frame_base_locexpr_funcs): Replace reference to
block_op_get_frame_base by reference to locexpr_get_frame_base.
(loclist_get_frame_base): New function, near identical copy of
locexpr_get_frame_base.
(dwarf2_block_frame_base_loclist_funcs): Replace reference to
block_op_get_frame_base by reference to loclist_get_frame_base.
Tested on x86_64-darwin (AdaCore testsuite), and x86_64-linux
(official testsuite).
bfd/ChangeLog:
* targets.c (enum bfd_flavour): Add comment.
(bfd_flavour_name): New function.
* bfd-in2.h: Regenerate.
gdb/ChangeLog:
* findvar.c (default_read_var_value) <LOC_UNRESOLVED>: Include the
kind of minimal symbol in the error message.
* objfiles.c (objfile_flavour_name): New function.
* objfiles.h (objfile_flavour_name): Declare.
gdb/testsuite/ChangeLog:
* gdb.dwarf2/dw2-bad-unresolved.c: New file.
* gdb.dwarf2/dw2-bad-unresolved.exp: New file.
2015-09-18 Sandra Loosemore <sandra@codesourcery.com>
gdb/testsuite/
* gdb.mi/mi-pending.exp: Don't use directory prefix when setting
the pending breakpoint. Remove timeout override for "Run till
MI pending breakpoint on pendfunc3 on thread 2" test.
With the kernle fix <http://lists.infradead.org/pipermail/linux-arm-kernel/2015-July/356511.html>,
aarch64 GDB is able to read the base of thread area of 32-bit arm
program through NT_ARM_TLS.
This patch is to teach both GDB and GDBserver to read the base of
thread area correctly in the multi-arch case. A new function
aarch64_ps_get_thread_area is added, and is shared between GDB and
GDBserver.
With this patch applied, the following fails in multi-arch testing
(GDB is aarch64 but the test cases are arm) are fixed,
-FAIL: gdb.threads/tls-nodebug.exp: thread local storage
-FAIL: gdb.threads/tls-shared.exp: print thread local storage variable
-FAIL: gdb.threads/tls-so_extern.exp: print thread local storage variable
-FAIL: gdb.threads/tls-var.exp: print tls_var
-FAIL: gdb.threads/tls.exp: first thread local storage
-FAIL: gdb.threads/tls.exp: first another thread local storage
-FAIL: gdb.threads/tls.exp: p a_thread_local
-FAIL: gdb.threads/tls.exp: p file2_thread_local
-FAIL: gdb.threads/tls.exp: p a_thread_local second time
gdb:
2015-09-18 Yao Qi <yao.qi@linaro.org>
* nat/aarch64-linux.c: Include elf/common.h,
nat/gdb_ptrace.h, asm/ptrace.h and sys/uio.h.
(aarch64_ps_get_thread_area): New function.
* nat/aarch64-linux.h: Include gdb_proc_service.h.
(aarch64_ps_get_thread_area): Declare.
* aarch64-linux-nat.c (ps_get_thread_area): Call
aarch64_ps_get_thread_area.
gdb/gdbserver:
2015-09-18 Yao Qi <yao.qi@linaro.org>
* linux-aarch64-low.c: Don't include sys/uio.h.
(ps_get_thread_area): Call aarch64_ps_get_thread_area.
In all-stop mode, record btrace maintains the old behaviour of an implicit
scheduler-locking on.
Now that we added a scheduler-locking mode to model this old behaviour, we
don't need the respective code in record btrace anymore. Remove it.
For all-stop targets, step inferior_ptid and continue other threads matching
the argument ptid. Assert that inferior_ptid matches the argument ptid.
This should make record btrace honour scheduler-locking.
gdb/
* record-btrace.c (record_btrace_resume): Honour scheduler-locking.
testsuite/
* gdb.btrace/multi-thread-step.exp: Test scheduler-locking on, step,
and replay.
Record targets behave as if scheduler-locking were on in replay mode. Add a
new scheduler-locking option "replay" to make this implicit behaviour explicit.
It behaves like "on" in replay mode and like "off" in record mode.
By making the current behaviour a scheduler-locking option, we allow the user
to change it. Since it is the current behaviour, this new option is also
the new default.
One caveat is that when resuming a thread that is at the end of its execution
history, record btrace implicitly stops replaying other threads and resumes
the entire process. This is a convenience feature to not require the user
to explicitly move all other threads to the end of their execution histories
before being able to resume the process.
We mimick this behaviour with scheduler-locking replay and move it from
record-btrace into infrun. With all-stop on top of non-stop, we can't do
this in record-btrace anymore.
Record full does not really support multi-threading and is therefore not
impacted. If it were extended to support multi-threading, it would 'benefit'
from this change. The good thing is that all record targets will behave the
same with respect to scheduler-locking.
I put the code for this into clear_proceed_status. It also sends the
about_to_proceed notification.
gdb/
* NEWS: Announce new scheduler-locking mode.
* infrun.c (schedlock_replay): New.
(scheduler_enums): Add schedlock_replay.
(scheduler_mode): Change default to schedlock_replay.
(user_visible_resume_ptid): Handle schedlock_replay.
(clear_proceed_status_thread): Stop replaying if resumed thread is
not replaying.
(schedlock_applies): Handle schedlock_replay.
(_initialize_infrun): Document new scheduler-locking mode.
* record-btrace.c (record_btrace_resume): Remove code to stop other
threads when not replaying the resumed thread.
doc/
* gdb.texinfo (All-Stop Mode): Describe new scheduler-locking mode.
Add a new target method to_record_will_replay to query if there is a record
target that will replay at least one thread matching the argument PTID if it
were executed in the argument execution direction.
gdb/
* record-btrace.c ((record_btrace_will_replay): New.
(init_record_btrace_ops): Initialize to_record_will_replay.
* record-full.c ((record_full_will_replay): New.
(init_record_full_ops): Initialize to_record_will_replay.
* target-delegates.c: Regenerated.
* target.c (target_record_will_replay): New.
* target.h (struct target_ops) <to_record_will_replay>: New.
(target_record_will_replay): New.
Signed-off-by: Markus Metzger <markus.t.metzger@intel.com>
The record btrace target does not allow accessing memory and storing registers
while replaying. For multi-threaded applications, this prevents those
accesses also for threads that are at the end of their execution history as
long as at least one thread is replaying.
Change this to only check if the selected thread is replaying. This allows
threads that are at the end of their execution history to read and write
memory and to store registers.
Also change the error message to reflect this change.
gdb/
* record-btrace.c (record_btrace_xfer_partial)
(record_btrace_store_registers, record_btrace_prepare_to_store):
Call record_btrace_is_replaying with inferior_ptid instead of
minus_one_ptid.
(record_btrace_store_registers): Change error message.
The to_record_is_replaying target method is used to query record targets if
they are replaying. This is currently interpreted as "is any thread being
replayed".
Add a PTID argument and change the interpretation to "is any thread matching
PTID being replayed".
Change all users to pass minus_one_ptid to preserve the old meaning.
The record full target does not really support multi-threading and ignores
the PTID argument.
gdb/
* record-btrace.c (record_btrace_is_replaying): Add ptid argument.
Update users to pass minus_one_ptid.
* record-full.c (record_full_is_replaying): Add ptid argument (ignored).
* record.c (cmd_record_delete): Pass inferior_ptid to
target_record_is_replaying.
* target-delegates.c: Regenerated.
* target.c (target_record_is_replaying): Add ptid argument.
* target.h (struct target_ops) <to_record_is_replaying>: Add ptid
argument.
(target_record_is_replaying): Add ptid argument.
A thread that runs out of its execution history is stopped. We already set
stop_pc and call stop_waiting. But we do not switch to the stopped thread.
In normal_stop, we call finish_thread_state_cleanup to set a thread's running
state. In all-stop mode, we call it with minus_one_ptid; in non-stop mode, we
only call it for inferior_ptid.
If in non-stop mode normal_stop is called on behalf of a thread that is not
inferior_ptid, that other thread will still be reported as running. If it is
actually stopped it can't be resumed again.
Record targets traditionally don't support non-stop and only resume
inferior_ptid. So this has not been a problem, so far.
Switch to the eventing thread for NO_HISTORY events as preparation to support
non-stop for the record btrace target.
gdb/
* infrun.c (handle_inferior_event_1): Switch to the eventing thread
in the TARKET_WAITKIND_NO_HISTORY case.
The record btrace target runs synchronous with GDB. That is, GDB steps
resumed threads in record btrace's to_wait method. Without GDB calling
to_wait, nothing happens 'on the target'.
Check for further expected events in to_wait before reporting the current
event and mark record btrace's async event handler in async mode.
gdb/
* record-btrace.c (record_btrace_maybe_mark_async_event): New.
(record_btrace_wait): Call record_btrace_maybe_mark_async_event.
Get_current_frame uses inferior_ptid. In record_btrace_start_replaying,
we need to get the current frame of the argument thread. So far, this
has always been inferior_ptid. With non-stop, this is not guaranteed.
Temporarily set inferior_ptid to the ptid of the argument thread.
We already temporarily set the argument thread's executing flag to false.
Move both into a new function get_thread_current_frame that does the temporary
adjustments, calls get_current_frame, and restores the previous values.
gdb/
* record-btrace.c (get_thread_current_frame): New.
(record_btrace_start_replaying): Call get_thread_current_frame.
The record targets are implicitly schedlocked. They only step the current
thread and keep other threads where they are.
Change record btrace to step all requested threads in to_resume.
For maintenance and debugging, we keep the old behaviour when the target below
is not non-stop. Enable with "maint set target-non-stop on".
gdb/
* record-btrace.c (record_btrace_resume_thread): A move request
overwrites a previous move request.
(record_btrace_find_resume_thread): Removed.
(record_btrace_resume): Resume all requested threads.
Record btrace's to_wait method picks a single thread to step. When passed
minus_one_ptid, it picks the current thread. All other threads remain where
they are.
Change this to step all resumed threads together, one step at a time, until
the first thread reports an event.
We do delay reporting NO_HISTORY events until there are no other events to
report to prevent threads at the end of their execution history from starving
other threads.
We keep threads at the end of their execution history moving and replaying
until we announce their stop in to_wait. This shouldn't really be user-visible
but its a detail worth mentioning.
Since record btrace's to_resume method also picks only a single thread to
resume, there shouldn't be a difference with the current all-stop.
With non-stop or all-stop on top of non-stop, we will see differences. The
behaviour should be more natural as we're moving all threads.
gdb/
* record-btrace.c: Include vec.h.
(record_btrace_find_thread_to_move): Removed.
(btrace_step_no_resumed, btrace_step_again)
(record_btrace_stop_replaying_at_end): New.
(record_btrace_cancel_resume): Call record_btrace_stop_replaying_at_end.
(record_btrace_single_step_forward): Remove calls to
record_btrace_stop_replaying.
(record_btrace_step_thread): Do only one step for BTHR_CONT and
BTHR_RCONT. Keep threads at the end of their history moving.
(record_btrace_wait): Call record_btrace_step_thread for all threads
until one reports an event. Call record_btrace_stop_replaying_at_end
for the eventing thread.
If a single-step ended right at the end of the execution history, we forgot
to announce that. Fix it.
gdb/
* record-btrace.c (record_btrace_single_step_forward): Return
NO_HISTORY if a step brings us to the end of the execution history.
Breakpoints are only checked for BTHR_CONT and BTHR_RCONT stepping requests.
A BTHR_STEP and BTHR_RSTEP request will always report stopped without reason.
Since breakpoints are reported correctly, I assume infrun is handling this.
Move the breakpoint check into the btrace single stepping functions. This
will cause us to report breakpoint hits now also for single-step requests.
One thing to notice is that
- when executing forwards, the breakpoint is checked before 'executing'
the instruction, i.e. before moving the PC to the next instruction.
- when executing backwards, the breakpoint is checked after 'executing'
the instruction, i.e. after moving the PC to the preceding instruction
in the recorded execution.
There is code in infrun (see, for example proceed and adjust_pc_after_break)
that handles this and also depends on this behaviour.
gdb/
* record-btrace.c (record_btrace_step_thread): Move breakpoint check
to ...
(record_btrace_single_step_forward): ... here and
(record_btrace_single_step_backward): ... here.
The code for BTHR_STEP and BTHR_CONT is fairly similar. Extract the common
parts into a new function record_btrace_single_step_forward. The function
returns TARGET_WAITKIND_SPURIOUS to indicate that the single-step completed
without triggering a trap.
Same for BTHR_RSTEP and BTHR_RCONT.
gdb/
* record-btrace.c (btrace_step_spurious)
(record_btrace_single_step_forward)
(record_btrace_single_step_backward): New.
(record_btrace_step_thread): Call record_btrace_single_step_forward
and record_btrace_single_step_backward.
There are two places where record_btrace_step_thread checks for a breakpoint
at the current replay position. Move this code into its own function.
gdb/
* record-btrace.c (record_btrace_replay_at_breakpoint): New.
(record_btrace_step_thread): Call record_btrace_replay_at_breakpoint.
Add support for the to_stop target method to the btrace record target.
gdb/
* btrace.h (enum btrace_thread_flag) <BTHR_STOP>: New.
* record-btrace (record_btrace_resume_thread): Clear BTHR_STOP.
(record_btrace_find_thread_to_move): Also accept threads that have
BTHR_STOP set.
(btrace_step_stopped_on_request, record_btrace_stop): New.
(record_btrace_step_thread): Support BTHR_STOP.
(record_btrace_wait): Also clear BTHR_STOP when stopping other threads.
(init_record_btrace_ops): Initialize to_stop.
The record btrace target stops other threads in non-stop mode after stepping
the to-be-resumed thread.
The check is done on the non_stop variable. It should rather be done on
target_is_non_stop_p (). With all-stop on top of non-stop, infrun will
take care of stopping other threads.
gdb/
* record-btrace.c (record_btrace_wait): Replace non_stop check with
target_is_non_stop_p ().
Sometimes it may be of benefit to force use of the __tls_get_addr_opt
call stub even when the glibc being used during linking does not
advertise __tls_get_addr_opt.
bfd/
* elf64-ppc.h (struct ppc64_elf_params <tls_get_addr_opt>): Rename
from no_tls_get_addr_opt.
* elf64-ppc.c: Update for rename and inversion of tls_get_addr_opt.
(ppc64_elf_tls_setup): Set tls_get_addr_opt to 0 only when at
default of -1.
ld/
* emultempl/ppc64elf.em (params): Init tls_get_addr_opt field to -1.
(OPTION_TLS_GET_ADDR_OPT): Define.
(PARSE_AND_LIST_LONGOPTS): Handle --tls-get-addr-opt.
(PARSE_AND_LIST_OPTIONS, PARSE_AND_LIST_ARGS_CASES): Likewise.
* ld.texinfo: Document --tls-get-addr-optimize and
--no-tls-get-addr-optimize.
Giving linker script symbols defined outside of output sections a
section-relative value early, leads to them being used in expressions
as if they were defined inside an output section. This can mean loss
of the section VMA, and wrong results.
ld/
PR ld/18963
* ldexp.h (struct ldexp_control): Add rel_from_abs.
(ldexp_finalize_syms): Declare.
* ldexp.c (new_rel_from_abs): Keep absolute for expressions
outside of output section statements. Set rel_from_abs.
(make_abs, exp_fold_tree, exp_fold_tree_no_dot): Clear rel_from_abs.
(struct definedness_hash_entry): Add final_sec, and comment.
(update_definedness): Set final_sec.
(set_sym_sections, ldexp_finalize_syms): New functions.
* ldlang.c (lang_process): Call ldexp_finalize_syms.
ld/testsuite
PR ld/18963
* ld-scripts/pr18963.d,
* ld-scripts/pr18963.t: New test.
* ld-scripts/expr.exp: Run it.
* ld-elf/provide-hidden-2.ld: Explicitly make "dot" absolute.
* ld-mips-elf/gp-hidden.sd: Don't care about _gp section.
* ld-mips-elf/no-shared-1-n32.d: Don't care about symbol shown at
start of .data section.
* ld-mips-elf/no-shared-1-n64.d: Likewise.
* ld-mips-elf/no-shared-1-o32.d: Likewise.
This patch adds a test case for tracepoints with a condition expression.
Each case will test a condition against the number of frames that should
have been traced. Some of these tests fail on x86_64 and others on
i386, which have been marked as known failures for now, see PR/18955.
gdb/testsuite/ChangeLog:
2015-09-17 Pierre Langlois <pierre.langlois@arm.com>
Yao Qi <yao.qi@linaro.org>
* gdb.trace/trace-condition.c: New file.
* gdb.trace/trace-condition.exp: New file.
This patch fixes the argument passed to compiled_cond. It should be
regs buffer instead of tracepoint_hit_ctx. Test case is added as
well for testing compiled-cond.
gdb/gdbserver/ChangeLog
2015-09-16 Wei-cheng Wang <cole945@gmail.com>
* tracepoint.c (eval_result_type): Change prototype.
(condition_true_at_tracepoint): Fix argument to compiled_cond.
gdb/testsuite/ChangeLog
2015-09-16 Wei-cheng Wang <cole945@gmail.com>
* gdb.trace/ftrace.exp: (test_ftrace_condition) New function
for testing bytecode compilation.
On software single-step targets that don't support displaced stepping,
threads keep hitting each other's single-step breakpoints, and then
GDB needs to pause all threads to step past those. The end result is
that progress in the main thread will be slower and it may take a bit
longer for the signal to be queued. This patch bumps the timeout on
such targets.
gdb/testsuite/ChangeLog:
2015-09-16 Pedro Alves <palves@redhat.com>
Sandra Loosemore <sandra@codesourcery.com>
* gdb.threads/non-stop-fair-events.c (timeout): New global.
(SECONDS): Redefine.
(main): Call pthread_kill and alarm early.
* gdb.threads/non-stop-fair-events.exp: Probe displaced stepping
support.
(test): If the target can't hardware step and doesn't support
displaced stepping, increase the timeout.
If we enable infrun debug running this test, it quickly fails with a
full expect buffer. That can be simply handled with a couple
exp_continues. As it's annoying to hack this every time we need to
debug the test, this patch adds bits to enable debugging support
easily, with a one-line change.
And then, if any iteration of the test fails, we end up with a long
cascade of time outs. Just bail out when we see the first fail.
gdb/testsuite/
2015-09-16 Pedro Alves <palves@redhat.com>
* gdb.threads/non-stop-fair-events.exp (gdb_test_no_anchor)
(enable_debug): New procedures.
(test): Use them. Bail out if waiting for threads fails.
(top level): Bail out if a test fails.
This patch adds gdb.asm/aarch64.inc, so asm-source.exp isn't skipped
on aarch64 any more.
gdb/testsuite:
2015-09-16 Yao Qi <yao.qi@linaro.org>
* gdb.asm/asm-source.exp: Set asm-arch for
aarch64*-*-* target.
* gdb.asm/aarch64.inc: New file.
I chose insertion sort since relocs are mostly sorted, but there is a
common case we can handle better; A run of relocs put out of order
due to not linking input files in order.
PR 18867
* elflink.c (elf_link_adjust_relocs): Modify insertion sort to
insert a run. Return status in case of malloc failure.
Adjust callers.