the "ambiguous linespec" series
gdb 2011-12-06 Joel Brobecker <brobecker@acacore.com> * language.h (struct language_defn): Add new component la_symbol_name_compare. * symfile.h (struct quick_symbol_functions): Update the profile of parameter "name_matcher" for the expand_symtabs_matching method. Update the documentation accordingly. * ada-lang.h (ada_name_for_lookup): Add declaration. * ada-lang.c (ada_name_for_lookup): New function, extracted out from ada_iterate_over_symbols. (ada_iterate_over_symbols): Do not encode symbol name anymore. (ada_expand_partial_symbol_name): Adjust profile. (ada_language_defn): Add value for la_symbol_name_compare field. * linespec.c: #include "ada-lang.h". (iterate_name_matcher): Add language parameter. Replace call to strcmp_iw by call to language->la_symbol_name_compare. (decode_variable): Encode COPY if current language is Ada. * dwarf2read.c (dw2_expand_symtabs_matching): Adjust profile of name_matcher parameter. Adjust call to name_matcher. * psymtab.c (expand_symtabs_matching_via_partial): Likewise. (expand_partial_symbol_names): Update profile of parameter "fun". * psymtab.h (expand_partial_symbol_names): Update profile of parameter "fun". * symtab.c (demangle_for_lookup): Update function documentation. (search_symbols_name_matches): Add language parameter. (expand_partial_symbol_name): Likewise. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Add value for la_symbol_name_compare field. * d-lang.c (d_language_defn): Likewise. * f-lang.c (f_language_defn): Ditto. * jv-lang.c (java_language_defn): Ditto. * m2-lang.c (m2_language_defn): Ditto. * objc-lang.c (objc_language_defn): Ditto. * opencl-lang.c (opencl_language_defn): Ditto. * p-lang.c (pascal_language_defn): Ditto. * language.c (unknown_language_defn, auto_language_defn) (local_language_defn): Ditto. 2011-12-06 Tom Tromey <tromey@redhat.com> * linespec.c (iterate_over_all_matching_symtabs): Use LA_ITERATE_OVER_SYMBOLS. (lookup_prefix_sym, add_matching_symbols_to_info): Likewise. (find_function_symbols, decode_variable): Remove Ada special case. * language.h (struct language_defn) <la_iterate_over_symbols>: New field. (LA_ITERATE_OVER_SYMBOLS): New macro. * language.c (unknown_language_defn, auto_language_defn) (local_language_defn): Update. * c-lang.c (c_language_defn, cplus_language_defn) (asm_language_defn, minimal_language_defn): Update. * d-lang.c (d_language_defn): Update. * f-lang.c (f_language_defn): Update. * jv-lang.c (java_language_defn): Update. * m2-lang.c (m2_language_defn): Update. * objc-lang.c (objc_language_defn): Update. * opencl-lang.c (opencl_language_defn): Update. * p-lang.c (pascal_language_defn): Update. * ada-lang.c (ada_iterate_over_symbols): New function. (ada_language_defn): Update. 2011-12-06 Tom Tromey <tromey@redhat.com> Joel Brobecker <brobecker@acacore.com> PR breakpoints/13105, PR objc/8341, PR objc/8343, PR objc/8366, PR objc/8535, PR breakpoints/11657, PR breakpoints/11970, PR breakpoints/12023, PR breakpoints/12334, PR breakpoints/12856, PR shlibs/8929, PR shlibs/7393: * python/py-type.c (compare_maybe_null_strings): Rename from compare_strings. (check_types_equal): Update. * utils.c (compare_strings): New function. * tui/tui-winsource.c (tui_update_breakpoint_info): Update for location changes. * tracepoint.c (scope_info): Update. (trace_find_line_command): Use DECODE_LINE_FUNFIRSTLINE. * symtab.h (iterate_over_minimal_symbols) (iterate_over_some_symtabs, iterate_over_symtabs) (find_pcs_for_symtab_line, iterate_over_symbols) (demangle_for_lookup): Declare. (expand_line_sal): Remove. * symtab.c (iterate_over_some_symtabs, iterate_over_symtabs) (lookup_symtab_callback): New functions. (lookup_symtab): Rewrite. (demangle_for_lookup): New function, extract from lookup_symbol_in_language. (lookup_symbol_in_language): Use it. (iterate_over_symbols): New function. (find_line_symtab): Update. (find_pcs_for_symtab_line): New functions. (find_line_common): Add 'start' argument. (decode_line_spec): Update. Change argument to 'flags', change interpretation. (append_expanded_sal): Remove. (append_exact_match_to_sals): Remove. (expand_line_sal): Remove. * symfile.h (struct quick_symbol_functions) <lookup_symtab>: Remove. <map_symtabs_matching_filename>: New field. * stack.c (func_command): Only look in the current program space. Use DECODE_LINE_FUNFIRSTLINE. * source.c (line_info): Set pspace on sal. Check program space in the loop. Use DECODE_LINE_LIST_MODE. (select_source_symtab): Use DECODE_LINE_FUNFIRSTLINE. * solib-target.c: Remove DEF_VEC_I(CORE_ADDR). * python/python.c (gdbpy_decode_line): Update. * psymtab.c (partial_map_expand_apply): New function. (partial_map_symtabs_matching_filename): Rename from lookup_partial_symbol. Update arguments. (lookup_symtab_via_partial_symtab): Remove. (psym_functions): Update. * objc-lang.h (parse_selector, parse_method): Don't declare. (find_imps): Update. * objc-lang.c (parse_selector, parse_method): Now static. (find_methods): Change arguments. Fill in a vector of symbol names. (uniquify_strings): New function. (find_imps): Change arguments. * minsyms.c (iterate_over_minimal_symbols): New function. * linespec.h (enum decode_line_flags): New. (struct linespec_sals): New. (struct linespec_result) <canonical>: Remove. <pre_expanded, addr_string, sals>: New fields. (destroy_linespec_result, make_cleanup_destroy_linespec_result) (decode_line_full): Declare. (decode_line_1): Update. * linespec.c (struct address_entry, struct linespec_state, struct collect_info): New types. (add_sal_to_sals_basic, add_sal_to_sals, hash_address_entry) (eq_address_entry, maybe_add_address): New functions. (total_number_of_methods): Remove. (iterate_name_matcher, iterate_over_all_matching_symtabs): New functions. (find_methods): Change arguments. Don't canonicalize input. Simplify logic. (add_matching_methods, add_constructors) (build_canonical_line_spec): Remove. (filter_results, convert_results_to_lsals): New functions. (decode_line_2): Change arguments. Rewrite for new data structures. (decode_line_internal): Rename from decode_line_1. Change arguments. Add cleanups. Update for new data structures. (linespec_state_constructor, linespec_state_destructor) (decode_line_full, decode_line_1): New functions. (decode_indirect): Change arguments. Update. (locate_first_half): Use skip_spaces. (decode_objc): Change arguments. Update for new data structures. Simplify logic. (decode_compound): Change arguments. Add cleanups. Remove fallback code, replace with error. (struct decode_compound_collector): New type. (collect_one_symbol): New function. (lookup_prefix_sym): Change arguments. Update. (compare_symbol_name, add_all_symbol_names_from_pspace) (find_superclass_methods ): New functions. (find_method): Rewrite. (struct symtab_collector): New type. (add_symtabs_to_list, collect_symtabs_from_filename): New functions. (symtabs_from_filename): Change API. Rename from symtab_from_filename. (collect_function_symbols): New function. (find_function_symbols): Change API. Rename from find_function_symbol. Rewrite. (decode_all_digits): Change arguments. Rewrite. (decode_dollar): Change arguments. Use decode_variable. (decode_label): Change arguments. Rewrite. (collect_symbols): New function. (minsym_found): Change arguments. Rewrite. (check_minsym, search_minsyms_for_name) (add_matching_symbols_to_info): New function. (decode_variable): Change arguments. Iterate over all symbols. (symbol_found): Remove. (symbol_to_sal): New function. (init_linespec_result, destroy_linespec_result) (cleanup_linespec_result, make_cleanup_destroy_linespec_result): New functions. (decode_digits_list_mode, decode_digits_ordinary): New functions. * dwarf2read.c (dw2_map_expand_apply): New function. (dw2_map_symtabs_matching_filename): Rename from dw2_lookup_symtab. Change arguments. (dwarf2_gdb_index_functions): Update. * dwarf2loc.c: Remove DEF_VEC_I(CORE_ADDR). * defs.h (compare_strings): Declare. * cli/cli-cmds.c (compare_strings): Move to utils.c. (edit_command, list_command): Use DECODE_LINE_LIST_MODE. Call filter_sals. (compare_symtabs, filter_sals): New functions. * breakpoint.h (struct bp_location) <line_number, source_file>: New fields. (struct breakpoint) <line_number, source_file>: Remove. <filter>: New field. * breakpoint.c (print_breakpoint_location, init_raw_breakpoint) (momentary_breakpoint_from_master, add_location_to_breakpoint): Update for changes to locations. (init_breakpoint_sal): Add 'filter' argument. Set 'filter' on breakpoint. (create_breakpoint_sal): Add 'filter' argument. (remove_sal, expand_line_sal_maybe): Remove. (create_breakpoints_sal): Remove 'sals' argument. Handle pre-expanded sals and the filter. (parse_breakpoint_sals): Use decode_line_full. (check_fast_tracepoint_sals): Use get_sal_arch. (create_breakpoint): Create a linespec_sals. Update. (break_range_command): Use decode_line_full. Update. (until_break_command): Update. (clear_command): Update match conditions for linespec.c changes. Use DECODE_LINE_LIST_MODE. (say_where): Update for changes to locations. (bp_location_dtor): Free 'source_file'. (base_breakpoint_dtor): Free 'filter'. Don't free 'source_file'. (update_static_tracepoint): Update for changes to locations. (update_breakpoint_locations): Disable ranged breakpoint if too many locations match. Update. (addr_string_to_sals): Use decode_line_full. Resolve all sal PCs. (breakpoint_re_set_default): Don't call expand_line_sal_maybe. (decode_line_spec_1): Update. Change argument name to 'flags', change interpretation. * block.h (block_containing_function): Declare. * block.c (block_containing_function): New function. * skip.c (skip_function_command): Update. (skip_re_set): Update. * infcmd.c (jump_command): Use DECODE_LINE_FUNFIRSTLINE. * mi/mi-main.c (mi_cmd_trace_find): Use DECODE_LINE_FUNFIRSTLINE. * NEWS: Add entry. 2011-12-06 Tom Tromey <tromey@redhat.com> * elfread.c (elf_gnu_ifunc_resolver_return_stop): Allow breakpoint's pspace to be NULL. * breakpoint.h (struct breakpoint) <pspace>: Update comment. * breakpoint.c (init_raw_breakpoint): Conditionally set breakpoint's pspace. (init_breakpoint_sal): Don't set breakpoint's pspace. (prepare_re_set_context): Conditionally switch program space. (addr_string_to_sals): Check executing_startup on location's program space. 2011-12-06 Tom Tromey <tromey@redhat.com> * breakpoint.h (enum enable_state) <bp_startup_disabled>: Remove. * breakpoint.c (should_be_inserted): Explicitly check if program space is executing startup. (describe_other_breakpoints): Update. (disable_breakpoints_before_startup): Change executing_startup earlier. Remove loop. (enable_breakpoints_after_startup): Likewise. (init_breakpoint_sal): Don't use bp_startup_disabled. (create_breakpoint): Don't use bp_startup_disabled. (update_global_location_list): Use should_be_inserted. (bkpt_re_set): Update. gdb/testsuite 2011-12-06 Joel Brobecker <brobecker@acacore.com> * gdb.ada/fullname_bp.exp: Add tests for other valid linespecs involving a fully qualified function name. 2011-12-06 Tom Tromey <tromey@redhat.com> * gdb.ada/homonym.exp: Add three breakpoint tests. 2011-12-06 Tom Tromey <tromey@redhat.com> * gdb.base/solib-weak.exp (do_test): Remove kfail. * gdb.trace/tracecmd.exp: Disable pending breakpoints earlier. * gdb.objc/objcdecode.exp: Update for output changes. * gdb.linespec/linespec.exp: New file. * gdb.linespec/lspec.cc: New file. * gdb.linespec/lspec.h: New file. * gdb.linespec/body.h: New file. * gdb.linespec/base/two/thefile.cc: New file. * gdb.linespec/base/one/thefile.cc: New file. * gdb.linespec/Makefile.in: New file. * gdb.cp/templates.exp (test_template_breakpoints): Update for output changes. * gdb.cp/re-set-overloaded.exp: Remove kfail. * gdb.cp/ovldbreak.exp: Update for output changes. "all" test now makes one breakpoint. * gdb.cp/method2.exp (test_break): Update for output changes. * gdb.cp/mb-templates.exp: Update for output changes. * gdb.cp/mb-inline.exp: Update for output changes. * gdb.cp/mb-ctor.exp: Update for output changes. * gdb.cp/ovsrch.exp: Use fully-qualified names. * gdb.base/solib-symbol.exp: Run to main later. Breakpoint now has multiple matches. * gdb.base/sepdebug.exp: Disable pending breakpoints. Update for error message change. * gdb.base/list.exp (test_list_filename_and_number): Update for error message change. * gdb.base/break.exp: Disable pending breakpoints. Update for output changes. * configure.ac: Add gdb.linespec. * configure: Rebuild. * Makefile.in (ALL_SUBDIRS): Add gdb.linespec. gdb/doc 2011-12-06 Tom Tromey <tromey@redhat.com> * gdb.texinfo (Set Breaks): Update for new behavior.
This commit is contained in:
parent
75c8c9d72c
commit
f8eba3c616
76 changed files with 3544 additions and 2145 deletions
255
gdb/ChangeLog
255
gdb/ChangeLog
|
@ -1,3 +1,258 @@
|
||||||
|
2011-12-06 Joel Brobecker <brobecker@acacore.com>
|
||||||
|
|
||||||
|
* language.h (struct language_defn): Add new component
|
||||||
|
la_symbol_name_compare.
|
||||||
|
* symfile.h (struct quick_symbol_functions): Update the profile
|
||||||
|
of parameter "name_matcher" for the expand_symtabs_matching
|
||||||
|
method. Update the documentation accordingly.
|
||||||
|
* ada-lang.h (ada_name_for_lookup): Add declaration.
|
||||||
|
* ada-lang.c (ada_name_for_lookup): New function, extracted out
|
||||||
|
from ada_iterate_over_symbols.
|
||||||
|
(ada_iterate_over_symbols): Do not encode symbol name anymore.
|
||||||
|
(ada_expand_partial_symbol_name): Adjust profile.
|
||||||
|
(ada_language_defn): Add value for la_symbol_name_compare field.
|
||||||
|
* linespec.c: #include "ada-lang.h".
|
||||||
|
(iterate_name_matcher): Add language parameter. Replace call
|
||||||
|
to strcmp_iw by call to language->la_symbol_name_compare.
|
||||||
|
(decode_variable): Encode COPY if current language is Ada.
|
||||||
|
* dwarf2read.c (dw2_expand_symtabs_matching): Adjust profile
|
||||||
|
of name_matcher parameter. Adjust call to name_matcher.
|
||||||
|
* psymtab.c (expand_symtabs_matching_via_partial): Likewise.
|
||||||
|
(expand_partial_symbol_names): Update profile of parameter "fun".
|
||||||
|
* psymtab.h (expand_partial_symbol_names): Update profile of
|
||||||
|
parameter "fun".
|
||||||
|
* symtab.c (demangle_for_lookup): Update function documentation.
|
||||||
|
(search_symbols_name_matches): Add language parameter.
|
||||||
|
(expand_partial_symbol_name): Likewise.
|
||||||
|
* c-lang.c (c_language_defn, cplus_language_defn)
|
||||||
|
(asm_language_defn, minimal_language_defn): Add value for
|
||||||
|
la_symbol_name_compare field.
|
||||||
|
* d-lang.c (d_language_defn): Likewise.
|
||||||
|
* f-lang.c (f_language_defn): Ditto.
|
||||||
|
* jv-lang.c (java_language_defn): Ditto.
|
||||||
|
* m2-lang.c (m2_language_defn): Ditto.
|
||||||
|
* objc-lang.c (objc_language_defn): Ditto.
|
||||||
|
* opencl-lang.c (opencl_language_defn): Ditto.
|
||||||
|
* p-lang.c (pascal_language_defn): Ditto.
|
||||||
|
* language.c (unknown_language_defn, auto_language_defn)
|
||||||
|
(local_language_defn): Ditto.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* linespec.c (iterate_over_all_matching_symtabs): Use
|
||||||
|
LA_ITERATE_OVER_SYMBOLS.
|
||||||
|
(lookup_prefix_sym, add_matching_symbols_to_info): Likewise.
|
||||||
|
(find_function_symbols, decode_variable): Remove Ada special
|
||||||
|
case.
|
||||||
|
* language.h (struct language_defn) <la_iterate_over_symbols>: New
|
||||||
|
field.
|
||||||
|
(LA_ITERATE_OVER_SYMBOLS): New macro.
|
||||||
|
* language.c (unknown_language_defn, auto_language_defn)
|
||||||
|
(local_language_defn): Update.
|
||||||
|
* c-lang.c (c_language_defn, cplus_language_defn)
|
||||||
|
(asm_language_defn, minimal_language_defn): Update.
|
||||||
|
* d-lang.c (d_language_defn): Update.
|
||||||
|
* f-lang.c (f_language_defn): Update.
|
||||||
|
* jv-lang.c (java_language_defn): Update.
|
||||||
|
* m2-lang.c (m2_language_defn): Update.
|
||||||
|
* objc-lang.c (objc_language_defn): Update.
|
||||||
|
* opencl-lang.c (opencl_language_defn): Update.
|
||||||
|
* p-lang.c (pascal_language_defn): Update.
|
||||||
|
* ada-lang.c (ada_iterate_over_symbols): New function.
|
||||||
|
(ada_language_defn): Update.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
Joel Brobecker <brobecker@acacore.com>
|
||||||
|
|
||||||
|
PR breakpoints/13105, PR objc/8341, PR objc/8343, PR objc/8366,
|
||||||
|
PR objc/8535, PR breakpoints/11657, PR breakpoints/11970,
|
||||||
|
PR breakpoints/12023, PR breakpoints/12334, PR breakpoints/12856,
|
||||||
|
PR shlibs/8929, PR shlibs/7393:
|
||||||
|
* python/py-type.c (compare_maybe_null_strings): Rename from
|
||||||
|
compare_strings.
|
||||||
|
(check_types_equal): Update.
|
||||||
|
* utils.c (compare_strings): New function.
|
||||||
|
* tui/tui-winsource.c (tui_update_breakpoint_info): Update for
|
||||||
|
location changes.
|
||||||
|
* tracepoint.c (scope_info): Update.
|
||||||
|
(trace_find_line_command): Use DECODE_LINE_FUNFIRSTLINE.
|
||||||
|
* symtab.h (iterate_over_minimal_symbols)
|
||||||
|
(iterate_over_some_symtabs, iterate_over_symtabs)
|
||||||
|
(find_pcs_for_symtab_line, iterate_over_symbols)
|
||||||
|
(demangle_for_lookup): Declare.
|
||||||
|
(expand_line_sal): Remove.
|
||||||
|
* symtab.c (iterate_over_some_symtabs, iterate_over_symtabs)
|
||||||
|
(lookup_symtab_callback): New functions.
|
||||||
|
(lookup_symtab): Rewrite.
|
||||||
|
(demangle_for_lookup): New function, extract from
|
||||||
|
lookup_symbol_in_language.
|
||||||
|
(lookup_symbol_in_language): Use it.
|
||||||
|
(iterate_over_symbols): New function.
|
||||||
|
(find_line_symtab): Update.
|
||||||
|
(find_pcs_for_symtab_line): New functions.
|
||||||
|
(find_line_common): Add 'start' argument.
|
||||||
|
(decode_line_spec): Update. Change argument to 'flags', change
|
||||||
|
interpretation.
|
||||||
|
(append_expanded_sal): Remove.
|
||||||
|
(append_exact_match_to_sals): Remove.
|
||||||
|
(expand_line_sal): Remove.
|
||||||
|
* symfile.h (struct quick_symbol_functions) <lookup_symtab>:
|
||||||
|
Remove.
|
||||||
|
<map_symtabs_matching_filename>: New field.
|
||||||
|
* stack.c (func_command): Only look in the current program space.
|
||||||
|
Use DECODE_LINE_FUNFIRSTLINE.
|
||||||
|
* source.c (line_info): Set pspace on sal. Check program space in
|
||||||
|
the loop. Use DECODE_LINE_LIST_MODE.
|
||||||
|
(select_source_symtab): Use DECODE_LINE_FUNFIRSTLINE.
|
||||||
|
* solib-target.c: Remove DEF_VEC_I(CORE_ADDR).
|
||||||
|
* python/python.c (gdbpy_decode_line): Update.
|
||||||
|
* psymtab.c (partial_map_expand_apply): New function.
|
||||||
|
(partial_map_symtabs_matching_filename): Rename from
|
||||||
|
lookup_partial_symbol. Update arguments.
|
||||||
|
(lookup_symtab_via_partial_symtab): Remove.
|
||||||
|
(psym_functions): Update.
|
||||||
|
* objc-lang.h (parse_selector, parse_method): Don't declare.
|
||||||
|
(find_imps): Update.
|
||||||
|
* objc-lang.c (parse_selector, parse_method): Now static.
|
||||||
|
(find_methods): Change arguments. Fill in a vector of symbol
|
||||||
|
names.
|
||||||
|
(uniquify_strings): New function.
|
||||||
|
(find_imps): Change arguments.
|
||||||
|
* minsyms.c (iterate_over_minimal_symbols): New function.
|
||||||
|
* linespec.h (enum decode_line_flags): New.
|
||||||
|
(struct linespec_sals): New.
|
||||||
|
(struct linespec_result) <canonical>: Remove.
|
||||||
|
<pre_expanded, addr_string, sals>: New fields.
|
||||||
|
(destroy_linespec_result, make_cleanup_destroy_linespec_result)
|
||||||
|
(decode_line_full): Declare.
|
||||||
|
(decode_line_1): Update.
|
||||||
|
* linespec.c (struct address_entry, struct linespec_state, struct
|
||||||
|
collect_info): New types.
|
||||||
|
(add_sal_to_sals_basic, add_sal_to_sals, hash_address_entry)
|
||||||
|
(eq_address_entry, maybe_add_address): New functions.
|
||||||
|
(total_number_of_methods): Remove.
|
||||||
|
(iterate_name_matcher, iterate_over_all_matching_symtabs): New
|
||||||
|
functions.
|
||||||
|
(find_methods): Change arguments. Don't canonicalize input.
|
||||||
|
Simplify logic.
|
||||||
|
(add_matching_methods, add_constructors)
|
||||||
|
(build_canonical_line_spec): Remove.
|
||||||
|
(filter_results, convert_results_to_lsals): New functions.
|
||||||
|
(decode_line_2): Change arguments. Rewrite for new data
|
||||||
|
structures.
|
||||||
|
(decode_line_internal): Rename from decode_line_1. Change
|
||||||
|
arguments. Add cleanups. Update for new data structures.
|
||||||
|
(linespec_state_constructor, linespec_state_destructor)
|
||||||
|
(decode_line_full, decode_line_1): New functions.
|
||||||
|
(decode_indirect): Change arguments. Update.
|
||||||
|
(locate_first_half): Use skip_spaces.
|
||||||
|
(decode_objc): Change arguments. Update for new data structures.
|
||||||
|
Simplify logic.
|
||||||
|
(decode_compound): Change arguments. Add cleanups. Remove
|
||||||
|
fallback code, replace with error.
|
||||||
|
(struct decode_compound_collector): New type.
|
||||||
|
(collect_one_symbol): New function.
|
||||||
|
(lookup_prefix_sym): Change arguments. Update.
|
||||||
|
(compare_symbol_name, add_all_symbol_names_from_pspace)
|
||||||
|
(find_superclass_methods ): New functions.
|
||||||
|
(find_method): Rewrite.
|
||||||
|
(struct symtab_collector): New type.
|
||||||
|
(add_symtabs_to_list, collect_symtabs_from_filename): New
|
||||||
|
functions.
|
||||||
|
(symtabs_from_filename): Change API. Rename from
|
||||||
|
symtab_from_filename.
|
||||||
|
(collect_function_symbols): New function.
|
||||||
|
(find_function_symbols): Change API. Rename from
|
||||||
|
find_function_symbol. Rewrite.
|
||||||
|
(decode_all_digits): Change arguments. Rewrite.
|
||||||
|
(decode_dollar): Change arguments. Use decode_variable.
|
||||||
|
(decode_label): Change arguments. Rewrite.
|
||||||
|
(collect_symbols): New function.
|
||||||
|
(minsym_found): Change arguments. Rewrite.
|
||||||
|
(check_minsym, search_minsyms_for_name)
|
||||||
|
(add_matching_symbols_to_info): New function.
|
||||||
|
(decode_variable): Change arguments. Iterate over all symbols.
|
||||||
|
(symbol_found): Remove.
|
||||||
|
(symbol_to_sal): New function.
|
||||||
|
(init_linespec_result, destroy_linespec_result)
|
||||||
|
(cleanup_linespec_result, make_cleanup_destroy_linespec_result):
|
||||||
|
New functions.
|
||||||
|
(decode_digits_list_mode, decode_digits_ordinary): New functions.
|
||||||
|
* dwarf2read.c (dw2_map_expand_apply): New function.
|
||||||
|
(dw2_map_symtabs_matching_filename): Rename from
|
||||||
|
dw2_lookup_symtab. Change arguments.
|
||||||
|
(dwarf2_gdb_index_functions): Update.
|
||||||
|
* dwarf2loc.c: Remove DEF_VEC_I(CORE_ADDR).
|
||||||
|
* defs.h (compare_strings): Declare.
|
||||||
|
* cli/cli-cmds.c (compare_strings): Move to utils.c.
|
||||||
|
(edit_command, list_command): Use DECODE_LINE_LIST_MODE. Call
|
||||||
|
filter_sals.
|
||||||
|
(compare_symtabs, filter_sals): New functions.
|
||||||
|
* breakpoint.h (struct bp_location) <line_number, source_file>:
|
||||||
|
New fields.
|
||||||
|
(struct breakpoint) <line_number, source_file>: Remove.
|
||||||
|
<filter>: New field.
|
||||||
|
* breakpoint.c (print_breakpoint_location, init_raw_breakpoint)
|
||||||
|
(momentary_breakpoint_from_master, add_location_to_breakpoint):
|
||||||
|
Update for changes to locations.
|
||||||
|
(init_breakpoint_sal): Add 'filter' argument. Set 'filter' on
|
||||||
|
breakpoint.
|
||||||
|
(create_breakpoint_sal): Add 'filter' argument.
|
||||||
|
(remove_sal, expand_line_sal_maybe): Remove.
|
||||||
|
(create_breakpoints_sal): Remove 'sals' argument. Handle
|
||||||
|
pre-expanded sals and the filter.
|
||||||
|
(parse_breakpoint_sals): Use decode_line_full.
|
||||||
|
(check_fast_tracepoint_sals): Use get_sal_arch.
|
||||||
|
(create_breakpoint): Create a linespec_sals. Update.
|
||||||
|
(break_range_command): Use decode_line_full. Update.
|
||||||
|
(until_break_command): Update.
|
||||||
|
(clear_command): Update match conditions for linespec.c changes.
|
||||||
|
Use DECODE_LINE_LIST_MODE.
|
||||||
|
(say_where): Update for changes to locations.
|
||||||
|
(bp_location_dtor): Free 'source_file'.
|
||||||
|
(base_breakpoint_dtor): Free 'filter'. Don't free 'source_file'.
|
||||||
|
(update_static_tracepoint): Update for changes to locations.
|
||||||
|
(update_breakpoint_locations): Disable ranged breakpoint if too
|
||||||
|
many locations match. Update.
|
||||||
|
(addr_string_to_sals): Use decode_line_full. Resolve all sal
|
||||||
|
PCs.
|
||||||
|
(breakpoint_re_set_default): Don't call expand_line_sal_maybe.
|
||||||
|
(decode_line_spec_1): Update. Change argument name to 'flags',
|
||||||
|
change interpretation.
|
||||||
|
* block.h (block_containing_function): Declare.
|
||||||
|
* block.c (block_containing_function): New function.
|
||||||
|
* skip.c (skip_function_command): Update.
|
||||||
|
(skip_re_set): Update.
|
||||||
|
* infcmd.c (jump_command): Use DECODE_LINE_FUNFIRSTLINE.
|
||||||
|
* mi/mi-main.c (mi_cmd_trace_find): Use DECODE_LINE_FUNFIRSTLINE.
|
||||||
|
* NEWS: Add entry.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* elfread.c (elf_gnu_ifunc_resolver_return_stop): Allow
|
||||||
|
breakpoint's pspace to be NULL.
|
||||||
|
* breakpoint.h (struct breakpoint) <pspace>: Update comment.
|
||||||
|
* breakpoint.c (init_raw_breakpoint): Conditionally set
|
||||||
|
breakpoint's pspace.
|
||||||
|
(init_breakpoint_sal): Don't set breakpoint's pspace.
|
||||||
|
(prepare_re_set_context): Conditionally switch program space.
|
||||||
|
(addr_string_to_sals): Check executing_startup on location's
|
||||||
|
program space.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* breakpoint.h (enum enable_state) <bp_startup_disabled>: Remove.
|
||||||
|
* breakpoint.c (should_be_inserted): Explicitly check if program
|
||||||
|
space is executing startup.
|
||||||
|
(describe_other_breakpoints): Update.
|
||||||
|
(disable_breakpoints_before_startup): Change executing_startup
|
||||||
|
earlier. Remove loop.
|
||||||
|
(enable_breakpoints_after_startup): Likewise.
|
||||||
|
(init_breakpoint_sal): Don't use bp_startup_disabled.
|
||||||
|
(create_breakpoint): Don't use bp_startup_disabled.
|
||||||
|
(update_global_location_list): Use should_be_inserted.
|
||||||
|
(bkpt_re_set): Update.
|
||||||
|
|
||||||
2011-12-06 Tom Tromey <tromey@redhat.com>
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
* python/lib/gdb/command/pretty_printers.py
|
* python/lib/gdb/command/pretty_printers.py
|
||||||
|
|
6
gdb/NEWS
6
gdb/NEWS
|
@ -3,6 +3,12 @@
|
||||||
|
|
||||||
*** Changes since GDB 7.3.1
|
*** Changes since GDB 7.3.1
|
||||||
|
|
||||||
|
* GDB now handles ambiguous linespecs more consistently; the existing
|
||||||
|
FILE:LINE support has been expanded to other types of linespecs. A
|
||||||
|
breakpoint will now be set on all matching locations in all
|
||||||
|
inferiors, and locations will be added or removed according to
|
||||||
|
inferior changes.
|
||||||
|
|
||||||
* GDB now allows you to skip uninteresting functions and files when
|
* GDB now allows you to skip uninteresting functions and files when
|
||||||
stepping with the "skip function" and "skip file" commands.
|
stepping with the "skip function" and "skip file" commands.
|
||||||
|
|
||||||
|
|
|
@ -5052,6 +5052,50 @@ done:
|
||||||
return ndefns;
|
return ndefns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If NAME is the name of an entity, return a string that should
|
||||||
|
be used to look that entity up in Ada units. This string should
|
||||||
|
be deallocated after use using xfree.
|
||||||
|
|
||||||
|
NAME can have any form that the "break" or "print" commands might
|
||||||
|
recognize. In other words, it does not have to be the "natural"
|
||||||
|
name, or the "encoded" name. */
|
||||||
|
|
||||||
|
char *
|
||||||
|
ada_name_for_lookup (const char *name)
|
||||||
|
{
|
||||||
|
char *canon;
|
||||||
|
int nlen = strlen (name);
|
||||||
|
|
||||||
|
if (name[0] == '<' && name[nlen - 1] == '>')
|
||||||
|
{
|
||||||
|
canon = xmalloc (nlen - 1);
|
||||||
|
memcpy (canon, name + 1, nlen - 2);
|
||||||
|
canon[nlen - 2] = '\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
canon = xstrdup (ada_encode (ada_fold_name (name)));
|
||||||
|
return canon;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of the la_iterate_over_symbols method. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
ada_iterate_over_symbols (const struct block *block,
|
||||||
|
const char *name, domain_enum domain,
|
||||||
|
int (*callback) (struct symbol *, void *),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
int ndefs, i;
|
||||||
|
struct ada_symbol_info *results;
|
||||||
|
|
||||||
|
ndefs = ada_lookup_symbol_list (name, block, domain, &results);
|
||||||
|
for (i = 0; i < ndefs; ++i)
|
||||||
|
{
|
||||||
|
if (! (*callback) (results[i].sym, data))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct symbol *
|
struct symbol *
|
||||||
ada_lookup_encoded_symbol (const char *name, const struct block *block0,
|
ada_lookup_encoded_symbol (const char *name, const struct block *block0,
|
||||||
domain_enum namespace, struct block **block_found)
|
domain_enum namespace, struct block **block_found)
|
||||||
|
@ -5633,7 +5677,8 @@ struct add_partial_datum
|
||||||
|
|
||||||
/* A callback for expand_partial_symbol_names. */
|
/* A callback for expand_partial_symbol_names. */
|
||||||
static int
|
static int
|
||||||
ada_expand_partial_symbol_name (const char *name, void *user_data)
|
ada_expand_partial_symbol_name (const struct language_defn *language,
|
||||||
|
const char *name, void *user_data)
|
||||||
{
|
{
|
||||||
struct add_partial_datum *data = user_data;
|
struct add_partial_datum *data = user_data;
|
||||||
|
|
||||||
|
@ -12282,6 +12327,8 @@ const struct language_defn ada_language_defn = {
|
||||||
ada_print_array_index,
|
ada_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
compare_names,
|
||||||
|
ada_iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -365,6 +365,8 @@ extern char *ada_breakpoint_rewrite (char *, int *);
|
||||||
|
|
||||||
extern char *ada_main_name (void);
|
extern char *ada_main_name (void);
|
||||||
|
|
||||||
|
extern char *ada_name_for_lookup (const char *name);
|
||||||
|
|
||||||
/* Tasking-related: ada-tasks.c */
|
/* Tasking-related: ada-tasks.c */
|
||||||
|
|
||||||
extern int valid_task_id (int);
|
extern int valid_task_id (int);
|
||||||
|
|
14
gdb/block.c
14
gdb/block.c
|
@ -82,6 +82,20 @@ block_linkage_function (const struct block *bl)
|
||||||
return BLOCK_FUNCTION (bl);
|
return BLOCK_FUNCTION (bl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the symbol for the function which contains a specified
|
||||||
|
block, described by a struct block BL. The return value will be
|
||||||
|
the closest enclosing function, which might be an inline
|
||||||
|
function. */
|
||||||
|
|
||||||
|
struct symbol *
|
||||||
|
block_containing_function (const struct block *bl)
|
||||||
|
{
|
||||||
|
while (BLOCK_FUNCTION (bl) == NULL && BLOCK_SUPERBLOCK (bl) != NULL)
|
||||||
|
bl = BLOCK_SUPERBLOCK (bl);
|
||||||
|
|
||||||
|
return BLOCK_FUNCTION (bl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return one if BL represents an inlined function. */
|
/* Return one if BL represents an inlined function. */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -131,6 +131,8 @@ struct blockvector
|
||||||
|
|
||||||
extern struct symbol *block_linkage_function (const struct block *);
|
extern struct symbol *block_linkage_function (const struct block *);
|
||||||
|
|
||||||
|
extern struct symbol *block_containing_function (const struct block *);
|
||||||
|
|
||||||
extern int block_inlined_p (const struct block *block);
|
extern int block_inlined_p (const struct block *block);
|
||||||
|
|
||||||
extern int contained_in (const struct block *, const struct block *);
|
extern int contained_in (const struct block *, const struct block *);
|
||||||
|
|
646
gdb/breakpoint.c
646
gdb/breakpoint.c
File diff suppressed because it is too large
Load diff
|
@ -186,14 +186,6 @@ enum enable_state
|
||||||
automatically enabled and reset when the
|
automatically enabled and reset when the
|
||||||
call "lands" (either completes, or stops
|
call "lands" (either completes, or stops
|
||||||
at another eventpoint). */
|
at another eventpoint). */
|
||||||
bp_startup_disabled, /* The eventpoint has been disabled during
|
|
||||||
inferior startup. This is necessary on
|
|
||||||
some targets where the main executable
|
|
||||||
will get relocated during startup, making
|
|
||||||
breakpoint addresses invalid. The
|
|
||||||
eventpoint will be automatically enabled
|
|
||||||
and reset once inferior startup is
|
|
||||||
complete. */
|
|
||||||
bp_permanent /* There is a breakpoint instruction
|
bp_permanent /* There is a breakpoint instruction
|
||||||
hard-wired into the target's code. Don't
|
hard-wired into the target's code. Don't
|
||||||
try to write another breakpoint
|
try to write another breakpoint
|
||||||
|
@ -405,6 +397,14 @@ struct bp_location
|
||||||
This variable keeps a number of events still to go, when
|
This variable keeps a number of events still to go, when
|
||||||
it becomes 0 this location is retired. */
|
it becomes 0 this location is retired. */
|
||||||
int events_till_retirement;
|
int events_till_retirement;
|
||||||
|
|
||||||
|
/* Line number of this address. */
|
||||||
|
|
||||||
|
int line_number;
|
||||||
|
|
||||||
|
/* Source file name of this address. */
|
||||||
|
|
||||||
|
char *source_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This structure is a collection of function pointers that, if available,
|
/* This structure is a collection of function pointers that, if available,
|
||||||
|
@ -552,14 +552,6 @@ struct breakpoint
|
||||||
/* Location(s) associated with this high-level breakpoint. */
|
/* Location(s) associated with this high-level breakpoint. */
|
||||||
struct bp_location *loc;
|
struct bp_location *loc;
|
||||||
|
|
||||||
/* Line number of this address. */
|
|
||||||
|
|
||||||
int line_number;
|
|
||||||
|
|
||||||
/* Source file name of this address. */
|
|
||||||
|
|
||||||
char *source_file;
|
|
||||||
|
|
||||||
/* Non-zero means a silent breakpoint (don't print frame info
|
/* Non-zero means a silent breakpoint (don't print frame info
|
||||||
if we stop here). */
|
if we stop here). */
|
||||||
unsigned char silent;
|
unsigned char silent;
|
||||||
|
@ -575,12 +567,19 @@ struct breakpoint
|
||||||
equals this. */
|
equals this. */
|
||||||
struct frame_id frame_id;
|
struct frame_id frame_id;
|
||||||
|
|
||||||
/* The program space used to set the breakpoint. */
|
/* The program space used to set the breakpoint. This is only set
|
||||||
|
for breakpoints which are specific to a program space; for
|
||||||
|
ordinary breakpoints this is NULL. */
|
||||||
struct program_space *pspace;
|
struct program_space *pspace;
|
||||||
|
|
||||||
/* String we used to set the breakpoint (malloc'd). */
|
/* String we used to set the breakpoint (malloc'd). */
|
||||||
char *addr_string;
|
char *addr_string;
|
||||||
|
|
||||||
|
/* The filter that should be passed to decode_line_full when
|
||||||
|
re-setting this breakpoint. This may be NULL, but otherwise is
|
||||||
|
allocated with xmalloc. */
|
||||||
|
char *filter;
|
||||||
|
|
||||||
/* For a ranged breakpoint, the string we used to find
|
/* For a ranged breakpoint, the string we used to find
|
||||||
the end of the range (malloc'd). */
|
the end of the range (malloc'd). */
|
||||||
char *addr_string_range_end;
|
char *addr_string_range_end;
|
||||||
|
|
|
@ -863,6 +863,8 @@ const struct language_defn c_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -984,6 +986,8 @@ const struct language_defn cplus_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
cp_pass_by_reference,
|
cp_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1023,6 +1027,8 @@ const struct language_defn asm_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1067,6 +1073,8 @@ const struct language_defn minimal_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,9 @@ void apropos_command (char *, int);
|
||||||
/* Prototypes for local utility functions */
|
/* Prototypes for local utility functions */
|
||||||
|
|
||||||
static void ambiguous_line_spec (struct symtabs_and_lines *);
|
static void ambiguous_line_spec (struct symtabs_and_lines *);
|
||||||
|
|
||||||
|
static void filter_sals (struct symtabs_and_lines *);
|
||||||
|
|
||||||
|
|
||||||
/* Limit the call depth of user-defined commands */
|
/* Limit the call depth of user-defined commands */
|
||||||
int max_user_call_depth;
|
int max_user_call_depth;
|
||||||
|
@ -246,16 +249,6 @@ help_command (char *command, int from_tty)
|
||||||
help_cmd (command, gdb_stdout);
|
help_cmd (command, gdb_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* String compare function for qsort. */
|
|
||||||
static int
|
|
||||||
compare_strings (const void *arg1, const void *arg2)
|
|
||||||
{
|
|
||||||
const char **s1 = (const char **) arg1;
|
|
||||||
const char **s2 = (const char **) arg2;
|
|
||||||
|
|
||||||
return strcmp (*s1, *s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The "complete" command is used by Emacs to implement completion. */
|
/* The "complete" command is used by Emacs to implement completion. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -796,8 +789,9 @@ edit_command (char *arg, int from_tty)
|
||||||
/* Now should only be one argument -- decode it in SAL. */
|
/* Now should only be one argument -- decode it in SAL. */
|
||||||
|
|
||||||
arg1 = arg;
|
arg1 = arg;
|
||||||
sals = decode_line_1 (&arg1, 0, 0, 0, 0);
|
sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
|
||||||
|
|
||||||
|
filter_sals (&sals);
|
||||||
if (! sals.nelts)
|
if (! sals.nelts)
|
||||||
{
|
{
|
||||||
/* C++ */
|
/* C++ */
|
||||||
|
@ -926,8 +920,9 @@ list_command (char *arg, int from_tty)
|
||||||
dummy_beg = 1;
|
dummy_beg = 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sals = decode_line_1 (&arg1, 0, 0, 0, 0);
|
sals = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
|
||||||
|
|
||||||
|
filter_sals (&sals);
|
||||||
if (!sals.nelts)
|
if (!sals.nelts)
|
||||||
return; /* C++ */
|
return; /* C++ */
|
||||||
if (sals.nelts > 1)
|
if (sals.nelts > 1)
|
||||||
|
@ -959,9 +954,11 @@ list_command (char *arg, int from_tty)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dummy_beg)
|
if (dummy_beg)
|
||||||
sals_end = decode_line_1 (&arg1, 0, 0, 0, 0);
|
sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE, 0, 0);
|
||||||
else
|
else
|
||||||
sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line, 0);
|
sals_end = decode_line_1 (&arg1, DECODE_LINE_LIST_MODE,
|
||||||
|
sal.symtab, sal.line);
|
||||||
|
filter_sals (&sals);
|
||||||
if (sals_end.nelts == 0)
|
if (sals_end.nelts == 0)
|
||||||
return;
|
return;
|
||||||
if (sals_end.nelts > 1)
|
if (sals_end.nelts > 1)
|
||||||
|
@ -1472,6 +1469,85 @@ ambiguous_line_spec (struct symtabs_and_lines *sals)
|
||||||
sals->sals[i].symtab->filename, sals->sals[i].line);
|
sals->sals[i].symtab->filename, sals->sals[i].line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort function for filter_sals. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
compare_symtabs (const void *a, const void *b)
|
||||||
|
{
|
||||||
|
const struct symtab_and_line *sala = a;
|
||||||
|
const struct symtab_and_line *salb = b;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
if (!sala->symtab->dirname)
|
||||||
|
{
|
||||||
|
if (salb->symtab->dirname)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (!salb->symtab->dirname)
|
||||||
|
{
|
||||||
|
if (sala->symtab->dirname)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
r = filename_cmp (sala->symtab->dirname, salb->symtab->dirname);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = filename_cmp (sala->symtab->filename, salb->symtab->filename);
|
||||||
|
if (r)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (sala->line < salb->line)
|
||||||
|
return -1;
|
||||||
|
return sala->line == salb->line ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove any SALs that do not match the current program space, or
|
||||||
|
which appear to be "file:line" duplicates. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
filter_sals (struct symtabs_and_lines *sals)
|
||||||
|
{
|
||||||
|
int i, out, prev;
|
||||||
|
|
||||||
|
out = 0;
|
||||||
|
for (i = 0; i < sals->nelts; ++i)
|
||||||
|
{
|
||||||
|
if (sals->sals[i].pspace == current_program_space
|
||||||
|
|| sals->sals[i].symtab == NULL)
|
||||||
|
{
|
||||||
|
sals->sals[out] = sals->sals[i];
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sals->nelts = out;
|
||||||
|
|
||||||
|
qsort (sals->sals, sals->nelts, sizeof (struct symtab_and_line),
|
||||||
|
compare_symtabs);
|
||||||
|
|
||||||
|
out = 1;
|
||||||
|
prev = 0;
|
||||||
|
for (i = 1; i < sals->nelts; ++i)
|
||||||
|
{
|
||||||
|
if (compare_symtabs (&sals->sals[prev], &sals->sals[i]))
|
||||||
|
{
|
||||||
|
/* Symtabs differ. */
|
||||||
|
sals->sals[out] = sals->sals[i];
|
||||||
|
prev = out;
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sals->nelts = out;
|
||||||
|
|
||||||
|
if (sals->nelts == 0)
|
||||||
|
{
|
||||||
|
xfree (sals->sals);
|
||||||
|
sals->sals = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_debug (char *arg, int from_tty)
|
set_debug (char *arg, int from_tty)
|
||||||
{
|
{
|
||||||
|
|
|
@ -273,6 +273,8 @@ static const struct language_defn d_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
NULL,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,7 @@ char *ldirname (const char *filename);
|
||||||
char **gdb_buildargv (const char *);
|
char **gdb_buildargv (const char *);
|
||||||
|
|
||||||
int compare_positive_ints (const void *ap, const void *bp);
|
int compare_positive_ints (const void *ap, const void *bp);
|
||||||
|
int compare_strings (const void *ap, const void *bp);
|
||||||
|
|
||||||
/* A wrapper for bfd_errmsg to produce a more helpful error message
|
/* A wrapper for bfd_errmsg to produce a more helpful error message
|
||||||
in the case of bfd_error_file_ambiguously recognized.
|
in the case of bfd_error_file_ambiguously recognized.
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* gdb.texinfo (Set Breaks): Update for new behavior.
|
||||||
|
|
||||||
2011-12-02 Jan Kratochvil <jan.kratochvil@redhat.com>
|
2011-12-02 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||||
|
|
||||||
* gdb.texinfo (Requirements, Remote Protocol): Reference also `Library
|
* gdb.texinfo (Requirements, Remote Protocol): Reference also `Library
|
||||||
|
|
|
@ -3521,6 +3521,9 @@ It is possible that a breakpoint corresponds to several locations
|
||||||
in your program. Examples of this situation are:
|
in your program. Examples of this situation are:
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Multiple functions in the program may have the same name.
|
||||||
|
|
||||||
@item
|
@item
|
||||||
For a C@t{++} constructor, the @value{NGCC} compiler generates several
|
For a C@t{++} constructor, the @value{NGCC} compiler generates several
|
||||||
instances of the function body, used in different cases.
|
instances of the function body, used in different cases.
|
||||||
|
@ -3535,11 +3538,7 @@ several places where that function is inlined.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
In all those cases, @value{GDBN} will insert a breakpoint at all
|
In all those cases, @value{GDBN} will insert a breakpoint at all
|
||||||
the relevant locations@footnote{
|
the relevant locations.
|
||||||
As of this writing, multiple-location breakpoints work only if there's
|
|
||||||
line number information for all the locations. This means that they
|
|
||||||
will generally not work in system libraries, unless you have debug
|
|
||||||
info with line numbers for them.}.
|
|
||||||
|
|
||||||
A breakpoint with multiple locations is displayed in the breakpoint
|
A breakpoint with multiple locations is displayed in the breakpoint
|
||||||
table using several rows---one header row, followed by one row for
|
table using several rows---one header row, followed by one row for
|
||||||
|
|
|
@ -443,9 +443,6 @@ func_addr_to_tail_call_list (struct gdbarch *gdbarch, CORE_ADDR addr)
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define VEC (CORE_ADDR) functions. */
|
|
||||||
DEF_VEC_I (CORE_ADDR);
|
|
||||||
|
|
||||||
/* Verify function with entry point exact address ADDR can never call itself
|
/* Verify function with entry point exact address ADDR can never call itself
|
||||||
via its tail calls (incl. transitively). Throw NO_ENTRY_VALUE_ERROR if it
|
via its tail calls (incl. transitively). Throw NO_ENTRY_VALUE_ERROR if it
|
||||||
can call itself via tail calls.
|
can call itself via tail calls.
|
||||||
|
|
|
@ -2439,10 +2439,38 @@ dw2_forget_cached_source_info (struct objfile *objfile)
|
||||||
dw2_free_cached_file_names, NULL);
|
dw2_free_cached_file_names, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function for dw2_map_symtabs_matching_filename that expands
|
||||||
|
the symtabs and calls the iterator. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dw2_lookup_symtab (struct objfile *objfile, const char *name,
|
dw2_map_expand_apply (struct objfile *objfile,
|
||||||
const char *full_path, const char *real_path,
|
struct dwarf2_per_cu_data *per_cu,
|
||||||
struct symtab **result)
|
const char *name,
|
||||||
|
const char *full_path, const char *real_path,
|
||||||
|
int (*callback) (struct symtab *, void *),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct symtab *last_made = objfile->symtabs;
|
||||||
|
|
||||||
|
/* Don't visit already-expanded CUs. */
|
||||||
|
if (per_cu->v.quick->symtab)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* This may expand more than one symtab, and we want to iterate over
|
||||||
|
all of them. */
|
||||||
|
dw2_instantiate_symtab (objfile, per_cu);
|
||||||
|
|
||||||
|
return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
|
||||||
|
objfile->symtabs, last_made);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of the map_symtabs_matching_filename method. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
|
||||||
|
const char *full_path, const char *real_path,
|
||||||
|
int (*callback) (struct symtab *, void *),
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const char *name_basename = lbasename (name);
|
const char *name_basename = lbasename (name);
|
||||||
|
@ -2472,8 +2500,10 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
|
||||||
|
|
||||||
if (FILENAME_CMP (name, this_name) == 0)
|
if (FILENAME_CMP (name, this_name) == 0)
|
||||||
{
|
{
|
||||||
*result = dw2_instantiate_symtab (objfile, per_cu);
|
if (dw2_map_expand_apply (objfile, per_cu,
|
||||||
return 1;
|
name, full_path, real_path,
|
||||||
|
callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_basename && ! base_cu
|
if (check_basename && ! base_cu
|
||||||
|
@ -2494,8 +2524,10 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
|
||||||
if (this_real_name != NULL
|
if (this_real_name != NULL
|
||||||
&& FILENAME_CMP (full_path, this_real_name) == 0)
|
&& FILENAME_CMP (full_path, this_real_name) == 0)
|
||||||
{
|
{
|
||||||
*result = dw2_instantiate_symtab (objfile, per_cu);
|
if (dw2_map_expand_apply (objfile, per_cu,
|
||||||
return 1;
|
name, full_path, real_path,
|
||||||
|
callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2507,8 +2539,10 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
|
||||||
if (this_real_name != NULL
|
if (this_real_name != NULL
|
||||||
&& FILENAME_CMP (real_path, this_real_name) == 0)
|
&& FILENAME_CMP (real_path, this_real_name) == 0)
|
||||||
{
|
{
|
||||||
*result = dw2_instantiate_symtab (objfile, per_cu);
|
if (dw2_map_expand_apply (objfile, per_cu,
|
||||||
return 1;
|
name, full_path, real_path,
|
||||||
|
callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2516,8 +2550,10 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name,
|
||||||
|
|
||||||
if (base_cu)
|
if (base_cu)
|
||||||
{
|
{
|
||||||
*result = dw2_instantiate_symtab (objfile, base_cu);
|
if (dw2_map_expand_apply (objfile, base_cu,
|
||||||
return 1;
|
name, full_path, real_path,
|
||||||
|
callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2720,11 +2756,12 @@ dw2_map_matching_symbols (const char * name, domain_enum namespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dw2_expand_symtabs_matching (struct objfile *objfile,
|
dw2_expand_symtabs_matching
|
||||||
int (*file_matcher) (const char *, void *),
|
(struct objfile *objfile,
|
||||||
int (*name_matcher) (const char *, void *),
|
int (*file_matcher) (const char *, void *),
|
||||||
enum search_domain kind,
|
int (*name_matcher) (const struct language_defn *, const char *, void *),
|
||||||
void *data)
|
enum search_domain kind,
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
offset_type iter;
|
offset_type iter;
|
||||||
|
@ -2776,7 +2813,7 @@ dw2_expand_symtabs_matching (struct objfile *objfile,
|
||||||
|
|
||||||
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
|
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
|
||||||
|
|
||||||
if (! (*name_matcher) (name, data))
|
if (! (*name_matcher) (current_language, name, data))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* The name was matched, now expand corresponding CUs that were
|
/* The name was matched, now expand corresponding CUs that were
|
||||||
|
@ -2867,7 +2904,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
|
||||||
dw2_has_symbols,
|
dw2_has_symbols,
|
||||||
dw2_find_last_source_symtab,
|
dw2_find_last_source_symtab,
|
||||||
dw2_forget_cached_source_info,
|
dw2_forget_cached_source_info,
|
||||||
dw2_lookup_symtab,
|
dw2_map_symtabs_matching_filename,
|
||||||
dw2_lookup_symbol,
|
dw2_lookup_symbol,
|
||||||
dw2_pre_expand_symtabs_matching,
|
dw2_pre_expand_symtabs_matching,
|
||||||
dw2_print_stats,
|
dw2_print_stats,
|
||||||
|
|
|
@ -1032,7 +1032,7 @@ elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
|
||||||
}
|
}
|
||||||
gdb_assert (b->type == bp_gnu_ifunc_resolver);
|
gdb_assert (b->type == bp_gnu_ifunc_resolver);
|
||||||
|
|
||||||
gdb_assert (current_program_space == b->pspace);
|
gdb_assert (current_program_space == b->pspace || b->pspace == NULL);
|
||||||
elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);
|
elf_gnu_ifunc_record_cache (b->addr_string, resolved_pc);
|
||||||
|
|
||||||
sal = find_pc_line (resolved_pc, 0);
|
sal = find_pc_line (resolved_pc, 0);
|
||||||
|
|
|
@ -309,6 +309,8 @@ const struct language_defn f_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,7 @@
|
||||||
#include "tracepoint.h"
|
#include "tracepoint.h"
|
||||||
#include "inf-loop.h"
|
#include "inf-loop.h"
|
||||||
#include "continuations.h"
|
#include "continuations.h"
|
||||||
|
#include "linespec.h"
|
||||||
|
|
||||||
/* Functions exported for general use, in inferior.h: */
|
/* Functions exported for general use, in inferior.h: */
|
||||||
|
|
||||||
|
@ -1116,7 +1117,7 @@ jump_command (char *arg, int from_tty)
|
||||||
if (!arg)
|
if (!arg)
|
||||||
error_no_arg (_("starting address"));
|
error_no_arg (_("starting address"));
|
||||||
|
|
||||||
sals = decode_line_spec_1 (arg, 1);
|
sals = decode_line_spec_1 (arg, DECODE_LINE_FUNFIRSTLINE);
|
||||||
if (sals.nelts != 1)
|
if (sals.nelts != 1)
|
||||||
{
|
{
|
||||||
error (_("Unreasonable jump request"));
|
error (_("Unreasonable jump request"));
|
||||||
|
|
|
@ -1197,6 +1197,8 @@ const struct language_defn java_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1200,6 +1200,8 @@ const struct language_defn unknown_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1241,6 +1243,8 @@ const struct language_defn auto_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1280,6 +1284,8 @@ const struct language_defn local_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,40 @@ struct language_defn
|
||||||
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
|
void (*la_get_string) (struct value *value, gdb_byte **buffer, int *length,
|
||||||
struct type **chartype, const char **charset);
|
struct type **chartype, const char **charset);
|
||||||
|
|
||||||
|
/* Compare two symbol names according to language rules. For
|
||||||
|
instance, in C++, we might want to ignore whitespaces in
|
||||||
|
the symbol name. Or some case-insensitive language might
|
||||||
|
want to ignore casing during the match.
|
||||||
|
|
||||||
|
Both STR1 and STR2 are expected to be demangled name, except
|
||||||
|
for Ada, where STR1 and STR2 are expected to be encoded names.
|
||||||
|
The latter is because searches are performed using the encoded
|
||||||
|
name in Ada.
|
||||||
|
|
||||||
|
The return value follows the same spirit as strcmp. */
|
||||||
|
|
||||||
|
int (*la_symbol_name_compare) (const char *str1, const char *str2);
|
||||||
|
|
||||||
|
/* Find all symbols in the current program space matching NAME in
|
||||||
|
DOMAIN, according to this language's rules.
|
||||||
|
|
||||||
|
The search starts with BLOCK. This function iterates upward
|
||||||
|
through blocks. When the outermost block has been finished,
|
||||||
|
the function returns.
|
||||||
|
|
||||||
|
For each one, call CALLBACK with the symbol and the DATA
|
||||||
|
argument. If CALLBACK returns zero, the iteration ends at that
|
||||||
|
point.
|
||||||
|
|
||||||
|
This field can be NULL, meaning that this language doesn't need
|
||||||
|
any special code aside from ordinary searches of the symbol
|
||||||
|
table. */
|
||||||
|
void (*la_iterate_over_symbols) (const struct block *block,
|
||||||
|
const char *name,
|
||||||
|
domain_enum domain,
|
||||||
|
int (*callback) (struct symbol *, void *),
|
||||||
|
void *data);
|
||||||
|
|
||||||
/* Add fields above this point, so the magic number is always last. */
|
/* Add fields above this point, so the magic number is always last. */
|
||||||
/* Magic number for compat checking. */
|
/* Magic number for compat checking. */
|
||||||
|
|
||||||
|
@ -422,6 +456,10 @@ extern enum language set_language (enum language);
|
||||||
#define LA_PRINT_ARRAY_INDEX(index_value, stream, options) \
|
#define LA_PRINT_ARRAY_INDEX(index_value, stream, options) \
|
||||||
(current_language->la_print_array_index(index_value, stream, options))
|
(current_language->la_print_array_index(index_value, stream, options))
|
||||||
|
|
||||||
|
#define LA_ITERATE_OVER_SYMBOLS(BLOCK, NAME, DOMAIN, CALLBACK, DATA) \
|
||||||
|
(current_language->la_iterate_over_symbols (BLOCK, NAME, DOMAIN, CALLBACK, \
|
||||||
|
DATA))
|
||||||
|
|
||||||
/* Test a character to decide whether it can be printed in literal form
|
/* Test a character to decide whether it can be printed in literal form
|
||||||
or needs to be printed in another representation. For example,
|
or needs to be printed in another representation. For example,
|
||||||
in C the literal form of the character with octal value 141 is 'a'
|
in C the literal form of the character with octal value 141 is 'a'
|
||||||
|
|
2555
gdb/linespec.c
2555
gdb/linespec.c
File diff suppressed because it is too large
Load diff
114
gdb/linespec.h
114
gdb/linespec.h
|
@ -20,8 +20,44 @@
|
||||||
|
|
||||||
struct symtab;
|
struct symtab;
|
||||||
|
|
||||||
|
#include "vec.h"
|
||||||
|
|
||||||
|
/* Flags to pass to decode_line_1 and decode_line_full. */
|
||||||
|
|
||||||
|
enum decode_line_flags
|
||||||
|
{
|
||||||
|
/* Set this flag if you want the resulting SALs to describe the
|
||||||
|
first line of indicated functions. */
|
||||||
|
DECODE_LINE_FUNFIRSTLINE = 1,
|
||||||
|
|
||||||
|
/* Set this flag if you want "list mode". In this mode, a
|
||||||
|
FILE:LINE linespec will always return a result, and such
|
||||||
|
linespecs will not be expanded to all matches. */
|
||||||
|
DECODE_LINE_LIST_MODE = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
/* decode_line_full returns a vector of these. */
|
||||||
|
|
||||||
|
struct linespec_sals
|
||||||
|
{
|
||||||
|
/* This is the linespec corresponding to the sals contained in this
|
||||||
|
object. It can be passed as the FILTER argument to future calls
|
||||||
|
to decode_line_full. This is freed by
|
||||||
|
destroy_linespec_result. */
|
||||||
|
char *canonical;
|
||||||
|
|
||||||
|
/* Sals. The 'sals' field is destroyed by
|
||||||
|
destroy_linespec_result. */
|
||||||
|
struct symtabs_and_lines sals;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct linespec_sals linespec_sals;
|
||||||
|
DEF_VEC_O (linespec_sals);
|
||||||
|
|
||||||
/* An instance of this may be filled in by decode_line_1. The caller
|
/* An instance of this may be filled in by decode_line_1. The caller
|
||||||
must call init_linespec_result to initialize it. */
|
must call init_linespec_result to initialize it and
|
||||||
|
destroy_linespec_result to destroy it. The caller must make copies
|
||||||
|
of any data that it needs to keep. */
|
||||||
|
|
||||||
struct linespec_result
|
struct linespec_result
|
||||||
{
|
{
|
||||||
|
@ -30,22 +66,78 @@ struct linespec_result
|
||||||
display mechanism would do the wrong thing. */
|
display mechanism would do the wrong thing. */
|
||||||
int special_display;
|
int special_display;
|
||||||
|
|
||||||
/* If non-NULL, an array of canonical names for returned
|
/* If non-zero, the linespec result should be considered to be a
|
||||||
symtab_and_line objects. The array has as many elements as the
|
"pre-expanded" multi-location linespec. A pre-expanded linespec
|
||||||
`nelts' field in the symtabs_and_line returned by decode_line_1.
|
holds all matching locations in a single linespec_sals
|
||||||
An element in the array may be NULL. The array and each non-NULL
|
object. */
|
||||||
element in it are allocated with xmalloc and must be freed by the
|
int pre_expanded;
|
||||||
caller. */
|
|
||||||
char **canonical;
|
/* If PRE_EXPANDED is non-zero, this is set to the linespec entered
|
||||||
|
by the user. This will be freed by destroy_linespec_result. */
|
||||||
|
char *addr_string;
|
||||||
|
|
||||||
|
/* The sals. The vector will be freed by
|
||||||
|
destroy_linespec_result. */
|
||||||
|
VEC (linespec_sals) *sals;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize a linespec_result. */
|
/* Initialize a linespec_result. */
|
||||||
|
|
||||||
extern void init_linespec_result (struct linespec_result *);
|
extern void init_linespec_result (struct linespec_result *);
|
||||||
|
|
||||||
|
/* Destroy a linespec_result. */
|
||||||
|
|
||||||
|
extern void destroy_linespec_result (struct linespec_result *);
|
||||||
|
|
||||||
|
/* Return a cleanup that destroys a linespec_result. */
|
||||||
|
|
||||||
|
extern struct cleanup *
|
||||||
|
make_cleanup_destroy_linespec_result (struct linespec_result *);
|
||||||
|
|
||||||
extern struct symtabs_and_lines
|
extern struct symtabs_and_lines
|
||||||
decode_line_1 (char **argptr, int funfirstline,
|
decode_line_1 (char **argptr, int flags,
|
||||||
struct symtab *default_symtab, int default_line,
|
struct symtab *default_symtab, int default_line);
|
||||||
struct linespec_result *canonical);
|
|
||||||
|
/* Parse *ARGPTR as a linespec and return results. This is the "full"
|
||||||
|
interface to this module, which handles multiple results
|
||||||
|
properly.
|
||||||
|
|
||||||
|
For FLAGS, see decode_line_flags. DECODE_LINE_LIST_MODE is not
|
||||||
|
valid for this function.
|
||||||
|
|
||||||
|
DEFAULT_SYMTAB and DEFAULT_LINE describe the default location.
|
||||||
|
DEFAULT_SYMTAB can be NULL, in which case the current symtab and
|
||||||
|
line are used.
|
||||||
|
|
||||||
|
CANONICAL is where the results are stored. It must not be NULL.
|
||||||
|
|
||||||
|
SELECT_MODE must be one of the multiple_symbols_* constants, or
|
||||||
|
NULL. It determines how multiple results will be handled. If
|
||||||
|
NULL, the appropriate CLI value will be used.
|
||||||
|
|
||||||
|
FILTER can either be NULL or a string holding a canonical name.
|
||||||
|
This is only valid when SELECT_MODE is multiple_symbols_all.
|
||||||
|
|
||||||
|
Multiple results are handled differently depending on the
|
||||||
|
arguments:
|
||||||
|
|
||||||
|
. With multiple_symbols_cancel, an exception is thrown.
|
||||||
|
|
||||||
|
. With multiple_symbols_ask, a menu is presented to the user. The
|
||||||
|
user may select none, in which case an exception is thrown; or all,
|
||||||
|
which is handled like multiple_symbols_all, below. Otherwise,
|
||||||
|
CANONICAL->SALS will have one entry for each name the user chose.
|
||||||
|
|
||||||
|
. With multiple_symbols_all, CANONICAL->SALS will have a single
|
||||||
|
entry describing all the matching locations. If FILTER is
|
||||||
|
non-NULL, then only locations whose canonical name is equal (in the
|
||||||
|
strcmp sense) to FILTER will be returned; all others will be
|
||||||
|
filtered out. */
|
||||||
|
|
||||||
|
extern void decode_line_full (char **argptr, int flags,
|
||||||
|
struct symtab *default_symtab, int default_line,
|
||||||
|
struct linespec_result *canonical,
|
||||||
|
const char *select_mode,
|
||||||
|
const char *filter);
|
||||||
|
|
||||||
#endif /* defined (LINESPEC_H) */
|
#endif /* defined (LINESPEC_H) */
|
||||||
|
|
|
@ -401,6 +401,8 @@ const struct language_defn m2_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include "splay-tree.h"
|
#include "splay-tree.h"
|
||||||
#include "tracepoint.h"
|
#include "tracepoint.h"
|
||||||
#include "ada-lang.h"
|
#include "ada-lang.h"
|
||||||
|
#include "linespec.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -2437,7 +2438,7 @@ mi_cmd_trace_find (char *command, char **argv, int argc)
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
error (_("Line is required"));
|
error (_("Line is required"));
|
||||||
|
|
||||||
sals = decode_line_spec (argv[1], 1);
|
sals = decode_line_spec (argv[1], DECODE_LINE_FUNFIRSTLINE);
|
||||||
back_to = make_cleanup (xfree, sals.sals);
|
back_to = make_cleanup (xfree, sals.sals);
|
||||||
|
|
||||||
sal = sals.sals[0];
|
sal = sals.sals[0];
|
||||||
|
|
|
@ -310,6 +310,46 @@ lookup_minimal_symbol (const char *name, const char *sfile,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Iterate over all the minimal symbols in the objfile OBJF which
|
||||||
|
match NAME. Both the ordinary and demangled names of each symbol
|
||||||
|
are considered. The caller is responsible for canonicalizing NAME,
|
||||||
|
should that need to be done.
|
||||||
|
|
||||||
|
For each matching symbol, CALLBACK is called with the symbol and
|
||||||
|
USER_DATA as arguments. */
|
||||||
|
|
||||||
|
void
|
||||||
|
iterate_over_minimal_symbols (struct objfile *objf, const char *name,
|
||||||
|
void (*callback) (struct minimal_symbol *,
|
||||||
|
void *),
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
unsigned int hash;
|
||||||
|
struct minimal_symbol *iter;
|
||||||
|
int (*cmp) (const char *, const char *);
|
||||||
|
|
||||||
|
/* The first pass is over the ordinary hash table. */
|
||||||
|
hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
|
iter = objf->msymbol_hash[hash];
|
||||||
|
cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
if (cmp (SYMBOL_LINKAGE_NAME (iter), name) == 0)
|
||||||
|
(*callback) (iter, user_data);
|
||||||
|
iter = iter->hash_next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The second pass is over the demangled table. */
|
||||||
|
hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
|
||||||
|
iter = objf->msymbol_demangled_hash[hash];
|
||||||
|
while (iter)
|
||||||
|
{
|
||||||
|
if (SYMBOL_MATCHES_SEARCH_NAME (iter, name))
|
||||||
|
(*callback) (iter, user_data);
|
||||||
|
iter = iter->demangled_hash_next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Look through all the current minimal symbol tables and find the
|
/* Look through all the current minimal symbol tables and find the
|
||||||
first minimal symbol that matches NAME and has text type. If OBJF
|
first minimal symbol that matches NAME and has text type. If OBJF
|
||||||
is non-NULL, limit the search to that objfile. Returns a pointer
|
is non-NULL, limit the search to that objfile. Returns a pointer
|
||||||
|
|
296
gdb/objc-lang.c
296
gdb/objc-lang.c
|
@ -541,6 +541,8 @@ const struct language_defn objc_language_defn = {
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -952,49 +954,7 @@ classes_info (char *regexp, int from_tty)
|
||||||
printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
|
printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static char *
|
||||||
* Function: find_imps (char *selector, struct symbol **sym_arr)
|
|
||||||
*
|
|
||||||
* Input: a string representing a selector
|
|
||||||
* a pointer to an array of symbol pointers
|
|
||||||
* possibly a pointer to a symbol found by the caller.
|
|
||||||
*
|
|
||||||
* Output: number of methods that implement that selector. Side
|
|
||||||
* effects: The array of symbol pointers is filled with matching syms.
|
|
||||||
*
|
|
||||||
* By analogy with function "find_methods" (symtab.c), builds a list
|
|
||||||
* of symbols matching the ambiguous input, so that "decode_line_2"
|
|
||||||
* (symtab.c) can list them and ask the user to choose one or more.
|
|
||||||
* In this case the matches are objective c methods
|
|
||||||
* ("implementations") matching an objective c selector.
|
|
||||||
*
|
|
||||||
* Note that it is possible for a normal (c-style) function to have
|
|
||||||
* the same name as an objective c selector. To prevent the selector
|
|
||||||
* from eclipsing the function, we allow the caller (decode_line_1) to
|
|
||||||
* search for such a function first, and if it finds one, pass it in
|
|
||||||
* to us. We will then integrate it into the list. We also search
|
|
||||||
* for one here, among the minsyms.
|
|
||||||
*
|
|
||||||
* NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
|
|
||||||
* into two parts: debuggable (struct symbol) syms, and
|
|
||||||
* non_debuggable (struct minimal_symbol) syms. The debuggable
|
|
||||||
* ones will come first, before NUM_DEBUGGABLE (which will thus
|
|
||||||
* be the index of the first non-debuggable one).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Function: total_number_of_imps (char *selector);
|
|
||||||
*
|
|
||||||
* Input: a string representing a selector
|
|
||||||
* Output: number of methods that implement that selector.
|
|
||||||
*
|
|
||||||
* By analogy with function "total_number_of_methods", this allows
|
|
||||||
* decode_line_1 (symtab.c) to detect if there are objective c methods
|
|
||||||
* matching the input, and to allocate an array of pointers to them
|
|
||||||
* which can be manipulated by "decode_line_2" (also in symtab.c).
|
|
||||||
*/
|
|
||||||
|
|
||||||
char *
|
|
||||||
parse_selector (char *method, char **selector)
|
parse_selector (char *method, char **selector)
|
||||||
{
|
{
|
||||||
char *s1 = NULL;
|
char *s1 = NULL;
|
||||||
|
@ -1050,7 +1010,7 @@ parse_selector (char *method, char **selector)
|
||||||
return s2;
|
return s2;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
static char *
|
||||||
parse_method (char *method, char *type, char **class,
|
parse_method (char *method, char *type, char **class,
|
||||||
char **category, char **selector)
|
char **category, char **selector)
|
||||||
{
|
{
|
||||||
|
@ -1154,15 +1114,11 @@ parse_method (char *method, char *type, char **class,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
find_methods (struct symtab *symtab, char type,
|
find_methods (char type, const char *class, const char *category,
|
||||||
const char *class, const char *category,
|
const char *selector,
|
||||||
const char *selector, struct symbol **syms,
|
VEC (const_char_ptr) **symbol_names)
|
||||||
unsigned int *nsym, unsigned int *ndebug)
|
|
||||||
{
|
{
|
||||||
struct objfile *objfile = NULL;
|
struct objfile *objfile = NULL;
|
||||||
struct minimal_symbol *msymbol = NULL;
|
|
||||||
struct block *block = NULL;
|
|
||||||
struct symbol *sym = NULL;
|
|
||||||
|
|
||||||
char *symname = NULL;
|
char *symname = NULL;
|
||||||
|
|
||||||
|
@ -1171,21 +1127,15 @@ find_methods (struct symtab *symtab, char type,
|
||||||
char *ncategory = NULL;
|
char *ncategory = NULL;
|
||||||
char *nselector = NULL;
|
char *nselector = NULL;
|
||||||
|
|
||||||
unsigned int csym = 0;
|
|
||||||
unsigned int cdebug = 0;
|
|
||||||
|
|
||||||
static char *tmp = NULL;
|
static char *tmp = NULL;
|
||||||
static unsigned int tmplen = 0;
|
static unsigned int tmplen = 0;
|
||||||
|
|
||||||
gdb_assert (nsym != NULL);
|
gdb_assert (symbol_names != NULL);
|
||||||
gdb_assert (ndebug != NULL);
|
|
||||||
|
|
||||||
if (symtab)
|
|
||||||
block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
|
|
||||||
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
{
|
{
|
||||||
unsigned int *objc_csym;
|
unsigned int *objc_csym;
|
||||||
|
struct minimal_symbol *msymbol = NULL;
|
||||||
|
|
||||||
/* The objfile_csym variable counts the number of ObjC methods
|
/* The objfile_csym variable counts the number of ObjC methods
|
||||||
that this objfile defines. We save that count as a private
|
that this objfile defines. We save that count as a private
|
||||||
|
@ -1202,7 +1152,6 @@ find_methods (struct symtab *symtab, char type,
|
||||||
ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
|
ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
|
||||||
{
|
{
|
||||||
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
struct gdbarch *gdbarch = get_objfile_arch (objfile);
|
||||||
CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
|
|
||||||
|
|
||||||
QUIT;
|
QUIT;
|
||||||
|
|
||||||
|
@ -1216,18 +1165,8 @@ find_methods (struct symtab *symtab, char type,
|
||||||
/* Not a method name. */
|
/* Not a method name. */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* The minimal symbol might point to a function descriptor;
|
|
||||||
resolve it to the actual code address instead. */
|
|
||||||
pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc,
|
|
||||||
¤t_target);
|
|
||||||
|
|
||||||
objfile_csym++;
|
objfile_csym++;
|
||||||
|
|
||||||
if (symtab)
|
|
||||||
if (pc < BLOCK_START (block) || pc >= BLOCK_END (block))
|
|
||||||
/* Not in the specified symtab. */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Now that thinks are a bit sane, clean up the symname. */
|
/* Now that thinks are a bit sane, clean up the symname. */
|
||||||
while ((strlen (symname) + 1) >= tmplen)
|
while ((strlen (symname) + 1) >= tmplen)
|
||||||
{
|
{
|
||||||
|
@ -1255,41 +1194,9 @@ find_methods (struct symtab *symtab, char type,
|
||||||
((nselector == NULL) || (strcmp (selector, nselector) != 0)))
|
((nselector == NULL) || (strcmp (selector, nselector) != 0)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
sym = find_pc_function (pc);
|
VEC_safe_push (const_char_ptr, *symbol_names, symname);
|
||||||
if (sym != NULL)
|
|
||||||
{
|
|
||||||
const char *newsymname = SYMBOL_NATURAL_NAME (sym);
|
|
||||||
|
|
||||||
if (strcmp (symname, newsymname) == 0)
|
|
||||||
{
|
|
||||||
/* Found a high-level method sym: swap it into the
|
|
||||||
lower part of sym_arr (below num_debuggable). */
|
|
||||||
if (syms != NULL)
|
|
||||||
{
|
|
||||||
syms[csym] = syms[cdebug];
|
|
||||||
syms[cdebug] = sym;
|
|
||||||
}
|
|
||||||
csym++;
|
|
||||||
cdebug++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
warning (
|
|
||||||
"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
|
|
||||||
newsymname, symname);
|
|
||||||
if (syms != NULL)
|
|
||||||
syms[csym] = (struct symbol *) msymbol;
|
|
||||||
csym++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Found a non-debuggable method symbol. */
|
|
||||||
if (syms != NULL)
|
|
||||||
syms[csym] = (struct symbol *) msymbol;
|
|
||||||
csym++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objc_csym == NULL)
|
if (objc_csym == NULL)
|
||||||
{
|
{
|
||||||
objc_csym = obstack_alloc (&objfile->objfile_obstack,
|
objc_csym = obstack_alloc (&objfile->objfile_obstack,
|
||||||
|
@ -1301,38 +1208,79 @@ find_methods (struct symtab *symtab, char type,
|
||||||
/* Count of ObjC methods in this objfile should be constant. */
|
/* Count of ObjC methods in this objfile should be constant. */
|
||||||
gdb_assert (*objc_csym == objfile_csym);
|
gdb_assert (*objc_csym == objfile_csym);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nsym != NULL)
|
|
||||||
*nsym = csym;
|
|
||||||
if (ndebug != NULL)
|
|
||||||
*ndebug = cdebug;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *find_imps (struct symtab *symtab, struct block *block,
|
/* Uniquify a VEC of strings. */
|
||||||
char *method, struct symbol **syms,
|
|
||||||
unsigned int *nsym, unsigned int *ndebug)
|
static void
|
||||||
|
uniquify_strings (VEC (const_char_ptr) **strings)
|
||||||
|
{
|
||||||
|
int ix;
|
||||||
|
const char *elem, *last = NULL;
|
||||||
|
int out;
|
||||||
|
|
||||||
|
qsort (VEC_address (const_char_ptr, *strings),
|
||||||
|
VEC_length (const_char_ptr, *strings),
|
||||||
|
sizeof (const_char_ptr),
|
||||||
|
compare_strings);
|
||||||
|
out = 0;
|
||||||
|
for (ix = 0; VEC_iterate (const_char_ptr, *strings, ix, elem); ++ix)
|
||||||
|
{
|
||||||
|
if (last == NULL || strcmp (last, elem) != 0)
|
||||||
|
{
|
||||||
|
/* Keep ELEM. */
|
||||||
|
VEC_replace (const_char_ptr, *strings, out, elem);
|
||||||
|
++out;
|
||||||
|
}
|
||||||
|
last = elem;
|
||||||
|
}
|
||||||
|
VEC_truncate (const_char_ptr, *strings, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function: find_imps (char *selector, struct symbol **sym_arr)
|
||||||
|
*
|
||||||
|
* Input: a string representing a selector
|
||||||
|
* a pointer to an array of symbol pointers
|
||||||
|
* possibly a pointer to a symbol found by the caller.
|
||||||
|
*
|
||||||
|
* Output: number of methods that implement that selector. Side
|
||||||
|
* effects: The array of symbol pointers is filled with matching syms.
|
||||||
|
*
|
||||||
|
* By analogy with function "find_methods" (symtab.c), builds a list
|
||||||
|
* of symbols matching the ambiguous input, so that "decode_line_2"
|
||||||
|
* (symtab.c) can list them and ask the user to choose one or more.
|
||||||
|
* In this case the matches are objective c methods
|
||||||
|
* ("implementations") matching an objective c selector.
|
||||||
|
*
|
||||||
|
* Note that it is possible for a normal (c-style) function to have
|
||||||
|
* the same name as an objective c selector. To prevent the selector
|
||||||
|
* from eclipsing the function, we allow the caller (decode_line_1) to
|
||||||
|
* search for such a function first, and if it finds one, pass it in
|
||||||
|
* to us. We will then integrate it into the list. We also search
|
||||||
|
* for one here, among the minsyms.
|
||||||
|
*
|
||||||
|
* NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
|
||||||
|
* into two parts: debuggable (struct symbol) syms, and
|
||||||
|
* non_debuggable (struct minimal_symbol) syms. The debuggable
|
||||||
|
* ones will come first, before NUM_DEBUGGABLE (which will thus
|
||||||
|
* be the index of the first non-debuggable one).
|
||||||
|
*/
|
||||||
|
|
||||||
|
char *
|
||||||
|
find_imps (char *method, VEC (const_char_ptr) **symbol_names)
|
||||||
{
|
{
|
||||||
char type = '\0';
|
char type = '\0';
|
||||||
char *class = NULL;
|
char *class = NULL;
|
||||||
char *category = NULL;
|
char *category = NULL;
|
||||||
char *selector = NULL;
|
char *selector = NULL;
|
||||||
|
|
||||||
unsigned int csym = 0;
|
|
||||||
unsigned int cdebug = 0;
|
|
||||||
|
|
||||||
unsigned int ncsym = 0;
|
|
||||||
unsigned int ncdebug = 0;
|
|
||||||
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
|
|
||||||
gdb_assert (nsym != NULL);
|
int selector_case = 0;
|
||||||
gdb_assert (ndebug != NULL);
|
|
||||||
|
|
||||||
if (nsym != NULL)
|
gdb_assert (symbol_names != NULL);
|
||||||
*nsym = 0;
|
|
||||||
if (ndebug != NULL)
|
|
||||||
*ndebug = 0;
|
|
||||||
|
|
||||||
buf = (char *) alloca (strlen (method) + 1);
|
buf = (char *) alloca (strlen (method) + 1);
|
||||||
strcpy (buf, method);
|
strcpy (buf, method);
|
||||||
|
@ -1340,99 +1288,37 @@ char *find_imps (struct symtab *symtab, struct block *block,
|
||||||
|
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
{
|
{
|
||||||
struct symbol *sym = NULL;
|
|
||||||
struct minimal_symbol *msym = NULL;
|
|
||||||
|
|
||||||
strcpy (buf, method);
|
strcpy (buf, method);
|
||||||
tmp = parse_selector (buf, &selector);
|
tmp = parse_selector (buf, &selector);
|
||||||
|
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
sym = lookup_symbol (selector, block, VAR_DOMAIN, 0);
|
selector_case = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
find_methods (type, class, category, selector, symbol_names);
|
||||||
|
|
||||||
|
/* If we hit the "selector" case, and we found some methods, then
|
||||||
|
add the selector itself as a symbol, if it exists. */
|
||||||
|
if (selector_case && !VEC_empty (const_char_ptr, *symbol_names))
|
||||||
|
{
|
||||||
|
struct symbol *sym = lookup_symbol (selector, NULL, VAR_DOMAIN, 0);
|
||||||
|
|
||||||
if (sym != NULL)
|
if (sym != NULL)
|
||||||
|
VEC_safe_push (const_char_ptr, *symbol_names,
|
||||||
|
SYMBOL_NATURAL_NAME (sym));
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (syms)
|
struct minimal_symbol *msym = lookup_minimal_symbol (selector, 0, 0);
|
||||||
syms[csym] = sym;
|
|
||||||
csym++;
|
|
||||||
cdebug++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sym == NULL)
|
if (msym != NULL)
|
||||||
msym = lookup_minimal_symbol (selector, 0, 0);
|
VEC_safe_push (const_char_ptr, *symbol_names,
|
||||||
|
SYMBOL_NATURAL_NAME (msym));
|
||||||
if (msym != NULL)
|
|
||||||
{
|
|
||||||
if (syms)
|
|
||||||
syms[csym] = (struct symbol *)msym;
|
|
||||||
csym++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (syms != NULL)
|
uniquify_strings (symbol_names);
|
||||||
find_methods (symtab, type, class, category, selector,
|
|
||||||
syms + csym, &ncsym, &ncdebug);
|
|
||||||
else
|
|
||||||
find_methods (symtab, type, class, category, selector,
|
|
||||||
NULL, &ncsym, &ncdebug);
|
|
||||||
|
|
||||||
/* If we didn't find any methods, just return. */
|
|
||||||
if (ncsym == 0 && ncdebug == 0)
|
|
||||||
return method;
|
|
||||||
|
|
||||||
/* Take debug symbols from the second batch of symbols and swap them
|
|
||||||
* with debug symbols from the first batch. Repeat until either the
|
|
||||||
* second section is out of debug symbols or the first section is
|
|
||||||
* full of debug symbols. Either way we have all debug symbols
|
|
||||||
* packed to the beginning of the buffer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (syms != NULL)
|
|
||||||
{
|
|
||||||
while ((cdebug < csym) && (ncdebug > 0))
|
|
||||||
{
|
|
||||||
struct symbol *s = NULL;
|
|
||||||
/* First non-debugging symbol. */
|
|
||||||
unsigned int i = cdebug;
|
|
||||||
/* Last of second batch of debug symbols. */
|
|
||||||
unsigned int j = csym + ncdebug - 1;
|
|
||||||
|
|
||||||
s = syms[j];
|
|
||||||
syms[j] = syms[i];
|
|
||||||
syms[i] = s;
|
|
||||||
|
|
||||||
/* We've moved a symbol from the second debug section to the
|
|
||||||
first one. */
|
|
||||||
cdebug++;
|
|
||||||
ncdebug--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
csym += ncsym;
|
|
||||||
cdebug += ncdebug;
|
|
||||||
|
|
||||||
if (nsym != NULL)
|
|
||||||
*nsym = csym;
|
|
||||||
if (ndebug != NULL)
|
|
||||||
*ndebug = cdebug;
|
|
||||||
|
|
||||||
if (syms == NULL)
|
|
||||||
return method + (tmp - buf);
|
|
||||||
|
|
||||||
if (csym > 1)
|
|
||||||
{
|
|
||||||
/* Sort debuggable symbols. */
|
|
||||||
if (cdebug > 1)
|
|
||||||
qsort (syms, cdebug, sizeof (struct minimal_symbol *),
|
|
||||||
compare_classes);
|
|
||||||
|
|
||||||
/* Sort minimal_symbols. */
|
|
||||||
if ((csym - cdebug) > 1)
|
|
||||||
qsort (&syms[cdebug], csym - cdebug,
|
|
||||||
sizeof (struct minimal_symbol *), compare_classes);
|
|
||||||
}
|
|
||||||
/* Terminate the sym_arr list. */
|
|
||||||
syms[csym] = 0;
|
|
||||||
|
|
||||||
return method + (tmp - buf);
|
return method + (tmp - buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#if !defined(OBJC_LANG_H)
|
#if !defined(OBJC_LANG_H)
|
||||||
#define OBJC_LANG_H
|
#define OBJC_LANG_H
|
||||||
|
|
||||||
|
#include "cp-support.h" /* For VEC (const_char_ptr) */
|
||||||
|
|
||||||
struct stoken;
|
struct stoken;
|
||||||
|
|
||||||
struct value;
|
struct value;
|
||||||
|
@ -39,15 +41,7 @@ extern char *objc_demangle (const char *mangled, int options);
|
||||||
|
|
||||||
extern int find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc);
|
extern int find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc);
|
||||||
|
|
||||||
extern char *parse_selector (char *method, char **selector);
|
extern char *find_imps (char *method, VEC (const_char_ptr) **symbol_names);
|
||||||
|
|
||||||
extern char *parse_method (char *method, char *type,
|
|
||||||
char **class, char **category,
|
|
||||||
char **selector);
|
|
||||||
|
|
||||||
extern char *find_imps (struct symtab *symtab, struct block *block,
|
|
||||||
char *method, struct symbol **syms,
|
|
||||||
unsigned int *nsym, unsigned int *ndebug);
|
|
||||||
|
|
||||||
extern struct value *value_nsstring (struct gdbarch *gdbarch,
|
extern struct value *value_nsstring (struct gdbarch *gdbarch,
|
||||||
char *ptr, int len);
|
char *ptr, int len);
|
||||||
|
|
|
@ -1024,6 +1024,8 @@ const struct language_defn opencl_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
c_get_string,
|
c_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,8 @@ const struct language_defn pascal_language_defn =
|
||||||
default_print_array_index,
|
default_print_array_index,
|
||||||
default_pass_by_reference,
|
default_pass_by_reference,
|
||||||
default_get_string,
|
default_get_string,
|
||||||
|
strcmp_iw_ordered,
|
||||||
|
iterate_over_symbols,
|
||||||
LANG_MAGIC
|
LANG_MAGIC
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
100
gdb/psymtab.c
100
gdb/psymtab.c
|
@ -125,13 +125,42 @@ require_partial_symbols (struct objfile *objfile, int verbose)
|
||||||
ALL_OBJFILES (objfile) \
|
ALL_OBJFILES (objfile) \
|
||||||
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
|
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
|
||||||
|
|
||||||
/* Lookup the partial symbol table of a source file named NAME.
|
/* Helper function for partial_map_symtabs_matching_filename that
|
||||||
*If* there is no '/' in the name, a match after a '/'
|
expands the symtabs and calls the iterator. */
|
||||||
in the psymtab filename will also work. */
|
|
||||||
|
|
||||||
static struct partial_symtab *
|
static int
|
||||||
lookup_partial_symtab (struct objfile *objfile, const char *name,
|
partial_map_expand_apply (struct objfile *objfile,
|
||||||
const char *full_path, const char *real_path)
|
const char *name,
|
||||||
|
const char *full_path,
|
||||||
|
const char *real_path,
|
||||||
|
struct partial_symtab *pst,
|
||||||
|
int (*callback) (struct symtab *, void *),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct symtab *last_made = objfile->symtabs;
|
||||||
|
|
||||||
|
/* Don't visit already-expanded psymtabs. */
|
||||||
|
if (pst->readin)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* This may expand more than one symtab, and we want to iterate over
|
||||||
|
all of them. */
|
||||||
|
psymtab_to_symtab (pst);
|
||||||
|
|
||||||
|
return iterate_over_some_symtabs (name, full_path, real_path, callback, data,
|
||||||
|
objfile->symtabs, last_made);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Implementation of the map_symtabs_matching_filename method. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
partial_map_symtabs_matching_filename (struct objfile *objfile,
|
||||||
|
const char *name,
|
||||||
|
const char *full_path,
|
||||||
|
const char *real_path,
|
||||||
|
int (*callback) (struct symtab *,
|
||||||
|
void *),
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
struct partial_symtab *pst;
|
struct partial_symtab *pst;
|
||||||
const char *name_basename = lbasename (name);
|
const char *name_basename = lbasename (name);
|
||||||
|
@ -140,7 +169,9 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
|
||||||
{
|
{
|
||||||
if (FILENAME_CMP (name, pst->filename) == 0)
|
if (FILENAME_CMP (name, pst->filename) == 0)
|
||||||
{
|
{
|
||||||
return (pst);
|
if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
||||||
|
pst, callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Before we invoke realpath, which can get expensive when many
|
/* Before we invoke realpath, which can get expensive when many
|
||||||
|
@ -157,7 +188,9 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
|
||||||
if (pst->fullname != NULL
|
if (pst->fullname != NULL
|
||||||
&& FILENAME_CMP (full_path, pst->fullname) == 0)
|
&& FILENAME_CMP (full_path, pst->fullname) == 0)
|
||||||
{
|
{
|
||||||
return pst;
|
if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
||||||
|
pst, callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +205,9 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
|
||||||
}
|
}
|
||||||
if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
|
if (rp != NULL && FILENAME_CMP (real_path, rp) == 0)
|
||||||
{
|
{
|
||||||
return pst;
|
if (partial_map_expand_apply (objfile, name, full_path, real_path,
|
||||||
|
pst, callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,29 +218,12 @@ lookup_partial_symtab (struct objfile *objfile, const char *name,
|
||||||
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
|
ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
|
||||||
{
|
{
|
||||||
if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
|
if (FILENAME_CMP (lbasename (pst->filename), name) == 0)
|
||||||
return (pst);
|
if (partial_map_expand_apply (objfile, name, full_path, real_path, pst,
|
||||||
|
callback, data))
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (NULL);
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
lookup_symtab_via_partial_symtab (struct objfile *objfile, const char *name,
|
|
||||||
const char *full_path, const char *real_path,
|
|
||||||
struct symtab **result)
|
|
||||||
{
|
|
||||||
struct partial_symtab *ps;
|
|
||||||
|
|
||||||
ps = lookup_partial_symtab (objfile, name, full_path, real_path);
|
|
||||||
if (!ps)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (ps->readin)
|
|
||||||
error (_("Internal: readin %s pst for `%s' found when no symtab found."),
|
|
||||||
ps->filename, name);
|
|
||||||
|
|
||||||
*result = PSYMTAB_TO_SYMTAB (ps);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
|
/* Find which partial symtab contains PC and SECTION starting at psymtab PST.
|
||||||
|
@ -1231,13 +1249,12 @@ map_matching_symbols_psymtab (const char *name, domain_enum namespace,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
expand_symtabs_matching_via_partial (struct objfile *objfile,
|
expand_symtabs_matching_via_partial
|
||||||
int (*file_matcher) (const char *,
|
(struct objfile *objfile,
|
||||||
void *),
|
int (*file_matcher) (const char *, void *),
|
||||||
int (*name_matcher) (const char *,
|
int (*name_matcher) (const struct language_defn *, const char *, void *),
|
||||||
void *),
|
enum search_domain kind,
|
||||||
enum search_domain kind,
|
void *data)
|
||||||
void *data)
|
|
||||||
{
|
{
|
||||||
struct partial_symtab *ps;
|
struct partial_symtab *ps;
|
||||||
|
|
||||||
|
@ -1287,7 +1304,8 @@ expand_symtabs_matching_via_partial (struct objfile *objfile,
|
||||||
&& SYMBOL_CLASS (*psym) == LOC_BLOCK)
|
&& SYMBOL_CLASS (*psym) == LOC_BLOCK)
|
||||||
|| (kind == TYPES_DOMAIN
|
|| (kind == TYPES_DOMAIN
|
||||||
&& SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
&& SYMBOL_CLASS (*psym) == LOC_TYPEDEF))
|
||||||
&& (*name_matcher) (SYMBOL_NATURAL_NAME (*psym), data))
|
&& (*name_matcher) (current_language,
|
||||||
|
SYMBOL_NATURAL_NAME (*psym), data))
|
||||||
{
|
{
|
||||||
PSYMTAB_TO_SYMTAB (ps);
|
PSYMTAB_TO_SYMTAB (ps);
|
||||||
keep_going = 0;
|
keep_going = 0;
|
||||||
|
@ -1309,7 +1327,7 @@ const struct quick_symbol_functions psym_functions =
|
||||||
objfile_has_psyms,
|
objfile_has_psyms,
|
||||||
find_last_source_symtab_from_partial,
|
find_last_source_symtab_from_partial,
|
||||||
forget_cached_source_info_partial,
|
forget_cached_source_info_partial,
|
||||||
lookup_symtab_via_partial_symtab,
|
partial_map_symtabs_matching_filename,
|
||||||
lookup_symbol_aux_psymtabs,
|
lookup_symbol_aux_psymtabs,
|
||||||
pre_expand_symtabs_matching_psymtabs,
|
pre_expand_symtabs_matching_psymtabs,
|
||||||
print_psymtab_stats_for_objfile,
|
print_psymtab_stats_for_objfile,
|
||||||
|
@ -1927,7 +1945,9 @@ maintenance_check_symtabs (char *ignore, int from_tty)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
expand_partial_symbol_names (int (*fun) (const char *, void *), void *data)
|
expand_partial_symbol_names (int (*fun) (const struct language_defn *,
|
||||||
|
const char *, void *),
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,8 @@ extern struct psymbol_bcache *psymbol_bcache_init (void);
|
||||||
extern void psymbol_bcache_free (struct psymbol_bcache *);
|
extern void psymbol_bcache_free (struct psymbol_bcache *);
|
||||||
extern struct bcache *psymbol_bcache_get_bcache (struct psymbol_bcache *);
|
extern struct bcache *psymbol_bcache_get_bcache (struct psymbol_bcache *);
|
||||||
|
|
||||||
void expand_partial_symbol_names (int (*fun) (const char *, void *),
|
void expand_partial_symbol_names (int (*fun) (const struct language_defn *,
|
||||||
|
const char *, void *),
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
void map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
|
void map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
|
||||||
|
|
|
@ -947,7 +947,7 @@ DEF_VEC_O (type_equality_entry_d);
|
||||||
the same, 0 otherwise. Handles NULLs properly. */
|
the same, 0 otherwise. Handles NULLs properly. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
compare_strings (const char *s, const char *t)
|
compare_maybe_null_strings (const char *s, const char *t)
|
||||||
{
|
{
|
||||||
if (s == NULL && t != NULL)
|
if (s == NULL && t != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -983,9 +983,10 @@ check_types_equal (struct type *type1, struct type *type2,
|
||||||
|| TYPE_NFIELDS (type1) != TYPE_NFIELDS (type2))
|
|| TYPE_NFIELDS (type1) != TYPE_NFIELDS (type2))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
|
|
||||||
if (!compare_strings (TYPE_TAG_NAME (type1), TYPE_TAG_NAME (type2)))
|
if (!compare_maybe_null_strings (TYPE_TAG_NAME (type1),
|
||||||
|
TYPE_TAG_NAME (type2)))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
if (!compare_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
|
if (!compare_maybe_null_strings (TYPE_NAME (type1), TYPE_NAME (type2)))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
|
|
||||||
if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
|
if (TYPE_CODE (type1) == TYPE_CODE_RANGE)
|
||||||
|
@ -1008,7 +1009,8 @@ check_types_equal (struct type *type1, struct type *type2,
|
||||||
|| FIELD_BITSIZE (*field1) != FIELD_BITSIZE (*field2)
|
|| FIELD_BITSIZE (*field1) != FIELD_BITSIZE (*field2)
|
||||||
|| FIELD_LOC_KIND (*field1) != FIELD_LOC_KIND (*field2))
|
|| FIELD_LOC_KIND (*field1) != FIELD_LOC_KIND (*field2))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
if (!compare_strings (FIELD_NAME (*field1), FIELD_NAME (*field2)))
|
if (!compare_maybe_null_strings (FIELD_NAME (*field1),
|
||||||
|
FIELD_NAME (*field2)))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
switch (FIELD_LOC_KIND (*field1))
|
switch (FIELD_LOC_KIND (*field1))
|
||||||
{
|
{
|
||||||
|
@ -1022,8 +1024,8 @@ check_types_equal (struct type *type1, struct type *type2,
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
break;
|
break;
|
||||||
case FIELD_LOC_KIND_PHYSNAME:
|
case FIELD_LOC_KIND_PHYSNAME:
|
||||||
if (!compare_strings (FIELD_STATIC_PHYSNAME (*field1),
|
if (!compare_maybe_null_strings (FIELD_STATIC_PHYSNAME (*field1),
|
||||||
FIELD_STATIC_PHYSNAME (*field2)))
|
FIELD_STATIC_PHYSNAME (*field2)))
|
||||||
return Py_NE;
|
return Py_NE;
|
||||||
break;
|
break;
|
||||||
case FIELD_LOC_KIND_DWARF_BLOCK:
|
case FIELD_LOC_KIND_DWARF_BLOCK:
|
||||||
|
|
|
@ -512,7 +512,7 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
|
||||||
{
|
{
|
||||||
copy = xstrdup (arg);
|
copy = xstrdup (arg);
|
||||||
make_cleanup (xfree, copy);
|
make_cleanup (xfree, copy);
|
||||||
sals = decode_line_1 (©, 0, 0, 0, 0);
|
sals = decode_line_1 (©, 0, 0, 0);
|
||||||
make_cleanup (xfree, sals.sals);
|
make_cleanup (xfree, sals.sals);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -164,7 +164,7 @@ skip_function_command (char *arg, int from_tty)
|
||||||
|
|
||||||
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
|
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
|
||||||
{
|
{
|
||||||
sals = decode_line_1 (&arg, 1, 0, 0, 0);
|
sals = decode_line_1 (&arg, DECODE_LINE_FUNFIRSTLINE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decode_exception.reason < 0)
|
if (decode_exception.reason < 0)
|
||||||
|
@ -514,7 +514,7 @@ skip_re_set (void)
|
||||||
|
|
||||||
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
|
TRY_CATCH (decode_exception, RETURN_MASK_ERROR)
|
||||||
{
|
{
|
||||||
sals = decode_line_1 (&func_name, 1, 0, 0, 0);
|
sals = decode_line_1 (&func_name, DECODE_LINE_FUNFIRSTLINE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decode_exception.reason >= 0
|
if (decode_exception.reason >= 0
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
|
|
||||||
#include "gdb_string.h"
|
#include "gdb_string.h"
|
||||||
|
|
||||||
DEF_VEC_I(CORE_ADDR);
|
|
||||||
|
|
||||||
/* Private data for each loaded library. */
|
/* Private data for each loaded library. */
|
||||||
struct lm_info
|
struct lm_info
|
||||||
{
|
{
|
||||||
|
|
12
gdb/source.c
12
gdb/source.c
|
@ -245,7 +245,7 @@ select_source_symtab (struct symtab *s)
|
||||||
if one exists. */
|
if one exists. */
|
||||||
if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0))
|
if (lookup_symbol (main_name (), 0, VAR_DOMAIN, 0))
|
||||||
{
|
{
|
||||||
sals = decode_line_spec (main_name (), 1);
|
sals = decode_line_spec (main_name (), DECODE_LINE_FUNFIRSTLINE);
|
||||||
sal = sals.sals[0];
|
sal = sals.sals[0];
|
||||||
xfree (sals.sals);
|
xfree (sals.sals);
|
||||||
current_source_pspace = sal.pspace;
|
current_source_pspace = sal.pspace;
|
||||||
|
@ -1415,12 +1415,14 @@ line_info (char *arg, int from_tty)
|
||||||
struct symtab_and_line sal;
|
struct symtab_and_line sal;
|
||||||
CORE_ADDR start_pc, end_pc;
|
CORE_ADDR start_pc, end_pc;
|
||||||
int i;
|
int i;
|
||||||
|
struct cleanup *cleanups;
|
||||||
|
|
||||||
init_sal (&sal); /* initialize to zeroes */
|
init_sal (&sal); /* initialize to zeroes */
|
||||||
|
|
||||||
if (arg == 0)
|
if (arg == 0)
|
||||||
{
|
{
|
||||||
sal.symtab = current_source_symtab;
|
sal.symtab = current_source_symtab;
|
||||||
|
sal.pspace = current_program_space;
|
||||||
sal.line = last_line_listed;
|
sal.line = last_line_listed;
|
||||||
sals.nelts = 1;
|
sals.nelts = 1;
|
||||||
sals.sals = (struct symtab_and_line *)
|
sals.sals = (struct symtab_and_line *)
|
||||||
|
@ -1429,16 +1431,20 @@ line_info (char *arg, int from_tty)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sals = decode_line_spec_1 (arg, 0);
|
sals = decode_line_spec_1 (arg, DECODE_LINE_LIST_MODE);
|
||||||
|
|
||||||
dont_repeat ();
|
dont_repeat ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanups = make_cleanup (xfree, sals.sals);
|
||||||
|
|
||||||
/* C++ More than one line may have been specified, as when the user
|
/* C++ More than one line may have been specified, as when the user
|
||||||
specifies an overloaded function name. Print info on them all. */
|
specifies an overloaded function name. Print info on them all. */
|
||||||
for (i = 0; i < sals.nelts; i++)
|
for (i = 0; i < sals.nelts; i++)
|
||||||
{
|
{
|
||||||
sal = sals.sals[i];
|
sal = sals.sals[i];
|
||||||
|
if (sal.pspace != current_program_space)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (sal.symtab == 0)
|
if (sal.symtab == 0)
|
||||||
{
|
{
|
||||||
|
@ -1504,7 +1510,7 @@ line_info (char *arg, int from_tty)
|
||||||
printf_filtered (_("Line number %d is out of range for \"%s\".\n"),
|
printf_filtered (_("Line number %d is out of range for \"%s\".\n"),
|
||||||
sal.line, sal.symtab->filename);
|
sal.line, sal.symtab->filename);
|
||||||
}
|
}
|
||||||
xfree (sals.sals);
|
do_cleanups (cleanups);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commands to search the source file for a regexp. */
|
/* Commands to search the source file for a regexp. */
|
||||||
|
|
19
gdb/stack.c
19
gdb/stack.c
|
@ -47,6 +47,7 @@
|
||||||
#include "cp-support.h"
|
#include "cp-support.h"
|
||||||
#include "disasm.h"
|
#include "disasm.h"
|
||||||
#include "inline-frame.h"
|
#include "inline-frame.h"
|
||||||
|
#include "linespec.h"
|
||||||
|
|
||||||
#include "gdb_assert.h"
|
#include "gdb_assert.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -2444,20 +2445,25 @@ func_command (char *arg, int from_tty)
|
||||||
int i;
|
int i;
|
||||||
int level = 1;
|
int level = 1;
|
||||||
struct function_bounds *func_bounds = NULL;
|
struct function_bounds *func_bounds = NULL;
|
||||||
|
struct cleanup *cleanups;
|
||||||
|
|
||||||
if (arg != NULL)
|
if (arg != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
frame = parse_frame_specification ("0");
|
frame = parse_frame_specification ("0");
|
||||||
sals = decode_line_spec (arg, 1);
|
sals = decode_line_spec (arg, DECODE_LINE_FUNFIRSTLINE);
|
||||||
|
cleanups = make_cleanup (xfree, sals.sals);
|
||||||
func_bounds = (struct function_bounds *) xmalloc (
|
func_bounds = (struct function_bounds *) xmalloc (
|
||||||
sizeof (struct function_bounds) * sals.nelts);
|
sizeof (struct function_bounds) * sals.nelts);
|
||||||
|
make_cleanup (xfree, func_bounds);
|
||||||
for (i = 0; (i < sals.nelts && !found); i++)
|
for (i = 0; (i < sals.nelts && !found); i++)
|
||||||
{
|
{
|
||||||
if (sals.sals[i].pc == 0
|
if (sals.sals[i].pspace != current_program_space)
|
||||||
|| find_pc_partial_function (sals.sals[i].pc, NULL,
|
func_bounds[i].low = func_bounds[i].high = 0;
|
||||||
&func_bounds[i].low,
|
else if (sals.sals[i].pc == 0
|
||||||
&func_bounds[i].high) == 0)
|
|| find_pc_partial_function (sals.sals[i].pc, NULL,
|
||||||
|
&func_bounds[i].low,
|
||||||
|
&func_bounds[i].high) == 0)
|
||||||
{
|
{
|
||||||
func_bounds[i].low = func_bounds[i].high = 0;
|
func_bounds[i].low = func_bounds[i].high = 0;
|
||||||
}
|
}
|
||||||
|
@ -2476,8 +2482,7 @@ func_command (char *arg, int from_tty)
|
||||||
}
|
}
|
||||||
while (!found && level == 0);
|
while (!found && level == 0);
|
||||||
|
|
||||||
if (func_bounds)
|
do_cleanups (cleanups);
|
||||||
xfree (func_bounds);
|
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
printf_filtered (_("'%s' not within current stack frame.\n"), arg);
|
printf_filtered (_("'%s' not within current stack frame.\n"), arg);
|
||||||
|
|
|
@ -152,22 +152,24 @@ struct quick_symbol_functions
|
||||||
/* Forget all cached full file names for OBJFILE. */
|
/* Forget all cached full file names for OBJFILE. */
|
||||||
void (*forget_cached_source_info) (struct objfile *objfile);
|
void (*forget_cached_source_info) (struct objfile *objfile);
|
||||||
|
|
||||||
/* Look up the symbol table, in OBJFILE, of a source file named
|
/* Expand and iterate over each "partial" symbol table in OBJFILE
|
||||||
NAME. If there is no '/' in the name, a match after a '/' in the
|
where the source file is named NAME.
|
||||||
symbol table's file name will also work. FULL_PATH is the
|
|
||||||
absolute file name, and REAL_PATH is the same, run through
|
|
||||||
gdb_realpath.
|
|
||||||
|
|
||||||
If no such symbol table can be found, returns 0.
|
If there is no '/' in the name, a match after a '/' in the symbol
|
||||||
|
table's file name will also work. FULL_PATH is the absolute file
|
||||||
|
name, and REAL_PATH is the same, run through gdb_realpath.
|
||||||
|
|
||||||
Otherwise, sets *RESULT to the symbol table and returns 1. This
|
If a match is found, the "partial" symbol table is expanded.
|
||||||
might return 1 and set *RESULT to NULL if the requested file is
|
Then, this calls iterate_over_some_symtabs (or equivalent) over
|
||||||
an include file that does not have a symtab of its own. */
|
all newly-created symbol tables, passing CALLBACK and DATA to it.
|
||||||
int (*lookup_symtab) (struct objfile *objfile,
|
The result of this call is returned. */
|
||||||
const char *name,
|
int (*map_symtabs_matching_filename) (struct objfile *objfile,
|
||||||
const char *full_path,
|
const char *name,
|
||||||
const char *real_path,
|
const char *full_path,
|
||||||
struct symtab **result);
|
const char *real_path,
|
||||||
|
int (*callback) (struct symtab *,
|
||||||
|
void *),
|
||||||
|
void *data);
|
||||||
|
|
||||||
/* Check to see if the symbol is defined in a "partial" symbol table
|
/* Check to see if the symbol is defined in a "partial" symbol table
|
||||||
of OBJFILE. KIND should be either GLOBAL_BLOCK or STATIC_BLOCK,
|
of OBJFILE. KIND should be either GLOBAL_BLOCK or STATIC_BLOCK,
|
||||||
|
@ -259,9 +261,12 @@ struct quick_symbol_functions
|
||||||
|
|
||||||
Otherwise, if KIND does not match this symbol is skipped.
|
Otherwise, if KIND does not match this symbol is skipped.
|
||||||
|
|
||||||
If even KIND matches, then NAME_MATCHER is called for each symbol defined
|
If even KIND matches, then NAME_MATCHER is called for each symbol
|
||||||
in the file. The symbol's "natural" name and DATA are passed to
|
defined in the file. The current language, the symbol name and
|
||||||
NAME_MATCHER.
|
DATA are passed to NAME_MATCHER. The symbol "natural" name should
|
||||||
|
be passed to NAME_MATCHER for all languages except Ada, where
|
||||||
|
the encoded name is passed instead (see la_symbol_name_compare in
|
||||||
|
struct language_defn for more details on this).
|
||||||
|
|
||||||
If NAME_MATCHER returns zero, then this symbol is skipped.
|
If NAME_MATCHER returns zero, then this symbol is skipped.
|
||||||
|
|
||||||
|
@ -269,11 +274,12 @@ struct quick_symbol_functions
|
||||||
|
|
||||||
DATA is user data that is passed unmodified to the callback
|
DATA is user data that is passed unmodified to the callback
|
||||||
functions. */
|
functions. */
|
||||||
void (*expand_symtabs_matching) (struct objfile *objfile,
|
void (*expand_symtabs_matching)
|
||||||
int (*file_matcher) (const char *, void *),
|
(struct objfile *objfile,
|
||||||
int (*name_matcher) (const char *, void *),
|
int (*file_matcher) (const char *, void *),
|
||||||
enum search_domain kind,
|
int (*name_matcher) (const struct language_defn *, const char *, void *),
|
||||||
void *data);
|
enum search_domain kind,
|
||||||
|
void *data);
|
||||||
|
|
||||||
/* Return the symbol table from OBJFILE that contains PC and
|
/* Return the symbol table from OBJFILE that contains PC and
|
||||||
SECTION. Return NULL if there is no such symbol table. This
|
SECTION. Return NULL if there is no such symbol table. This
|
||||||
|
|
560
gdb/symtab.c
560
gdb/symtab.c
|
@ -81,7 +81,7 @@ static void sources_info (char *, int);
|
||||||
|
|
||||||
static void output_source_filename (const char *, int *);
|
static void output_source_filename (const char *, int *);
|
||||||
|
|
||||||
static int find_line_common (struct linetable *, int, int *);
|
static int find_line_common (struct linetable *, int, int *, int);
|
||||||
|
|
||||||
static struct symbol *lookup_symbol_aux (const char *name,
|
static struct symbol *lookup_symbol_aux (const char *name,
|
||||||
const struct block *block,
|
const struct block *block,
|
||||||
|
@ -147,44 +147,38 @@ multiple_symbols_select_mode (void)
|
||||||
|
|
||||||
const struct block *block_found;
|
const struct block *block_found;
|
||||||
|
|
||||||
/* Check for a symtab of a specific name; first in symtabs, then in
|
/* Check for a symtab of a specific name by searching some symtabs.
|
||||||
psymtabs. *If* there is no '/' in the name, a match after a '/'
|
This is a helper function for callbacks of iterate_over_symtabs.
|
||||||
in the symtab filename will also work. */
|
|
||||||
|
|
||||||
struct symtab *
|
The return value, NAME, FULL_PATH, REAL_PATH, CALLBACK, and DATA
|
||||||
lookup_symtab (const char *name)
|
are identical to the `map_symtabs_matching_filename' method of
|
||||||
|
quick_symbol_functions.
|
||||||
|
|
||||||
|
FIRST and AFTER_LAST indicate the range of symtabs to search.
|
||||||
|
AFTER_LAST is one past the last symtab to search; NULL means to
|
||||||
|
search until the end of the list. */
|
||||||
|
|
||||||
|
int
|
||||||
|
iterate_over_some_symtabs (const char *name,
|
||||||
|
const char *full_path,
|
||||||
|
const char *real_path,
|
||||||
|
int (*callback) (struct symtab *symtab,
|
||||||
|
void *data),
|
||||||
|
void *data,
|
||||||
|
struct symtab *first,
|
||||||
|
struct symtab *after_last)
|
||||||
{
|
{
|
||||||
int found;
|
|
||||||
struct symtab *s = NULL;
|
struct symtab *s = NULL;
|
||||||
struct objfile *objfile;
|
|
||||||
char *real_path = NULL;
|
|
||||||
char *full_path = NULL;
|
|
||||||
struct cleanup *cleanup;
|
struct cleanup *cleanup;
|
||||||
const char* base_name = lbasename (name);
|
const char* base_name = lbasename (name);
|
||||||
|
|
||||||
cleanup = make_cleanup (null_cleanup, NULL);
|
for (s = first; s != NULL && s != after_last; s = s->next)
|
||||||
|
|
||||||
/* Here we are interested in canonicalizing an absolute path, not
|
|
||||||
absolutizing a relative path. */
|
|
||||||
if (IS_ABSOLUTE_PATH (name))
|
|
||||||
{
|
{
|
||||||
full_path = xfullpath (name);
|
if (FILENAME_CMP (name, s->filename) == 0)
|
||||||
make_cleanup (xfree, full_path);
|
{
|
||||||
real_path = gdb_realpath (name);
|
if (callback (s, data))
|
||||||
make_cleanup (xfree, real_path);
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
got_symtab:
|
|
||||||
|
|
||||||
/* First, search for an exact match. */
|
|
||||||
|
|
||||||
ALL_SYMTABS (objfile, s)
|
|
||||||
{
|
|
||||||
if (FILENAME_CMP (name, s->filename) == 0)
|
|
||||||
{
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Before we invoke realpath, which can get expensive when many
|
/* Before we invoke realpath, which can get expensive when many
|
||||||
files are involved, do a quick comparison of the basenames. */
|
files are involved, do a quick comparison of the basenames. */
|
||||||
|
@ -201,8 +195,8 @@ got_symtab:
|
||||||
|
|
||||||
if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
|
if (fp != NULL && FILENAME_CMP (full_path, fp) == 0)
|
||||||
{
|
{
|
||||||
do_cleanups (cleanup);
|
if (callback (s, data))
|
||||||
return s;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,62 +210,114 @@ got_symtab:
|
||||||
|
|
||||||
make_cleanup (xfree, rp);
|
make_cleanup (xfree, rp);
|
||||||
if (FILENAME_CMP (real_path, rp) == 0)
|
if (FILENAME_CMP (real_path, rp) == 0)
|
||||||
{
|
{
|
||||||
do_cleanups (cleanup);
|
if (callback (s, data))
|
||||||
return s;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, search for a matching tail (only if name doesn't have any dirs). */
|
/* Now, search for a matching tail (only if name doesn't have any dirs). */
|
||||||
|
|
||||||
if (lbasename (name) == name)
|
if (lbasename (name) == name)
|
||||||
ALL_SYMTABS (objfile, s)
|
|
||||||
{
|
{
|
||||||
if (FILENAME_CMP (lbasename (s->filename), name) == 0)
|
for (s = first; s != NULL && s != after_last; s = s->next)
|
||||||
{
|
{
|
||||||
do_cleanups (cleanup);
|
if (FILENAME_CMP (lbasename (s->filename), name) == 0)
|
||||||
return s;
|
{
|
||||||
|
if (callback (s, data))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for a symtab of a specific name; first in symtabs, then in
|
||||||
|
psymtabs. *If* there is no '/' in the name, a match after a '/'
|
||||||
|
in the symtab filename will also work.
|
||||||
|
|
||||||
|
Calls CALLBACK with each symtab that is found and with the supplied
|
||||||
|
DATA. If CALLBACK returns true, the search stops. */
|
||||||
|
|
||||||
|
void
|
||||||
|
iterate_over_symtabs (const char *name,
|
||||||
|
int (*callback) (struct symtab *symtab,
|
||||||
|
void *data),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
struct symtab *s = NULL;
|
||||||
|
struct objfile *objfile;
|
||||||
|
char *real_path = NULL;
|
||||||
|
char *full_path = NULL;
|
||||||
|
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
|
||||||
|
|
||||||
|
/* Here we are interested in canonicalizing an absolute path, not
|
||||||
|
absolutizing a relative path. */
|
||||||
|
if (IS_ABSOLUTE_PATH (name))
|
||||||
|
{
|
||||||
|
full_path = xfullpath (name);
|
||||||
|
make_cleanup (xfree, full_path);
|
||||||
|
real_path = gdb_realpath (name);
|
||||||
|
make_cleanup (xfree, real_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ALL_OBJFILES (objfile)
|
||||||
|
{
|
||||||
|
if (iterate_over_some_symtabs (name, full_path, real_path, callback, data,
|
||||||
|
objfile->symtabs, NULL))
|
||||||
|
{
|
||||||
|
do_cleanups (cleanups);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Same search rules as above apply here, but now we look thru the
|
/* Same search rules as above apply here, but now we look thru the
|
||||||
psymtabs. */
|
psymtabs. */
|
||||||
|
|
||||||
found = 0;
|
|
||||||
ALL_OBJFILES (objfile)
|
ALL_OBJFILES (objfile)
|
||||||
{
|
{
|
||||||
if (objfile->sf
|
if (objfile->sf
|
||||||
&& objfile->sf->qf->lookup_symtab (objfile, name, full_path, real_path,
|
&& objfile->sf->qf->map_symtabs_matching_filename (objfile,
|
||||||
&s))
|
name,
|
||||||
|
full_path,
|
||||||
|
real_path,
|
||||||
|
callback,
|
||||||
|
data))
|
||||||
{
|
{
|
||||||
found = 1;
|
do_cleanups (cleanups);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s != NULL)
|
do_cleanups (cleanups);
|
||||||
{
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
do_cleanups (cleanup);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* At this point, we have located the psymtab for this file, but
|
|
||||||
the conversion to a symtab has failed. This usually happens
|
|
||||||
when we are looking up an include file. In this case,
|
|
||||||
PSYMTAB_TO_SYMTAB doesn't return a symtab, even though one has
|
|
||||||
been created. So, we need to run through the symtabs again in
|
|
||||||
order to find the file.
|
|
||||||
XXX - This is a crock, and should be fixed inside of the
|
|
||||||
symbol parsing routines. */
|
|
||||||
goto got_symtab;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The callback function used by lookup_symtab. */
|
||||||
|
|
||||||
|
static int
|
||||||
|
lookup_symtab_callback (struct symtab *symtab, void *data)
|
||||||
|
{
|
||||||
|
struct symtab **result_ptr = data;
|
||||||
|
|
||||||
|
*result_ptr = symtab;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A wrapper for iterate_over_symtabs that returns the first matching
|
||||||
|
symtab, or NULL. */
|
||||||
|
|
||||||
|
struct symtab *
|
||||||
|
lookup_symtab (const char *name)
|
||||||
|
{
|
||||||
|
struct symtab *result = NULL;
|
||||||
|
|
||||||
|
iterate_over_symtabs (name, lookup_symtab_callback, &result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
|
/* Mangle a GDB method stub type. This actually reassembles the pieces of the
|
||||||
full method name, which consist of the class name (from T), the unadorned
|
full method name, which consist of the class name (from T), the unadorned
|
||||||
|
@ -1006,33 +1052,30 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile)
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the definition for a specified symbol name NAME
|
/* Compute the demangled form of NAME as used by the various symbol
|
||||||
in domain DOMAIN, visible from lexical block BLOCK.
|
lookup functions. The result is stored in *RESULT_NAME. Returns a
|
||||||
Returns the struct symbol pointer, or zero if no symbol is found.
|
cleanup which can be used to clean up the result.
|
||||||
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
|
|
||||||
NAME is a field of the current implied argument `this'. If so set
|
|
||||||
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
|
|
||||||
BLOCK_FOUND is set to the block in which NAME is found (in the case of
|
|
||||||
a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
|
|
||||||
|
|
||||||
/* This function has a bunch of loops in it and it would seem to be
|
For Ada, this function just sets *RESULT_NAME to NAME, unmodified.
|
||||||
attractive to put in some QUIT's (though I'm not really sure
|
Normally, Ada symbol lookups are performed using the encoded name
|
||||||
whether it can run long enough to be really important). But there
|
rather than the demangled name, and so it might seem to make sense
|
||||||
are a few calls for which it would appear to be bad news to quit
|
for this function to return an encoded version of NAME.
|
||||||
out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
|
Unfortunately, we cannot do this, because this function is used in
|
||||||
that there is C++ code below which can error(), but that probably
|
circumstances where it is not appropriate to try to encode NAME.
|
||||||
doesn't affect these calls since they are looking for a known
|
For instance, when displaying the frame info, we demangle the name
|
||||||
variable and thus can probably assume it will never hit the C++
|
of each parameter, and then perform a symbol lookup inside our
|
||||||
code). */
|
function using that demangled name. In Ada, certain functions
|
||||||
|
have internally-generated parameters whose name contain uppercase
|
||||||
|
characters. Encoding those name would result in those uppercase
|
||||||
|
characters to become lowercase, and thus cause the symbol lookup
|
||||||
|
to fail. */
|
||||||
|
|
||||||
struct symbol *
|
struct cleanup *
|
||||||
lookup_symbol_in_language (const char *name, const struct block *block,
|
demangle_for_lookup (const char *name, enum language lang,
|
||||||
const domain_enum domain, enum language lang,
|
const char **result_name)
|
||||||
int *is_a_field_of_this)
|
|
||||||
{
|
{
|
||||||
char *demangled_name = NULL;
|
char *demangled_name = NULL;
|
||||||
const char *modified_name = NULL;
|
const char *modified_name = NULL;
|
||||||
struct symbol *returnval;
|
|
||||||
struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
|
struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
|
||||||
|
|
||||||
modified_name = name;
|
modified_name = name;
|
||||||
|
@ -1079,6 +1122,38 @@ lookup_symbol_in_language (const char *name, const struct block *block,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*result_name = modified_name;
|
||||||
|
return cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the definition for a specified symbol name NAME
|
||||||
|
in domain DOMAIN, visible from lexical block BLOCK.
|
||||||
|
Returns the struct symbol pointer, or zero if no symbol is found.
|
||||||
|
C++: if IS_A_FIELD_OF_THIS is nonzero on entry, check to see if
|
||||||
|
NAME is a field of the current implied argument `this'. If so set
|
||||||
|
*IS_A_FIELD_OF_THIS to 1, otherwise set it to zero.
|
||||||
|
BLOCK_FOUND is set to the block in which NAME is found (in the case of
|
||||||
|
a field of `this', value_of_this sets BLOCK_FOUND to the proper value.) */
|
||||||
|
|
||||||
|
/* This function has a bunch of loops in it and it would seem to be
|
||||||
|
attractive to put in some QUIT's (though I'm not really sure
|
||||||
|
whether it can run long enough to be really important). But there
|
||||||
|
are a few calls for which it would appear to be bad news to quit
|
||||||
|
out of here: find_proc_desc in alpha-tdep.c and mips-tdep.c. (Note
|
||||||
|
that there is C++ code below which can error(), but that probably
|
||||||
|
doesn't affect these calls since they are looking for a known
|
||||||
|
variable and thus can probably assume it will never hit the C++
|
||||||
|
code). */
|
||||||
|
|
||||||
|
struct symbol *
|
||||||
|
lookup_symbol_in_language (const char *name, const struct block *block,
|
||||||
|
const domain_enum domain, enum language lang,
|
||||||
|
int *is_a_field_of_this)
|
||||||
|
{
|
||||||
|
const char *modified_name;
|
||||||
|
struct symbol *returnval;
|
||||||
|
struct cleanup *cleanup = demangle_for_lookup (name, lang, &modified_name);
|
||||||
|
|
||||||
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
|
returnval = lookup_symbol_aux (modified_name, block, domain, lang,
|
||||||
is_a_field_of_this);
|
is_a_field_of_this);
|
||||||
do_cleanups (cleanup);
|
do_cleanups (cleanup);
|
||||||
|
@ -1771,6 +1846,44 @@ lookup_block_symbol (const struct block *block, const char *name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Iterate over the symbols named NAME, matching DOMAIN, starting with
|
||||||
|
BLOCK.
|
||||||
|
|
||||||
|
For each symbol that matches, CALLBACK is called. The symbol and
|
||||||
|
DATA are passed to the callback.
|
||||||
|
|
||||||
|
If CALLBACK returns zero, the iteration ends. Otherwise, the
|
||||||
|
search continues. This function iterates upward through blocks.
|
||||||
|
When the outermost block has been finished, the function
|
||||||
|
returns. */
|
||||||
|
|
||||||
|
void
|
||||||
|
iterate_over_symbols (const struct block *block, const char *name,
|
||||||
|
const domain_enum domain,
|
||||||
|
int (*callback) (struct symbol *, void *),
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
while (block)
|
||||||
|
{
|
||||||
|
struct dict_iterator iter;
|
||||||
|
struct symbol *sym;
|
||||||
|
|
||||||
|
for (sym = dict_iter_name_first (BLOCK_DICT (block), name, &iter);
|
||||||
|
sym != NULL;
|
||||||
|
sym = dict_iter_name_next (name, &iter))
|
||||||
|
{
|
||||||
|
if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
|
||||||
|
SYMBOL_DOMAIN (sym), domain))
|
||||||
|
{
|
||||||
|
if (!callback (sym, data))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block = BLOCK_SUPERBLOCK (block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Find the symtab associated with PC and SECTION. Look through the
|
/* Find the symtab associated with PC and SECTION. Look through the
|
||||||
psymtabs and read in another symtab if necessary. */
|
psymtabs and read in another symtab if necessary. */
|
||||||
|
|
||||||
|
@ -2196,7 +2309,7 @@ find_line_symtab (struct symtab *symtab, int line,
|
||||||
/* First try looking it up in the given symtab. */
|
/* First try looking it up in the given symtab. */
|
||||||
best_linetable = LINETABLE (symtab);
|
best_linetable = LINETABLE (symtab);
|
||||||
best_symtab = symtab;
|
best_symtab = symtab;
|
||||||
best_index = find_line_common (best_linetable, line, &exact);
|
best_index = find_line_common (best_linetable, line, &exact, 0);
|
||||||
if (best_index < 0 || !exact)
|
if (best_index < 0 || !exact)
|
||||||
{
|
{
|
||||||
/* Didn't find an exact match. So we better keep looking for
|
/* Didn't find an exact match. So we better keep looking for
|
||||||
|
@ -2241,7 +2354,7 @@ find_line_symtab (struct symtab *symtab, int line,
|
||||||
&& FILENAME_CMP (symtab->fullname, s->fullname) != 0)
|
&& FILENAME_CMP (symtab->fullname, s->fullname) != 0)
|
||||||
continue;
|
continue;
|
||||||
l = LINETABLE (s);
|
l = LINETABLE (s);
|
||||||
ind = find_line_common (l, line, &exact);
|
ind = find_line_common (l, line, &exact, 0);
|
||||||
if (ind >= 0)
|
if (ind >= 0)
|
||||||
{
|
{
|
||||||
if (exact)
|
if (exact)
|
||||||
|
@ -2272,6 +2385,46 @@ done:
|
||||||
|
|
||||||
return best_symtab;
|
return best_symtab;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given SYMTAB, returns all the PCs function in the symtab that
|
||||||
|
exactly match LINE. Returns NULL if there are no exact matches,
|
||||||
|
but updates BEST_ITEM in this case. */
|
||||||
|
|
||||||
|
VEC (CORE_ADDR) *
|
||||||
|
find_pcs_for_symtab_line (struct symtab *symtab, int line,
|
||||||
|
struct linetable_entry **best_item)
|
||||||
|
{
|
||||||
|
int start = 0, ix;
|
||||||
|
struct symbol *previous_function = NULL;
|
||||||
|
VEC (CORE_ADDR) *result = NULL;
|
||||||
|
|
||||||
|
/* First, collect all the PCs that are at this line. */
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int was_exact;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = find_line_common (LINETABLE (symtab), line, &was_exact, start);
|
||||||
|
if (idx < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!was_exact)
|
||||||
|
{
|
||||||
|
struct linetable_entry *item = &LINETABLE (symtab)->item[idx];
|
||||||
|
|
||||||
|
if (*best_item == NULL || item->line < (*best_item)->line)
|
||||||
|
*best_item = item;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
VEC_safe_push (CORE_ADDR, result, LINETABLE (symtab)->item[idx].pc);
|
||||||
|
start = idx + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Set the PC value for a given source file and line number and return true.
|
/* Set the PC value for a given source file and line number and return true.
|
||||||
Returns zero for invalid line number (and sets the PC to 0).
|
Returns zero for invalid line number (and sets the PC to 0).
|
||||||
|
@ -2340,12 +2493,13 @@ find_line_pc_range (struct symtab_and_line sal, CORE_ADDR *startptr,
|
||||||
/* Given a line table and a line number, return the index into the line
|
/* Given a line table and a line number, return the index into the line
|
||||||
table for the pc of the nearest line whose number is >= the specified one.
|
table for the pc of the nearest line whose number is >= the specified one.
|
||||||
Return -1 if none is found. The value is >= 0 if it is an index.
|
Return -1 if none is found. The value is >= 0 if it is an index.
|
||||||
|
START is the index at which to start searching the line table.
|
||||||
|
|
||||||
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
|
Set *EXACT_MATCH nonzero if the value returned is an exact match. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
find_line_common (struct linetable *l, int lineno,
|
find_line_common (struct linetable *l, int lineno,
|
||||||
int *exact_match)
|
int *exact_match, int start)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int len;
|
int len;
|
||||||
|
@ -2365,7 +2519,7 @@ find_line_common (struct linetable *l, int lineno,
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
len = l->nitems;
|
len = l->nitems;
|
||||||
for (i = 0; i < len; i++)
|
for (i = start; i < len; i++)
|
||||||
{
|
{
|
||||||
struct linetable_entry *item = &(l->item[i]);
|
struct linetable_entry *item = &(l->item[i]);
|
||||||
|
|
||||||
|
@ -3012,7 +3166,8 @@ search_symbols_file_matches (const char *filename, void *user_data)
|
||||||
|
|
||||||
/* A callback for expand_symtabs_matching. */
|
/* A callback for expand_symtabs_matching. */
|
||||||
static int
|
static int
|
||||||
search_symbols_name_matches (const char *symname, void *user_data)
|
search_symbols_name_matches (const struct language_defn *language,
|
||||||
|
const char *symname, void *user_data)
|
||||||
{
|
{
|
||||||
struct search_symbols_data *data = user_data;
|
struct search_symbols_data *data = user_data;
|
||||||
|
|
||||||
|
@ -3820,7 +3975,8 @@ add_macro_name (const char *name, const struct macro_definition *ignore,
|
||||||
|
|
||||||
/* A callback for expand_partial_symbol_names. */
|
/* A callback for expand_partial_symbol_names. */
|
||||||
static int
|
static int
|
||||||
expand_partial_symbol_name (const char *name, void *user_data)
|
expand_partial_symbol_name (const struct language_defn *language,
|
||||||
|
const char *name, void *user_data)
|
||||||
{
|
{
|
||||||
struct add_name_data *datum = (struct add_name_data *) user_data;
|
struct add_name_data *datum = (struct add_name_data *) user_data;
|
||||||
|
|
||||||
|
@ -4518,7 +4674,7 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct symtabs_and_lines
|
struct symtabs_and_lines
|
||||||
decode_line_spec (char *string, int funfirstline)
|
decode_line_spec (char *string, int flags)
|
||||||
{
|
{
|
||||||
struct symtabs_and_lines sals;
|
struct symtabs_and_lines sals;
|
||||||
struct symtab_and_line cursal;
|
struct symtab_and_line cursal;
|
||||||
|
@ -4530,9 +4686,8 @@ decode_line_spec (char *string, int funfirstline)
|
||||||
and get a default or it will recursively call us! */
|
and get a default or it will recursively call us! */
|
||||||
cursal = get_current_source_symtab_and_line ();
|
cursal = get_current_source_symtab_and_line ();
|
||||||
|
|
||||||
sals = decode_line_1 (&string, funfirstline,
|
sals = decode_line_1 (&string, flags,
|
||||||
cursal.symtab, cursal.line,
|
cursal.symtab, cursal.line);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (*string)
|
if (*string)
|
||||||
error (_("Junk at end of line specification: %s"), string);
|
error (_("Junk at end of line specification: %s"), string);
|
||||||
|
@ -4620,211 +4775,6 @@ symtab_observer_executable_changed (void)
|
||||||
set_main_name (NULL);
|
set_main_name (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper to expand_line_sal below. Appends new sal to SAL,
|
|
||||||
initializing it from SYMTAB, LINENO and PC. */
|
|
||||||
static void
|
|
||||||
append_expanded_sal (struct symtabs_and_lines *sal,
|
|
||||||
struct program_space *pspace,
|
|
||||||
struct symtab *symtab,
|
|
||||||
int lineno, CORE_ADDR pc)
|
|
||||||
{
|
|
||||||
sal->sals = xrealloc (sal->sals,
|
|
||||||
sizeof (sal->sals[0])
|
|
||||||
* (sal->nelts + 1));
|
|
||||||
init_sal (sal->sals + sal->nelts);
|
|
||||||
sal->sals[sal->nelts].pspace = pspace;
|
|
||||||
sal->sals[sal->nelts].symtab = symtab;
|
|
||||||
sal->sals[sal->nelts].section = NULL;
|
|
||||||
sal->sals[sal->nelts].end = 0;
|
|
||||||
sal->sals[sal->nelts].line = lineno;
|
|
||||||
sal->sals[sal->nelts].pc = pc;
|
|
||||||
++sal->nelts;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Helper to expand_line_sal below. Search in the symtabs for any
|
|
||||||
linetable entry that exactly matches FULLNAME and LINENO and append
|
|
||||||
them to RET. If FULLNAME is NULL or if a symtab has no full name,
|
|
||||||
use FILENAME and LINENO instead. If there is at least one match,
|
|
||||||
return 1; otherwise, return 0, and return the best choice in BEST_ITEM
|
|
||||||
and BEST_SYMTAB. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
append_exact_match_to_sals (char *filename, char *fullname, int lineno,
|
|
||||||
struct symtabs_and_lines *ret,
|
|
||||||
struct linetable_entry **best_item,
|
|
||||||
struct symtab **best_symtab)
|
|
||||||
{
|
|
||||||
struct program_space *pspace;
|
|
||||||
struct objfile *objfile;
|
|
||||||
struct symtab *symtab;
|
|
||||||
int exact = 0;
|
|
||||||
int j;
|
|
||||||
*best_item = 0;
|
|
||||||
*best_symtab = 0;
|
|
||||||
|
|
||||||
ALL_PSPACES (pspace)
|
|
||||||
ALL_PSPACE_SYMTABS (pspace, objfile, symtab)
|
|
||||||
{
|
|
||||||
if (FILENAME_CMP (filename, symtab->filename) == 0)
|
|
||||||
{
|
|
||||||
struct linetable *l;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
if (fullname != NULL
|
|
||||||
&& symtab_to_fullname (symtab) != NULL
|
|
||||||
&& FILENAME_CMP (fullname, symtab->fullname) != 0)
|
|
||||||
continue;
|
|
||||||
l = LINETABLE (symtab);
|
|
||||||
if (!l)
|
|
||||||
continue;
|
|
||||||
len = l->nitems;
|
|
||||||
|
|
||||||
for (j = 0; j < len; j++)
|
|
||||||
{
|
|
||||||
struct linetable_entry *item = &(l->item[j]);
|
|
||||||
|
|
||||||
if (item->line == lineno)
|
|
||||||
{
|
|
||||||
exact = 1;
|
|
||||||
append_expanded_sal (ret, objfile->pspace,
|
|
||||||
symtab, lineno, item->pc);
|
|
||||||
}
|
|
||||||
else if (!exact && item->line > lineno
|
|
||||||
&& (*best_item == NULL
|
|
||||||
|| item->line < (*best_item)->line))
|
|
||||||
{
|
|
||||||
*best_item = item;
|
|
||||||
*best_symtab = symtab;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exact;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compute a set of all sals in all program spaces that correspond to
|
|
||||||
same file and line as SAL and return those. If there are several
|
|
||||||
sals that belong to the same block, only one sal for the block is
|
|
||||||
included in results. */
|
|
||||||
|
|
||||||
struct symtabs_and_lines
|
|
||||||
expand_line_sal (struct symtab_and_line sal)
|
|
||||||
{
|
|
||||||
struct symtabs_and_lines ret;
|
|
||||||
int i, j;
|
|
||||||
struct objfile *objfile;
|
|
||||||
int lineno;
|
|
||||||
int deleted = 0;
|
|
||||||
struct block **blocks = NULL;
|
|
||||||
int *filter;
|
|
||||||
struct cleanup *old_chain;
|
|
||||||
|
|
||||||
ret.nelts = 0;
|
|
||||||
ret.sals = NULL;
|
|
||||||
|
|
||||||
/* Only expand sals that represent file.c:line. */
|
|
||||||
if (sal.symtab == NULL || sal.line == 0 || sal.pc != 0)
|
|
||||||
{
|
|
||||||
ret.sals = xmalloc (sizeof (struct symtab_and_line));
|
|
||||||
ret.sals[0] = sal;
|
|
||||||
ret.nelts = 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct program_space *pspace;
|
|
||||||
struct linetable_entry *best_item = 0;
|
|
||||||
struct symtab *best_symtab = 0;
|
|
||||||
int exact = 0;
|
|
||||||
char *match_filename;
|
|
||||||
|
|
||||||
lineno = sal.line;
|
|
||||||
match_filename = sal.symtab->filename;
|
|
||||||
|
|
||||||
/* We need to find all symtabs for a file which name
|
|
||||||
is described by sal. We cannot just directly
|
|
||||||
iterate over symtabs, since a symtab might not be
|
|
||||||
yet created. We also cannot iterate over psymtabs,
|
|
||||||
calling PSYMTAB_TO_SYMTAB and working on that symtab,
|
|
||||||
since PSYMTAB_TO_SYMTAB will return NULL for psymtab
|
|
||||||
corresponding to an included file. Therefore, we do
|
|
||||||
first pass over psymtabs, reading in those with
|
|
||||||
the right name. Then, we iterate over symtabs, knowing
|
|
||||||
that all symtabs we're interested in are loaded. */
|
|
||||||
|
|
||||||
old_chain = save_current_program_space ();
|
|
||||||
ALL_PSPACES (pspace)
|
|
||||||
{
|
|
||||||
set_current_program_space (pspace);
|
|
||||||
ALL_PSPACE_OBJFILES (pspace, objfile)
|
|
||||||
{
|
|
||||||
if (objfile->sf)
|
|
||||||
objfile->sf->qf->expand_symtabs_with_filename (objfile,
|
|
||||||
sal.symtab->filename);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
do_cleanups (old_chain);
|
|
||||||
|
|
||||||
/* Now search the symtab for exact matches and append them. If
|
|
||||||
none is found, append the best_item and all its exact
|
|
||||||
matches. */
|
|
||||||
symtab_to_fullname (sal.symtab);
|
|
||||||
exact = append_exact_match_to_sals (sal.symtab->filename,
|
|
||||||
sal.symtab->fullname, lineno,
|
|
||||||
&ret, &best_item, &best_symtab);
|
|
||||||
if (!exact && best_item)
|
|
||||||
append_exact_match_to_sals (best_symtab->filename,
|
|
||||||
best_symtab->fullname, best_item->line,
|
|
||||||
&ret, &best_item, &best_symtab);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* For optimized code, compiler can scatter one source line accross
|
|
||||||
disjoint ranges of PC values, even when no duplicate functions
|
|
||||||
or inline functions are involved. For example, 'for (;;)' inside
|
|
||||||
non-template non-inline non-ctor-or-dtor function can result
|
|
||||||
in two PC ranges. In this case, we don't want to set breakpoint
|
|
||||||
on first PC of each range. To filter such cases, we use containing
|
|
||||||
blocks -- for each PC found above we see if there are other PCs
|
|
||||||
that are in the same block. If yes, the other PCs are filtered out. */
|
|
||||||
|
|
||||||
old_chain = save_current_program_space ();
|
|
||||||
filter = alloca (ret.nelts * sizeof (int));
|
|
||||||
blocks = alloca (ret.nelts * sizeof (struct block *));
|
|
||||||
for (i = 0; i < ret.nelts; ++i)
|
|
||||||
{
|
|
||||||
set_current_program_space (ret.sals[i].pspace);
|
|
||||||
|
|
||||||
filter[i] = 1;
|
|
||||||
blocks[i] = block_for_pc_sect (ret.sals[i].pc, ret.sals[i].section);
|
|
||||||
}
|
|
||||||
do_cleanups (old_chain);
|
|
||||||
|
|
||||||
for (i = 0; i < ret.nelts; ++i)
|
|
||||||
if (blocks[i] != NULL)
|
|
||||||
for (j = i+1; j < ret.nelts; ++j)
|
|
||||||
if (blocks[j] == blocks[i])
|
|
||||||
{
|
|
||||||
filter[j] = 0;
|
|
||||||
++deleted;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
struct symtab_and_line *final =
|
|
||||||
xmalloc (sizeof (struct symtab_and_line) * (ret.nelts-deleted));
|
|
||||||
|
|
||||||
for (i = 0, j = 0; i < ret.nelts; ++i)
|
|
||||||
if (filter[i])
|
|
||||||
final[j++] = ret.sals[i];
|
|
||||||
|
|
||||||
ret.nelts -= deleted;
|
|
||||||
xfree (ret.sals);
|
|
||||||
ret.sals = final;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return 1 if the supplied producer string matches the ARM RealView
|
/* Return 1 if the supplied producer string matches the ARM RealView
|
||||||
compiler (armcc). */
|
compiler (armcc). */
|
||||||
|
|
||||||
|
|
37
gdb/symtab.h
37
gdb/symtab.h
|
@ -22,6 +22,8 @@
|
||||||
#if !defined (SYMTAB_H)
|
#if !defined (SYMTAB_H)
|
||||||
#define SYMTAB_H 1
|
#define SYMTAB_H 1
|
||||||
|
|
||||||
|
#include "vec.h"
|
||||||
|
|
||||||
/* Opaque declarations. */
|
/* Opaque declarations. */
|
||||||
struct ui_file;
|
struct ui_file;
|
||||||
struct frame_info;
|
struct frame_info;
|
||||||
|
@ -1056,6 +1058,12 @@ extern struct minimal_symbol *lookup_minimal_symbol_by_pc_name
|
||||||
|
|
||||||
extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
|
extern struct minimal_symbol *lookup_minimal_symbol_by_pc (CORE_ADDR);
|
||||||
|
|
||||||
|
extern void iterate_over_minimal_symbols (struct objfile *objf,
|
||||||
|
const char *name,
|
||||||
|
void (*callback) (struct minimal_symbol *,
|
||||||
|
void *),
|
||||||
|
void *user_data);
|
||||||
|
|
||||||
extern int in_gnu_ifunc_stub (CORE_ADDR pc);
|
extern int in_gnu_ifunc_stub (CORE_ADDR pc);
|
||||||
|
|
||||||
/* Functions for resolving STT_GNU_IFUNC symbols which are implemented only
|
/* Functions for resolving STT_GNU_IFUNC symbols which are implemented only
|
||||||
|
@ -1295,8 +1303,6 @@ struct symbol *lookup_global_symbol_from_objfile (const struct objfile *,
|
||||||
const char *name,
|
const char *name,
|
||||||
const domain_enum domain);
|
const domain_enum domain);
|
||||||
|
|
||||||
extern struct symtabs_and_lines expand_line_sal (struct symtab_and_line sal);
|
|
||||||
|
|
||||||
/* Return 1 if the supplied producer string matches the ARM RealView
|
/* Return 1 if the supplied producer string matches the ARM RealView
|
||||||
compiler (armcc). */
|
compiler (armcc). */
|
||||||
int producer_is_realview (const char *producer);
|
int producer_is_realview (const char *producer);
|
||||||
|
@ -1308,4 +1314,31 @@ struct objfile *lookup_objfile_from_block (const struct block *block);
|
||||||
|
|
||||||
extern int basenames_may_differ;
|
extern int basenames_may_differ;
|
||||||
|
|
||||||
|
int iterate_over_some_symtabs (const char *name,
|
||||||
|
const char *full_path,
|
||||||
|
const char *real_path,
|
||||||
|
int (*callback) (struct symtab *symtab,
|
||||||
|
void *data),
|
||||||
|
void *data,
|
||||||
|
struct symtab *first,
|
||||||
|
struct symtab *after_last);
|
||||||
|
|
||||||
|
void iterate_over_symtabs (const char *name,
|
||||||
|
int (*callback) (struct symtab *symtab,
|
||||||
|
void *data),
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
DEF_VEC_I (CORE_ADDR);
|
||||||
|
|
||||||
|
VEC (CORE_ADDR) *find_pcs_for_symtab_line (struct symtab *symtab, int line,
|
||||||
|
struct linetable_entry **best_entry);
|
||||||
|
|
||||||
|
void iterate_over_symbols (const struct block *block, const char *name,
|
||||||
|
const domain_enum domain,
|
||||||
|
int (*callback) (struct symbol *, void *),
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
struct cleanup *demangle_for_lookup (const char *name, enum language lang,
|
||||||
|
const char **result_name);
|
||||||
|
|
||||||
#endif /* !defined(SYMTAB_H) */
|
#endif /* !defined(SYMTAB_H) */
|
||||||
|
|
|
@ -1,3 +1,46 @@
|
||||||
|
2011-12-06 Joel Brobecker <brobecker@acacore.com>
|
||||||
|
|
||||||
|
* gdb.ada/fullname_bp.exp: Add tests for other valid linespecs
|
||||||
|
involving a fully qualified function name.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* gdb.ada/homonym.exp: Add three breakpoint tests.
|
||||||
|
|
||||||
|
2011-12-06 Tom Tromey <tromey@redhat.com>
|
||||||
|
|
||||||
|
* gdb.base/solib-weak.exp (do_test): Remove kfail.
|
||||||
|
* gdb.trace/tracecmd.exp: Disable pending breakpoints earlier.
|
||||||
|
* gdb.objc/objcdecode.exp: Update for output changes.
|
||||||
|
* gdb.linespec/linespec.exp: New file.
|
||||||
|
* gdb.linespec/lspec.cc: New file.
|
||||||
|
* gdb.linespec/lspec.h: New file.
|
||||||
|
* gdb.linespec/body.h: New file.
|
||||||
|
* gdb.linespec/base/two/thefile.cc: New file.
|
||||||
|
* gdb.linespec/base/one/thefile.cc: New file.
|
||||||
|
* gdb.linespec/Makefile.in: New file.
|
||||||
|
* gdb.cp/templates.exp (test_template_breakpoints): Update for
|
||||||
|
output changes.
|
||||||
|
* gdb.cp/re-set-overloaded.exp: Remove kfail.
|
||||||
|
* gdb.cp/ovldbreak.exp: Update for output changes. "all" test now
|
||||||
|
makes one breakpoint.
|
||||||
|
* gdb.cp/method2.exp (test_break): Update for output changes.
|
||||||
|
* gdb.cp/mb-templates.exp: Update for output changes.
|
||||||
|
* gdb.cp/mb-inline.exp: Update for output changes.
|
||||||
|
* gdb.cp/mb-ctor.exp: Update for output changes.
|
||||||
|
* gdb.cp/ovsrch.exp: Use fully-qualified names.
|
||||||
|
* gdb.base/solib-symbol.exp: Run to main later. Breakpoint now
|
||||||
|
has multiple matches.
|
||||||
|
* gdb.base/sepdebug.exp: Disable pending breakpoints. Update for
|
||||||
|
error message change.
|
||||||
|
* gdb.base/list.exp (test_list_filename_and_number): Update for
|
||||||
|
error message change.
|
||||||
|
* gdb.base/break.exp: Disable pending breakpoints. Update for
|
||||||
|
output changes.
|
||||||
|
* configure.ac: Add gdb.linespec.
|
||||||
|
* configure: Rebuild.
|
||||||
|
* Makefile.in (ALL_SUBDIRS): Add gdb.linespec.
|
||||||
|
|
||||||
2011-12-06 Ulrich Weigand <uweigand@de.ibm.com>
|
2011-12-06 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
* gdb.base/callfuncs.exp (fetch_all_registers): Filter out read-only
|
* gdb.base/callfuncs.exp (fetch_all_registers): Filter out read-only
|
||||||
|
|
|
@ -35,7 +35,7 @@ SUBDIRS = @subdirs@
|
||||||
RPATH_ENVVAR = @RPATH_ENVVAR@
|
RPATH_ENVVAR = @RPATH_ENVVAR@
|
||||||
ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.cell gdb.cp gdb.disasm \
|
ALL_SUBDIRS = gdb.ada gdb.arch gdb.asm gdb.base gdb.cell gdb.cp gdb.disasm \
|
||||||
gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
|
gdb.dwarf2 gdb.fortran gdb.gdb gdb.hp \
|
||||||
gdb.java gdb.mi gdb.modula2 gdb.multi \
|
gdb.java gdb.linespec gdb.mi gdb.modula2 gdb.multi \
|
||||||
gdb.objc gdb.opencl gdb.opt gdb.pascal gdb.python gdb.server \
|
gdb.objc gdb.opencl gdb.opt gdb.pascal gdb.python gdb.server \
|
||||||
gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml \
|
gdb.stabs gdb.reverse gdb.threads gdb.trace gdb.xml \
|
||||||
$(SUBDIRS)
|
$(SUBDIRS)
|
||||||
|
|
3
gdb/testsuite/configure
vendored
3
gdb/testsuite/configure
vendored
|
@ -3448,7 +3448,7 @@ done
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
|
ac_config_files="$ac_config_files Makefile gdb.ada/Makefile gdb.arch/Makefile gdb.asm/Makefile gdb.base/Makefile gdb.cell/Makefile gdb.cp/Makefile gdb.disasm/Makefile gdb.dwarf2/Makefile gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile gdb.threads/Makefile gdb.trace/Makefile gdb.xml/Makefile"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
|
@ -4166,6 +4166,7 @@ do
|
||||||
"gdb.hp/gdb.aCC/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.aCC/Makefile" ;;
|
"gdb.hp/gdb.aCC/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.aCC/Makefile" ;;
|
||||||
"gdb.hp/gdb.compat/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.compat/Makefile" ;;
|
"gdb.hp/gdb.compat/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.compat/Makefile" ;;
|
||||||
"gdb.hp/gdb.defects/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.defects/Makefile" ;;
|
"gdb.hp/gdb.defects/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.hp/gdb.defects/Makefile" ;;
|
||||||
|
"gdb.linespec/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.linespec/Makefile" ;;
|
||||||
"gdb.mi/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.mi/Makefile" ;;
|
"gdb.mi/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.mi/Makefile" ;;
|
||||||
"gdb.modula2/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.modula2/Makefile" ;;
|
"gdb.modula2/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.modula2/Makefile" ;;
|
||||||
"gdb.multi/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.multi/Makefile" ;;
|
"gdb.multi/Makefile") CONFIG_FILES="$CONFIG_FILES gdb.multi/Makefile" ;;
|
||||||
|
|
|
@ -95,7 +95,7 @@ AC_OUTPUT([Makefile \
|
||||||
gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile \
|
gdb.fortran/Makefile gdb.server/Makefile gdb.java/Makefile \
|
||||||
gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile \
|
gdb.hp/Makefile gdb.hp/gdb.objdbg/Makefile gdb.hp/gdb.base-hp/Makefile \
|
||||||
gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile \
|
gdb.hp/gdb.aCC/Makefile gdb.hp/gdb.compat/Makefile \
|
||||||
gdb.hp/gdb.defects/Makefile \
|
gdb.hp/gdb.defects/Makefile gdb.linespec/Makefile \
|
||||||
gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
|
gdb.mi/Makefile gdb.modula2/Makefile gdb.multi/Makefile \
|
||||||
gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
|
gdb.objc/Makefile gdb.opencl/Makefile gdb.opt/Makefile gdb.pascal/Makefile \
|
||||||
gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
|
gdb.python/Makefile gdb.reverse/Makefile gdb.stabs/Makefile \
|
||||||
|
|
|
@ -25,6 +25,9 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug ]] != "" }
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Note: We restart the debugger before setting each breakpoint, because
|
||||||
|
# we want to test the situation where the symtab for our breakpoint
|
||||||
|
# has not been created yet.
|
||||||
clean_restart ${testfile}
|
clean_restart ${testfile}
|
||||||
|
|
||||||
# Break on "pck.hello" rather than just "hello" to make sure we trigger
|
# Break on "pck.hello" rather than just "hello" to make sure we trigger
|
||||||
|
@ -32,3 +35,23 @@ clean_restart ${testfile}
|
||||||
gdb_test "break pck.hello" \
|
gdb_test "break pck.hello" \
|
||||||
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
|
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
|
||||||
|
|
||||||
|
# Do the same, but this time using a linespec where the user also
|
||||||
|
# provided a filename.
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
gdb_test "break pck.adb:pck.hello" \
|
||||||
|
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
|
||||||
|
|
||||||
|
# Same scenarios as above, but with a function name that is spelled
|
||||||
|
# with upper-case letters.
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
gdb_test "break Pck.Hello" \
|
||||||
|
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
|
||||||
|
|
||||||
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
gdb_test "break pck.adb:Pck.Hello" \
|
||||||
|
"Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*pck.adb, line \[0-9\]+."
|
||||||
|
|
|
@ -31,6 +31,24 @@ if {[gdb_compile_ada "${srcfile}" "${binfile}" executable [list debug]] != "" }
|
||||||
|
|
||||||
clean_restart ${testfile}
|
clean_restart ${testfile}
|
||||||
|
|
||||||
|
|
||||||
|
# Do these tests before running, so we are operating in a known
|
||||||
|
# environment.
|
||||||
|
|
||||||
|
gdb_test "break Get_Value" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: Get_Value. .2 locations." \
|
||||||
|
"set breakpoint at Get_Value"
|
||||||
|
|
||||||
|
gdb_test "break homonym.adb:Get_Value" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: homonym.adb:Get_Value. .2 locations." \
|
||||||
|
"set breakpoint at homonym.adb:Get_Value"
|
||||||
|
|
||||||
|
gdb_test "break <homonym__get_value>" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: <homonym__get_value>. .2 locations." \
|
||||||
|
"set breakpoint at <homonym__get_value>"
|
||||||
|
|
||||||
|
delete_breakpoints
|
||||||
|
|
||||||
set bp_location [gdb_get_line_number "BREAK_1" ${testdir}/homonym.adb]
|
set bp_location [gdb_get_line_number "BREAK_1" ${testdir}/homonym.adb]
|
||||||
runto "homonym.adb:$bp_location"
|
runto "homonym.adb:$bp_location"
|
||||||
|
|
||||||
|
@ -86,6 +104,3 @@ gdb_test "ptype lcl" \
|
||||||
gdb_test "print lcl" \
|
gdb_test "print lcl" \
|
||||||
"= 17" \
|
"= 17" \
|
||||||
"print lcl at BREAK_2"
|
"print lcl at BREAK_2"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -540,8 +540,9 @@ gdb_test_multiple "catch exec" "$name" {
|
||||||
# Verify that GDB responds gracefully when asked to set a breakpoint
|
# Verify that GDB responds gracefully when asked to set a breakpoint
|
||||||
# on a nonexistent source line.
|
# on a nonexistent source line.
|
||||||
#
|
#
|
||||||
|
gdb_test_no_output "set breakpoint pending off"
|
||||||
gdb_test "break 999" \
|
gdb_test "break 999" \
|
||||||
"No line 999 in file .*" \
|
"No line 999 in the current file." \
|
||||||
"break on non-existent source line"
|
"break on non-existent source line"
|
||||||
|
|
||||||
# Run to the desired default location. If not positioned here, the
|
# Run to the desired default location. If not positioned here, the
|
||||||
|
|
|
@ -489,7 +489,7 @@ proc test_list_filename_and_function {} {
|
||||||
|
|
||||||
gdb_test "list foobar.c:main" "No source file named foobar.c.|Location not found" "list filename:function; nonexistant file"
|
gdb_test "list foobar.c:main" "No source file named foobar.c.|Location not found" "list filename:function; nonexistant file"
|
||||||
|
|
||||||
gdb_test "list list0.h:foobar" "Function \"foobar\" not defined.|Location not found" "list filename:function; nonexistant function"
|
gdb_test "list list0.h:foobar" "Function \"foobar\" not defined in \"list0.h\"." "list filename:function; nonexistant function"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -337,7 +337,8 @@ gdb_test_multiple "catch exec" $name {
|
||||||
# on a nonexistent source line.
|
# on a nonexistent source line.
|
||||||
#
|
#
|
||||||
|
|
||||||
gdb_test "break 999" "No line 999 in file .*" \
|
gdb_test_no_output "set breakpoint pending off"
|
||||||
|
gdb_test "break 999" "No line 999 in the current file." \
|
||||||
"break on non-existent source line"
|
"break on non-existent source line"
|
||||||
|
|
||||||
# Run to the desired default location. If not positioned here, the
|
# Run to the desired default location. If not positioned here, the
|
||||||
|
|
|
@ -46,11 +46,6 @@ gdb_reinitialize_dir $srcdir/$subdir
|
||||||
gdb_load ${binfile}
|
gdb_load ${binfile}
|
||||||
gdb_load_shlibs $binfile_lib
|
gdb_load_shlibs $binfile_lib
|
||||||
|
|
||||||
if ![runto_main] then {
|
|
||||||
fail "Can't run to main"
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set a breakpoint in the binary.
|
# Set a breakpoint in the binary.
|
||||||
gdb_test "br foo2" \
|
gdb_test "br foo2" \
|
||||||
"Breakpoint.*file.*${testfile}\\.c.*" \
|
"Breakpoint.*file.*${testfile}\\.c.*" \
|
||||||
|
@ -58,6 +53,11 @@ gdb_test "br foo2" \
|
||||||
|
|
||||||
delete_breakpoints
|
delete_breakpoints
|
||||||
|
|
||||||
|
if ![runto_main] then {
|
||||||
|
fail "Can't run to main"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
# Break in the library.
|
# Break in the library.
|
||||||
gdb_test "br foo" \
|
gdb_test "br foo" \
|
||||||
"Breakpoint.*file.*${libname}\\.c.*" \
|
"Breakpoint.*file.*${libname}\\.c.*" \
|
||||||
|
@ -67,9 +67,9 @@ gdb_test "continue" \
|
||||||
"Continuing.*" \
|
"Continuing.*" \
|
||||||
"continue"
|
"continue"
|
||||||
|
|
||||||
# This symbol is now looked up in the ELF library.
|
# This symbol is now looked up in the ELF library and the binary.
|
||||||
gdb_test "br foo2" \
|
gdb_test "br foo2" \
|
||||||
"Breakpoint.*file.*${libname}\\.c.*" \
|
"Breakpoint.*: foo2. .2 locations..*" \
|
||||||
"foo2 in mdlib"
|
"foo2 in mdlib"
|
||||||
|
|
||||||
gdb_exit
|
gdb_exit
|
||||||
|
|
|
@ -101,15 +101,6 @@ proc do_test { lib1opts lib2opts lib1first } {
|
||||||
|
|
||||||
gdb_breakpoint "bar"
|
gdb_breakpoint "bar"
|
||||||
|
|
||||||
# If the library which will be used is compiled without debugging
|
|
||||||
# information, GDB will pick the wrong copy of "bar", i.e. the one
|
|
||||||
# with debugging information.
|
|
||||||
|
|
||||||
if {(${lib1opts} == "" && ${lib2opts} != "" && ${lib1first} == 1)
|
|
||||||
|| (${lib1opts} != "" && ${lib2opts} == "" && ${lib1first} == 0)} {
|
|
||||||
setup_kfail gdb/1824 *-*-*
|
|
||||||
}
|
|
||||||
|
|
||||||
gdb_test "continue" "Breakpoint .* \\.?bar .*${expected_file}\\..*" \
|
gdb_test "continue" "Breakpoint .* \\.?bar .*${expected_file}\\..*" \
|
||||||
"run to breakpoint - $testopts"
|
"run to breakpoint - $testopts"
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,13 @@ if ![runto_main] then {
|
||||||
# and a condition.
|
# and a condition.
|
||||||
|
|
||||||
gdb_test "break 'Derived::Derived(int)'" \
|
gdb_test "break 'Derived::Derived(int)'" \
|
||||||
"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: Derived::Derived.int.. \\(2 locations\\).*" \
|
||||||
"set-breakpoint at ctor"
|
"set-breakpoint at ctor"
|
||||||
|
|
||||||
gdb_breakpoint [gdb_get_line_number "set breakpoint here"]
|
gdb_breakpoint [gdb_get_line_number "set breakpoint here"]
|
||||||
|
|
||||||
gdb_test "break 'Derived::~Derived()'" \
|
gdb_test "break 'Derived::~Derived()'" \
|
||||||
"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: Derived::~Derived... \\(2 locations\\).*" \
|
||||||
"set-breakpoint at dtor"
|
"set-breakpoint at dtor"
|
||||||
|
|
||||||
gdb_test "continue" \
|
gdb_test "continue" \
|
||||||
|
|
|
@ -62,7 +62,7 @@ set bp_location [gdb_get_line_number "set breakpoint here" $hdrfile]
|
||||||
# Set a breakpoint with multiple locations.
|
# Set a breakpoint with multiple locations.
|
||||||
|
|
||||||
gdb_test "break $hdrfile:$bp_location" \
|
gdb_test "break $hdrfile:$bp_location" \
|
||||||
"Breakpoint.*at.* file .*$hdrfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: $hdrfile:$bp_location. \\(2 locations\\).*" \
|
||||||
"set breakpoint"
|
"set breakpoint"
|
||||||
|
|
||||||
gdb_run_cmd
|
gdb_run_cmd
|
||||||
|
@ -128,7 +128,7 @@ if { ![runto_main] } {
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_test "break $hdrfile:$bp_location" \
|
gdb_test "break $hdrfile:$bp_location" \
|
||||||
"Breakpoint.*at.* file .*$hdrfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: $hdrfile:$bp_location. \\(2 locations\\).*" \
|
||||||
"set multi_line_foo breakpoint"
|
"set multi_line_foo breakpoint"
|
||||||
gdb_test "continue" \
|
gdb_test "continue" \
|
||||||
".*Breakpoint.*multi_line_foo \\(i=0\\).*" \
|
".*Breakpoint.*multi_line_foo \\(i=0\\).*" \
|
||||||
|
|
|
@ -52,7 +52,7 @@ set bp_location [gdb_get_line_number "set breakpoint here"]
|
||||||
# and a condition.
|
# and a condition.
|
||||||
|
|
||||||
gdb_test "break $srcfile:$bp_location if i==1" \
|
gdb_test "break $srcfile:$bp_location if i==1" \
|
||||||
"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
|
||||||
"initial condition: set breakpoint"
|
"initial condition: set breakpoint"
|
||||||
|
|
||||||
gdb_run_cmd
|
gdb_run_cmd
|
||||||
|
@ -80,7 +80,7 @@ gdb_reinitialize_dir $srcdir/$subdir
|
||||||
gdb_load ${binfile}
|
gdb_load ${binfile}
|
||||||
|
|
||||||
gdb_test "break $srcfile:$bp_location" \
|
gdb_test "break $srcfile:$bp_location" \
|
||||||
"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
|
||||||
"separate condition: set breakpoint"
|
"separate condition: set breakpoint"
|
||||||
|
|
||||||
gdb_test_no_output "condition 1 i==1" \
|
gdb_test_no_output "condition 1 i==1" \
|
||||||
|
@ -177,7 +177,7 @@ if { ![runto_main] } {
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_test "break $srcfile:$bp_location" \
|
gdb_test "break $srcfile:$bp_location" \
|
||||||
"Breakpoint.*at.* file .*$srcfile, line.*\\(2 locations\\).*" \
|
"Breakpoint.*at.*: $srcfile:$bp_location. \\(2 locations\\).*" \
|
||||||
"set multi_line_foo breakpoint"
|
"set multi_line_foo breakpoint"
|
||||||
gdb_test "continue" \
|
gdb_test "continue" \
|
||||||
".*Breakpoint.*multi_line_foo<int> \\(i=0\\).*" \
|
".*Breakpoint.*multi_line_foo<int> \\(i=0\\).*" \
|
||||||
|
|
|
@ -51,7 +51,7 @@ proc test_break { lang } {
|
||||||
"setting language $lang"
|
"setting language $lang"
|
||||||
|
|
||||||
gdb_test_multiple "break A::method" "breaking in method ($lang)" {
|
gdb_test_multiple "break A::method" "breaking in method ($lang)" {
|
||||||
-re ".0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. A::method\\(A\\*\\) at .*\[\r\n\]*.3. A::method\\(int\\) at .*\[\r\n\]*\[\r\n\]*.4. A::method\\(\\) at .*\[\r\n\]*> $" {
|
-re ".0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. .*:A::method\\(A\\*\\)\[\r\n\]*.3. .*:A::method\\(int\\)\[\r\n\]*.4. .*:A::method\\(\\)\[\r\n\]*> $" {
|
||||||
gdb_test "0" \
|
gdb_test "0" \
|
||||||
"canceled" \
|
"canceled" \
|
||||||
"breaking in method ($lang)"
|
"breaking in method ($lang)"
|
||||||
|
|
|
@ -130,18 +130,18 @@ proc set_bp_overloaded {name expectedmenu mychoice bpnumber linenumber} {
|
||||||
|
|
||||||
set menu_overload1arg "\\\[0\\\] cancel\r\n"
|
set menu_overload1arg "\\\[0\\\] cancel\r\n"
|
||||||
append menu_overload1arg "\\\[1\\\] all\r\n"
|
append menu_overload1arg "\\\[1\\\] all\r\n"
|
||||||
append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n"
|
append menu_overload1arg "\\\[2\\\] .*$srcfile:foo::overload1arg\\(double\\)\r\n"
|
||||||
append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n"
|
append menu_overload1arg "\\\[3\\\] .*$srcfile:foo::overload1arg\\(float\\)\r\n"
|
||||||
append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n"
|
append menu_overload1arg "\\\[4\\\] .*$srcfile:foo::overload1arg\\((unsigned long|long unsigned)( int)?\\)\r\n"
|
||||||
append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n"
|
append menu_overload1arg "\\\[5\\\] .*$srcfile:foo::overload1arg\\(long( int)?\\)\r\n"
|
||||||
append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n"
|
append menu_overload1arg "\\\[6\\\] .*$srcfile:foo::overload1arg\\((unsigned int|unsigned)\\)\r\n"
|
||||||
append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n"
|
append menu_overload1arg "\\\[7\\\] .*$srcfile:foo::overload1arg\\(int\\)\r\n"
|
||||||
append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n"
|
append menu_overload1arg "\\\[8\\\] .*$srcfile:foo::overload1arg\\((unsigned short|short unsigned)( int)?\\)\r\n"
|
||||||
append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n"
|
append menu_overload1arg "\\\[9\\\] .*$srcfile:foo::overload1arg\\(short( int)?\\)\r\n"
|
||||||
append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n"
|
append menu_overload1arg "\\\[10\\\] .*$srcfile:foo::overload1arg\\(unsigned char\\)\r\n"
|
||||||
append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n"
|
append menu_overload1arg "\\\[11\\\] .*$srcfile:foo::overload1arg\\(signed char\\)\r\n"
|
||||||
append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n"
|
append menu_overload1arg "\\\[12\\\] .*$srcfile:foo::overload1arg\\(char\\)\r\n"
|
||||||
append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n"
|
append menu_overload1arg "\\\[13\\\] .*$srcfile:foo::overload1arg\\((void|)\\)\r\n"
|
||||||
append menu_overload1arg "> $"
|
append menu_overload1arg "> $"
|
||||||
|
|
||||||
# Set multiple-symbols to "ask", to allow us to test the use
|
# Set multiple-symbols to "ask", to allow us to test the use
|
||||||
|
@ -279,7 +279,7 @@ gdb_expect {
|
||||||
# Choose all.
|
# Choose all.
|
||||||
send_gdb "1\n"
|
send_gdb "1\n"
|
||||||
gdb_expect {
|
gdb_expect {
|
||||||
-re "Breakpoint $decimal at $hex: file.*$srcfile, line 121.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 120.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 119.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 118.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 117.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 116.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 115.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 114.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 113.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 112.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 111.\r\nBreakpoint $decimal at $hex: file.*$srcfile, line 110.\r\nwarning: Multiple breakpoints were set.\r\nUse the .delete. command to delete unwanted breakpoints.\r\n$gdb_prompt $" {
|
-re "Breakpoint $decimal at $hex: foo::overload1arg. .12 locations.\r\n.*$gdb_prompt $" {
|
||||||
pass "set bp on overload1arg all"
|
pass "set bp on overload1arg all"
|
||||||
}
|
}
|
||||||
-re ".*$gdb_prompt $" {
|
-re ".*$gdb_prompt $" {
|
||||||
|
@ -306,18 +306,19 @@ gdb_expect {
|
||||||
|
|
||||||
gdb_test "info break" \
|
gdb_test "info break" \
|
||||||
"Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
|
"Num Type\[\t \]+Disp Enb Address\[\t \]+What.*
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
|
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+<MULTIPLE>\[\t \]*\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
|
\[0-9\]+.1\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
|
\[0-9\]+.2\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
|
\[0-9\]+.3\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
|
\[0-9\]+.4\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
|
\[0-9\]+.5\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
|
\[0-9\]+.6\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
|
\[0-9\]+.7\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
|
\[0-9\]+.8\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
|
\[0-9\]+.9\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
|
\[0-9\]+.10\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
|
||||||
\[0-9\]+\[\t \]+breakpoint keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
|
\[0-9\]+.11\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
|
||||||
|
\[0-9\]+.12\[\t \]+y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
|
||||||
"breakpoint info (after setting on all)"
|
"breakpoint info (after setting on all)"
|
||||||
|
|
||||||
|
|
||||||
|
@ -333,10 +334,10 @@ proc continue_to_bp_overloaded {might_kfail bpnumber argtype actuals} {
|
||||||
|
|
||||||
send_gdb "continue\n"
|
send_gdb "continue\n"
|
||||||
gdb_expect {
|
gdb_expect {
|
||||||
-re "Continuing.\r\n\r\nBreakpoint ${bpnumber}, (${hex} in )?foo::overload1arg(\\(${argtype}\\))? \\(this=${hex}(, )?${actuals}\\) at.*${srcfile}:${decimal}\r\n${decimal}\[\t \]+int foo::overload1arg \\(${argtype}( arg)?\\).*\r\n.*$gdb_prompt $" {
|
-re "Continuing.\r\n\r\nBreakpoint ${bpnumber}, foo::overload1arg \\(this=${hex}(, )?${actuals}\\) at.*${srcfile}:${decimal}\r\n${decimal}\[\t \]+int foo::overload1arg \\(${argtype}( arg)?\\).*\r\n.*$gdb_prompt $" {
|
||||||
pass "continue to bp overloaded : ${argtype}"
|
pass "continue to bp overloaded : ${argtype}"
|
||||||
}
|
}
|
||||||
-re "Continuing.\r\n\r\nBreakpoint ${bpnumber}, (${hex} in )?foo::overload1arg(\\(${argtype}\\))? \\(this=${hex}, arg=.*\\) at.*${srcfile}:${decimal}\r\n${decimal}\[\t \]+int foo::overload1arg \\(${argtype}( arg)?\\).*\r\n.*$gdb_prompt $" {
|
-re "Continuing.\r\n\r\nBreakpoint ${bpnumber}, foo::overload1arg \\(this=${hex}, arg=.*\\) at.*${srcfile}:${decimal}\r\n${decimal}\[\t \]+int foo::overload1arg \\(${argtype}( arg)?\\).*\r\n.*$gdb_prompt $" {
|
||||||
if $might_kfail {
|
if $might_kfail {
|
||||||
kfail "gdb/1025" "continue to bp overloaded : ${argtype}"
|
kfail "gdb/1025" "continue to bp overloaded : ${argtype}"
|
||||||
} else {
|
} else {
|
||||||
|
@ -352,17 +353,17 @@ proc continue_to_bp_overloaded {might_kfail bpnumber argtype actuals} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue_to_bp_overloaded 0 25 "(void|)" ""
|
continue_to_bp_overloaded 0 14 "(void|)" ""
|
||||||
continue_to_bp_overloaded 1 24 "char" "arg=2 \\'\\\\002\\'"
|
continue_to_bp_overloaded 1 14 "char" "arg=2 \\'\\\\002\\'"
|
||||||
continue_to_bp_overloaded 1 23 "signed char" "arg=3 \\'\\\\003\\'"
|
continue_to_bp_overloaded 1 14 "signed char" "arg=3 \\'\\\\003\\'"
|
||||||
continue_to_bp_overloaded 1 22 "unsigned char" "arg=4 \\'\\\\004\\'"
|
continue_to_bp_overloaded 1 14 "unsigned char" "arg=4 \\'\\\\004\\'"
|
||||||
continue_to_bp_overloaded 1 21 "short" "arg=5"
|
continue_to_bp_overloaded 1 14 "short" "arg=5"
|
||||||
continue_to_bp_overloaded 1 20 "unsigned short" "arg=6"
|
continue_to_bp_overloaded 1 14 "unsigned short" "arg=6"
|
||||||
continue_to_bp_overloaded 0 19 "int" "arg=7"
|
continue_to_bp_overloaded 0 14 "int" "arg=7"
|
||||||
continue_to_bp_overloaded 0 18 "(unsigned|unsigned int)" "arg=8"
|
continue_to_bp_overloaded 0 14 "(unsigned|unsigned int)" "arg=8"
|
||||||
continue_to_bp_overloaded 0 17 "long" "arg=9"
|
continue_to_bp_overloaded 0 14 "long" "arg=9"
|
||||||
continue_to_bp_overloaded 0 16 "unsigned long" "arg=10"
|
continue_to_bp_overloaded 0 14 "unsigned long" "arg=10"
|
||||||
continue_to_bp_overloaded 0 15 "float" "arg=100"
|
continue_to_bp_overloaded 0 14 "float" "arg=100"
|
||||||
continue_to_bp_overloaded 1 14 "double" "arg=200"
|
continue_to_bp_overloaded 1 14 "double" "arg=200"
|
||||||
|
|
||||||
# Test breaking on an overloaded function when multiple-symbols
|
# Test breaking on an overloaded function when multiple-symbols
|
||||||
|
@ -375,7 +376,7 @@ gdb_test "break foo::foofunc" \
|
||||||
# is set to "all"
|
# is set to "all"
|
||||||
gdb_test_no_output "set multiple-symbols all"
|
gdb_test_no_output "set multiple-symbols all"
|
||||||
gdb_test "break foo::foofunc" \
|
gdb_test "break foo::foofunc" \
|
||||||
"Breakpoint \[0-9\]+ at ${hex}: file .*ovldbreak\\.cc, line \[0-9\]+\\.\r\nBreakpoint \[0-9\]+ at ${hex}: file .*ovldbreak\\.cc, line \[0-9\]+\\.\r\nwarning: Multiple breakpoints were set\\.\r\nUse the \"delete\" command to delete unwanted breakpoints\\."
|
"Breakpoint \[0-9\]+ at ${hex}: foo::foofunc. .2 locations..*"
|
||||||
|
|
||||||
# That's all, folks.
|
# That's all, folks.
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ proc test_class {class} {
|
||||||
|
|
||||||
# Test whether open parentheses are correctly identified as overload
|
# Test whether open parentheses are correctly identified as overload
|
||||||
# information or conditional.
|
# information or conditional.
|
||||||
gdb_test "break ${class}::foo if (a == 3)" "Breakpoint (\[0-9\]).*"
|
gdb_test "break ${class}::hibob if (a_param == 3)" "Breakpoint (\[0-9\]).*"
|
||||||
}
|
}
|
||||||
|
|
||||||
if { [skip_cplus_tests] } { continue }
|
if { [skip_cplus_tests] } { continue }
|
||||||
|
@ -73,28 +73,28 @@ if {![runto_main]} {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Break in A::stop_here and run tests.
|
# Break in A::stop_here and run tests.
|
||||||
if {[gdb_breakpoint "stop_here"]} {
|
if {[gdb_breakpoint "A::stop_here"]} {
|
||||||
pass "break stop_here"
|
pass "break A::stop_here"
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[gdb_breakpoint "'stop_here'"]} {
|
if {[gdb_breakpoint "'A::stop_here'"]} {
|
||||||
pass "break 'stop_here'"
|
pass "break 'A::stop_here'"
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_continue_to_breakpoint "stop_here"
|
gdb_continue_to_breakpoint "stop_here"
|
||||||
test_class outer
|
test_class A::outer
|
||||||
|
|
||||||
# Break in A::B::stop_here_too and run tests.
|
# Break in A::B::stop_here_too and run tests.
|
||||||
if {[gdb_breakpoint "B::stop_here_too"]} {
|
if {[gdb_breakpoint "A::B::stop_here_too"]} {
|
||||||
pass "break B::stop_here_too"
|
pass "break A::B::stop_here_too"
|
||||||
}
|
}
|
||||||
|
|
||||||
if {[gdb_breakpoint "'B::stop_here_too'"]} {
|
if {[gdb_breakpoint "'A::B::stop_here_too'"]} {
|
||||||
pass "break 'B::stop_here_too'"
|
pass "break 'A::B::stop_here_too'"
|
||||||
}
|
}
|
||||||
|
|
||||||
gdb_continue_to_breakpoint "stop_here_too"
|
gdb_continue_to_breakpoint "stop_here_too"
|
||||||
test_class inner
|
test_class A::B::inner
|
||||||
|
|
||||||
gdb_exit
|
gdb_exit
|
||||||
return 0
|
return 0
|
||||||
|
|
|
@ -24,6 +24,8 @@ namespace A
|
||||||
void foo (int) const;
|
void foo (int) const;
|
||||||
void foo (char *) const;
|
void foo (char *) const;
|
||||||
bool func (void) { return true; }
|
bool func (void) { return true; }
|
||||||
|
void hibob (int) const;
|
||||||
|
void hibob (char *) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace B
|
namespace B
|
||||||
|
@ -34,6 +36,8 @@ namespace A
|
||||||
void foo (void) const;
|
void foo (void) const;
|
||||||
void foo (int) const;
|
void foo (int) const;
|
||||||
void foo (char *) const;
|
void foo (char *) const;
|
||||||
|
void hibob (int) const;
|
||||||
|
void hibob (char *) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,21 @@
|
||||||
#include "ovsrch.h"
|
#include "ovsrch.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
A::outer::foo (int a) const
|
A::outer::foo (int a_param) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
A::B::inner::foo (int a) const
|
A::B::inner::foo (int a_param) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
A::outer::hibob (int a_param) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
A::B::inner::hibob (int a_param) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,21 @@
|
||||||
#include "ovsrch.h"
|
#include "ovsrch.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
A::outer::foo (char *a) const
|
A::outer::foo (char *a_param) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
A::B::inner::foo (char *a) const
|
A::B::inner::foo (char *a_param) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
A::outer::hibob (char *a_param) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
A::B::inner::hibob (char *a_param) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ gdb_test_no_output {set variable $brk = $bpnum}
|
||||||
# runto or runto_main would call delete_breakpoints.
|
# runto or runto_main would call delete_breakpoints.
|
||||||
gdb_breakpoint "main"
|
gdb_breakpoint "main"
|
||||||
gdb_run_cmd
|
gdb_run_cmd
|
||||||
setup_kfail breakpoints/11657 *-*-*
|
|
||||||
gdb_test "" ".*" "start"
|
gdb_test "" ".*" "start"
|
||||||
|
|
||||||
set test "breakpoint resolved"
|
set test "breakpoint resolved"
|
||||||
|
|
|
@ -109,12 +109,7 @@ proc test_template_breakpoints {} {
|
||||||
global hp_aCC_compiler
|
global hp_aCC_compiler
|
||||||
|
|
||||||
gdb_test_multiple "break T5<int>::T5" "constructor breakpoint" {
|
gdb_test_multiple "break T5<int>::T5" "constructor breakpoint" {
|
||||||
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2. T5<int>::T5\\(int\\) at .*\[\r\n\]*.3. T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\) at .*\[\r\n\]*> $" {
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*templates.cc:T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\)\[\r\n\]*.3.*templates.cc:T5<int>::T5\\(int\\)\[\r\n\]*> $" {
|
||||||
gdb_test "0" \
|
|
||||||
"canceled" \
|
|
||||||
"constructor breakpoint (obsolete format!)"
|
|
||||||
}
|
|
||||||
-re ".0. cancel\[\r\n\]*.1. all\[\r\n\]*.2. T5<int>::T5\\((T5<int> const|const T5<int>) ?&\\) at .*templates.cc:.*\[\r\n\]*.3. T5<int>::T5\\(int\\) at .*templates.cc:.*\[\r\n\]*> $" {
|
|
||||||
gdb_test "0" \
|
gdb_test "0" \
|
||||||
"canceled" \
|
"canceled" \
|
||||||
"constructor breakpoint"
|
"constructor breakpoint"
|
||||||
|
@ -152,9 +147,26 @@ proc test_template_breakpoints {} {
|
||||||
|
|
||||||
set bp_location [gdb_get_line_number \
|
set bp_location [gdb_get_line_number \
|
||||||
"set breakpoint on a line with no real code"]
|
"set breakpoint on a line with no real code"]
|
||||||
gdb_test "break ${testfile}.cc:${bp_location}" \
|
|
||||||
"Breakpoint.*at.* file .*${testfile}.cc, line.*(2 locations).*" \
|
gdb_test_multiple "break ${testfile}.cc:${bp_location}" \
|
||||||
"breakpoint on a line with no real code"
|
"breakpoint on a line with no real code" {
|
||||||
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*templates.cc:GetMax<int>\\(int, int\\)\[\r\n\]*.3.*templates.cc:GetMax<long>\\(long, long\\)\[\r\n\]*> $" {
|
||||||
|
gdb_test "0" \
|
||||||
|
"canceled" \
|
||||||
|
"breakpoint on a line with no real code"
|
||||||
|
}
|
||||||
|
-re "0. cancel.*\[\r\n\]*.1. all.*\[\r\n\]*.2.*\[\r\n\]*.3.*\[\r\n\]*> $" {
|
||||||
|
gdb_test "0" \
|
||||||
|
"nonsense intended to insure that this test fails" \
|
||||||
|
"breakpoint on a line with no real code"
|
||||||
|
}
|
||||||
|
-re ".*\n> $" {
|
||||||
|
gdb_test "0" \
|
||||||
|
"nonsense intended to insure that this test fails" \
|
||||||
|
"breakpoint on a line with no real code"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete_breakpoints
|
delete_breakpoints
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
gdb/testsuite/gdb.linespec/Makefile.in
Normal file
14
gdb/testsuite/gdb.linespec/Makefile.in
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
|
||||||
|
EXECUTABLES = lspec
|
||||||
|
|
||||||
|
all info install-info dvi install uninstall installcheck check:
|
||||||
|
@echo "Nothing to be done for $@..."
|
||||||
|
|
||||||
|
clean mostlyclean:
|
||||||
|
-rm -f *~ *.o *.ci
|
||||||
|
-rm -f core $(EXECUTABLES)
|
||||||
|
|
||||||
|
distclean maintainer-clean realclean: clean
|
||||||
|
-rm -f Makefile config.status config.log gdb.log gdb.sum
|
20
gdb/testsuite/gdb.linespec/base/one/thefile.cc
Normal file
20
gdb/testsuite/gdb.linespec/base/one/thefile.cc
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* The commented line must have the same line number in the other
|
||||||
|
"thefile.c". */
|
||||||
|
|
||||||
|
#define WANT_F1
|
||||||
|
#include "../../lspec.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int m(int x)
|
||||||
|
{
|
||||||
|
return x + 23; /* thefile breakpoint */
|
||||||
|
}
|
||||||
|
|
||||||
|
int NameSpace::overload(int x)
|
||||||
|
{
|
||||||
|
return x + 23;
|
||||||
|
}
|
20
gdb/testsuite/gdb.linespec/base/two/thefile.cc
Normal file
20
gdb/testsuite/gdb.linespec/base/two/thefile.cc
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/* The commented line must have the same line number in the other
|
||||||
|
"thefile.c". */
|
||||||
|
|
||||||
|
#define WANT_F2
|
||||||
|
#include "../../lspec.h"
|
||||||
|
|
||||||
|
static int dupname(int y)
|
||||||
|
{
|
||||||
|
label: return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int n(int y)
|
||||||
|
{
|
||||||
|
return dupname(y) - 23; /* thefile breakpoint */
|
||||||
|
}
|
||||||
|
|
||||||
|
int NameSpace::overload(double x)
|
||||||
|
{
|
||||||
|
return (int) x - 23;
|
||||||
|
}
|
5
gdb/testsuite/gdb.linespec/body.h
Normal file
5
gdb/testsuite/gdb.linespec/body.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
/* This is included directly into the body of a function. */
|
||||||
|
|
||||||
|
/* body breakpoint no code */
|
||||||
|
|
||||||
|
return x;
|
117
gdb/testsuite/gdb.linespec/linespec.exp
Normal file
117
gdb/testsuite/gdb.linespec/linespec.exp
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
# Copyright 2011 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# Tests of ambiguous linespecs.
|
||||||
|
|
||||||
|
set testfile linespec
|
||||||
|
|
||||||
|
set exefile lspec
|
||||||
|
set binfile ${objdir}/${subdir}/${exefile}
|
||||||
|
|
||||||
|
set baseone base/one/thefile.cc
|
||||||
|
set basetwo base/two/thefile.cc
|
||||||
|
|
||||||
|
if {[skip_cplus_tests]} {
|
||||||
|
unsupported linespec.exp
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[prepare_for_testing ${testfile}.exp $exefile \
|
||||||
|
[list lspec.cc $baseone $basetwo] \
|
||||||
|
{debug nowarnings}]} {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test_no_output "set multiple-symbols all" \
|
||||||
|
"set multiple-symbols to all for linespec tests"
|
||||||
|
|
||||||
|
set l1 [gdb_get_line_number "thefile breakpoint" $baseone]
|
||||||
|
set l2 [gdb_get_line_number "thefile breakpoint" $basetwo]
|
||||||
|
|
||||||
|
if {$l1 != $l2} {
|
||||||
|
error "somebody incompatibly modified the source files needed by linespec.exp"
|
||||||
|
}
|
||||||
|
|
||||||
|
gdb_test "break thefile.cc:$l1" \
|
||||||
|
"Breakpoint 1 at $hex: thefile.cc:$l1. \[(\]2 locations\[)\]" \
|
||||||
|
"multi-location break using file:line"
|
||||||
|
|
||||||
|
# We'd like this to work, but it currently does not.
|
||||||
|
# gdb_test "break one/thefile.cc:$l1"
|
||||||
|
|
||||||
|
gdb_test "break dupname" \
|
||||||
|
"Breakpoint 2 at $hex: dupname. \[(\]2 locations\[)\]" \
|
||||||
|
"multi-location break using duplicate function name"
|
||||||
|
|
||||||
|
gdb_test "break dupname:label" \
|
||||||
|
"Breakpoint 3 at $hex: dupname:label. \[(\]2 locations\[)\]" \
|
||||||
|
"multi-location break using duplicate function name and label"
|
||||||
|
|
||||||
|
gdb_test_no_output "set breakpoint pending off" \
|
||||||
|
"disable pending breakpoints for linespec tests"
|
||||||
|
|
||||||
|
# This is PR breakpoints/12856.
|
||||||
|
gdb_test "break lspec.cc:nosuchfunction" \
|
||||||
|
"Function \"nosuchfunction\" not defined in \"lspec.cc\"." \
|
||||||
|
"set breakpoint on non-existent function"
|
||||||
|
|
||||||
|
gdb_test "break NameSpace::overload" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: NameSpace::overload. \[(\]3 locations\[)\]" \
|
||||||
|
"set breakpoint at all instances of NameSpace::overload"
|
||||||
|
|
||||||
|
gdb_test "break lspec.cc:NameSpace::overload" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: file .*lspec.cc, line 7." \
|
||||||
|
"set breakpoint at lspec.cc instance of NameSpace::overload"
|
||||||
|
|
||||||
|
gdb_test "break lspec.cc:NameSpace::overload(double)" \
|
||||||
|
"Function \"NameSpace::overload\\(double\\)\" not defined in \"lspec.cc\"." \
|
||||||
|
"set breakpoint at non-existent lspec.cc instance of NameSpace::overload"
|
||||||
|
|
||||||
|
gdb_test "break NameSpace::overload()" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: file .*lspec.cc, line 7." \
|
||||||
|
"set breakpoint at specific instance of NameSpace::overload"
|
||||||
|
|
||||||
|
# This should manage to set a breakpoint even though body.h does not
|
||||||
|
# include all of the function in question.
|
||||||
|
set line [gdb_get_line_number "body breakpoint no code" body.h]
|
||||||
|
gdb_test "break body.h:$line" \
|
||||||
|
"Breakpoint \[0-9\]+.*" \
|
||||||
|
"set breakpoint in body.h"
|
||||||
|
|
||||||
|
# This should only have a single location -- in f1.
|
||||||
|
set line [gdb_get_line_number "f1 breakpoint" lspec.h]
|
||||||
|
gdb_test "break lspec.h:$line" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: file .*lspec.h, line $line." \
|
||||||
|
"set breakpoint in f1"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multi-inferior tests.
|
||||||
|
#
|
||||||
|
|
||||||
|
gdb_test "add-inferior" "Added inferior 2" \
|
||||||
|
"add inferior for linespec tests"
|
||||||
|
|
||||||
|
gdb_test "inferior 2" "Switching to inferior 2 .*" \
|
||||||
|
"switch to inferior 2 for linespec tests"
|
||||||
|
|
||||||
|
# Note that in particular this should not cause errors when re-setting
|
||||||
|
# breakpoints.
|
||||||
|
gdb_test "file $binfile" \
|
||||||
|
"Reading symbols from .*done." \
|
||||||
|
"set the new inferior file for linespec tests"
|
||||||
|
|
||||||
|
gdb_test "break main" \
|
||||||
|
"Breakpoint \[0-9\]+ at $hex: main. .2 locations." \
|
||||||
|
"set breakpoint at main in both inferiors"
|
19
gdb/testsuite/gdb.linespec/lspec.cc
Normal file
19
gdb/testsuite/gdb.linespec/lspec.cc
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include "lspec.h"
|
||||||
|
|
||||||
|
static int dupname (int x) { label: return x; }
|
||||||
|
|
||||||
|
int NameSpace::overload()
|
||||||
|
{
|
||||||
|
return 23;
|
||||||
|
}
|
||||||
|
|
||||||
|
int body_elsewhere()
|
||||||
|
{
|
||||||
|
int x = 5;
|
||||||
|
#include "body.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return dupname(0) + m(0) + n(0) + f1() + f2() + body_elsewhere();
|
||||||
|
}
|
26
gdb/testsuite/gdb.linespec/lspec.h
Normal file
26
gdb/testsuite/gdb.linespec/lspec.h
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
extern int m(int x);
|
||||||
|
extern int n(int y);
|
||||||
|
|
||||||
|
namespace NameSpace {
|
||||||
|
int overload ();
|
||||||
|
int overload (int);
|
||||||
|
int overload (double);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef WANT_F1
|
||||||
|
int f1(void)
|
||||||
|
{
|
||||||
|
return 1; /* f1 breakpoint */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern int f1(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WANT_F2
|
||||||
|
int f2(void)
|
||||||
|
{
|
||||||
|
return 1; /* f2 breakpoint */
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
extern int f2(void);
|
||||||
|
#endif
|
|
@ -52,17 +52,19 @@ proc do_objc_tests {} {
|
||||||
|
|
||||||
do_objc_tests
|
do_objc_tests
|
||||||
|
|
||||||
|
gdb_test_no_output "set multiple-symbols ask"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Break on multiply defined method (PR objc/1236)
|
# Break on multiply defined method (PR objc/1236)
|
||||||
#
|
#
|
||||||
set name "break on multiply defined method"
|
set name "break on multiply defined method"
|
||||||
gdb_test_multiple "break multipleDef" $name \
|
gdb_test_multiple "break multipleDef" $name \
|
||||||
{
|
{
|
||||||
-re "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] -.Decode multipleDef. at .*\r\n\\\[3\\\] multipleDef at .*\r\n> $" {
|
-re "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] .*${srcfile}:-.Decode multipleDef.\r\n\\\[3\\\] .*${srcfile}:multipleDef\r\n> $" {
|
||||||
send_gdb "3\n"
|
send_gdb "3\n"
|
||||||
exp_continue
|
exp_continue
|
||||||
}
|
}
|
||||||
-re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: file .*\r\n$gdb_prompt $" { pass $name }
|
-re "Breakpoint \[0-9\]+ at 0x\[0-9a-f\]+: .*\r\n$gdb_prompt $" { pass $name }
|
||||||
-re ".*$gdb_prompt $" { kfail "gdb/1236" $name }
|
-re ".*$gdb_prompt $" { kfail "gdb/1236" $name }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ gdb_test "info trace" "in gdb_recursion_test.*$srcfile:$testline2" \
|
||||||
|
|
||||||
# 1.2 trace invalid source line
|
# 1.2 trace invalid source line
|
||||||
gdb_delete_tracepoints
|
gdb_delete_tracepoints
|
||||||
|
gdb_test_no_output "set breakpoint pending off"
|
||||||
gdb_test "trace $srcfile:99999" "No line 99999 in file \".*$srcfile\"." \
|
gdb_test "trace $srcfile:99999" "No line 99999 in file \".*$srcfile\"." \
|
||||||
"1.2a: trace invalid line in sourcefile"
|
"1.2a: trace invalid line in sourcefile"
|
||||||
gdb_test "info trace" "No tracepoints.*" \
|
gdb_test "info trace" "No tracepoints.*" \
|
||||||
|
@ -81,7 +82,6 @@ gdb_test "info trace" "No tracepoints.*" \
|
||||||
|
|
||||||
# 1.3 trace line in invalid source file
|
# 1.3 trace line in invalid source file
|
||||||
gdb_delete_tracepoints
|
gdb_delete_tracepoints
|
||||||
gdb_test_no_output "set breakpoint pending off"
|
|
||||||
gdb_test "trace NoSuChFiLe.c:1" "No source file named NoSuChFiLe.c." \
|
gdb_test "trace NoSuChFiLe.c:1" "No source file named NoSuChFiLe.c." \
|
||||||
"1.3a: trace invalid source file"
|
"1.3a: trace invalid source file"
|
||||||
gdb_test "info trace" "No tracepoints.*" \
|
gdb_test "info trace" "No tracepoints.*" \
|
||||||
|
|
|
@ -2456,7 +2456,7 @@ trace_find_line_command (char *args, int from_tty)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sals = decode_line_spec (args, 1);
|
sals = decode_line_spec (args, DECODE_LINE_FUNFIRSTLINE);
|
||||||
sal = sals.sals[0];
|
sal = sals.sals[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2584,7 +2584,7 @@ scope_info (char *args, int from_tty)
|
||||||
error (_("requires an argument (function, "
|
error (_("requires an argument (function, "
|
||||||
"line or *addr) to define a scope"));
|
"line or *addr) to define a scope"));
|
||||||
|
|
||||||
sals = decode_line_1 (&args, 1, NULL, 0, NULL);
|
sals = decode_line_1 (&args, DECODE_LINE_FUNFIRSTLINE, NULL, 0);
|
||||||
if (sals.nelts == 0)
|
if (sals.nelts == 0)
|
||||||
return; /* Presumably decode_line_1 has already warned. */
|
return; /* Presumably decode_line_1 has already warned. */
|
||||||
|
|
||||||
|
|
|
@ -455,29 +455,34 @@ tui_update_breakpoint_info (struct tui_win_info *win,
|
||||||
bp != (struct breakpoint *) NULL;
|
bp != (struct breakpoint *) NULL;
|
||||||
bp = bp->next)
|
bp = bp->next)
|
||||||
{
|
{
|
||||||
|
struct bp_location *loc;
|
||||||
|
|
||||||
gdb_assert (line->line_or_addr.loa == LOA_LINE
|
gdb_assert (line->line_or_addr.loa == LOA_LINE
|
||||||
|| line->line_or_addr.loa == LOA_ADDRESS);
|
|| line->line_or_addr.loa == LOA_ADDRESS);
|
||||||
if ((win == TUI_SRC_WIN
|
|
||||||
&& bp->source_file
|
for (loc = bp->loc; loc != NULL; loc = loc->next)
|
||||||
&& (filename_cmp (src->filename, bp->source_file) == 0)
|
{
|
||||||
&& line->line_or_addr.loa == LOA_LINE
|
if ((win == TUI_SRC_WIN
|
||||||
&& bp->line_number == line->line_or_addr.u.line_no)
|
&& loc->source_file
|
||||||
|| (win == TUI_DISASM_WIN
|
&& (filename_cmp (src->filename, loc->source_file) == 0)
|
||||||
&& line->line_or_addr.loa == LOA_ADDRESS
|
&& line->line_or_addr.loa == LOA_LINE
|
||||||
&& bp->loc != NULL
|
&& loc->line_number == line->line_or_addr.u.line_no)
|
||||||
&& bp->loc->address == line->line_or_addr.u.addr))
|
|| (win == TUI_DISASM_WIN
|
||||||
{
|
&& line->line_or_addr.loa == LOA_ADDRESS
|
||||||
if (bp->enable_state == bp_disabled)
|
&& loc->address == line->line_or_addr.u.addr))
|
||||||
mode |= TUI_BP_DISABLED;
|
{
|
||||||
else
|
if (bp->enable_state == bp_disabled)
|
||||||
mode |= TUI_BP_ENABLED;
|
mode |= TUI_BP_DISABLED;
|
||||||
if (bp->hit_count)
|
else
|
||||||
mode |= TUI_BP_HIT;
|
mode |= TUI_BP_ENABLED;
|
||||||
if (bp->loc->cond)
|
if (bp->hit_count)
|
||||||
mode |= TUI_BP_CONDITIONAL;
|
mode |= TUI_BP_HIT;
|
||||||
if (bp->type == bp_hardware_breakpoint)
|
if (bp->loc->cond)
|
||||||
mode |= TUI_BP_HARDWARE;
|
mode |= TUI_BP_CONDITIONAL;
|
||||||
}
|
if (bp->type == bp_hardware_breakpoint)
|
||||||
|
mode |= TUI_BP_HARDWARE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (line->has_break != mode)
|
if (line->has_break != mode)
|
||||||
{
|
{
|
||||||
|
|
11
gdb/utils.c
11
gdb/utils.c
|
@ -3651,6 +3651,17 @@ compare_positive_ints (const void *ap, const void *bp)
|
||||||
return * (int *) ap - * (int *) bp;
|
return * (int *) ap - * (int *) bp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* String compare function for qsort. */
|
||||||
|
|
||||||
|
int
|
||||||
|
compare_strings (const void *arg1, const void *arg2)
|
||||||
|
{
|
||||||
|
const char **s1 = (const char **) arg1;
|
||||||
|
const char **s2 = (const char **) arg2;
|
||||||
|
|
||||||
|
return strcmp (*s1, *s2);
|
||||||
|
}
|
||||||
|
|
||||||
#define AMBIGUOUS_MESS1 ".\nMatching formats:"
|
#define AMBIGUOUS_MESS1 ".\nMatching formats:"
|
||||||
#define AMBIGUOUS_MESS2 \
|
#define AMBIGUOUS_MESS2 \
|
||||||
".\nUse \"set gnutarget format-name\" to specify the format."
|
".\nUse \"set gnutarget format-name\" to specify the format."
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue