mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
With the test changed as in the patch, against current mainline, we get: (gdb) PASS: gdb.ada/tasks.exp: info tasks before inserting breakpoint break break_me task 1 Breakpoint 2 at 0x4030b0: file /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/tasks/foo.adb, line 27. (gdb) PASS: gdb.ada/tasks.exp: break break_me task 1 break break_me task 3 Note: breakpoint 2 also set at pc 0x4030b0. Breakpoint 3 at 0x4030b0: file /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/tasks/foo.adb, line 27. (gdb) PASS: gdb.ada/tasks.exp: break break_me task 3 continue Continuing. [Switching to Thread 0x7ffff7dc7700 (LWP 27133)] Breakpoint 2, foo.break_me () at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/tasks/foo.adb:27 27 null; (gdb) FAIL: gdb.ada/tasks.exp: continue to breakpoint info tasks ID TID P-ID Pri State Name 1 63b010 48 Waiting on RV with 3 main_task 2 63bd80 1 48 Accept or Select Term task_list(1) * 3 63f510 1 48 Accepting RV with 1 task_list(2) 4 642ca0 1 48 Accept or Select Term task_list(3) (gdb) PASS: gdb.ada/tasks.exp: info tasks after hitting breakpoint The breakpoint that caused a stop is breakpoint 3, but GDB end up reporting (and running breakpoint commands of) "Breakpoint 2" instead. The issue is that the bpstat_check_breakpoint_conditions logic of "wrong thread" is missing the "wrong task" check. This is usually harmless, because the thread hop code in infrun.c code that handles wrong-task-hitting-breakpoint does check for task-specific breakpoints (within breakpoint_thread_match): /* 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; } IOW, usually, when one only has a task specific breakpoint at a given address, things work correctly. Put another task-specific or non-task-specific breakpoint there, and things break. A patch that eliminates the special thread hop code in infrun.c is what exposed this, as after that GDB solely relies on bpstat_check_breakpoint_conditions to know whether the right or wrong task hit a breakpoint. IOW, given the latent bug, Ada task-specific breakpoints become non-task-specific, and that is caught by the testsuite, as: break break_me task 3 Breakpoint 2 at 0x4030b0: file /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/tasks/foo.adb, line 27. (gdb) PASS: gdb.ada/tasks.exp: break break_me task 3 continue Continuing. [Switching to Thread 0x7ffff7fcb700 (LWP 17122)] Breakpoint 2, foo.break_me () at /home/pedro/gdb/mygit/src/gdb/testsuite/gdb.ada/tasks/foo.adb:27 27 null; (gdb) PASS: gdb.ada/tasks.exp: continue to breakpoint info tasks ID TID P-ID Pri State Name 1 63b010 48 Waiting on RV with 2 main_task * 2 63bd80 1 48 Accepting RV with 1 task_list(1) 3 63f510 1 48 Accept or Select Term task_list(2) 4 642ca0 1 48 Accept or Select Term task_list(3) (gdb) FAIL: gdb.ada/tasks.exp: info tasks after hitting breakpoint It was after seeing this that I thought of how to expose the bug with current mainline. Tested on x86_64 Fedora 17. gdb/ 2014-02-26 Pedro Alves <palves@redhat.com> * breakpoint.c (bpstat_check_breakpoint_conditions): Handle task-specific breakpoints. gdb/testsuite/ 2014-02-26 Pedro Alves <palves@redhat.com> * gdb.ada/tasks.exp: Set a task-specific breakpoint at break_me that won't ever trigger. Make sure that GDB reports the correct breakpoint that caused the stop. |
||
---|---|---|
.. | ||
aliased_array | ||
array_bounds | ||
array_char_idx | ||
array_return | ||
array_subscript_addr | ||
arraydim | ||
arrayidx | ||
arrayparam | ||
arrayptr | ||
atomic_enum | ||
bad-task-bp-keyword | ||
bp_enum_homonym | ||
bp_on_var | ||
bp_range_type | ||
bp_reset | ||
call_pn | ||
catch_ex | ||
char_enum | ||
char_param | ||
complete | ||
cond_lang | ||
dot_all | ||
dyn_loc | ||
enum_idx_packed | ||
exec_changed | ||
expr_delims | ||
exprs | ||
fixed_cmp | ||
fixed_points | ||
float_param | ||
formatted_ref | ||
frame_args | ||
fullname_bp | ||
fun_addr | ||
fun_in_declare | ||
funcall_param | ||
homonym | ||
info_exc | ||
info_locals_renaming | ||
int_deref | ||
interface | ||
iwide | ||
lang_switch | ||
mi_catch_ex | ||
mi_ex_cond | ||
mi_exc_info | ||
mi_interface | ||
mi_task_arg | ||
mi_task_info | ||
mod_from_name | ||
nested | ||
null_array | ||
null_record | ||
O2_float_param | ||
operator_bp | ||
optim_drec | ||
packed_array | ||
packed_tagged | ||
pp-rec-component | ||
print_chars | ||
ptr_typedef | ||
ptype_field | ||
ptype_tagged_param | ||
py_range | ||
rdv_wait | ||
rec_return | ||
ref_param | ||
ref_tick_size | ||
same_enum | ||
set_pckd_arr_elt | ||
set_wstr | ||
small_reg_param | ||
start | ||
str_ref_cmp | ||
sym_print_name | ||
taft_type | ||
tagged | ||
tagged_not_init | ||
task_bp | ||
tasks | ||
tick_last_segv | ||
tick_length_array_enum_idx | ||
type_coercion | ||
unc_arr_ptr_in_var_rec | ||
uninitialized_vars | ||
variant_record_packed_array | ||
watch_arg | ||
whatis_array_val | ||
widewide | ||
win_fu_syms | ||
aliased_array.exp | ||
array_bounds.exp | ||
array_char_idx.exp | ||
array_return.exp | ||
array_subscript_addr.exp | ||
arraydim.exp | ||
arrayidx.exp | ||
arrayparam.exp | ||
arrayptr.exp | ||
assign_1.exp | ||
atomic_enum.exp | ||
bad-task-bp-keyword.exp | ||
boolean_expr.exp | ||
bp_enum_homonym.exp | ||
bp_on_var.exp | ||
bp_range_type.exp | ||
bp_reset.exp | ||
call_pn.exp | ||
catch_ex.exp | ||
char_enum.exp | ||
char_param.exp | ||
complete.exp | ||
cond_lang.exp | ||
dot_all.exp | ||
dyn_loc.exp | ||
enum_idx_packed.exp | ||
exec_changed.exp | ||
expr_delims.exp | ||
exprs.exp | ||
fixed_cmp.exp | ||
fixed_points.exp | ||
float_param.exp | ||
formatted_ref.exp | ||
frame_args.exp | ||
fullname_bp.exp | ||
fun_addr.exp | ||
fun_in_declare.exp | ||
funcall_param.exp | ||
gnat_ada.gpr | ||
homonym.exp | ||
info_exc.exp | ||
info_locals_renaming.exp | ||
info_types.c | ||
info_types.exp | ||
int_deref.exp | ||
interface.exp | ||
iwide.exp | ||
lang_switch.exp | ||
Makefile.in | ||
mi_catch_ex.exp | ||
mi_ex_cond.exp | ||
mi_exc_info.exp | ||
mi_interface.exp | ||
mi_task_arg.exp | ||
mi_task_info.exp | ||
mod_from_name.exp | ||
nested.exp | ||
null_array.exp | ||
null_record.exp | ||
O2_float_param.exp | ||
operator_bp.exp | ||
optim_drec.exp | ||
packed_array.exp | ||
packed_tagged.exp | ||
pp-rec-component.exp | ||
pp-rec-component.py | ||
print_chars.exp | ||
print_pc.exp | ||
ptr_typedef.exp | ||
ptype_arith_binop.exp | ||
ptype_field.exp | ||
ptype_tagged_param.exp | ||
py_range.exp | ||
rdv_wait.exp | ||
rec_return.exp | ||
ref_param.exp | ||
ref_tick_size.exp | ||
same_enum.exp | ||
set_pckd_arr_elt.exp | ||
set_wstr.exp | ||
small_reg_param.exp | ||
start.exp | ||
str_ref_cmp.exp | ||
sym_print_name.exp | ||
taft_type.exp | ||
tagged_not_init.exp | ||
tagged.exp | ||
task_bp.exp | ||
tasks.exp | ||
tick_last_segv.exp | ||
tick_length_array_enum_idx.exp | ||
type_coercion.exp | ||
unc_arr_ptr_in_var_rec.exp | ||
uninitialized_vars.exp | ||
variant_record_packed_array.exp | ||
watch_arg.exp | ||
whatis_array_val.exp | ||
widewide.exp | ||
win_fu_syms.exp |