Before, on systems that did not support PTRACE_EVENT_CLONE, both GDB and
GDBServer coordinated with libthread_db.so to insert breakpoints at magic
locations in libpthread.so, in order to break at thread creation and
thread death.
Support for thread events was removed from GDBServer as patch:
https://sourceware.org/ml/gdb-patches/2015-11/msg00466.html
This patch removes support for thread events in GDB.
No regressions found on Ubuntu 14.04 x86_64.
gdb/ChangeLog:
* breakpoint.c (remove_thread_event_breakpoints): Remove.
* breakpoint.h (remove_thread_event_breakpoints): Remove
declaration.
* linux-nat.c (in_pid_list_p): Remove.
(lin_lwp_attach_lwp): Remove.
* linux-nat.h (lin_lwp_attach_lwp): Remove declaration.
* linux-thread-db.c (thread_db_use_events): Remove.
(struct thread_db_info) <td_create_bp_addr>: Remove.
<td_death_bp_addr>: Likewise.
<td_ta_event_addr_p>: Likewise.
<td_ta_set_event_p>: Likewise.
<td_ta_clear_event_p>: Likewise.
<td_ta_event_getmsg_p>: Likewise.
<td_thr_event_enable_p>: Likewise.
(attach_thread): Likewise.
(detach_thread): Likewise.
(have_threads_callback): Likewise.
(have_threads): Likewise.
(enable_thread_event): Likewise.
(enable_thread_event_reporting): Likewise.
(try_thread_db_load_1): Remove td_ta_event_addr, td_ta_set_event,
td_ta_clear_event, td_ta_event_getmsg, td_thr_event_enable
initializations.
(try_thread_db_load_1): Remove enable_thread_event_reporting call.
(disable_thread_event_reporting): Remove.
(record_thread): Adapt to thread_db_use_event removal.
(detach_thread): Remove.
(thread_db_detach): Adapt to thread_db_use_event removal.
(check_event): Remove.
(thread_db_wait): Adapt to thread events support removal.
(thread_db_mourn_inferior): Likewise.
(find_new_threads_callback): Likewise.
(find_new_threads_once): Likewise.
(thread_db_update_thread_list): Likewise.
Assuming displaced stepping is enabled, and a breakpoint is set in the
memory region of the scratch pad, things break. One of two cases can
happen:
#1 - The breakpoint wasn't inserted yet (all threads were stopped), so
after setting up the displaced stepping scratch pad with the
adjusted copy of the instruction we're trying to single-step, we
insert the breakpoint, which corrupts the scratch pad, and the
inferior executes the wrong instruction. (Example below.)
This is clearly unacceptable.
#2 - The breakpoint was already inserted, so setting up the displaced
stepping scratch pad overwrites the breakpoint. This is OK in
the sense that we already assume that no thread is going to
executes the code in the scratch pad range (after initial
startup) anyway.
This commit addresses both cases by simply punting on displaced
stepping if we have a breakpoint in the scratch pad range.
The #1 case above explains a few regressions exposed by the AS/NS
series on x86:
Running ./gdb.dwarf2/callframecfa.exp ...
FAIL: gdb.dwarf2/callframecfa.exp: set display for call-frame-cfa
FAIL: gdb.dwarf2/callframecfa.exp: step 1 for call-frame-cfa
FAIL: gdb.dwarf2/callframecfa.exp: step 2 for call-frame-cfa
FAIL: gdb.dwarf2/callframecfa.exp: step 3 for call-frame-cfa
FAIL: gdb.dwarf2/callframecfa.exp: step 4 for call-frame-cfa
Running ./gdb.dwarf2/typeddwarf.exp ...
FAIL: gdb.dwarf2/typeddwarf.exp: continue to breakpoint: continue to typeddwarf.c:53
FAIL: gdb.dwarf2/typeddwarf.exp: check value of x at typeddwarf.c:53
FAIL: gdb.dwarf2/typeddwarf.exp: check value of y at typeddwarf.c:53
FAIL: gdb.dwarf2/typeddwarf.exp: check value of z at typeddwarf.c:53
FAIL: gdb.dwarf2/typeddwarf.exp: continue to breakpoint: continue to typeddwarf.c:73
FAIL: gdb.dwarf2/typeddwarf.exp: check value of w at typeddwarf.c:73
FAIL: gdb.dwarf2/typeddwarf.exp: check value of x at typeddwarf.c:73
FAIL: gdb.dwarf2/typeddwarf.exp: check value of y at typeddwarf.c:73
FAIL: gdb.dwarf2/typeddwarf.exp: check value of z at typeddwarf.c:73
Enabling "maint set target-non-stop on" implies displaced stepping
enabled as well, and it's the latter that's to blame here. We can see
the same failures with "maint set target-non-stop off + set displaced
on".
Diffing (good/bad) gdb.log for callframecfa.exp shows:
@@ -99,29 +99,29 @@ Breakpoint 2 at 0x80481b0: file q.c, lin
continue
Continuing.
-Breakpoint 2, func (arg=77) at q.c:2
+Breakpoint 2, func (arg=52301) at q.c:2
2 in q.c
(gdb) PASS: gdb.dwarf2/callframecfa.exp: continue to breakpoint: continue to breakpoint for call-frame-cfa
display arg
-1: arg = 77
-(gdb) PASS: gdb.dwarf2/callframecfa.exp: set display for call-frame-cfa
+1: arg = 52301
+(gdb) FAIL: gdb.dwarf2/callframecfa.exp: set display for call-frame-cfa
The problem is here, when setting up the func call:
Breakpoint 1, main (argc=-13345, argv=0x0) at q.c:7
7 in q.c
(gdb) disassemble
Dump of assembler code for function main:
0x080481bb <+0>: push %ebp
0x080481bc <+1>: mov %esp,%ebp
0x080481be <+3>: sub $0x4,%esp
=> 0x080481c1 <+6>: movl $0x4d,(%esp)
0x080481c8 <+13>: call 0x80481b0 <func>
0x080481cd <+18>: leave
0x080481ce <+19>: ret
End of assembler dump.
(gdb) disassemble /r
Dump of assembler code for function main:
0x080481bb <+0>: 55 push %ebp
0x080481bc <+1>: 89 e5 mov %esp,%ebp
0x080481be <+3>: 83 ec 04 sub $0x4,%esp
=> 0x080481c1 <+6>: c7 04 24 4d 00 00 00 movl $0x4d,(%esp)
0x080481c8 <+13>: e8 e3 ff ff ff call 0x80481b0 <func>
0x080481cd <+18>: c9 leave
0x080481ce <+19>: c3 ret
End of assembler dump.
Note the breakpoint at main is set at 0x080481c1. Right at the
instruction that sets up func's argument. Executing that instruction
should write 0x4d to the address pointed at by $esp. However, if we
stepi, the program manages to write 52301/0xcc4d there instead (0xcc
is int3, the x86 breakpoint instruction), because the breakpoint
address is 4 bytes inside the scratch pad location, which is
0x080481bd:
(gdb) p 0x080481c1 - 0x080481bd
$1 = 4
IOW, instead of executing:
"c7 04 24 4d 00 00 00" [ movl $0x4d,(%esp) ]
the inferior executes:
"c7 04 24 4d cc 00 00" [ movl $0xcc4d,(%esp) ]
gdb/ChangeLog:
2015-10-30 Pedro Alves <palves@redhat.com>
* breakpoint.c (breakpoint_in_range_p)
(breakpoint_location_address_range_overlap): New functions.
* breakpoint.h (breakpoint_in_range_p): New declaration.
* infrun.c (displaced_step_prepare_throw): If there's a breakpoint
in the scratch pad range, don't displaced step.
This adds an object oriented replacement for the "struct continuation"
mechanism, and converts the stepping commands (step, next, stepi,
nexti) and the "finish" commands to use it.
It adds a new thread "class" (struct thread_fsm) that contains the
necessary info and callbacks to manage the state machine of a thread's
execution command.
This allows getting rid of some hacks. E.g., in fetch_inferior_event
and normal_stop we no longer need to know whether a thread is doing a
multi-step (e.g., step N). This effectively makes the
intermediate_continuations unused -- they'll be garbage collected in a
separate patch. (They were never a proper abstraction, IMO. See how
fetch_inferior_event needs to check step_multi before knowing whether
to call INF_EXEC_CONTINUE or INF_EXEC_COMPLETE.)
The target async vs !async uiout hacks in mi_on_normal_stop go away
too.
print_stop_event is no longer called from normal_stop. Instead it is
now called from within each interpreter's normal_stop observer. This
clears the path to make each interpreter print a stop event the way it
sees fit. Currently we have some hacks in common code to
differenciate CLI vs TUI vs MI around this area.
The "finish" command's FSM class stores the return value plus that
value's position in the value history, so that those can be printed to
both MI and CLI's streams. This fixes the CLI "finish" command when
run from MI -- it now also includes the function's return value in the
CLI stream:
(gdb)
~"callee3 (strarg=0x400730 \"A string argument.\") at src/gdb/testsuite/gdb.mi/basics.c:35\n"
~"35\t}\n"
+~"Value returned is $1 = 0\n"
*stopped,reason="function-finished",frame=...,gdb-result-var="$1",return-value="0",thread-id="1",stopped-threads="all",core="0"
-FAIL: gdb.mi/mi-cli.exp: CLI finish: check CLI output
+PASS: gdb.mi/mi-cli.exp: CLI finish: check CLI output
gdb/ChangeLog:
2015-09-09 Pedro Alves <palves@redhat.com>
* Makefile.in (COMMON_OBS): Add thread-fsm.o.
* breakpoint.c (handle_jit_event): Print debug output.
(bpstat_what): Split event callback handling to ...
(bpstat_run_callbacks): ... this new function.
(momentary_bkpt_print_it): No longer handle bp_finish here.
* breakpoint.h (bpstat_run_callbacks): Declare.
* gdbthread.h (struct thread_info) <step_multi>: Delete field.
<thread_fsm>: New field.
(thread_cancel_execution_command): Declare.
* infcmd.c: Include thread-fsm.h.
(struct step_command_fsm): New.
(step_command_fsm_ops): New global.
(new_step_command_fsm, step_command_fsm_prepare): New functions.
(step_1): Adjust to use step_command_fsm_prepare and
prepare_one_step.
(struct step_1_continuation_args): Delete.
(step_1_continuation): Delete.
(step_command_fsm_should_stop): New function.
(step_once): Delete.
(step_command_fsm_clean_up, step_command_fsm_async_reply_reason)
(prepare_one_step): New function, based on step_once.
(until_next_command): Remove step_multi reference.
(struct return_value_info): New.
(print_return_value): Rename to ...
(print_return_value_1): ... this. New struct return_value_info
parameter. Adjust.
(print_return_value): Reimplement as wrapper around
print_return_value_1.
(struct finish_command_fsm): New.
(finish_command_continuation): Delete.
(finish_command_fsm_ops): New global.
(new_finish_command_fsm, finish_command_fsm_should_stop): New
functions.
(finish_command_fsm_clean_up, finish_command_fsm_return_value):
New.
(finish_command_continuation_free_arg): Delete.
(finish_command_fsm_async_reply_reason): New.
(finish_backward, finish_forward): Change symbol parameter to a
finish_command_fsm. Adjust.
(finish_command): Create a finish_command_fsm. Adjust.
* infrun.c: Include "thread-fsm.h".
(clear_proceed_status_thread): Delete the thread's FSM.
(infrun_thread_stop_requested_callback): Cancel the thread's
execution command.
(clean_up_just_stopped_threads_fsms): New function.
(fetch_inferior_event): Handle the event_thread's should_stop
method saying the command isn't done yet.
(process_event_stop_test): Run breakpoint callbacks here.
(print_stop_event): Rename to ...
(print_stop_location): ... this.
(restore_current_uiout_cleanup): New function.
(print_stop_event): Reimplement.
(normal_stop): No longer notify the end_stepping_range observers
here handle "step N" nor "finish" here. No longer call
print_stop_event here.
* infrun.h (struct return_value_info): Forward declare.
(print_return_value): Declare.
(print_stop_event): Change prototype.
* thread-fsm.c: New file.
* thread-fsm.h: New file.
* thread.c: Include "thread-fsm.h".
(thread_cancel_execution_command): New function.
(clear_thread_inferior_resources): Call it.
* cli/cli-interp.c (cli_on_normal_stop): New function.
(cli_interpreter_init): Install cli_on_normal_stop as normal_stop
observer.
* mi/mi-interp.c: Include "thread-fsm.h".
(restore_current_uiout_cleanup): Delete.
(mi_on_normal_stop): If the thread has an FSM associated, and it
finished, ask it for the async-reply-reason to print. Always call
print_stop_event here, regardless of the top-level interpreter.
Check bpstat_what to tell whether an asynchronous breakpoint hit
triggered.
* tui/tui-interp.c (tui_on_normal_stop): New function.
(tui_init): Install tui_on_normal_stop as normal_stop observer.
gdb/testsuite/ChangeLog:
2015-09-09 Pedro Alves <palves@redhat.com>
* gdb.mi/mi-cli.exp: Add CLI finish tests.
This patch converts the code base to use the new struct event_location
API being introduced. This patch preserves the current functionality and
adds no new features.
The "big picture" API usage introduced by this patch may be illustrated
with a simple exmaple. Where previously developers would write:
void
my_command (char *arg, int from_tty)
{
create_breakpoint (..., arg, ...);
...
}
one now uses:
void
my_command (char *arg, int from_tty)
{
struct event_locaiton *location;
struct cleanup *back_to;
location = string_to_event_locaiton (&arg, ...);
back_to = make_cleanup_delete_event_location (location);
create_breakpoint (..., location, ...);
do_cleanups (back_to);
}
Linespec-decoding functions (now called location-decoding) such as
decode_line_full no longer skip argument pointers over processed input.
That functionality has been moved into string_to_event_location as
demonstrated above.
gdb/ChangeLog
* ax-gdb.c: Include location.h.
(agent_command_1) Use linespec location instead of address
string.
* break-catch-throw.c: Include location.h.
(re_set_exception_catchpoint): Use linespec locations instead
of address strings.
* breakpoint.c: Include location.h.
(create_overlay_event_breakpoint, create_longjmp_master_breakpoint)
(create_std_terminate_master_breakpoint)
(create_exception_master_breakpoint, update_breakpoints_after_exec):
Use linespec location instead of address string.
(print_breakpoint_location): Use locations and
event_location_to_string.
Print extra_string for pending locations for non-MI streams.
(print_one_breakpoint_location): Use locations and
event_location_to_string.
(init_raw_breakpoint_without_location): Initialize b->location.
(create_thread_event_breakpoint): Use linespec location instead of
address string.
(init_breakpoint_sal): Likewise.
Only save extra_string if it is non-NULL and not the empty string.
Use event_location_to_string instead of `addr_string'.
Constify `p' and `endp'.
Use skip_spaces_const/skip_space_const instead of non-const versions.
Copy the location into the breakpoint.
If LOCATION is NULL, save the breakpoint address as a linespec location
instead of an address string.
(create_breakpoint_sal): Change `addr_string' parameter to a struct
event_location. All uses updated.
(create_breakpoints_sal): Likewise for local variable `addr_string'.
(parse_breakpoint_sals): Use locations instead of address strings.
Remove check for empty linespec with conditional.
Refactor.
(decode_static_tracepoint_spec): Make argument const and update
function.
(create_breakpoint): Change `arg' to a struct event_location and
rename.
Remove `copy_arg' and `addr_start'.
If EXTRA_STRING is empty, set it to NULL.
Don't populate `canonical' for pending breakpoints.
Pass `extra_string' to find_condition_and_thread.
Clear `extra_string' if `rest' was NULL.
Do not error with "garbage after location" if setting a dprintf
breakpoint.
Copy the location into the breakpoint instead of an address string.
(break_command_1): Use string_to_event_location and pass this to
create_breakpoint instead of an address string.
Check against `arg_cp' for a probe linespec.
(dprintf_command): Use string_to_event_location and pass this to
create_breakpoint instead of an address string.
Throw an exception if no format string was specified.
(print_recreate_ranged_breakpoint): Use event_location_to_string
instead of address strings.
(break_range_command, until_break_command)
(init_ada_exception_breakpoint): Use locations instead
of address strings.
(say_where): Print out extra_string for pending locations.
(base_breakpoint_dtor): Delete `location' and `location_range_end' of
the breakpoint.
(base_breakpoint_create_sals_from_location): Use struct event_location
instead of address string.
Remove `addr_start' and `copy_arg' parameters.
(base_breakpoint_decode_location): Use struct event_location instead of
address string.
(bkpt_re_set): Use locations instead of address strings.
Use event_location_empty_p to check for unset location.
(bkpt_print_recreate): Use event_location_to_string instead of
an address string.
Print out extra_string for pending locations.
(bkpt_create_sals_from_location, bkpt_decode_location)
(bkpt_probe_create_sals_from_location): Use struct event_location
instead of address string.
(bkpt_probe_decode_location): Use struct event_location instead of
address string.
(tracepoint_print_recreate): Use event_location_to_string to
recreate the tracepoint.
(tracepoint_create_sals_from_location, tracepoint_decode_location)
(tracepoint_probe_create_sals_from_location)
(tracepoint_probe_decode_location): Use struct event_location
instead of address string.
(dprintf_print_recreate): Use event_location_to_string to recreate
the dprintf.
(dprintf_re_set): Remove check for valid/missing format string.
(strace_marker_create_sals_from_location)
(strace_marker_create_breakpoints_sal, strace_marker_decode_location)
(update_static_tracepoint): Use struct event_location instead of
address string.
(location_to_sals): Likewise.
Pass `extra_string' to find_condition_and_thread.
For newly resolved pending breakpoint locations, clear the location's
string representation.
Assert that the breakpoint's condition string is NULL when
condition_not_parsed.
(breakpoint_re_set_default, create_sals_from_location_default)
(decode_location_default, trace_command, ftrace_command)
(strace_command, create_tracepoint_from_upload): Use locations
instead of address strings.
* breakpoint.h (struct breakpoint_ops) <create_sals_from_location>:
Use struct event_location instead of address string.
Update all uses.
<decode_location>: Likewise.
(struct breakpoint) <addr_string>: Change to struct event_location
and rename `location'.
<addr_string_range_end>: Change to struct event_location and rename
`location_range_end'.
(create_breakpoint): Use struct event_location instead of address
string.
* cli/cli-cmds.c: Include location.h.
(edit_command, list_command): Use locations instead of address strings.
* elfread.c: Include location.h.
(elf_gnu_ifunc_resolver_return_stop): Use event_location_to_string.
* guile/scm-breakpoint.c: Include location.h.
(bpscm_print_breakpoint_smob): Use event_location_to_string.
(gdbscm_register_breakpoint): Use locations instead of address
strings.
* linespec.c: Include location.h.
(struct ls_parser) <stream>: Change to const char *.
(PARSER_STREAM): Update.
(lionespec_lexer_lex_keyword): According to find_condition_and_thread,
keywords must be followed by whitespace.
(canonicalize_linespec): Save a linespec location into `canonical'.
Save a canonical linespec into `canonical'.
(parse_linespec): Change `argptr' to const char * and rename `arg'.
All uses updated.
Update function description.
(linespec_parser_new): Initialize `parser'.
Update initialization of parsing stream.
(event_location_to_sals): New function.
(decode_line_full): Change `argptr' to a struct event_location and
rename it `location'.
Use locations instead of address strings.
Call event_location_to_sals instead of parse_linespec.
(decode_line_1): Likewise.
(decode_line_with_current_source, decode_line_with_last_displayed)
Use locations instead of address strings.
(decode_objc): Likewise.
Change `argptr' to const char * and rename `arg'.
(destroy_linespec_result): Delete the linespec result's location
instead of freeing the address string.
* linespec.h (struct linespec_result) <addr_string>: Change to
struct event_location and rename to ...
<location>: ... this.
(decode_line_1, decode_line_full): Change `argptr' to struct
event_location. All callers updated.
* mi/mi-cmd-break.c: Include language.h, location.h, and linespec.h.
(mi_cmd_break_insert_1): Use locations instead of address strings.
Throw an error if there was "garbage" at the end of the specified
linespec.
* probe.c: Include location.h.
(parse_probes): Change `argptr' to struct event_location.
Use event locations instead of address strings.
* probe.h (parse_probes): Change `argptr' to struct event_location.
* python/py-breakpoint.c: Include location.h.
(bppy_get_location): Constify local variable `str'.
Use event_location_to_string.
(bppy_init): Use locations instead of address strings.
* python/py-finishbreakpoint.c: Include location.h.
(bpfinishpy_init): Remove local variable `addr_str'.
Use locations instead of address strings.
* python/python.c: Include location.h.
(gdbpy_decode_line): Use locations instead of address strings.
* remote.c: Include location.h.
(remote_download_tracepoint): Use locations instead of address
strings.
* spu-tdep.c: Include location.h.
(spu_catch_start): Remove local variable `buf'.
Use locations instead of address strings.
* tracepoint.c: Include location.h.
(scope_info): Use locations instead of address strings.
(encode_source_string): Constify parameter `src'.
* tracepoint.h (encode_source_string): Likewise.
gdb/testsuite/ChangeLog
* gdb.base/dprintf-pending.exp: Update dprintf "without format"
test.
Add tests for missing ",FMT" and ",".
This patch renames all occurrances of "addr_string" and "address
string" in the breakpoint/linespec APIs. This will emphasize the
change from address strings used in setting breakpoints (et al) to the
new locations-based API introduced in subsequent patches.
gdb/ChangeLog:
* breakpoint.h (struct breakpoint_ops) <create_sals_from_address>:
Renamed to create_sals_from_location.
<decode_linespec>: Renamed to decode_location.
Update all callers.
* breakpoint.c (create_sals_from_address_default): Renamed to ...
(create_sals_from_location_default): ... this.
(addr_string_to_sals): Renamed to ...
(location_to_sals): ... this.
(decode_linespec_default): Renamed to ...
(decode_location_default): ... this.
(base_breakpoint_create_sals_from_address): Renamed to ...
(base_breakpoint_create_sals_from_location): ... this.
(bkpt_create_sals_from_address): Renamed to ...
(bkpt_create_sals_from_location): ... this.
(bkpt_decode_linespec): Renamed to ...
(bkpt_decode_location): ... this.
(bkpt_probe_create_sals_from_address): Renamed to ...
(bkpt_probe_create_sals_from_location): ... this.
(tracepoint_create_sals_from_address): Renamed to ...
(tracepoint_create_sals_from_location): ... this.
(tracepoint_decode_linespec): Renamed to ...
(tracepoint_decode_location): ... this.
(tracepoint_probe_create_sals_from_address): Renamed to ...
(tracepoint_probe_create_sals_from_location): ... this.
(tracepoint_probe_decode_linespec): Renamed to ...
(tracepoint_probe_decode_location): ... this.
(strace_marker_create_sals_from_address): Renamed to ...
(strace_marker_create_sals_from_location): ... this.
(decode_linespec_default): Renamed to ...
(decode_location_default): ... this.
make_breakpoint_permanent is no longer used anywhere and can be
safely removed.
gdb/ChangeLog:
2015-06-17 Luis Machado <lgustavo@codesourcery.com>
* breakpoint.c (make_breakpoint_permanent): Remove unused
function.
* breakpoint.h (make_breakpoint_permanent): Remove declaration.
This commit implements the 'breakpoint_find_if' function, which allows
code external to gdb/breakpoint.c to iterate through the list of
'struct breakpoint *'. This is needed in order to create the
'gdb/break-catch-syscall.c' file, because one of its functions
(catching_syscall_number) needs to do this iteration.
My first thought was to share the ALL_BREAKPOINTS* macros on
gdb/breakpoint.h, but they use a global variable local to
gdb/breakpoint.c, and I did not want to share that variable. So, in
order to keep the minimal separation, I decided to implement this
way of iterating through the existing 'struct breakpoint *'.
This function was based on BFD's bfd_sections_find_if. If the
user-provided function returns 0, the iteration proceeds. Otherwise,
the iteration stops and the function returns the 'struct breakpoint *'
that is being processed. This means that the return value of this
function can be either NULL or a pointer to a 'struct breakpoint'.
gdb/ChangeLog:
2015-03-11 Sergio Durigan Junior <sergiodj@redhat.com>
* breakpoint.c (breakpoint_find_if): New function.
* breakpoint.h (breakpoint_find_if): New prototype.
The moribund locations heuristics are problematic. This patch teaches
GDB about targets that can reliably tell whether a trap was caused by
a software or hardware breakpoint, and thus don't need moribund
locations, thus bypassing all the problems that mechanism has.
The non-stop-fair-events.exp test is frequently failing currently.
E.g., see https://sourceware.org/ml/gdb-testers/2015-q1/msg03148.html.
The root cause is a fundamental problem with moribund locations. For
example, the stepped_breakpoint logic added by af48d08f breaks in this
case (which is what happens with that test):
- Step thread A, no breakpoint is set at PC.
- The kernel doesn't schedule thread A yet.
- Insert breakpoint at A's PC, for some reason (e.g., a step-resume
breakpoint for thread B).
- Kernel finally schedules thread A.
- thread A's stepped_breakpoint flag is not set, even though it now
stepped a breakpoint instruction.
- adjust_pc_after_break gets the PC wrong, because PC == PREV_PC, but
stepped_breakpoint is not set.
We needed the stepped_breakpoint logic to workaround moribund
locations, because otherwise adjust_pc_after_break could apply an
adjustment when it shouldn't just because there _used_ to be a
breakpoint at PC (a moribund breakpoint location). For example, on
x86, that's wrong if the thread really hasn't executed an int3, but
instead executed some other 1-byte long instruction. Getting the PC
adjustment wrong of course leads to the inferior executing the wrong
instruction.
Other problems with moribund locations are:
- if a true SIGTRAP happens to be raised when the program is
executing the PC that used to have a breakpoint, GDB will assume
that is a trap for a breakpoint that has recently been removed, and
thus we miss reporting the random signal to the user.
- to minimize that, we get rid of moribund location after a while.
That while is defined as just a certain number of events being
processed. That number of events sometimes passes by before a
delayed breakpoint is processed, and GDB confuses the trap for a
random signal, thus reporting the random trap. Once the user
resumes the thread, the program crashes because the PC was not
adjusted...
The fix for all this is to bite the bullet and get rid of heuristics
and instead rely on the target knowing accurately what caused the
SIGTRAP. The target/kernel/stub is in the best position to know what
that, because it can e.g. consult priviledged CPU flags GDB has no
access to, or by knowing which exception vector entry was called when
the instruction trapped, etc. Most debug APIs I've seen to date
report breakpoint hits as a distinct event in some fashion. For
example, on the Linux kernel, whether a breakpoint was executed is
exposed to userspace in the si_code field of the SIGTRAP's siginfo.
On Windows, the debug API reports a EXCEPTION_BREAKPOINT exception
code.
We needed to keep around deleted breakpoints in an on-the-side list
(the moribund locations) for two main reasons:
- Know that a SIGTRAP actually is a delayed event for a hit of a
breakpoint that was removed before the event was processed, and
thus should not be reported as a random signal.
- So we still do the decr_pc_after_break adjustment in that case, so
that the thread is resumed at the correct address.
In the new model, if GDB processes an event the target tells is a
breakpoint trap, and GDB doesn't find the corresponding breakpoint in
its breakpoint tables, it means that event is a delayed event for a
breakpoint that has since been removed, and thus the event should be
ignored.
For the decr_pc_after_after issue, it ends up being much simpler that
on targets that can reliably tell whether a breakpoint trapped, for
the breakpoint trap to present the PC already adjusted. Proper
multi-threading support already implies that targets needs to be doing
decr_pc_after_break adjustment themselves, otherwise for example, in
all-stop if two threads hit a breakpoint simultaneously, and the user
does "info threads", he'll see the non-event thread that hit the
breakpoint stopped at the wrong PC.
This way (target adjusts) also ends up eliminating the need for some
awkward re-incrementing of the PC in the record-full and Linux targets
that we do today, and the need for the target_decr_pc_after_break
hook.
If the target always adjusts, then there's a case where GDB needs to
re-increment the PC. Say, on x86, an "int3" instruction that was
explicitly written in the program traps. In this case, GDB should
report a random SIGTRAP signal to the user, with the PC pointing at
the instruction past the int3, just like if GDB was not debugging the
program. The user may well decide to pass the SIGTRAP to the program
because the program being debugged has a SIGTRAP handler that handles
its own breakpoints, and expects the PC to be unadjusted.
Tested on x86-64 Fedora 20.
gdb/ChangeLog:
2015-03-04 Pedro Alves <palves@redhat.com>
* breakpoint.c (need_moribund_for_location_type): New function.
(bpstat_stop_status): Don't skipping checking moribund locations
of breakpoint types which the target tell caused a stop.
(program_breakpoint_here_p): New function, factored out from ...
(bp_loc_is_permanent): ... this.
(update_global_location_list): Don't create a moribund location if
the target supports reporting stops of the type of the removed
breakpoint.
* breakpoint.h (program_breakpoint_here_p): New declaration.
* infrun.c (adjust_pc_after_break): Return early if the target has
already adjusted the PC. Add comments.
(handle_signal_stop): If nothing explains a signal, and the target
tells us the stop was caused by a software breakpoint, check if
there's a breakpoint instruction in the memory. If so, adjust the
PC before presenting the stop to the user. Otherwise, ignore the
trap. If nothing explains a signal, and the target tells us the
stop was caused by a hardware breakpoint, ignore the trap.
* target.h (struct target_ops) <to_stopped_by_sw_breakpoint,
to_supports_stopped_by_sw_breakpoint, to_stopped_by_hw_breakpoint,
to_supports_stopped_by_hw_breakpoint>: New fields.
(target_stopped_by_sw_breakpoint)
(target_supports_stopped_by_sw_breakpoint)
(target_stopped_by_hw_breakpoint)
(target_supports_stopped_by_hw_breakpoint): Define.
* target-delegates.c: Regenerate.
Building GDB in C++, we get:
src/gdb/breakpoint.h:529:8: error: use of enum ‘print_stop_action’ without previous declaration
We can't forward declare enums in C++.
gdb/ChangeLog:
2015-02-27 Pedro Alves <palves@redhat.com>
* breakpoint.h (enum print_stop_action): Move further up in the
file.
Running the testsuite with a series that reimplements user-visible
all-stop behavior on top of a target running in non-stop mode revealed
problems related to event starvation avoidance.
For example, I see
gdb.threads/signal-while-stepping-over-bp-other-thread.exp failing.
What happens is that GDB core never gets to see the signal event. It
ends up processing the events for the same threads over an over,
because Linux's waitpid(-1, ...) returns that first task in the task
list that has an event, starving threads on the tail of the task list.
So I wrote a non-stop mode test originally inspired by
signal-while-stepping-over-bp-other-thread.exp, to stress this
independently of all-stop on top of non-stop. Fixing it required the
changes described below. The test will be added in a following
commit.
1) linux-nat.c has code in place that picks an event LWP at random out
of all that have had events. This is because on the kernel side,
"waitpid(-1, ...)" just walks the task list linearly looking for the
first that had an event. But, this code is currently only used in
all-stop mode. So with a multi-threaded program that has multiple
events triggering debug events in parallel, GDB ends up starving some
threads.
To make the event randomization work in non-stop mode too, the patch
makes us pull out all the already pending events on the kernel side,
with waitpid, before deciding which LWP to report to the core.
There's some code in linux_wait that takes care of leaving events
pending if they were for LWPs the caller is not interested in. The
patch moves that to linux_nat_filter_event, so that we only have one
place that leaves events pending. With that in place, conceptually,
the flow is simpler and more normalized:
#1 - walk the LWP list looking for an LWP with a pending event to report.
#2 - if no pending event, pull events out of the kernel, and store
them in the LWP structures as pending.
#3- goto #1.
2) Then, currently the event randomization code only considers SIGTRAP
(or trap-like) events. That means that if e.g., have have multiple
threads stepping in parallel that hit a breakpoint that needs stepping
over, and one gets a signal, the signal may end up never getting
processed, because GDB will always be giving priority to the SIGTRAPs.
The patch fixes this by making the randomization code consider all
kinds of pending events.
3) If multiple threads hit a breakpoint, we report one of those, and
"cancel" the others. Cancelling means decrementing the PC, and
discarding the event. If the next time the LWP is resumed the
breakpoint is still installed, the LWP should hit it again, and we'll
report the hit then. The problem I found is that this delays threads
from advancing too much, with the kernel potentially ending up
scheduling the same threads over and over, and others not advancing.
So the patch switches away from cancelling the breakpoints, and
instead remembering that the LWP had stopped for a breakpoint. If on
resume the breakpoint is still installed, we report it. If it's no
longer installed, we discard the pending event then. This is actually
how GDBserver used to handle this before d50171e4 (Teach linux
gdbserver to step-over-breakpoints), but with the difference that back
then we'd delay adjusting the PC until resuming, which made it so that
"info threads" could wrongly see threads with unadjusted PCs.
gdb/
2015-01-09 Pedro Alves <palves@redhat.com>
* breakpoint.c (hardware_breakpoint_inserted_here_p): New
function.
* breakpoint.h (hardware_breakpoint_inserted_here_p): New
declaration.
* linux-nat.c (linux_nat_status_is_event): Move higher up in file.
(linux_resume_one_lwp): Store the thread's PC. Adjust to clear
stop_reason.
(check_stopped_by_watchpoint): New function.
(save_sigtrap): Reimplement.
(linux_nat_stopped_by_watchpoint): Adjust.
(linux_nat_lp_status_is_event): Delete.
(stop_wait_callback): Only call save_sigtrap after storing the
pending status.
(status_callback): If the thread had been stopped for a breakpoint
that has since been removed, discard the event and resume the LWP.
(count_events_callback, select_event_lwp_callback): Use
lwp_status_pending_p instead of linux_nat_lp_status_is_event.
(cancel_breakpoint): Rename to ...
(check_stopped_by_breakpoint): ... this. Record whether the LWP
stopped for a software breakpoint or hardware breakpoint.
(select_event_lwp): Only give preference to the stepping LWP in
all-stop mode. Adjust comments.
(stop_and_resume_callback): Remove references to new_pending_p.
(linux_nat_filter_event): Likewise. Leave exit events of the
leader thread pending here. Handle signal short circuiting here.
Only call save_sigtrap after storing the pending waitstatus.
(linux_nat_wait_1): Remove 'retry' label. Remove references to
new_pending. Don't handle leaving events the caller is not
interested in pending here, nor handle signal short-circuiting
here. 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-nat.h (enum lwp_stop_reason): New.
(struct lwp_info) <stop_pc>: New field.
(struct lwp_info) <stopped_by_watchpoint>: Delete field.
(struct lwp_info) <stop_reason>: New field.
* x86-linux-nat.c (x86_linux_prepare_to_resume): Adjust.
"permanent"-ness is currently a property of the breakpoint. But, it
should actually be an implementation detail of a _location_. Consider
this bit in infrun.c:
/* Normally, by the time we reach `resume', the breakpoints are either
removed or inserted, as appropriate. The exception is if we're sitting
at a permanent breakpoint; we need to step over it, but permanent
breakpoints can't be removed. So we have to test for it here. */
if (breakpoint_here_p (aspace, pc) == permanent_breakpoint_here)
{
if (gdbarch_skip_permanent_breakpoint_p (gdbarch))
gdbarch_skip_permanent_breakpoint (gdbarch, regcache);
else
error (_("\
The program is stopped at a permanent breakpoint, but GDB does not know\n\
how to step past a permanent breakpoint on this architecture. Try using\n\
a command like `return' or `jump' to continue execution."));
}
This will wrongly skip a non-breakpoint instruction if we have a
multiple location breakpoint where the whole breakpoint was set to
"permanent" because one of the locations happened to be permanent,
even if the one GDB is resuming from is not.
Related, because the permanent breakpoints are only marked as such in
init_breakpoint_sal, we currently miss marking momentary breakpoints
as permanent. A test added by a following patch trips on that.
Making permanent-ness be per-location, and marking locations as such
in add_location_to_breakpoint, the natural place to do this, fixes
this issue...
... and then exposes a latent issue with mark_breakpoints_out. It's
clearing the inserted flag of permanent breakpoints. This results in
assertions failing like this:
Breakpoint 1, main () at testsuite/gdb.base/callexit.c:32
32 return 0;
(gdb) call callexit()
[Inferior 1 (process 15849) exited normally]
gdb/breakpoint.c:12854: internal-error: allegedly permanent breakpoint is not actually inserted
A problem internal to GDB has been detected,
further debugging may prove unreliable.
The call dummy breakpoint, which is a momentary breakpoint, is set on
top of a manually inserted breakpoint instruction, and so is now
rightfully marked as a permanent breakpoint. See "Write a legitimate
instruction at the point where the infcall breakpoint is going to be
inserted." comment in infcall.c.
Re. make_breakpoint_permanent. That's only called by solib-pa64.c.
Permanent breakpoints were actually originally invented for HP-UX [1].
I believe that that call (the only one in the tree) is unnecessary
nowadays, given that nowadays the core breakpoints code analyzes the
instruction under the breakpoint to automatically detect whether it's
setting a breakpoint on top of a breakpoint instruction in the
program. I know close to nothing about HP-PA/HP-UX, though.
[1] https://sourceware.org/ml/gdb-patches/1999-q3/msg00245.html, and
https://sourceware.org/ml/gdb-patches/1999-q3/msg00242.html
In addition to the per-location issue, "permanent breakpoints" are
currently always displayed as enabled=='n':
(gdb) b main
Breakpoint 3 at 0x40053c: file ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S, line 29.
(gdb) info breakpoints
Num Type Disp Enb Address What
3 breakpoint keep n 0x000000000040053c ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S:29
But OTOH they're always enabled; there's no way to disable them...
In turn, this means that if one adds commands to such a breakpoint,
they're _always_ run:
(gdb) start
Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.arch/i386-permbkpt
...
Temporary breakpoint 1, main () at ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S:29
29 int3
(gdb) b main
Breakpoint 2 at 0x40053c: file ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S, line 29.
(gdb) info breakpoints
Num Type Disp Enb Address What
2 breakpoint keep n 0x000000000040053c ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S:29
(gdb) commands
Type commands for breakpoint(s) 2, one per line.
End with a line saying just "end".
>echo "hello!"
>end
(gdb) disable 2
(gdb) start
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Temporary breakpoint 3 at 0x40053c: file ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S, line 29.
Starting program: /home/pedro/gdb/mygit/build/gdb/testsuite/gdb.arch/i386-permbkpt
Breakpoint 2, main () at ../../../src/gdb/testsuite/gdb.arch/i386-permbkpt.S:29
29 int3
"hello!"(gdb)
IMO, one should be able to disable such a breakpoint, and GDB should
then behave just like if the user hadn't created the breakpoint in the
first place (that is, report a SIGTRAP).
By making permanent-ness a property of the location, and eliminating
the bp_permanent enum enable_state state ends up fixing that as well.
No tests are added for these changes yet; they'll be added in a follow
up patch, as skipping permanent breakpoints is currently broken and
trips on an assertion in infrun.
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/ChangeLog:
2014-11-12 Pedro Alves <palves@redhat.com>
Mark locations as permanent, not the whole breakpoint.
* breakpoint.c (remove_breakpoint_1, remove_breakpoint): Adjust.
(mark_breakpoints_out): Don't mark permanent breakpoints as
uninserted.
(breakpoint_init_inferior): Use mark_breakpoints_out.
(breakpoint_here_p): Adjust.
(bpstat_stop_status, describe_other_breakpoints): Remove handling
of permanent breakpoints.
(make_breakpoint_permanent): Mark each location as permanent,
instead of marking the breakpoint.
(add_location_to_breakpoint): If the location is permanent, mark
it as such, and as inserted.
(init_breakpoint_sal): Don't make the breakpoint permanent here.
(bp_location_compare, update_global_location_list): Adjust.
(update_breakpoint_locations): Don't make the breakpoint permanent
here.
(disable_breakpoint, enable_breakpoint_disp): Don't skip permanent
breakpoints.
* breakpoint.h (enum enable_state) <bp_permanent>: Delete field.
(struct bp_location) <permanent>: New field.
* guile/scm-breakpoint.c (bpscm_enable_state_to_string): Remove
reference to bp_permanent.
Used to be necessary for the thread-hop code, but that's gone now.
Nothing uses this anymore.
gdb/
2014-11-04 Pedro Alves <palves@redhat.com>
* breakpoint.c (breakpoint_thread_match): Delete function.
* breakpoint.h (breakpoint_thread_match): Delete declaration.
This patch finally makes each thread have its own set of single-step
breakpoints. This paves the way to have multiple threads software
single-stepping, though this patch doesn't flip that switch on yet.
That'll be done on a subsequent patch.
gdb/
2014-10-15 Pedro Alves <palves@redhat.com>
* breakpoint.c (single_step_breakpoints): Delete global.
(insert_single_step_breakpoint): Adjust to store the breakpoint
pointer in the current thread.
(single_step_breakpoints_inserted, remove_single_step_breakpoints)
(cancel_single_step_breakpoints): Delete functions.
(breakpoint_has_location_inserted_here): Make extern.
(single_step_breakpoint_inserted_here_p): Adjust to walk the
breakpoint list.
* breakpoint.h (breakpoint_has_location_inserted_here): New
declaration.
(single_step_breakpoints_inserted, remove_single_step_breakpoints)
(cancel_single_step_breakpoints): Remove declarations.
* gdbthread.h (struct thread_control_state)
<single_step_breakpoints>: New field.
(delete_single_step_breakpoints)
(thread_has_single_step_breakpoints_set)
(thread_has_single_step_breakpoint_here): New declarations.
* infrun.c (follow_exec): Also clear the single-step breakpoints.
(singlestep_breakpoints_inserted_p, singlestep_ptid)
(singlestep_pc): Delete globals.
(infrun_thread_ptid_changed): Remove references to removed
globals.
(resume_cleanups): Delete the current thread's single-step
breakpoints.
(maybe_software_singlestep): Remove references to removed globals.
(resume): Adjust to use thread_has_single_step_breakpoints_set and
delete_single_step_breakpoints.
(init_wait_for_inferior): Remove references to removed globals.
(delete_thread_infrun_breakpoints): Delete the thread's
single-step breakpoints too.
(delete_just_stopped_threads_infrun_breakpoints): Don't delete
single-step breakpoints here.
(delete_stopped_threads_single_step_breakpoints): New function.
(adjust_pc_after_break): Adjust to use
thread_has_single_step_breakpoints_set.
(handle_inferior_event): Remove references to removed globals.
Use delete_stopped_threads_single_step_breakpoints.
(handle_signal_stop): Adjust to per-thread single-step
breakpoints. Swap test order to do cheaper tests first.
(switch_back_to_stepped_thread): Extend debug output. Remove
references to removed globals.
* record-full.c (record_full_wait_1): Adjust to per-thread
single-step breakpoints.
* thread.c (delete_single_step_breakpoints)
(thread_has_single_step_breakpoints_set)
(thread_has_single_step_breakpoint_here): New functions.
(clear_thread_inferior_resources): Also delete the thread's
single-step breakpoints.
There are no users of deprecated_{insert,remove}_raw_breakpoint left.
gdb/
2014-10-15 Pedro Alves <palves@redhat.com>
* breakpoint.c (regular_breakpoint_inserted_here_p): Inline ...
(breakpoint_inserted_here_p): ... here. Remove special case for
software single-step breakpoints.
(find_non_raw_software_breakpoint_inserted_here): Inline ...
(software_breakpoint_inserted_here_p): ... here. Remove special
case for software single-step breakpoints.
(bp_target_info_copy_insertion_state)
(deprecated_insert_raw_breakpoint)
(deprecated_remove_raw_breakpoint): Delete functions.
* breakpoint.h (deprecated_insert_raw_breakpoint)
(deprecated_remove_raw_breakpoint): Remove declarations.
This patch makes single-step breakpoints "real" breakpoints on the
global location list.
There are several benefits to this:
- It removes the currently limitation that only 2 single-step
breakpoints can be inserted. See an example here of a discussion
around a case that wants more than 2, possibly unbounded:
https://sourceware.org/ml/gdb-patches/2014-03/msg00663.html
- makes software single-step work on read-only code regions.
The logic to convert a software breakpoint to a hardware breakpoint
if the memory map says the breakpoint address is in read only memory
is in insert_bp_location. Because software single-step breakpoints
bypass all that go and straight to target_insert_breakpoint, we
can't software single-step over read only memory. This patch
removes that limitation, and adds a test that makes sure that works,
by forcing a code region to read-only with "mem LOW HIGH ro" and
then stepping through that.
- Fixes PR breakpoints/9649
This is an assertion failure in insert_single_step_breakpoint in
breakpoint.c, because we may leave stale single-step breakpoints
behind on error.
The tests for stepping through read-only regions exercise the root
cause of the bug, which is that we leave single-step breakpoints
behind if we fail to insert any single-step breakpoint. Deleting
the single-step breakpoints in resume_cleanups,
delete_just_stopped_threads_infrun_breakpoints, and
fetch_inferior_event fixes this. Without that, we'd no longer hit
the assertion, as that code is deleted, but we'd instead run into
errors/warnings trying to insert/remove the stale breakpoints on
next resume.
- Paves the way to have multiple threads software single-stepping at
the same time, leaving update_global_location_list to worry about
duplicate locations.
- Makes the moribund location machinery aware of software single-step
breakpoints, paving the way to enable software single-step on
non-stop, instead of forcing serialized displaced stepping for all
single steps.
- It's generaly cleaner.
We no longer have to play games with single-step breakpoints
inserted at the same address as regular breakpoints, like we
recently had to do for 7.8. See this discussion:
https://sourceware.org/ml/gdb-patches/2014-06/msg00052.html.
Tested on x86_64 Fedora 20, on top of my 'single-step breakpoints on
x86' series.
gdb/
2014-10-15 Pedro Alves <palves@redhat.com>
PR breakpoints/9649
* breakpoint.c (single_step_breakpoints, single_step_gdbarch):
Delete array globals.
(single_step_breakpoints): New global.
(breakpoint_xfer_memory): Remove special handling for single-step
breakpoints.
(update_breakpoints_after_exec): Delete bp_single_step
breakpoints.
(detach_breakpoints): Remove special handling for single-step
breakpoints.
(breakpoint_init_inferior): Delete bp_single_step breakpoints.
(bpstat_stop_status): Add comment.
(bpstat_what, bptype_string, print_one_breakpoint_location)
(adjust_breakpoint_address, init_bp_location): Handle
bp_single_step.
(new_single_step_breakpoint): New function.
(set_momentary_breakpoint, bkpt_remove_location): Remove special
handling for single-step breakpoints.
(insert_single_step_breakpoint, single_step_breakpoints_inserted)
(remove_single_step_breakpoints, cancel_single_step_breakpoints):
Rewrite.
(detach_single_step_breakpoints, find_single_step_breakpoint):
Delete functions.
(breakpoint_has_location_inserted_here): New function.
(single_step_breakpoint_inserted_here_p): Rewrite.
* breakpoint.h: Remove FIXME.
(enum bptype) <bp_single_step>: New enum value.
(insert_single_step_breakpoint): Update comment.
* infrun.c (resume_cleanups)
(delete_step_thread_step_resume_breakpoint): Remove single-step
breakpoints.
(fetch_inferior_event): Install a cleanup that removes infrun
breakpoints.
(switch_back_to_stepped_thread) <expect thread advanced also>:
Clear step-over info.
gdb/testsuite/
2014-10-15 Pedro Alves <palves@redhat.com>
PR breakpoints/9649
* gdb.base/breakpoint-in-ro-region.c (main): Add more instructions.
* gdb.base/breakpoint-in-ro-region.exp
(probe_target_hardware_step): New procedure.
(top level): Probe hardware stepping and hardware breakpoint
support. Test stepping through a read-only region, with both
"breakpoint auto-hw" on and off and both "always-inserted" on and
off.
This change:
commit b775012e84
Author: Luis Machado <luisgpm@br.ibm.com>
Date: Fri Feb 24 15:10:59 2012 +0000
2012-02-24 Luis Machado <lgustavo@codesourcery.com>
* remote.c (remote_supports_cond_breakpoints): New forward
declaration.
[...]
changed the way breakpoints are inserted and removed such that
`insert_bp_location' can now be called with the breakpoint being handled
already in place, while previously the call was only ever made for
breakpoints that have not been put in place. This in turn caused an
issue for software breakpoints and targets for which a breakpoint's
`placed_address' may not be the same as the original requested address.
The issue is `insert_bp_location' overwrites the previously adjusted
value in `placed_address' with the original address, that is only
replaced back with the correct adjusted address later on when
`gdbarch_breakpoint_from_pc' is called. Meanwhile there's a window
where the value in `placed_address' does not correspond to data stored
in `shadow_contents', leading to incorrect instruction bytes being
supplied when `one_breakpoint_xfer_memory' is called to supply the
instruction overlaid by the breakpoint.
And this is exactly what happens on the MIPS target with software
breakpoints placed in microMIPS code. In this case not only
`placed_address' is not the original address because of the ISA bit, but
`mips_breakpoint_from_pc' has to read the original instruction to
determine which one of the two software breakpoint instruction encodings
to choose as well. The 16-bit encoding is used to replace 16-bit
instructions and similarly the 32-bit one is used with 32-bit
instructions, to satisfy branch delay slot size requirements.
The mismatch between `placed_address' and the address data in
`shadow_contents' has been obtained from leads to the wrong encoding
being used in some cases, which in the case of a 32-bit software
breakpoint instruction replacing a 16-bit instruction causes corruption
to the adjacent following instruction and leads the debug session astray
if execution reaches there e.g. with a jump.
To address this problem I made the change below, that adds a
`reqstd_address' field to `struct bp_target_info' and leaves
`placed_address' unchanged once it has been set. This ensures data in
`shadow_contents' is always consistent with `placed_address'.
This approach also has this good side effect that all the places that
examine the breakpoint's address see a consistent value, either
`reqstd_address' or `placed_address', as required. Currently some
places see either the original or the adjusted address in
`placed_address', depending on whether they have been called before
`gdbarch_remote_breakpoint_from_pc' or afterwards. This is in
particular true for subsequent calls to
`gdbarch_remote_breakpoint_from_pc' itself, e.g. from
`one_breakpoint_xfer_memory'. This is also important for places like
`find_single_step_breakpoint' where a breakpoint's address is compared
to the raw value of $pc.
* breakpoint.h (bp_target_info): Add `reqstd_address' member,
update comments.
* breakpoint.c (one_breakpoint_xfer_memory): Use `reqstd_address'
for the breakpoint's address. Don't preinitialize `placed_size'.
(insert_bp_location): Set `reqstd_address' rather than
`placed_address'.
(bp_target_info_copy_insertion_state): Also copy `placed_address'.
(bkpt_insert_location): Use `reqstd_address' for the breakpoint's
address.
(bkpt_remove_location): Likewise.
(deprecated_insert_raw_breakpoint): Likewise.
(deprecated_remove_raw_breakpoint): Likewise.
(find_single_step_breakpoint): Likewise.
* mem-break.c (default_memory_insert_breakpoint): Use
`reqstd_address' for the breakpoint's address. Don't set
`placed_address' or `placed_size' if breakpoint contents couldn't
have been determined.
* remote.c (remote_insert_breakpoint): Use `reqstd_address' for
the breakpoint's address.
(remote_insert_hw_breakpoint): Likewise. Don't set
`placed_address' or `placed_size' if breakpoint couldn't have been
set.
* aarch64-linux-nat.c (aarch64_linux_insert_hw_breakpoint): Use
`reqstd_address' for the breakpoint's address.
* arm-linux-nat.c (arm_linux_hw_breakpoint_initialize): Likewise.
* ia64-tdep.c (ia64_memory_insert_breakpoint): Likewise.
* m32r-tdep.c (m32r_memory_insert_breakpoint): Likewise.
* microblaze-linux-tdep.c
(microblaze_linux_memory_remove_breakpoint): Likewise.
* monitor.c (monitor_insert_breakpoint): Likewise.
* nto-procfs.c (procfs_insert_breakpoint): Likewise.
(procfs_insert_hw_breakpoint): Likewise.
* ppc-linux-nat.c (ppc_linux_insert_hw_breakpoint): Likewise.
* ppc-linux-tdep.c (ppc_linux_memory_remove_breakpoint): Likewise.
* remote-m32r-sdi.c (m32r_insert_breakpoint): Likewise.
* remote-mips.c (mips_insert_breakpoint): Likewise.
* x86-nat.c (x86_insert_hw_breakpoint): Likewise.
Commit a25a5a45 (Fix "breakpoint always-inserted off"; remove
"breakpoint always-inserted auto") regressed non-stop remote
debugging.
This was exposed by mi-nsintrall.exp intermittently failing with a
spurious SIGTRAP.
The problem is that when debugging with "target remote", new threads
the target has spawned but have never reported a stop aren't visible
to GDB until it explicitly resyncs its thread list with the target's.
For example, in a program like this:
int
main (void)
{
pthread_t child_thread;
pthread_create (&child_thread, NULL, child_function, NULL);
return 0; <<<< set breakpoint here
}
If the user sets a breakpoint at the "return" statement, and runs the
program, when that breakpoint hit is reported, GDB is only aware of
the main thread. So if we base the decision to remove or insert
breakpoints from the target based on whether all the threads we know
about are stopped, we'll miss that child_thread is running, and thus
we'll remove breakpoints from the target, even through they should
still remain inserted, otherwise child_thread will miss them.
The break-while-running.exp test actually should also be exposing this
thread-list-out-of-synch problem. That test sets a breakpoint while
the main thread is stopped, but other threads are running. Because
other threads are running, the breakpoint is supposed to be inserted
immediately. But, unless something forces a refetch of the thread
list, like, e.g., "info threads", GDB won't be aware of the other
threads that had been spawned by the main thread, and so won't insert
new or old breakpoints in the target. And it turns out that the test
is exactly doing an explicit "info threads", masking out the
problem... This commit adjust the test to exercise the case of not
issuing "info threads". The test then fails without the GDB fix.
In the ni-nsintrall.exp case, what happens is that several threads hit
the same breakpoint, and when the first thread reports the stop,
because GDB wasn't aware other threads exist, all threads known to GDB
are found stopped, so GDB removes the breakpoints from the target.
The other threads follow up with SIGTRAPs too for that same
breakpoint, which has already been removed. For the first few
threads, the moribund breakpoints machinery suppresses the SIGTRAPs,
but after a few events (precisely '3 * thread_count () + 1' at the
time the breakpoint was removed, see update_global_location_list), the
moribund breakpoint machinery is no longer aware of the removed
breakpoint, and the SIGTRAP is reported as a spurious stop.
The fix is naturally then to stop assuming that if no thread in the
list is executing, then the target is fully stopped. We can't know
that until we fully sync the thread list. Because updating the thread
list on every stop would be too much RSP traffic, I chose instead to
update it whenever we're about to present a stop to the user.
Actually updating the thread list at that point happens to be an item
I had added to the local/remote parity wiki page a while ago:
Native GNU/Linux debugging adds new threads to the thread list as
the program creates them "The [New Thread foo] messages". Remote
debugging can't do that, and it's arguable whether we shouldn't even
stop native debugging from doing that, as it hinders inferior
performance. However, a related issue is that with remote targets
(and gdbserver), even after the program stops, the user still needs
to do "info threads" to pull an updated thread list. This, should
most likely be addressed, so that GDB pulls the list itself, perhaps
just before presenting a stop to the user.
With that in place, the need to delay "Program received signal FOO"
was actually caught by the manythreads.exp test. Without that bit, I
was getting:
[Thread 0x7ffff7f13700 (LWP 4499) exited]
[New Thread 0x7ffff7f0b700 (LWP 4500)]
^C
Program received signal SIGINT, Interrupt.
[New Thread 0x7ffff7f03700 (LWP 4501)] <<< new output
[Switching to Thread 0x7ffff7f0b700 (LWP 4500)]
__GI___nptl_death_event () at events.c:31
31 {
(gdb) FAIL: gdb.threads/manythreads.exp: stop threads 1
That is, I was now getting "New Thread" lines after the "Program
received signal" line, and the test doesn't expect them. As the
number of new threads discovered before and after the "Program
received signal" output is unbounded, it's much nicer to defer
"Program received signal" until after synching the thread list, thus
close to the "switching to thread" output and "current frame/source"
info:
[Thread 0x7ffff7863700 (LWP 7647) exited]
^C[New Thread 0x7ffff786b700 (LWP 7648)]
Program received signal SIGINT, Interrupt.
[Switching to Thread 0x7ffff7fc4740 (LWP 6243)]
__GI___nptl_create_event () at events.c:25
25 {
(gdb) PASS: gdb.threads/manythreads.exp: stop threads 1
Tested on x86_64 Fedora 20, native and gdbserver.
gdb/
2014-10-02 Pedro Alves <palves@redhat.com>
* breakpoint.c (breakpoints_should_be_inserted_now): Use
threads_are_executing.
* breakpoint.h (breakpoints_should_be_inserted_now): Add
describing comment.
* gdbthread.h (threads_are_executing): Declare.
(handle_signal_stop) <random signals>: Don't print about the
signal here if stopping.
(end_stepping_range): Don't notify observers here.
(normal_stop): Update the thread list. If stopped by a random
signal or a stepping range ended, notify observers.
* thread.c (threads_executing): New global.
(init_thread_list): Clear 'threads_executing'.
(set_executing): Set or clear 'threads_executing'.
(threads_are_executing): New function.
(update_threads_executing): New function.
(update_thread_list): Use it.
gdb/testsuite/
2014-10-02 Pedro Alves <palves@redhat.com>
* gdb.threads/break-while-running.exp (test): Add new
'update_thread_list' argument. Skip "info threads" if false.
(top level): Add new 'update_thread_list' axis.
By default, GDB removes all breakpoints from the target when the
target stops and the prompt is given back to the user. This is useful
in case GDB crashes while the user is interacting, as otherwise,
there's a higher chance breakpoints would be left planted on the
target.
But, as long as any thread is running free, we need to make sure to
keep breakpoints inserted, lest a thread misses a breakpoint. With
that in mind, in preparation for non-stop mode, we added a "breakpoint
always-inserted on" mode. This traded off the extra crash protection
for never having threads miss breakpoints, and in addition is more
efficient if there's a ton of breakpoints to remove/insert at each
user command (e.g., at each "step").
When we added non-stop mode, and for a period, we required users to
manually set "always-inserted on" when they enabled non-stop mode, as
otherwise GDB removes all breakpoints from the target as soon as any
thread stops, which means the other threads still running will miss
breakpoints. The test added by this patch exercises this.
That soon revealed a nuisance, and so later we added an extra
"breakpoint always-inserted auto" mode, that made GDB behave like
"always-inserted on" when non-stop was enabled, and "always-inserted
off" when non-stop was disabled. "auto" was made the default at the
same time.
In hindsight, this "auto" setting was unnecessary, and not the ideal
solution. Non-stop mode does depends on breakpoints always-inserted
mode, but only as long as any thread is running. If no thread is
running, no breakpoint can be missed. The same is true for all-stop
too. E.g., if, in all-stop mode, and the user does:
(gdb) c&
(gdb) b foo
That breakpoint at "foo" should be inserted immediately, but it
currently isn't -- currently it'll end up inserted only if the target
happens to trip on some event, and is re-resumed, e.g., an internal
breakpoint triggers that doesn't cause a user-visible stop, and so we
end up in keep_going calling insert_breakpoints. The test added by
this patch also covers this.
IOW, no matter whether in non-stop or all-stop, if the target fully
stops, we can remove breakpoints. And no matter whether in all-stop
or non-stop, if any thread is running in the target, then we need
breakpoints to be immediately inserted. And then, if the target has
global breakpoints, we need to keep breakpoints even when the target
is stopped.
So with that in mind, and aiming at reducing all-stop vs non-stop
differences for all-stop-on-stop-of-non-stop, this patch fixes
"breakpoint always-inserted off" to not remove breakpoints from the
target until it fully stops, and then removes the "auto" setting as
unnecessary. I propose removing it straight away rather than keeping
it as an alias, unless someone complains they have scripts that need
it and that can't adjust.
Tested on x86_64 Fedora 20.
gdb/
2014-09-22 Pedro Alves <palves@redhat.com>
* NEWS: Mention merge of "breakpoint always-inserted" modes "off"
and "auto" merged.
* breakpoint.c (enum ugll_insert_mode): New enum.
(always_inserted_mode): Now a plain boolean.
(show_always_inserted_mode): No longer handle AUTO_BOOLEAN_AUTO.
(breakpoints_always_inserted_mode): Delete.
(breakpoints_should_be_inserted_now): New function.
(insert_breakpoints): Pass UGLL_INSERT to
update_global_location_list instead of calling
insert_breakpoint_locations manually.
(create_solib_event_breakpoint_1): New, factored out from ...
(create_solib_event_breakpoint): ... this.
(create_and_insert_solib_event_breakpoint): Use
create_solib_event_breakpoint_1 instead of calling
insert_breakpoint_locations manually.
(update_global_location_list): Change parameter type from boolean
to enum ugll_insert_mode. All callers adjusted. Adjust to use
breakpoints_should_be_inserted_now and handle UGLL_INSERT.
(update_global_location_list_nothrow): Change parameter type from
boolean to enum ugll_insert_mode.
(_initialize_breakpoint): "breakpoint always-inserted" option is
now a boolean command. Update help text.
* breakpoint.h (breakpoints_always_inserted_mode): Delete declaration.
(breakpoints_should_be_inserted_now): New declaration.
* infrun.c (handle_inferior_event) <TARGET_WAITKIND_LOADED>:
Remove breakpoints_always_inserted_mode check.
(normal_stop): Adjust to use breakpoints_should_be_inserted_now.
* remote.c (remote_start_remote): Likewise.
gdb/doc/
2014-09-22 Pedro Alves <palves@redhat.com>
* gdb.texinfo (Set Breaks): Document that "set breakpoint
always-inserted off" is the default mode now. Delete
documentation of "set breakpoint always-inserted auto".
gdb/testsuite/
2014-09-22 Pedro Alves <palves@redhat.com>
* gdb.threads/break-while-running.exp: New file.
* gdb.threads/break-while-running.c: New file.
PR 12526 reports that -location watchpoints against bitfield arguments
trigger false positives when bits around the bitfield, but not the
bitfield itself, are modified.
This happens because -location watchpoints naturally operate at the
byte level, not at the bit level. When the address of a bitfield
lvalue is taken, information about the bitfield (i.e. its offset and
size) is lost in the process.
This information must first be retained throughout the lifetime of the
-location watchpoint. This patch achieves this by adding two new
fields to the watchpoint struct: val_bitpos and val_bitsize. These
fields are set when a watchpoint is first defined in watch_command_1.
They are both equal to zero if the watchpoint is not a -location
watchpoint or if the argument is not a bitfield.
Then these bitfield parameters are used inside update_watchpoint and
watchpoint_check to extract the actual value of the bitfield from the
watchpoint address, with the help of a local helper function
extract_bitfield_from_watchpoint_value.
Finally when creating a HW breakpoint pointing to a bitfield, we
optimize the address and length of the breakpoint. By skipping over
the bytes that don't cover the bitfield, this step reduces the
frequency at which a read watchpoint for the bitfield is triggered.
It also reduces the number of times a false-positive call to
check_watchpoint is triggered for a write watchpoint.
gdb/
PR breakpoints/12526
* breakpoint.h (struct watchpoint): New fields val_bitpos and
val_bitsize.
* breakpoint.c (watch_command_1): Use these fields to retain
bitfield information.
(extract_bitfield_from_watchpoint_value): New function.
(watchpoint_check): Use it.
(update_watchpoint): Use it. Optimize the address and length of a
HW watchpoint pointing to a bitfield.
* value.h (unpack_value_bitfield): New prototype.
* value.c (unpack_value_bitfield): Make extern.
gdb/testsuite/
PR breakpoints/12526
* gdb.base/watch-bitfields.exp: New file.
* gdb.base/watch-bitfields.c: New file.
The IRIX support wants to set a breakpoint to be hit when the startup
phase is complete, which is where shared libraries have been mapped
in. AFAIU, for most IRIX ports, that location is the entry point.
For MIPS IRIX however, GDB needs to set a breakpoint earlier, in
__dbx_link, as explained by:
#ifdef SYS_syssgi
/* On mips-irix, we need to stop the inferior early enough during
the startup phase in order to be able to load the shared library
symbols and insert the breakpoints that are located in these shared
libraries. Stopping at the program entry point is not good enough
because the -init code is executed before the execution reaches
that point.
So what we need to do is to insert a breakpoint in the runtime
loader (rld), more precisely in __dbx_link(). This procedure is
called by rld once all shared libraries have been mapped, but before
the -init code is executed. Unfortuantely, this is not straightforward,
as rld is not part of the executable we are running, and thus we need
the inferior to run until rld itself has been mapped in memory.
For this, we trace all syssgi() syscall exit events. Each time
we detect such an event, we iterate over each text memory maps,
get its associated fd, and scan the symbol table for __dbx_link().
When found, we know that rld has been mapped, and that we can insert
the breakpoint at the symbol address. Once the dbx_link() breakpoint
has been inserted, the syssgi() notifications are no longer necessary,
so they should be canceled. */
proc_trace_syscalls_1 (pi, SYS_syssgi, PR_SYSEXIT, FLAG_SET, 0);
#endif
The loop in irix_solib_create_inferior_hook then runs until whichever
breakpoint is hit first, the one set by solib-irix.c or the one set by
procfs.c.
Note the comment in disable_break talks about __dbx_init, but I think
that's a typo for __dbx_link:
- /* Note that it is possible that we have stopped at a location that
- is different from the location where we inserted our breakpoint.
- On mips-irix, we can actually land in __dbx_init(), so we should
- not check the PC against our breakpoint address here. See procfs.c
- for more details. */
This looks very much like referring to the loop in
irix_solib_create_inferior_hook stopping at __dbx_link instead of at
the entry point.
What this patch does is convert these deprecated raw breakpoints to
standard solib_event breakpoints. When the first solib-event
breakpoint is hit, we delete all solib-event breakpoints. We do that
in the so_ops->handle_event hook.
This allows getting rid of the loop in irix_solib_create_inferior_hook
completely, which should allow properly handling signals and other
events in the early startup phase, like in SVR4.
Built on x86_64 Fedora 20 with --enable-targets=all (builds
solib-irix.c).
Joel tested that with an earlier version of this patch "info shared"
after starting a program gave the same list of shared libraries as
before.
gdb/ChangeLog:
2014-09-12 Pedro Alves <palves@redhat.com>
* breakpoint.c (remove_solib_event_breakpoints_at_next_stop)
(create_and_insert_solib_event_breakpoint): New functions.
* breakpoint.h (create_and_insert_solib_event_breakpoint)
(remove_solib_event_breakpoints_at_next_stop): New declarations.
* procfs.c (dbx_link_bpt_addr, dbx_link_bpt): Delete globals.
(remove_dbx_link_breakpoint): Delete function.
(insert_dbx_link_bpt_in_file): Use
create_and_insert_solib_event_breakpoint instead of
deprecated_insert_raw_breakpoint.
(procfs_wait): Don't check whether we hit __dbx_link here.
(procfs_mourn_inferior): Don't delete the __dbx_link breakpoint
here.
* solib-irix.c (base_breakpoint): Delete global.
(disable_break): Delete function.
(enable_break): Use create_solib_event_breakpoint
instead of deprecated_insert_raw_breakpoint.
(irix_solib_handle_event): New function.
(irix_solib_create_inferior_hook): Don't run the target or disable
the mapping-complete breakpoint here.
(_initialize_irix_solib): Install irix_solib_handle_event as
so_ops->handle_event hook.
This patch changes a few more spots to use either cmd_sfunc_ftype or
cmd_cfunc_ftype, as appropriate. This is a bit cleaner.
Tested by rebuilding.
2014-07-01 Tom Tromey <tromey@redhat.com>
* breakpoint.c (add_catch_command): Use cmd_sfunc_ftype.
* breakpoint.h (add_catch_command): Use cmd_sfunc_ftype.
* cli/cli-decode.c (cmd_cfunc_eq, add_cmd, add_prefix_cmd)
(add_abbrev_prefix_cmd, add_info, add_com): Use cmd_cfunc_ftype.
* command.h (cmd_cfunc_ftype): Move earlier.
(add_cmd, add_prefix_cmd, add_abbrev_prefix_cmd, cmd_cfunc_eq)
(add_com, add_info): Use cmd_cfunc_ftype.
This patch is to add ptid into dummy_frame and extend frame_id to
dummy_frame_id (which has a ptid field). With this change, GDB uses
dummy_frame_id (thread ptid and frame_id) to find the dummy frames.
Currently, dummy frames are looked up by frame_id, which isn't
accurate in non-stop or multi-process mode. The test case
gdb.multi/dummy-frame-restore.exp shows the problem and this patch can
fix it.
Test dummy-frame-restore.exp makes two inferiors stop at
different functions, say, inferior 1 stops at f1 while inferior 2
stops at f2. Set a breakpoint to a function, do the inferior call
in two inferiors, and GDB has two dummy frames of the same frame_id.
When the inferior call is finished, GDB will look up a dummy frame
from its stack/list and restore the inferior's regcache. Two
inferiors are finished in different orders, the inferiors' states are
restored differently, which is wrong. Running dummy-frame-restore.exp
under un-patched GDB, we'll get two fails:
FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 2
FAIL: gdb.multi/dummy-frame-restore.exp: inf 2 first: after infcall: bt in inferior 1
With this patch applied, GDB will choose the correct dummy_frame to
restore for a given inferior, because ptid is considered when looking up
dummy frames. Two fails above are fixed.
Regression tested on x86_64-linux, both native and gdbserver.
gdb:
2014-06-27 Yao Qi <yao@codesourcery.com>
* breakpoint.c (check_longjmp_breakpoint_for_call_dummy):
Change parameter type to 'struct thread_info *'. Caller
updated.
* breakpoint.h (check_longjmp_breakpoint_for_call_dummy):
Update declaration.
* dummy-frame.c (struct dummy_frame_id): New.
(dummy_frame_id_eq): New function.
(struct dummy_frame) <id>: Change its type to 'struct
dummy_frame_id'.
(dummy_frame_push): Add parameter ptid and save it in
dummy_frame_id.
(pop_dummy_frame_bpt): Use ptid of dummy_frame instead of
inferior_ptid.
(pop_dummy_frame): Assert that the ptid of dummy_frame equals
to inferior_ptid.
(lookup_dummy_frame): Change parameter type to 'struct
dummy_frame_id *'. Callers updated. Call dummy_frame_id_eq
instead of frame_id_eq.
(dummy_frame_pop): Add parameter ptid. Callers updated.
Update comments. Compose dummy_frame_id and pass it to
lookup_dummy_frame.
(dummy_frame_discard): Add parameter ptid.
(dummy_frame_sniffer): Compose dummy_frame_id and call
dummy_frame_id_eq instead of frame_id_eq.
(fprint_dummy_frames): Print ptid.
* dummy-frame.h: Remove comments.
(dummy_frame_push): Add ptid in declaration.
(dummy_frame_pop, dummy_frame_discard): Likewise.
gdb/testsuite:
2014-06-27 Yao Qi <yao@codesourcery.com>
* gdb.multi/dummy-frame-restore.exp: New.
* gdb.multi/dummy-frame-restore.c: New.
gdb/doc:
2014-06-27 Yao Qi <yao@codesourcery.com>
* gdb.texinfo (Maintenance Commands): Update the output of
'maint print dummy-frames' command.
Even with deferred_step_ptid out of the way, GDB can still lose
watchpoints.
If a watchpoint triggers and the PC points to an address where a
thread-specific breakpoint for another thread is set, the thread-hop
code triggers, and we lose the watchpoint:
if (ecs->event_thread->suspend.stop_signal == GDB_SIGNAL_TRAP)
{
int thread_hop_needed = 0;
struct address_space *aspace =
get_regcache_aspace (get_thread_regcache (ecs->ptid));
/* Check if a regular breakpoint has been hit before checking
for a potential single step breakpoint. Otherwise, GDB will
not see this breakpoint hit when stepping onto breakpoints. */
if (regular_breakpoint_inserted_here_p (aspace, stop_pc))
{
if (!breakpoint_thread_match (aspace, stop_pc, ecs->ptid))
thread_hop_needed = 1;
^^^^^^^^^^^^^^^^^^^^^
}
And on software single-step targets, even without a thread-specific
breakpoint in the way, here in the thread-hop code:
else if (singlestep_breakpoints_inserted_p)
{
...
if (!ptid_equal (singlestep_ptid, ecs->ptid)
&& in_thread_list (singlestep_ptid))
{
/* If the PC of the thread we were trying to single-step
has changed, discard this event (which we were going
to ignore anyway), and pretend we saw that thread
trap. This prevents us continuously moving the
single-step breakpoint forward, one instruction at a
time. If the PC has changed, then the thread we were
trying to single-step has trapped or been signalled,
but the event has not been reported to GDB yet.
There might be some cases where this loses signal
information, if a signal has arrived at exactly the
same time that the PC changed, but this is the best
we can do with the information available. Perhaps we
should arrange to report all events for all threads
when they stop, or to re-poll the remote looking for
this particular thread (i.e. temporarily enable
schedlock). */
CORE_ADDR new_singlestep_pc
= regcache_read_pc (get_thread_regcache (singlestep_ptid));
if (new_singlestep_pc != singlestep_pc)
{
enum gdb_signal stop_signal;
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog, "infrun: unexpected thread,"
" but expected thread advanced also\n");
/* The current context still belongs to
singlestep_ptid. Don't swap here, since that's
the context we want to use. Just fudge our
state and continue. */
stop_signal = ecs->event_thread->suspend.stop_signal;
ecs->event_thread->suspend.stop_signal = GDB_SIGNAL_0;
ecs->ptid = singlestep_ptid;
ecs->event_thread = find_thread_ptid (ecs->ptid);
ecs->event_thread->suspend.stop_signal = stop_signal;
stop_pc = new_singlestep_pc;
}
else
{
if (debug_infrun)
fprintf_unfiltered (gdb_stdlog,
"infrun: unexpected thread\n");
thread_hop_needed = 1;
stepping_past_singlestep_breakpoint = 1;
saved_singlestep_ptid = singlestep_ptid;
}
}
}
we either end up with thread_hop_needed, ignoring the watchpoint
SIGTRAP, or switch to the stepping thread, again ignoring that the
SIGTRAP could be for some other event.
The new test added by this patch exercises both paths.
So the fix is similar to the deferred_step_ptid fix -- defer the
thread hop to _after_ the SIGTRAP had a change of passing through the
regular bpstat handling. If the wrong thread hits a breakpoint, we'll
just end up with BPSTAT_WHAT_SINGLE, and if nothing causes a stop,
keep_going starts a step-over.
Most of the stepping_past_singlestep_breakpoint mechanism is really
not necessary -- setting the thread to step over a breakpoint with
thread->trap_expected is sufficient to keep all other threads locked.
It's best to still keep the flag in some form though, because when we
get to keep_going, the software single-step breakpoint we need to step
over is already gone -- an optimization done by a follow up patch will
check whether a step-over is still be necessary by looking to see
whether the breakpoint is still there, and would find the thread no
longer needs a step-over, while we still want it.
Special care is still needed to handle the case of PC of the thread we
were trying to single-step having changed, like in the old code. We
can't just keep_going and re-step it, as in that case we can over-step
the thread (if it was already done with the step, but hasn't reported
it yet, we'd ask it to step even further). That's now handled in
switch_back_to_stepped_thread. As bonus, we're now using a technique
that doesn't lose signals, unlike the old code -- we now insert a
breakpoint at PC, and resume, which either reports the breakpoint
immediately, or any pending signal.
Tested on x86_64 Fedora 17, against pristine mainline, and against a
branch that implements software single-step on x86.
gdb/
2014-03-20 Pedro Alves <palves@redhat.com>
* breakpoint.c (single_step_breakpoint_inserted_here_p): Make
extern.
* breakpoint.h (single_step_breakpoint_inserted_here_p): Declare.
* infrun.c (saved_singlestep_ptid)
(stepping_past_singlestep_breakpoint): Delete.
(resume): Remove stepping_past_singlestep_breakpoint handling.
(proceed): Store the prev_pc of the stepping thread too.
(init_wait_for_inferior): Adjust. Clear singlestep_ptid and
singlestep_pc.
(enum infwait_states): Delete infwait_thread_hop_state.
(struct execution_control_state) <hit_singlestep_breakpoint>: New
field.
(handle_inferior_event): Adjust.
(handle_signal_stop): Delete stepping_past_singlestep_breakpoint
handling and the thread-hop code. Before removing single-step
breakpoints, check whether the thread hit a single-step breakpoint
of another thread. If it did, the trap is not a random signal.
(switch_back_to_stepped_thread): If the event thread hit a
single-step breakpoint, unblock it before switching to the
stepping thread. Handle the case of the stepped thread having
advanced already.
(keep_going): Handle the case of the current thread moving past a
single-step breakpoint.
gdb/testsuite/
2014-03-20 Pedro Alves <palves@redhat.com>
* gdb.threads/step-over-trips-on-watchpoint.c: New file.
* gdb.threads/step-over-trips-on-watchpoint.exp: New file.
Say the program is stopped at a breakpoint, and the user sets a
watchpoint. When the program is next resumed, GDB will first step
over the breakpoint, as explained in the manual:
@value {GDBN} normally ignores breakpoints when it resumes
execution, until at least one instruction has been executed. If it
it did not do this, you would be unable to proceed past a breakpoint
without first disabling the breakpoint. This rule applies whether
or not the breakpoint already existed when your program stopped.
However, GDB currently also removes watchpoints, catchpoints, etc.,
and that means that the first instruction off the breakpoint does not
trigger the watchpoint, catchpoint, etc.
testsuite/gdb.base/watchpoint.exp has a kfail for this.
The PR proposes installing watchpoints only when stepping over a
breakpoint, but that misses catchpoints, etc.
A better fix would instead work from the opposite direction -- remove
only real breakpoints, leaving all other kinds of breakpoints
inserted.
But, going further, it's really a waste to constantly remove/insert
all breakpoints when stepping over a single breakpoint (generating a
pair of RSP z/Z packets for each breakpoint), so the fix goes a step
further and makes GDB remove _only_ the breakpoint being stepped over,
leaving all others installed. This then has the added benefit of
reducing breakpoint-related RSP traffic substancialy when there are
many breakpoints set.
gdb/
2014-03-20 Pedro Alves <palves@redhat.com>
PR breakpoints/7143
* breakpoint.c (should_be_inserted): Don't insert breakpoints that
are being stepped over.
(breakpoint_address_match): Make extern.
* breakpoint.h (breakpoint_address_match): New declaration.
* inferior.h (stepping_past_instruction_at): New declaration.
* infrun.c (struct step_over_info): New type.
(step_over_info): New global.
(set_step_over_info, clear_step_over_info)
(stepping_past_instruction_at): New functions.
(handle_inferior_event): Clear the step-over info when
trap_expected is cleared.
(resume): Remove now stale comment.
(clear_proceed_status): Clear step-over info.
(proceed): Adjust step-over handling to set or clear the step-over
info instead of removing all breakpoints.
(handle_signal_stop): When setting up a thread-hop, don't remove
breakpoints here.
(stop_stepping): Clear step-over info.
(keep_going): Adjust step-over handling to set or clear step-over
info and then always inserting breakpoints, instead of removing
all breakpoints when stepping over one.
gdb/testsuite/
2014-03-20 Pedro Alves <palves@redhat.com>
PR breakpoints/7143
* gdb.base/watchpoint.exp: Mention bugzilla bug number instead of
old gnats gdb/38. Remove kfail. Adjust to use gdb_test instead
of gdb_test_multiple.
* gdb.cp/annota2.exp: Remove kfail for gdb/38.
* gdb.cp/annota3.exp: Remove kfail for gdb/38.
This patch is to remove parameter optional_p as it is always true,
in order to simplify get_tracepoint_by_number.
'optional_p' was added by this change,
1999-11-18 Tom Tromey <tromey@cygnus.com>
* tracepoint.h (get_tracepoint_by_number): Updated
declaration.
* tracepoint.c (trace_pass_command): Better error message.
Fixed logic when `all' not specified.
(get_tracepoint_by_number): Added `optional_p' argument. Fixed
all callers.
but after this patch,
FYI: remove `static's from cli-utils.c
https://sourceware.org/ml/gdb-patches/2011-03/msg00636.html
'optional_p' passed to get_tracepoint_by_number become always true.
gdb:
2014-03-06 Yao Qi <yao@codesourcery.com>
* breakpoint.c (get_tracepoint_by_number): Remove argument
optional_p. All callers updated. Adjust comments. Update
output message.
* breakpoint.h (get_tracepoint_by_number): Update declaration.
This changes the probes to be independent of the program space.
After this, when a probe's address is needed, it is determined by
applying offsets at the point of use.
This introduces a bound_probe object, similar to bound minimal
symbols. Objects of this type are used when it's necessary to pass a
probe and its corresponding objfile.
This removes the backlink from probe to objfile, which was primarily
used to fetch the architecture to use.
This adds a get_probe_address function which calls a probe method to
compute the probe's relocated address. Similarly, it adds an objfile
parameter to the semaphore methods so they can do the relocation
properly as well.
2014-03-03 Tom Tromey <tromey@redhat.com>
* break-catch-throw.c (fetch_probe_arguments): Use bound probes.
* breakpoint.c (create_longjmp_master_breakpoint): Use
get_probe_address.
(add_location_to_breakpoint, bkpt_probe_insert_location)
(bkpt_probe_remove_location): Update.
* breakpoint.h (struct bp_location) <probe>: Now a bound_probe.
* elfread.c (elf_symfile_relocate_probe): Remove.
(elf_probe_fns): Update.
(insert_exception_resume_breakpoint): Change type of "probe"
parameter to bound_probe.
(check_exception_resume): Update.
* objfiles.c (objfile_relocate1): Don't relocate probes.
* probe.c (bound_probe_s): New typedef.
(parse_probes): Use get_probe_address. Set sal's objfile.
(find_probe_by_pc): Return a bound_probe.
(collect_probes): Return a VEC(bound_probe_s).
(compare_probes): Update.
(gen_ui_out_table_header_info): Change type of "probes"
parameter. Update.
(info_probes_for_ops): Update.
(get_probe_address): New function.
(probe_safe_evaluate_at_pc): Update.
* probe.h (struct probe_ops) <get_probe_address>: New field.
<set_semaphore, clear_semaphore>: Add objfile parameter.
(struct probe) <objfile>: Remove field.
<arch>: New field.
<address>: Update comment.
(struct bound_probe): New.
(find_probe_by_pc): Return a bound_probe.
(get_probe_address): Declare.
* solib-svr4.c (struct probe_and_action) <address>: New field.
(hash_probe_and_action, equal_probe_and_action): Update.
(register_solib_event_probe): Add address parameter.
(solib_event_probe_at): Update.
(svr4_create_probe_breakpoints): Add objfile parameter. Use
get_probe_address.
* stap-probe.c (struct stap_probe) <sem_addr>: Update comment.
(stap_get_probe_address): New function.
(stap_can_evaluate_probe_arguments, compute_probe_arg)
(compile_probe_arg): Update.
(stap_set_semaphore, stap_clear_semaphore): Compute semaphore's
address.
(handle_stap_probe): Don't relocate the probe.
(stap_relocate): Remove.
(stap_gen_info_probes_table_values): Update.
(stap_probe_ops): Remove stap_relocate.
* symfile-debug.c (debug_sym_relocate_probe): Remove.
(debug_sym_probe_fns): Update.
* symfile.h (struct sym_probe_fns) <sym_relocate_probe>: Remove.
* symtab.c (init_sal): Use memset.
* symtab.h (struct symtab_and_line) <objfile>: New field.
* tracepoint.c (start_tracing, stop_tracing): Update.
* breakpoint.h (gdbpy_breakpoint_object): Renamed from
breakpoint_object. All uses updated.
* python/python-internal.h (gdbpy_breakpoint_object): Renamed from
breakpoint_object. All uses updated.
* python.c (*): All uses of breakpoint_object updated.
* python.h (*): All uses of breakpoint_object updated.
* python/py-breakpoint.c (*): All uses of breakpoint_object updated.
* python/py-finishbreakpoint.c (*): Ditto.
After the previous patch, there's actually no breakpoint type that
returns BPSTAT_SIGNAL_HIDE, so we can go back to having
bpstat_explains_signal return a boolean. The signal hiding actually
disappears.
gdb/
2013-11-14 Pedro Alves <palves@redhat.com>
* break-catch-sig.c (signal_catchpoint_explains_signal): Adjust to
return a boolean.
* breakpoint.c (bpstat_explains_signal): Adjust to return a
boolean.
(explains_signal_watchpoint, base_breakpoint_explains_signal):
Adjust to return a boolean.
* breakpoint.h (enum bpstat_signal_value): Delete.
(struct breakpoint_ops) <explains_signal>: New returns a boolean.
(bpstat_explains_signal): Likewise.
* infrun.c (handle_inferior_event) <random signal checks>:
bpstat_explains_signal now returns a boolean - adjust. No longer
consider hiding signals.
This patch introduces two new GDB/MI commands implementing the equivalent
of the "catch exception" and "catch assert" GDB/CLI commands.
gdb/ChangeLog:
* breakpoint.h (init_ada_exception_breakpoint): Add parameter
"enabled".
* breakpoint.c (init_ada_exception_breakpoint): Add parameter
"enabled". Set B->ENABLE_STATE accordingly.
* ada-lang.h (ada_exception_catchpoint_kind): Move here from
ada-lang.c.
(create_ada_exception_catchpoint): Add declaration.
* ada-lang.c (ada_exception_catchpoint_kind): Move to ada-lang.h.
(create_ada_exception_catchpoint): Make non-static. Add new
parameter "disabled". Use it in call to
init_ada_exception_breakpoint.
(catch_ada_exception_command): Add parameter "enabled" in call
to create_ada_exception_catchpoint.
(catch_assert_command): Likewise.
* mi/mi-cmds.h (mi_cmd_catch_assert, mi_cmd_catch_exception):
Add declarations.
* mi/mi-cmds.c (mi_cmds): Add the "catch-assert" and
"catch-exception" commands.
* mi/mi-cmd-catch.c: Add #include "ada-lang.h".
(mi_cmd_catch_assert, mi_cmd_catch_exception): New functions.
This fixes PR cli/15603.
The bug here is that when a software watchpoint is being used, gdb
will stop responding to C-c. This is a regression caused by the
"catch signal" patch.
The problem is that software watchpoints always end up on the bpstat
list. However, this makes bpstat_explains_signal return
BPSTAT_SIGNAL_HIDE, causing infrun to think that the signal is not a
"random signal".
The fix is to change bpstat_explains_signal to handle this better. I
chose to do it in a "clean API" way, by passing the signal value to
bpstat_explains_signal and then adding an explains_signal method for
watchpoints, which handles the specifics.
Built and regtested on x86-64 Fedora 18.
New test case included.
* break-catch-sig.c (signal_catchpoint_explains_signal): Add 'sig'
argument.
* breakpoint.c (bpstat_explains_signal): Add 'sig' argument.
Special case signals other than GDB_SIGNAL_TRAP.
(explains_signal_watchpoint): New function.
(base_breakpoint_explains_signal): Add 'sig' argument.
(initialize_breakpoint_ops): Set 'explains_signal' method for
watchpoints.
* breakpoint.h (struct breakpoint_ops) <explains_signal>: Add
signal argument.
(bpstat_explains_signal): Likewise.
* infrun.c (handle_syscall_event, handle_inferior_event): Update.
* gdb.base/random-signal.c: New file.
* gdb.base/random-signal.exp: New file.
* breakpoint.h (handle_solib_event): Moved function declaration
to solib.h.
* breakpoint.c (handle_solib_event): Moved function to solib.c.
(bpstat_stop_status): Pass new argument to handle_solib_event.
* solib.h (update_solib_breakpoints): New function declaration.
(handle_solib_event): Moved function declaration from
breakpoint.h.
* solib.c (update_solib_breakpoints): New function.
(handle_solib_event): Moved function from breakpoint.c.
Updated to call solib_ops->handle_event if not NULL.
* solist.h (target_so_ops): New fields "update_breakpoints" and
"handle_event".
* infrun.c (set_stop_on_solib_events): New function.
(_initialize_infrun): Use the above for "set
stop-on-solib-events".
(handle_inferior_event): Pass new argument to handle_solib_event.
* solib-svr4.c (probe.h): New include.
(svr4_free_library_list): New forward declaration.
(probe_action): New enum.
(probe_info): New struct.
(probe_info): New static variable.
(NUM_PROBES): New definition.
(svr4_info): New fields "using_xfer", "probes_table" and
"solib_list".
(free_probes_table): New function.
(free_solib_list): New function.
(svr4_pspace_data_cleanup): Free probes table and solib list.
(svr4_copy_library_list): New function.
(svr4_current_sos_via_xfer_libraries): New parameter "annex".
(svr4_read_so_list): New parameter "prev_lm".
(svr4_current_sos_direct): Renamed from "svr4_current_sos".
(svr4_current_sos): New function.
(probe_and_action): New struct.
(hash_probe_and_action): New function.
(equal_probe_and_action): Likewise.
(register_solib_event_probe): Likewise.
(solib_event_probe_at): Likewise.
(solib_event_probe_action): Likewise.
(solist_update_full): Likewise.
(solist_update_incremental): Likewise.
(disable_probes_interface_cleanup): Likewise.
(svr4_handle_solib_event): Likewise.
(svr4_update_solib_event_breakpoint): Likewise.
(svr4_update_solib_event_breakpoints): Likewise.
(svr4_create_solib_event_breakpoints): Likewise.
(enable_break): Free probes table before creating breakpoints.
Use svr4_create_solib_event_breakpoints to create breakpoints.
(svr4_solib_create_inferior_hook): Free the solib list.
(_initialize_svr4_solib): Initialise
svr4_so_ops.handle_solib_event and svr4_so_ops.update_breakpoints.
If !PARSE_CONDITION_AND_THREAD, then ARG is just the location, nothing
else. The fact that the describing comment of create_breakpoint
doesn't mention this just looks like an oversight of when extra_string
was added. "parse_condition_and_thread" has been a misnomer ever
since extra_string was added -- better rename it avoid more confusion.
This makes it "parse_arg", as that'll remain stable even if/when more
explicit parameters are added.
gdb/
2013-04-08 Pedro Alves <palves@redhat.com>
Keith Seitz <keiths@redhat.com>
* breakpoint.c (create_breakpoint): Rename
"parse_condition_and_thread" parameter to "parse_arg". Update
describing comment. If !PARSE_ARG, then error out if ARG is not
the empty string after extracting the location.
* breakpoint.h (create_breakpoint): Rename
"parse_condition_and_thread" parameter to "parse_arg".
gdb/testsuite/
2013-04-08 Pedro Alves <palves@redhat.com>
* gdb.mi/mi-break.exp (test_error): Add tests with garbage after
the location.
Code cleanup.
* breakpoint.c (print_breakpoint_location): Replace bp_location field
source_file references by symtab field references. Remove variables
sal and fullname.
(momentary_breakpoint_from_master, add_location_to_breakpoint):
(clear_command, say_where): Replace bp_location field source_file
references by symtab field references.
(bp_location_dtor): Remove the source_file reference.
(update_static_tracepoint): Replace bp_location field source_file
references by symtab field references.
(breakpoint_free_objfile): New function.
* breakpoint.h (struct bp_location): Extend the comment for line_number.
Replace the field source_file by field symtab, extend its comment.
(breakpoint_free_objfile): New declaration.
* objfiles.c (free_objfile): Call breakpoint_free_objfile.
* tui/tui-winsource.c (tui_update_breakpoint_info): Replace bp_location
field source_file references by symtab field references.
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.
They are equivalent to "catch load" and "catch unload" from CLI.
Rationale: GUIs might be interested in catching solib load or
unload events.
2012-11-16 Mircea Gherzan <mircea.gherzan@intel.com>
* Makefile.in (SUBDIR_MI_OBS): Add mi-cmd-catch.o.
(SUBDIR_MI_SRCS): Add mi/mi-cmd-catch.c.
* breakpoint.c (add_solib_catchpoint): New function that
can be used by both CLI and MI, factored out from
catch_load_or_unload.
(catch_load_or_unload): Strip it down and make it use the
new add_solib_catchpoint.
* breakpoint.h (add_solib_catchpoint): Declare it.
* mi/mi-cmd-break.h: New file.
* mi/mi-cmd-break.c: Include mi-cmd-break.h.
(setup_breakpoint_reporting): New function used for both
catchpoints and breakpoints.
(mi_cmd_break_insert): Use setup_breakpoint_reporting.
* mi/mi-cmd-catch.c: New file.
* mi/mi-cmds.c (mi_cmds): Add the handlers for -catch-load
and -catch-unload.
* mi/mi-cmds.h: Declare the handlers for -catch-load and
-catch-unload.
Before this change, detach_breakpoints would take a pid, and then
set inferior_ptid to a ptid that it constructs using pid_to_ptid (pid).
Unfortunately, this ptid is not necessarily valid. Consider for
instance the case of ia64-hpux, where ttrace refuses a register-read
operation if the LWP is not provided.
This problems shows up when GDB is trying to handle fork events.
Assuming GDB is configured to follow the parent, GDB will try to
detach from the child. But before doing so, it needs to remove
all breakpoints inside that child. On ia64, this involves reading
inferior (the child's) memory. And on ia64-hpux, reading memory
requires us to read the bsp and bspstore registers, in order to
determine where that memory is relative to the value of those
registers, and thus to determine which ttrace operation to use in
order to fetch that memory (see ia64_hpux_xfer_memory).
This patch therefore changes detach_breakpoints to take a ptid instead
of a pid, and then updates all callers.
One of the consequences of this patch is that it trips an assert
on GNU/Linux targets. But this assert appears to have not actual
purpose, and is thus removed.
gdb/ChangeLog:
* breakpoint.h (detach_breakpoints): pid parameter is now a ptid.
* breakpoint.c (detach_breakpoints): Change pid parameter into
a ptid. Adjust code accordingly.
* infrun.c (handle_inferior_event): Delete variable child_pid.
Update call to detach_breakpoints to pass the child ptid for
fork events.
* linux-nat.c (linux_nat_iterate_watchpoint_lwps): Remove
assert that inferior_ptid's lwp is zero.
(linux_handle_extended_wait): Update call to detach_breakpoints.
* inf-ttrace.c (inf_ttrace_follow_fork): Update call to
detach_breakpoints.
Remove stale dummy frames.
* breakpoint.c: Include dummy-frame.h.
(longjmp_breakpoint_ops): New variable.
(update_breakpoints_after_exec, breakpoint_init_inferior): Delete also
bp_longjmp_call_dummy.
(bpstat_what, bptype_string, print_one_breakpoint_location)
(init_bp_location): Support bp_longjmp_call_dummy.
(set_longjmp_breakpoint): Use longjmp_breakpoint_ops. Comment why.
(set_longjmp_breakpoint_for_call_dummy)
(check_longjmp_breakpoint_for_call_dummy, longjmp_bkpt_dtor): New
functions.
(initialize_breakpoint_ops): Initialize longjmp_breakpoint_ops.
* breakpoint.h (enum bptype): New item bp_longjmp_call_dummy. Delete
FIXME comment and extend the other comment for bp_call_dummy.
(set_longjmp_breakpoint_for_call_dummy)
(check_longjmp_breakpoint_for_call_dummy): New declarations.
* dummy-frame.c: Include gdbthread.h.
(pop_dummy_frame_bpt): New function.
(pop_dummy_frame): Call pop_dummy_frame_bpt.
(dummy_frame_discard): New function.
(cleanup_dummy_frames): Update the comment about longjmps.
* dummy-frame.h (dummy_frame_discard): New declaration.
* gdbthread.h (struct thread_info): Extend initiating_frame comment.
* infcall.c (call_function_by_hand): New variable longjmp_b. Call
set_longjmp_breakpoint_for_call_dummy. Chain its breakpoints with BPT.
* infrun.c (handle_inferior_event) <BPSTAT_WHAT_CLEAR_LONGJMP_RESUME>:
Add case 4 comment. Call check_longjmp_breakpoint_for_call_dummy and
keep_going if IS_LONGJMP and there is no other reason to stop.
gdb/testsuite/
Remove stale dummy frames.
* gdb.base/call-signal-resume.exp (maintenance print dummy-frames)
(maintenance info breakpoints): New tests.
* gdb.base/stale-infcall.c: New file.
* gdb.base/stale-infcall.exp: New file.
* breakpoint.h: Include command.h.
(add_catch_command): Use completer_ftype.
* cli/cli-decode.c (set_cmd_completer): Use completer_ftype.
* cli/cli-decode.h (struct cmd_list_element) <completer>:
Use completer_ftype.
* command.h (completer_ftype): New typedef.
(set_cmd_completer): Use it.
* python/py-cmd.c (struct cmdpy_completer) <completer>: Use
completer_ftype.
* breakpoint.h (bp_location): Add related_address member.
* inferior.h (get_return_value): Take a pointer to struct value
instead of struct type for the function requested.
* value.h (using_struct_return): Likewise.
* gdbarch.sh (return_value): Take a pointer to struct value
instead of struct type for the function requested.
* breakpoint.c (set_breakpoint_location_function): Initialize
related_address for bp_gnu_ifunc_resolver breakpoints.
* elfread.c (elf_gnu_ifunc_resolver_return_stop): Pass the
requested function's address to gdbarch_return_value.
* eval.c (evaluate_subexp_standard): Pass the requested
function's address to using_struct_return.
* infcall.c (call_function_by_hand): Pass the requested
function's address to using_struct_return and
gdbarch_return_value.
* infcmd.c (get_return_value): Take a pointer to struct value
instead of struct type for the function requested.
(print_return_value): Update accordingly.
(finish_command_continuation): Likewise.
* stack.c (return_command): Pass the requested function's
address to using_struct_return and gdbarch_return_value.
* value.c (using_struct_return): Take a pointer to struct value
instead of struct type for the function requested. Pass the
requested function's address to gdbarch_return_value.
* python/py-finishbreakpoint.c (finish_breakpoint_object):
New function_value member, replacing function_type.
(bpfinishpy_dealloc): Update accordingly.
(bpfinishpy_pre_stop_hook): Likewise.
(bpfinishpy_init): Likewise. Record the requested function's
address.
* mips-tdep.c (mips_fval_reg): New enum.
(mips_o32_push_dummy_call): For MIPS16 FP doubles do not swap
words put in GP registers.
(mips_o64_push_dummy_call): Update a comment.
(mips_o32_return_value): Take a pointer to struct value instead
of struct type for the function requested and use it to check if
using the MIPS16 calling convention. Return the designated
general purpose registers for floating-point values returned in
MIPS16 mode.
(mips_o64_return_value): Likewise.
* ppc-tdep.h (ppc_sysv_abi_return_value): Update prototype.
(ppc_sysv_abi_broken_return_value): Likewise.
(ppc64_sysv_abi_return_value): Likewise.
* alpha-tdep.c (alpha_return_value): Take a pointer to struct
value instead of struct type for the function requested.
* amd64-tdep.c (amd64_return_value): Likewise.
* amd64-windows-tdep.c (amd64_windows_return_value): Likewise.
* arm-tdep.c (arm_return_value): Likewise.
* avr-tdep.c (avr_return_value): Likewise.
* bfin-tdep.c (bfin_return_value): Likewise.
* cris-tdep.c (cris_return_value): Likewise.
* frv-tdep.c (frv_return_value): Likewise.
* h8300-tdep.c (h8300_return_value): Likewise.
(h8300h_return_value): Likewise.
* hppa-tdep.c (hppa32_return_value): Likewise.
(hppa64_return_value): Likewise.
* i386-tdep.c (i386_return_value): Likewise.
* ia64-tdep.c (ia64_return_value): Likewise.
* iq2000-tdep.c (iq2000_return_value): Likewise.
* lm32-tdep.c (lm32_return_value): Likewise.
* m32c-tdep.c (m32c_return_value): Likewise.
* m32r-tdep.c (m32r_return_value): Likewise.
* m68hc11-tdep.c (m68hc11_return_value): Likewise.
* m68k-tdep.c (m68k_return_value): Likewise.
(m68k_svr4_return_value): Likewise.
* m88k-tdep.c (m88k_return_value): Likewise.
* mep-tdep.c (mep_return_value): Likewise.
* microblaze-tdep.c (microblaze_return_value): Likewise.
* mn10300-tdep.c (mn10300_return_value): Likewise.
* moxie-tdep.c (moxie_return_value): Likewise.
* mt-tdep.c (mt_return_value): Likewise.
* ppc-linux-tdep.c (ppc_linux_return_value): Likewise.
* ppc-sysv-tdep.c (ppc_sysv_abi_return_value): Likewise.
(ppc_sysv_abi_broken_return_value): Likewise.
(ppc64_sysv_abi_return_value): Likewise.
* ppcnbsd-tdep.c (ppcnbsd_return_value): Likewise.
* rl78-tdep.c (rl78_return_value): Likewise.
* rs6000-aix-tdep.c (rs6000_return_value): Likewise.
* rx-tdep.c (rx_return_value): Likewise.
* s390-tdep.c (s390_return_value): Likewise.
* score-tdep.c (score_return_value): Likewise.
* sh-tdep.c (sh_return_value_nofpu): Likewise.
(sh_return_value_fpu): Likewise.
* sh64-tdep.c (sh64_return_value): Likewise.
* sparc-tdep.c (sparc32_return_value): Likewise.
* sparc64-tdep.c (sparc64_return_value): Likewise.
* spu-tdep.c (spu_return_value): Likewise.
* tic6x-tdep.c (tic6x_return_value): Likewise.
* v850-tdep.c (v850_return_value): Likewise.
* vax-tdep.c (vax_return_value): Likewise.
* xstormy16-tdep.c (xstormy16_return_value): Likewise.
* xtensa-tdep.c (xtensa_return_value): Likewise.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
gdb/testsuite/
* gdb.base/return-nodebug.exp: Also test float and double types.
Revert this patch to allow breakpoint always-inserted
in record target.
2011-12-05 Pedro Alves <pedro@codesourcery.com>
* breakpoint.c: Include record.h.
(breakpoints_always_inserted_mode): Return false when the record
target is in use.
* breakpoint.c (iterate_over_bp_locations): New.
* breakpoint.h: Declare.
New typedef walk_bp_location_callback.
* record.c (record_open): Call record_init_record_breakpoints.
(record_sync_record_breakpoints): New.
(record_init_record_breakpoints): New.
* NEWS: Mention supporting breakpoint always-inserted mode in
record target.
Pedro Alves <palves@redhat.com>
PR breakpoints/13776:
* breakpoint.c (breakpoint_init_inferior): Delete step-resume
breakpoints.
(delete_longjmp_breakpoint_at_next_stop): New.
* breakpoint.h (delete_longjmp_breakpoint_at_next_stop): Declare.
* target.c (generic_mourn_inferior): Call mark_breakpoints_out
before deleting the inferior. Add comments.
* thread.c (clear_thread_inferior_resources): Don't delete lonjmp
breakpoints immediately, but only on next stop. Move that code
next to where we mark other breakpoints for deletion.
* remote.c (remote_supports_cond_breakpoints): New forward
declaration.
(remote_add_target_side_condition): New function.
(remote_insert_breakpoint): Add target-side breakpoint
conditional if supported.
(remote_insert_hw_breakpoint): Likewise.
(init_remote_ops): Set to_supports_evaluation_of_breakpoint_conditions
hook.
* target.c (update_current_target): Inherit
to_supports_evaluation_of_breakpoint_conditions.
Default to_supports_evaluation_of_breakpoint_conditions to return_zero.
* target.h (struct target_ops)
<to_supports_evaluation_of_breakpoint_conditions>: New field.
(target_supports_evaluation_of_breakpoint_conditions): New #define.
* breakpoint.c (get_first_locp_gte_addr): New forward declaration.
(condition_evaluation_both, condition_evaluation_auto,
condition_evaluation_host, condition_evaluation_target,
condition_evaluation_enums, condition_evaluation_mode_1,
condition_evaluation_mode): New static globals.
(translate_condition_evaluation_mode): New function.
(breakpoint_condition_evaluation_mode): New function.
(gdb_evaluates_breakpoint_condition_p): New function.
(ALL_BP_LOCATIONS_AT_ADDR): New helper macro.
(mark_breakpoint_modified): New function.
(mark_breakpoint_location_modified): New function.
(set_condition_evaluation_mode): New function.
(show_condition_evaluation_mode): New function.
(bp_location_compare_addrs): New function.
(get_first_location_gte_addr): New helper function.
(set_breakpoint_condition): Free condition bytecode if locations
has become unconditional. Call mark_breakpoint_modified (...).
(condition_command): Call update_global_location_list (1) for
breakpoints.
(breakpoint_xfer_memory): Use is_breakpoint (...).
(is_breakpoint): New function.
(parse_cond_to_aexpr): New function.
(build_target_condition_list): New function.
(insert_bp_location): Handle target-side conditional
breakpoints and call build_target_condition_list (...).
(update_inserted_breakpoint_locations): New function.
(insert_breakpoint_locations): Handle target-side conditional
breakpoints.
(bpstat_check_breakpoint_conditions): Add comment.
(bp_condition_evaluator): New function.
(bp_location_condition_evaluator): New function.
(print_breakpoint_location): Print information on where the condition
will be evaluated.
(print_one_breakpoint_location): Likewise.
(init_bp_location): Call mark_breakpoint_location_modified (...) for
breakpoint location.
(force_breakpoint_reinsertion): New functions.
(update_global_location_list): Handle target-side breakpoint
conditions.
Reinsert locations that are already inserted if conditions have
changed.
(bp_location_dtor): Free agent expression bytecode.
(disable_breakpoint): Call mark_breakpoint_modified (...).
Call update_global_location_list (...) with parameter 1 for breakpoints.
(disable_command): Call mark_breakpoint_location_modified (...).
Call update_global_location_list (...) with parameter 1 for breakpoints.
(enable_breakpoint_disp): Call mark_breakpoint_modified (...).
(enable_command): mark_breakpoint_location_modified (...).
(_initialize_breakpoint): Update documentation and add
condition-evaluation breakpoint subcommand.
* breakpoint.h: Include ax.h.
(condition_list): New data structure.
(condition_status): New enum.
(bp_target_info) <cond_list>: New field.
(bp_location) <condition_changed, cond_bytecode>: New fields.
(is_breakpoint): New prototype.
* solib.c (update_solib_list): Update the program space's
added_solibs and deleted_solibs fields.
* progspace.h (struct program_space) <added_solibs,
deleted_solibs>: New fields.
(clear_program_space_solib_cache): Declare.
* progspace.c (release_program_space): Call
clear_program_space_solib_cache.
(clear_program_space_solib_cache): New function.
* infrun.c (handle_inferior_event) <TARGET_WAITKIND_LOADED>: Call
bpstat_stop_status. Use handle_solib_event.
* breakpoint.c: Include gdb_regex.h.
(print_solib_event): New function.
(bpstat_print): Use print_solib_event.
(bpstat_stop_status): Add special case for bp_shlib_event.
(handle_solib_event): New function.
(bpstat_what): Use handle_solib_event.
(struct solib_catchpoint): New.
(dtor_catch_solib, insert_catch_solib, remove_catch_solib)
(breakpoint_hit_catch_solib, check_status_catch_solib)
(print_it_catch_solib, print_one_catch_solib)
(print_mention_catch_solib, print_recreate_catch_solib): New
functions.
(catch_solib_breakpoint_ops): New global.
(catch_load_or_unload, catch_load_command_1)
(catch_unload_command_1): New functions.
(internal_bkpt_check_status): Add special case for
bp_shlib_event.
(internal_bkpt_print_it): Use print_solib_event.
(initialize_breakpoint_ops): Initialize
catch_solib_breakpoint_ops.
(_initialize_breakpoint): Register "catch load" and "catch
unload".
* breakpoint.h (handle_solib_event): Declare.
* NEWS: Add entry for "catch load" and "catch unload".
gdb/doc
* gdb.texinfo (Set Catchpoints): Document "catch load" and "catch
unload".
(Files): Mention new catch commands.
(GDB/MI Async Records): Likewise.
gdb/testsuite
* lib/mi-support.exp (mi_expect_stop): Add special case for
solib-event.
* gdb.base/catch-load-so.c: New file.
* gdb.base/catch-load.exp: New file.
* gdb.base/catch-load.c: New file.
* gdb.base/break-interp.exp (reach_1): Update regexp.
* breakpoint.c (create_sals_from_address_default): New function.
(create_breakpoints_sal_default): Likewise.
(decode_linespec_default): Likewise.
(is_marker_spec): Removed.
(strace_marker_p): New function.
(init_breakpoint_sal): Using `strace_marker_p' instead of
`is_marker_spec'.
(create_breakpoint): Call method `create_sals_from_address' from
breakpoint_ops, replacing code that created SALs conditionally
on the type of the breakpoint. Call method `create_breakpoints_sal',
replacing code that created breakpoints conditionally on the type
wanted.
(base_breakpoint_create_sals_from_address): New function.
(base_breakpoint_create_breakpoints_sal): Likewise.
(base_breakpoint_decode_linespec): Likewise.
(base_breakpoint_ops): Add methods
`base_breakpoint_create_sals_from_address',
`base_breakpoint_create_breakpoints_sal' and
`base_breakpoint_decode_linespec'.
(bkpt_create_sals_from_address): New function.
(bkpt_create_breakpoints_sal): Likewise.
(bkpt_decode_linespec): Likewise.
(tracepoint_create_sals_from_address): Likewise.
(tracepoint_create_breakpoints_sal): Likewise.
(tracepoint_decode_linespec): Likewise.
(strace_marker_create_sals_from_address): Likewise.
(strace_marker_create_breakpoints_sal): Likewise.
(strace_marker_decode_linespec): Likewise.
(strace_marker_breakpoint_ops): New variable.
(addr_string_to_sals): Remove `marker_spec'. Call method
`decode_linespec' from breakpoint_ops, replacing code that decoded
an address string into a SAL. Use `strace_marker_p' instead of
`marker_spec'.
(strace_command): Decide whether we are dealing with a static
tracepoint with marker or not. Use the appropriate breakpoint_ops.
(initialize_breakpoint_ops): Initialize new fields of breakpoint_ops.
* breakpoint.h (linespec_result, linespec_sals): New forward
declarations.
(breakpoint_ops) <create_sals_from_address>,
<create_breakpoints_sal>, <decode_linespec>: New methods.
* Makefile.in (SUBDIR_PYTHON_OBS): Add py-finishbreakpoint.o.
(SUBDIR_PYTHON_SRCS): Add python/py-finishbreakpoint.c.
Add build rule for this file.
* infcmd.c (print_return_value): Split to create get_return_value.
(get_return_value): New function based on print_return_value. Handle
case where stop_registers are not set.
* inferior.h (get_return_value): New prototype.
* python/py-breakpoint.c (bppy_pending_object): Make non-static.
(gdbpy_breakpoint_created): Set is_py_finish_bp is necessary.
(struct breakpoint_object): Move to python-internal.h
(BPPY_REQUIRE_VALID): Likewise.
(BPPY_SET_REQUIRE_VALID): Likewise.
(gdbpy_breakpoint_created): Initialize is_finish_bp.
(gdbpy_should_stop): Add pre/post hooks before/after calling stop
method.
* python/python-internal.h (breakpoint_object_type): Add as extern.
(bppy_pending_object): Likewise.
(typedef struct breakpoint_object) Removed.
(struct breakpoint_object): Moved from py-breakpoint.c.
Add field is_finish_bp.
(BPPY_REQUIRE_VALID): Moved from py-breakpoint.c.
(BPPY_SET_REQUIRE_VALID): Likewise.
(frame_object_to_frame_info): New prototype.
(gdbpy_initialize_finishbreakpoints): New prototype.
(bpfinishpy_is_finish_bp): Likewise.
(bpfinishpy_pre_stop_hook): Likewise.
(bpfinishpy_post_stop_hook): Likewise.
* python/py-finishbreakpoint.c: New file.
* python/py-frame.c(frame_object_to_frame_info): Make non-static and
accept PyObject instead of frame_object.
(frapy_is_valid): Don't cast to frame_object.
(frapy_name): Likewise.
(frapy_type): Likewise.
(frapy_unwind_stop_reason): Likewise.
(frapy_pc): Likewise.
(frapy_block): Likewise.
(frapy_function): Likewise.
(frapy_older): Likewise.
(frapy_newer): Likewise.
(frapy_find_sal): Likewise.
(frapy_read_var): Likewise.
(frapy_select): Likewise.
* python/python.c (gdbpy_is_stopped_at_finish_bp): New noop function.
(_initialize_python): Add gdbpy_initialize_finishbreakpoints.
* python/python.h: Include breakpoint.h
(gdbpy_is_stopped_at_finish_bp): New prototype.
doc/
* gdb.texinfo (Finish Breakpoints in Python): New subsection.
(Python API): Add menu entry for Finish Breakpoints.
testsuite/
* Makefile.in (EXECUTABLES): Add py-finish-breakpoint and
py-finish-breakpoint2
(MISCALLANEOUS): Add py-events-shlib.so and py-events-shlib-nodebug.so
* gdb.python/py-breakpoint.exp (mult_line): Define and use variable
instead of line number.
* gdb.python/py-finish-breakpoint.c: New file.
* gdb.python/py-finish-breakpoint.exp: New file.
* gdb.python/py-finish-breakpoint.py: New file.
* gdb.python/py-finish-breakpoint2.cc: New file.
* gdb.python/py-finish-breakpoint2.exp: New file.
* gdb.python/py-finish-breakpoint2.py: New file.
* breakpoint.h (struct tracepoint): New field traceframe_usage.
* breakpoint.c (print_one_breakpoint_location): Identify
tracepoints as such when reporting hit counts, report
trace buffer usage.
(create_tracepoint_from_upload): Copy status info.
* tracepoint.h (struct trace_status): Rename error_desc to stop_desc,
add fields user_name, notes, start_time, stop_time.
(struct uploaded_tp): Add fields hit_count, traceframe_usage.
* tracepoint.c (trace_user): New global.
(trace_notes): New global.
(trace_stop_notes): New global.
(start_tracing): Add argument and trace note handling.
(stop_tracing): Ditto.
(trace_start_command): Add notes argument.
(trace_stop_command): Ditto.
(trace_status_command): Report additional status info.
(trace_status_mi): Similarly.
(trace_save): Update, record tracepoint status.
(set_disconnected_tracing): Call target method directly.
(send_disconnected_tracing_value): Remove.
(set_trace_user): New function.
(set_trace_notes): New function.
(set_trace_stop_notes): New function.
(parse_trace_status): Handle additional status.
(parse_tracepoint_status): New function.
(parse_tracepoint_definition): Call it.
(tfile_get_tracepoint_status): New function.
(init_tfile_ops): Use it.
(_initialize_tracepoint): Add new setshows.
* target.h (struct target_ops): New methods to_get_tracepoint_status
and to_set_trace_notes.
(target_get_tracepoint_status): New macro.
(target_set_trace_notes): New macro.
* target.c (update_current_target): Add new methods.
* remote.c (remote_get_tracepoint_status): New function.
(remote_set_trace_notes): New function.
(init_remote_ops): Add them.
* mi/mi-main.c (mi_cmd_trace_start): Add argument to call.
(mi_cmd_trace_stop): Ditto.
* tracepoint.c (struct tracepoint): New field traceframe_usage.
(tracing_start_time): New global.
(tracing_stop_time): New global.
(tracing_user_name): New global.
(tracing_notes): New global.
(tracing_stop_note): New global.
(cmd_qtstart): Set traceframe_usage, start_time.
(stop_tracing): Set stop_time.
(cmd_qtstatus): Report additional status.
(cmd_qtp): New function.
(handle_tracepoint_query): Call it.
(cmd_qtnotes): New function.
(handle_tracepoint_general_set): Call it.
(get_timestamp): Rename from tsv_get_timestamp.
* gdb.texinfo (Starting and Stopping Trace Experiments): Document
note-related options and variables.
(Tracepoint Packets): Document packet changes.
* gdb.trace/tstatus.exp: New.
* gdb.trace/actions.c: Include string.h.
* breakpoint.h (pc_at_non_inline_function): Declare.
* breakpoint.c (is_non_inline_function,
pc_at_non_inline_function): New functions.
* infrun.c (handle_inferior_event): Don't call skip_inline_frames
if the stop is at a location where functions cannot be inlined.
No functionality change.
* breakpoint.c (bpstat_clear_actions): Remove the BS parameter, make
function comment a reference, new variables tp and bs, move here code
from throw_exception.
* breakpoint.h (bpstat_clear_actions): Remove the BS parameter,
describe it in the comment.
* exceptions.c (throw_exception): Remove variable tp, move the code for
bpstat_clear_actions to bpstat_clear_actions.
Code cleanup.
* breakpoint.c (bpstat_clear_actions): Remove clearing of commands_left.
(command_line_is_silent): New function.
(bpstat_do_actions_1): No longer use commands_left, use
command_line_is_silent for commands.
(bpstat_alloc): Remove clearing of commands_left.
(bpstat_stop_status): Remove initialization of commands_left, use
command_line_is_silent.
* breakpoint.h (struct bpstats): Remove commands_left.
Implement most breakpoint_ops methods for all breakpoint types,
and move the default handlings to the proper callbacks.
gdb/
* breakpoint.c (update_watchpoint): Always call the breakpoint's
works_in_software_mode method.
(insert_bp_location): Go through breakpoint_ops->insert_location
for software and hardware watchpoints.
(create_internal_breakpoint): Pass bkpt_breakpoint_ops as
breakpoint_ops.
(remove_breakpoint_1): Go through breakpoint_ops->remove_location
for software and hardware watchpoints.
(print_it_typical): Delete.
(print_bp_stop_message): Always call the breakpoint_ops->print_it
method.
(watchpoint_check): Adjust comment.
(bpstat_check_location): Simply always call the breakpoint's
breakpoint_hit method.
(bpstat_stop_status): Always call the breakpoint's check_status
method. Remove special cases for watchpoints and internal event
breakpoints from here (moved to the check_status implementations).
(print_one_breakpoint_location): Assume b->ops is never NULL.
Remove static tracepoint marker id printing from here (moved to
the print_one_detail callback implementation of tracepoints).
(init_bp_location): Assert OPS is never NULL.
(allocate_bp_location): Always call the breakpoint's
allocate_location method, and remove the default code from here.
(free_bp_location): Always call the location's dtor method, and
remove the default code from here.
(init_raw_breakpoint_without_location): Assert OPS is never NULL.
(set_raw_breakpoint_without_location): Add new breakpoint_ops
parameter. Pass it down.
(set_raw_breakpoint): Ditto.
(print_it_catch_fork): Adjust to take a bpstat as argument.
(catch_fork_breakpoint_ops): Install methods.
(print_it_catch_vfork): Adjust to take a bpstat as argument.
(catch_vfork_breakpoint_ops): Install methods.
(dtor_catch_syscall): Call the base dtor.
(print_it_catch_syscall): Adjust to take a bpstat as argument.
(catch_syscall_breakpoint_ops): Install methods.
(dtor_catch_exec): Call the base dtor.
(print_it_catch_exec): Adjust to take a bpstat as argument.
(catch_exec_breakpoint_ops): Install methods.
(hw_breakpoint_used_count, hw_watchpoint_used_count): Always call
the breakpoint's resources_needed method, and remove the default
code from here.
(set_momentary_breakpoint): Pass bkpt_breakpoint_ops as
breakpoint_ops.
(clone_momentary_breakpoint): Clone the original's ops.
(mention): Always call the breakpoint's print_mention method, and
remove the default code from here.
(create_breakpoint_sal): Adjust to pass the ops to
set_raw_breakpoint rather than setting it manually.
(create_breakpoint): Assert ops is never NULL. Adjust to pass the
ops to set_raw_breakpoint_without_location rather than setting it
manually.
(break_command_1): Pass bkpt_breakpoint_ops as breakpoint_ops.
(print_it_ranged_breakpoint): Adjust to take a bpstat as argument.
(ranged_breakpoint_ops): Install methods.
(break_range_command): Adjust to pass the ops to
set_raw_breakpoint rather than setting it manually.
(re_set_watchpoint, breakpoint_hit_watchpoint)
(check_status_watchpoint, resources_needed_watchpoint)
(works_in_software_mode_watchpoint, print_it_watchpoint)
(print_mention_watchpoint, print_recreate_watchpoint): New
functions.
(watchpoint_breakpoint_ops): Install new methods.
(print_it_masked_watchpoint): New function.
(masked_watchpoint_breakpoint_ops): Install new methods.
(watch_command_1): Adjust to pass the right breakpoint_ops to
set_raw_breakpoint_without_location rather than setting it
manually later. Record the current pspace.
(print_it_exception_catchpoint): Adjust to take a bpstat as
argument.
(gnu_v3_exception_catchpoint_ops): Install new methods.
(say_where): New function.
(null_re_set, null_check_status, null_works_in_software_mode)
(null_resources_needed, null_print_one_detail, bp_location_dtor):
New functions.
(bp_location_ops): New global.
(bkpt_dtor, bkpt_allocate_location, bkpt_re_set)
(bkpt_insert_location, bkpt_remove_location, bkpt_breakpoint_hit)
(bkpt_check_status, bkpt_resources_needed)
(bkpt_works_in_software_mode, bkpt_print_it, bkpt_print_mention)
(bkpt_print_recreate): New functions.
(bkpt_breakpoint_ops): New global.
(tracepoint_re_set, tracepoint_insert_location)
(tracepoint_remove_location, tracepoint_breakpoint_hit)
(tracepoint_check_status, tracepoint_works_in_software_mode)
(tracepoint_print_it, tracepoint_print_one_detail)
(tracepoint_print_mention, tracepoint_print_recreate): New
functions.
(tracepoint_breakpoint_ops): New global.
(delete_breakpoint): Always call the breakpoint's dtor method, and
remove the default handling from here.
(breakpoint_re_set_default): Make static.
(breakpoint_re_set_one): Always call the breakpoints re_set
method, and remove the default handling from here.
(trace_command, ftrace_command, strace_command)
(create_tracepoint_from_upload): Pass appropriate breakpoints_ops
to create_breakpoint.
(save_breakpoints): Always call the breakpoint's print_recreate
method, and remove the default handling from here.
* ada-lang.c (dtor_exception): Call the base dtor.
(re_set_exception): Call the base method.
(print_it_exception, print_it_catch_exception): Adjust to take a
bpstat as argument.
(catch_exception_breakpoint_ops): Install methods.
(print_it_catch_exception_unhandled): Adjust to take a bpstat as
argument.
(catch_exception_unhandled_breakpoint_ops): Install methods.
(print_it_catch_assert): Adjust to take a bpstat as argument.
(catch_assert_breakpoint_ops): Install methods.
* breakpoint.h (struct breakpoint_ops): Adjust the print_it method
to take a bpstat as argument.
(enum print_stop_action): Add describing comments to each enum
value.
(breakpoint_re_set_default): Delete declaration.
(null_re_set, null_works_in_software_mode, null_resources_needed)
(null_check_status, null_print_one_detail): Declare.
(bkpt_breakpoint_ops): Declare.
(bkpt_dtor, bkpt_allocate_location, bkpt_re_set)
(bkpt_insert_location, bkpt_remove_location, bkpt_breakpoint_hit)
(bkpt_check_status, bkpt_resources_needed)
(bkpt_works_in_software_mode, bkpt_print_it)
(null_print_one_detail, bkpt_print_mention, bkpt_print_recreate):
Declare.
* mi/mi-cmd-break.c (mi_cmd_break_insert): Adjust to pass
bkpt_breakpoint_ops.
* python/py-breakpoint.c (bppy_init): Ditto.
* breakpoint.c (bpstat_stop_status): Call the check_status
breakpoint_ops method.
(print_one_breakpoint_location): Also print the condition for Ada
exception catchpoints.
(allocate_bp_location): New, factored out from
allocate_bp_location.
(allocate_bp_location): Adjust. Call the owner breakpoint's
allocate_location method, if there is one.
(free_bp_location): Call the locations's dtor method, if there is
one.
(init_raw_breakpoint_without_location): New breakpoint_ops
parameter. Use it.
(set_raw_breakpoint_without_location): Adjust.
(init_raw_breakpoint): New breakpoint_ops parameter. Pass it down.
(set_raw_breakpoint): Adjust.
(catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops)
(catch_syscall_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(init_catchpoint): Don't memset, initialize thread, addr_string
and enable_state. Pass the ops down to init_raw_breakpoint.
(install_catchpoint): Rename to ...
(install_breakpoint): ... this, and make extern.
(create_fork_vfork_event_catchpoint): Adjust.
(catch_exec_breakpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_syscall_event_catchpoint): Adjust.
(ranged_breakpoint_ops, watchpoint_breakpoint_ops)
(masked_watchpoint_breakpoint_ops): Install NULL
allocate_location, re_set and check_status methods.
(catch_exec_command_1): Adjust.
(gnu_v3_exception_catchpoint_ops): Install NULL allocate_location,
re_set and check_status methods.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this. Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters. Use init_raw_breakpoint, and don't install or
mention the breakpoint yet. Don't clear breakpoint fields that
init_raw_breakpoint already clears.
(re_set_breakpoint): Delete, split into ...
(breakpoint_re_set_default, prepare_re_set_context): ... these new
functions.
(breakpoint_re_set_one): Call the breakpoint's
breakpoint_ops->re_set implementation, if there's one. Adjust.
* breakpoint.h: Forward declare struct bpstats and struct bp_location.
(struct bp_location_ops): New type.
(struct bp_location): New field `ops'.
(struct breakpoint_ops): New `allocate_location', `re_set' and
`check_status' fields. Make `breakpoint_hit''s description match
reality.
(init_bp_location): Declare.
(breakpoint_re_set_default): Declare.
(create_ada_exception_breakpoint): Rename to ...
(init_ada_exception_breakpoint): ... this. Add a struct
breakpoint parameter, and delete the exp_string, cond_string and
cond parameters.
(install_breakpoint): Declare.
* ada-lang.c: Include exceptions.h.
<Ada exceptions description>: Update.
(struct ada_catchpoint_location): New type.
(ada_catchpoint_location_dtor): New function.
(ada_catchpoint_location_ops): New global.
(ada_catchpoint): New type.
(create_excep_cond_exprs): New function.
(dtor_exception, allocate_location_exception, re_set_exception)
(should_stop_exception, check_status_exception): New functions.
(print_one_exception, print_mention_exception)
(print_recreate_exception): Adjust.
(dtor_catch_exception, allocate_location_catch_exception)
(re_set_catch_exception, check_status_catch_exception): New
functions.
(catch_exception_breakpoint_ops): Install them.
(dtor_catch_exception_unhandled)
(allocate_location_catch_exception_unhandled)
(re_set_catch_exception_unhandled)
(check_status_catch_exception_unhandled): New functions.
(catch_exception_unhandled_breakpoint_ops): Install them.
(dtor_catch_assert, allocate_location_catch_assert)
(re_set_catch_assert, check_status_catch_assert): New functions.
(catch_assert_breakpoint_ops): Install them.
(ada_exception_catchpoint_p): Delete.
(catch_ada_exception_command_split)
(ada_exception_catchpoint_cond_string): Rename exp_string
parameter to excep_string. Adjust.
(ada_parse_catchpoint_condition): Delete.
(ada_exception_sal): Rename the exp_string parameter to
excep_string. Delete the cond_string and cond parameters.
Adjust.
(ada_decode_exception_location): Rename the exp_string parameter
to excep_string. Delete the cond_string and cond parameters.
Adjust.
(create_ada_exception_catchpoint): New function.
(catch_ada_exception_command, ada_decode_assert_location)
(catch_assert_command): Adjust.
* ada-lang.h (ada_exception_catchpoint_p): Delete declaration.
* ada-lang.c: Include arch-utils.h.
(ada_decode_exception_location): Make static.
(catch_ada_exception_command): Moved here from breakpoint.c.
(ada_decode_assert_location): Make static.
(catch_assert_command): Moved here from breakpoint.c.
(_initialize_ada_lang): Install the exception and assert
catchpoint commands here.
* ada-lang.h (ada_decode_exception_location)
(ada_decode_assert_location): Delete declarations.
* breakpoint.c (CATCH_PERMANENT, CATCH_TEMPORARY): Moved to
breakpoint.h.
(create_ada_exception_breakpoint): Make extern.
(catch_ada_exception_command, catch_assert_command): Moved to
ada-lang.c.
(add_catch_command): Make extern.
(_initilize_breakpoint): Don't install the exception and assert
catchpoint commands here.
* breakpoint.h (CATCH_PERMANENT, CATCH_TEMPORARY): Moved from
breakpoint.c
(add_catch_command, create_ada_exception_breakpoint): Declare.
* breakpoint.h (struct breakpoint_ops): New field `dtor'.
(struct breakpoint): Delete field `syscalls_to_be_caught'.
* breakpoint.c (init_raw_breakpoint_without_location): Remove
reference to syscalls_to_be_caught.
(catch_fork_breakpoint_ops, catch_vfork_breakpoint_ops): Install a
NULL `dtor'.
(struct syscall_catchpoint): New type.
(dtor_catch_syscall): New function.
(insert_catch_syscall, remove_catch_syscall)
(breakpoint_hit_catch_syscall, print_one_catch_syscall)
(print_recreate_catch_syscall): Adjust.
(catch_syscall_breakpoint_ops): Install dtor_catch_syscall.
(catch_exec_breakpoint_ops): Install a NULL `dtor'.
(create_syscall_event_catchpoint): Adjust to use init_catchpoint.
(ranged_breakpoint_ops, watchpoint_breakpoint_ops)
(masked_watchpoint_breakpoint_ops)
(gnu_v3_exception_catchpoint_ops): Install a NULL `dtor'.
(delete_breakpoint): Call the `dtor' breakpoint_ops method, if
there is one. Remove references to syscalls_to_be_caught.
(catching_syscall_number): Adjust.
* ada-lang.c (catch_exception_breakpoint_ops)
(catch_exception_unhandled_breakpoint_ops)
(catch_assert_breakpoint_ops): Install a NULL `dtor'.
gdb/ChangeLog:
From Stephen Kitt <steve@sk2.org>
* breakpoint.c, breakpoint.h, cli/cli-dump.c, dwarf2expr.c,
gdbarch.c, gdbarch.sh, remote.c: Various spelling fixes.
gdb/testsuite/ChangeLog:
From Stephen Kitt <steve@sk2.org>
* gdb.base/help.exp: Adjust following some spelling corrections
in GDB.
Thiago Jung Bauermann <bauerman@br.ibm.com>
Implement support for PowerPC BookE masked watchpoints.
gdb/
* NEWS: Mention masked watchpoint support. Create "Changed commands"
section.
* breakpoint.h (struct breakpoint_ops) <works_in_software_mode>: New
method. Initialize to NULL in all existing breakpoint_ops instances.
(struct breakpoint) <hw_wp_mask>: New field.
* breakpoint.c (is_masked_watchpoint): Add prototype.
(update_watchpoint): Don't set b->val for masked watchpoints. Call
breakpoint's breakpoint_ops.works_in_software_mode if available.
(watchpoints_triggered): Handle the case of a hardware masked
watchpoint trigger.
(watchpoint_check): Likewise.
(works_in_software_mode_watchpoint): New function.
(insert_masked_watchpoint, remove_masked_watchpoint)
(resources_needed_masked_watchpoint)
(works_in_software_mode_masked_watchpoint, print_it_masked_watchpoint)
(print_one_detail_masked_watchpoint, print_mention_masked_watchpoint)
(print_recreate_masked_watchpoint, is_masked_watchpoint): New
functions.
(masked_watchpoint_breakpoint_ops): New structure.
(watch_command_1): Check for the existence of the `mask' parameter.
Set b->ops according to the type of hardware watchpoint being created.
* ppc-linux-nat.c (ppc_linux_insert_mask_watchpoint)
(ppc_linux_remove_mask_watchpoint)
(ppc_linux_masked_watch_num_registers): New functions.
(_initialize_ppc_linux_nat): Initialize to_insert_mask_watchpoint,
to_remove_mask_watchpoint and to_masked_watch_num_registers.
* target.c (update_current_target): Mention to_insert_mask_watchpoint,
to_remove_mask_watchpoint, and to_masked_watch_num_registers.
(target_insert_mask_watchpoint, target_remove_mask_watchpoint)
(target_masked_watch_num_registers): New functions.
* target.h (struct target_ops) <to_insert_mask_watchpoint>,
<to_remove_mask_watchpoint>, <to_masked_watch_num_registers>: New
methods.
(target_insert_mask_watchpoint, target_remove_mask_watchpoint)
(target_masked_watch_num_registers): Add prototypes.
gdb/doc/
* gdb.texinfo (Set Watchpoints): Document mask parameter.
(PowerPC Embedded): Mention support of masked watchpoints.
This rewrites the code generating the Ada exception catchpoint hit
notification for both the GDB/MI case as well as the non-MI case,
by using the relevant ui_out_* functions to generate the output.
the MI notifications for Ada exception catchpoints now include
the stop reason, and the breakpoint "disp", much like other breakpoint
events do. It also introduces a new field "exception-name" for
exception catchpoints (excluding "failed assertion catchpoints,
where we just want to know that it was a failed assertion).
gdb/ChangeLog:
* breakpoint.h (bpdisp_text): Add declaration.
* breakpoint.c (bpdisp_text): Make non-static.
* ada-lang.c: #include "mi/mi-common.h".
(print_it_exception): Rewrite to improve GDB/MI output.
gdb/doc/ChangeLog:
* gdb.texinfo (GDB/MI Ada Exception Information): Document
the "exception-name" field in the *stopped async record.
gdb/testsuite/ChangeLog:
* gdb.ada/mi_catch_ex: New testcase.
Sergio Durigan Junior <sergiodj@linux.vnet.ibm.com>
Implement support for PowerPC BookE ranged breakpoints.
gdb/
* NEWS: Mention support for ranged breakpoints on embedded PowerPC.
* breakpoint.h (struct bp_target_info) <length>: New member
variable.
(struct breakpoint_ops) <breakpoint_hit>: Take struct bp_location
instead of struct breakpoint as argument, and also add ASPACE
and BP_ADDR arguments. Update all callers.
(struct breakpoint_ops) <print_one_detail>: New method.
(struct breakpoint) <addr_string_range_end>: New member variable.
* breakpoint.c (breakpoint_location_address_match): Add function
prototype.
(insert_bp_location): Set bl->target_info.length.
(breakpoint_here_p): Call breakpoint_location_address_match.
(moribund_breakpoint_here_p): Likewise.
(regular_breakpoint_inserted_here_p): Likewise.
(breakpoint_thread_match): Likewise.
(bpstat_stop_status): Likewise.
(bpstat_check_location): Move call to
breakpoint_ops.breakpoint_hit to the top.
(print_one_breakpoint_location): Call
breakpoint_ops.print_one_detail if available.
(breakpoint_address_match_range): New function.
(breakpoint_location_address_match): Likewise.
(breakpoint_locations_match): Compare the length field of the
locations too.
(hw_breakpoint_used_count): Count resources used by all locations
in a breakpoint, and use breakpoint_ops.resources_needed if
available.
(breakpoint_hit_ranged_breakpoint): New function.
(resources_needed_ranged_breakpoint): Likewise.
(print_it_ranged_breakpoint): Likewise.
(print_one_ranged_breakpoint): Likewise.
(print_one_detail_ranged_breakpoint): Likewise.
(print_mention_ranged_breakpoint): Likewise.
(print_recreate_ranged_breakpoint): Likewise.
(ranged_breakpoint_ops): New structure.
(find_breakpoint_range_end): New function.
(break_range_command): Likewise.
(delete_breakpoint): Free addr_string_range_end.
(update_breakpoint_locations): Add SALS_END argument. Update
all callers. Calculate breakpoint length if a non-zero SALS_END
is given. Call breakpoint_locations_match instead of
breakpoint_address_match.
(reset_breakpoint): Find SaL of the end of the range if B is a
ranged breakpoint.
(_initialize_breakpoint): Register break-range command.
* defs.h (print_core_address): Add function prototype.
* ppc-linux-nat.c (ppc_linux_ranged_break_num_registers): New
function.
(ppc_linux_insert_hw_breakpoint): Support ranged breakpoints.
(ppc_linux_remove_hw_breakpoint): Likewise.
(_initialize_ppc_linux_nat): Initialize
to_ranged_break_num_registers.
* target.c (update_current_target): Add comment about
to_ranged_break_num_registers.
(target_ranged_break_num_registers): New function.
* target.h (struct target_ops) <to_ranged_break_num_registers>:
New method.
(target_ranged_break_num_registers): Add function prototype.
* ui-out.c (ui_out_field_core_addr): Move address-printing logic to ...
* utils.c (print_core_address): ... here.
gdb/doc/
* gdb.texinfo (PowerPC Embedded): Document ranged breakpoints.
Support resolution of STT_GNU_IFUNC via breakpoints.
* breakpoint.c (print_it_typical): Support bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return.
(bpstat_what): Rename parameter to bs_head, new variable bs, adjust
the loop. Support bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return. New comment after the loop. New loop
for bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return
breakpoints.
(bptype_string, print_one_breakpoint_location): Support
bp_gnu_ifunc_resolver and bp_gnu_ifunc_resolver_return.
(user_settable_breakpoint): Return true also for
bp_gnu_ifunc_resolver.
(allocate_bp_location): Support bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return.
(set_breakpoint_location_function): New parameter explicit_loc,
describe it. Call find_pc_partial_function_gnu_ifunc with new
variable IS_GNU_IFUNC and adjust the address for STT_GNU_IFUNC if
EXPLICIT_LOC is not set.
(set_raw_breakpoint): Set EXPLICIT_LOC for
set_breakpoint_location_function.
(clone_momentary_breakpoint): Use true for EXPLICIT_LOC of
set_breakpoint_location_function.
(mention): Support bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return.
(add_location_to_breakpoint): Set EXPLICIT_LOC for
set_breakpoint_location_function.
(update_breakpoint_locations): Remove static.
(breakpoint_re_set_one): Support bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return.
* breakpoint.h (enum bptype): New fields bp_gnu_ifunc_resolver and
bp_gnu_ifunc_resolver_return.
(update_breakpoint_locations): New declaration.
* elfread.c: Include gdbthread.h and regcache.h.
(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop): New
functions.
(elf_gnu_ifunc_fns): Install them.
* minsyms.c (stub_gnu_ifunc_resolver_stop)
(stub_gnu_ifunc_resolver_return_stop): New functions.
(stub_gnu_ifunc_fns): Install them.
* symtab.h (struct gnu_ifunc_fns): New fields gnu_ifunc_resolver_stop
and gnu_ifunc_resolver_return_stop.
(gnu_ifunc_resolver_stop, gnu_ifunc_resolver_return_stop): New.
* breakpoint.h (get_number_or_range): Declare.
* printcmd.c (ALL_DISPLAYS): Declare.
(delete_display): Reimplement taking a display pointer.
(undisplay_command): Accept a range of displays to delete, using
get_number_or_range.
* breakpoint.c (update_watchpoint): Fix name of the
update_global_location_list function.
(print_one_breakpoint): Fix typo.
(_initialize_breakpoint): Remove extra space in hbreak help
string.
* breakpoint.h (struct bp_location) <length>: Fix field
description.