From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 129462 invoked by alias); 2 Jun 2017 12:22:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 129332 invoked by uid 89); 2 Jun 2017 12:22:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-13.8 required=5.0 tests=BAYES_00,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,KAM_STOCKGEN,LIKELY_SPAM_BODY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=LCD, lcd, FULL, concluded X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 02 Jun 2017 12:22:37 +0000 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2098147CB for ; Fri, 2 Jun 2017 12:22:40 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 2098147CB Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx06.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=palves@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 2098147CB Received: from cascais.lan (ovpn04.gateway.prod.ext.ams2.redhat.com [10.39.146.4]) by smtp.corp.redhat.com (Postfix) with ESMTP id 62FFD5C550 for ; Fri, 2 Jun 2017 12:22:39 +0000 (UTC) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more Date: Fri, 02 Jun 2017 12:22:00 -0000 Message-Id: <1496406158-12663-1-git-send-email-palves@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-SW-Source: 2017-06/txt/msg00012.txt.bz2 This series a long story behind it. In sum, it: - teaches GDB to set breakpoints on all namespaces/scopes by default. - it adds a new option "break -qualified" to override the behavior. - adds a proper/smart linespec completer - gets rid of the need for quoting function names in tab completion and much more, but that's the gist of it. Most of the tests are close to the end of the series instead of being added incrementally, because the way they're written, they only really work when everything is blending nicely together. Documentation changes are in the last patch. A few months back I was looking at making GDB use gnulib's C++ namespace mode, because the default mode has gnulib define its replacements using macros, like "#define open rpl_open". In C++ that's a bad idea, given that using names like "open", "close", etc. in classes and namespaces is the natural thing to do. E.g., "struct target_ops::to_open" could be "class target::open". After experimentation, I concluded that the best would be to wrap all of GDB in: namespace gdb { } and so I tried it: https://github.com/palves/gdb/commits/palves/cxx-gdb-namespace however, when I actually got it working and started debugging that GDB, I immediately got frustrated with GDB's C++ support. I.e., the dog food didn't taste so good. The problem was that now you'd always need to prefix every function name with "gdb::". I.e., "b gdb::internal_error", etc., etc. And it gets annoying pretty fast. I thought that GDB should be able to do better. I thought that maybe GDB could infer the namespace from local context, so you'd still be able to do "b foo", and that would find "gdb::foo". However, that doesn't work well, because you want to be able to conveniently set breakpoints before starting a program, when there's no frame yet. And, running to main doesn't help, because main is not in any namespace. Also, the direction linespecs / setting breakpoints is aiming, is in not relying in local context at all. Instead, match the most possible, and let users filter it down if they want. I.e., e.g., "b foo" sets locations in all "foo" functions in the program in all compilation units, no matter whether they're both extern or static function, no matter where you're currently stopped in the program. Likewise "b source.c:foo" looks at all source files named "source.c", not just the current source if it happens to have that name. You can set set a breakpoint on a C++ symbol named "some_klass::method()", even if the current frame's language is C, not C++. Etc., etc. The idea then occurred to me. How about we make GDB ignore leading namespaces when setting breakpoints? I.e., just like "b foo" sets a breakpoint on all "foo"s in the program, and you can zoom in on specific "foo" functions by specifying a source file to scope the symbol search, like "b source.c:foo", by default we'd make "b foo" set a breakpoint on all functions and methods named "foo" too, like "A::foo", "B::A::foo", "(anonymous namespace)::foo", and of course global "foo". And then if you scope the name, like "A::foo", GDB would find both "A::foo", and "B::A::foo", but not the others. Etc., etc. E.g.,: (gdb) b function[TAB] A::function() B::A::function() function() (anonymous namespace)::function() (gdb) b function Breakpoint 1 at 0x4005ce: function. (4 locations) (gdb) b A::function[TAB] A::function() B::A::function() (gdb) b function Breakpoint 1 at 0x4005ce: function. (2 locations) That sounded quite promising to me. Turns out that that's what lldb does too, so I started experimenting with doing the same in GDB. Along the way, I realized that gdb's Ada support has always behaved like that... ada-lang.c calls it "wild matching" vs "full matching" (see full_match and wild_match). So it's not really a new idea for GDB. The problem is that Ada does that on its own little ada-lang.c corner, out of view.. :-P Actually, above I'm showing TAB completion. But there's more to that. Once it got it working for setting breakpoints, I realized that TAB completion would need to be adjusted too. TAB completion goes via different symbol search code paths... I required adjustment because while "b foo[RET]" would find all functions named "foo", "b foo[TAB]" would only show symbols that start with "foo"... Fixing that required virtually rewriting how GDB interacts with readline for completion. The main issue is that you want this to happen: (gdb) b func[TAB] # expands input line to ... (gdb) b function( # ... this (gdb) b function([TAB] # another tab now shows you the candidates A::B::function(int) A::C::function(long) Notice how the input line above was expanded to "function(", but, that's not actually the common leading prefix between all completion candidates! If we'd let readline compute what it calls the "lowest common denominator", then this is what you'd see: (gdb) b func[TAB] # expands input line to ... (gdb) b A:: # ... this... which is obviously bogus. Actually, notice how above I didn't quote "function(", like: (gdb) b 'function([TAB] ^ quote That's because while working on this series, I got even more annoyed with the fact that currently, you have overloads in your program, and you want to set a breakpoint in one of them: void function(int); // set breakpoint here. void function(long); (gdb) b func[TAB] (gdb) b function( # ok, gdb completed as much as possible. (gdb) b function([TAB] # show me the overloads, please. <_all_ symbols in the program are shown...> E.g., when debugging GDB, that'd be: (gdb) b function([TAB] (anonymous namespace)::get_global()::global pt_insn_get_offset@plt scm_new_port_table_entry asprintf pt_pkt_alloc_decoder scm_new_port_table_entry@plt asprintf@plt pt_pkt_alloc_decoder@plt scm_out_of_range bt_ctf_get_char_array pt_pkt_sync_forward scm_out_of_range@plt bt_ctf_get_char_array@plt pt_pkt_sync_forward@plt scm_putc bt_ctf_get_uint64 pwrite scm_putc@plt bt_ctf_get_uint64@plt pwrite@plt scm_reverse_x bt_ctf_iter_read_event PyErr_Restore scm_reverse_x@plt bt_ctf_iter_read_event@plt PyErr_Restore@plt scm_set_port_filename_x Now that's a load of completely useless completions. To get around that limitation, users need to quote the function name, like: (gdb) b 'function([TAB] function(int) function(long) (gdb) b 'function(i[TAB] (gdb) b 'function(int)' # now completes correctly! Note that the quoting is only necessary for completion. Creating the breakpoint does not require the quoting: (gdb) b function(int) [RET] Breakpoint 1 at .... This series eliminates the need for quoting, in both the explicit locations completer, and the linespec completer. Actually, the series adds a real linespec completer because we didn't have a real one. In the case above, we want the completer to figure out that it's completing a function name that starts with "function(i". It now does. On top of all that, the series fixes setting breakpoints on symbols with [abi:cxx11] tags, and more... Pedro Alves (40): Make gdb.base/dmsym.exp independent of "set language ada" Eliminate make_cleanup_obstack_free, introduce auto_obstack Fix gdb.base/completion.exp with --target_board=dwarf4-gdb-index Fix TAB-completion + .gdb_index slowness (generalize filename_seen_cache) command.h: Include scoped_restore_command.h Expression completer should not match explicit location options objfile_per_bfd_storage non-POD completion_list_add_name wrapper functions Rename make_symbol_completion_list_fn -> symbol_completer Clean up "completer_handle_brkchars" callback handling Introduce class completion_tracker & rewrite completion<->readline interaction "complete" command and completion word break characters Introduce strncmp_iw Introduce CP_OPERATOR_STR/CP_OPERATOR_LEN and use throughout Rewrite/enhance explicit locations completer, parse left->right Explicit locations -label completer Linespec lexing and C++ operators A smarter linespec completer Fix cp_find_first_component_aux bug Eliminate block_iter_name_* Use SYMBOL_MATCHES_SEARCH_NAME some more get_int_var_value Make language_def O(1) Per-language symbol name hashing algorithm Introduce lookup_name_info and generalize Ada's FULL/WILD name matching Optimize .gdb_index symbol name searching Make cp_remove_params return a unique_ptr lookup_name_info::make_ignore_params Simplify completion_list_add_name | remove sym_text / sym_text_len Use search_domain::FUNCTIONS_DOMAIN when setting breakpoints Handle custom completion match prefix / LCD Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching] Make the linespec/location completer ignore data symbols Make strcmp_iw NOT ignore whitespace in the middle of tokens Comprehensive C++ linespec/completer tests Add comprehensive C++ operator linespec/location/completion tests Fix completing an empty string Use TOLOWER in SYMBOL_HASH_NEXT Breakpoints in symbols with ABI tags (PR c++/19436) Document breakpoints / linespec & co improvements (manual + NEWS) gdb/doc/gdb.texinfo | 26 + gdb/NEWS | 36 + gdb/Makefile.in | 3 + gdb/ada-lang.c | 786 +++++------ gdb/ada-lang.h | 2 +- gdb/ada-lex.l | 22 +- gdb/ada-typeprint.c | 4 +- gdb/block.c | 107 +- gdb/block.h | 51 +- gdb/break-catch-syscall.c | 25 +- gdb/breakpoint.c | 23 +- gdb/buildsym.c | 25 +- gdb/buildsym.h | 4 +- gdb/c-exp.y | 20 +- gdb/c-lang.c | 46 +- gdb/c-typeprint.c | 2 +- gdb/cli/cli-cmds.c | 87 +- gdb/cli/cli-decode.c | 41 +- gdb/cli/cli-decode.h | 17 +- gdb/coffread.c | 4 +- gdb/command.h | 35 +- gdb/completer.c | 1786 +++++++++++++++++------- gdb/completer.h | 547 ++++++-- gdb/corefile.c | 5 +- gdb/cp-abi.c | 5 +- gdb/cp-support.c | 588 +++++++- gdb/cp-support.h | 18 +- gdb/d-exp.y | 11 +- gdb/d-lang.c | 9 +- gdb/dbxread.c | 12 +- gdb/defs.h | 3 +- gdb/dictionary.c | 111 +- gdb/dictionary.h | 36 +- gdb/disasm.c | 6 +- gdb/dwarf2loc.c | 7 +- gdb/dwarf2read.c | 919 ++++++++++-- gdb/f-lang.c | 22 +- gdb/filename-seen-cache.c | 73 + gdb/filename-seen-cache.h | 64 + gdb/gdb_obstack.h | 15 + gdb/gnu-v2-abi.c | 2 +- gdb/gnu-v3-abi.c | 2 +- gdb/go-exp.y | 9 +- gdb/go-lang.c | 9 +- gdb/guile/scm-cmd.c | 40 +- gdb/infrun.c | 13 +- gdb/interps.c | 8 +- gdb/interps.h | 7 +- gdb/jit.c | 6 +- gdb/language.c | 301 ++-- gdb/language.h | 90 +- gdb/linespec.c | 1074 ++++++++++++-- gdb/linespec.h | 29 + gdb/linux-tdep.c | 7 +- gdb/location.c | 326 ++++- gdb/location.h | 32 +- gdb/m2-lang.c | 9 +- gdb/mdebugread.c | 23 +- gdb/minsyms.c | 371 +++-- gdb/minsyms.h | 4 +- gdb/objc-lang.c | 8 +- gdb/objfiles.c | 15 +- gdb/objfiles.h | 39 +- gdb/opencl-lang.c | 8 +- gdb/p-lang.c | 16 +- gdb/printcmd.c | 12 +- gdb/psymtab.c | 129 +- gdb/python/py-cmd.c | 52 +- gdb/rust-exp.y | 15 +- gdb/rust-lang.c | 15 +- gdb/stabsread.h | 3 +- gdb/stack.c | 18 +- gdb/symfile-debug.c | 6 +- gdb/symfile.c | 4 +- gdb/symfile.h | 4 +- gdb/symmisc.c | 1 + gdb/symtab.c | 704 +++++----- gdb/symtab.h | 366 ++++- gdb/testsuite/gdb.ada/complete.exp | 10 + gdb/testsuite/gdb.base/complete-empty.exp | 46 + gdb/testsuite/gdb.base/completion.exp | 8 +- gdb/testsuite/gdb.base/default.exp | 2 +- gdb/testsuite/gdb.base/dmsym.c | 8 +- gdb/testsuite/gdb.base/dmsym.exp | 39 +- gdb/testsuite/gdb.base/dmsym_main.c | 10 +- gdb/testsuite/gdb.base/langs.exp | 2 +- gdb/testsuite/gdb.base/printcmds.exp | 6 + gdb/testsuite/gdb.cp/meth-typedefs.exp | 34 +- gdb/testsuite/gdb.cp/namespace.exp | 2 +- gdb/testsuite/gdb.linespec/base/one/thefile.cc | 5 + gdb/testsuite/gdb.linespec/base/two/thefile.cc | 5 + gdb/testsuite/gdb.linespec/cpcompletion.exp | 959 +++++++++++++ gdb/testsuite/gdb.linespec/cpls-abi-tag.cc | 93 ++ gdb/testsuite/gdb.linespec/cpls-abi-tag.exp | 312 +++++ gdb/testsuite/gdb.linespec/cpls-hyphen.cc | 14 + gdb/testsuite/gdb.linespec/cpls-ops.cc | 253 ++++ gdb/testsuite/gdb.linespec/cpls-ops.exp | 567 ++++++++ gdb/testsuite/gdb.linespec/cpls.cc | 386 +++++ gdb/testsuite/gdb.linespec/cpls2.cc | 46 + gdb/testsuite/gdb.linespec/explicit.exp | 209 ++- gdb/testsuite/gdb.linespec/linespec.exp | 93 +- gdb/testsuite/gdb.linespec/ls-errs.exp | 27 +- gdb/testsuite/lib/completion-support.exp | 513 +++++++ gdb/top.c | 2 +- gdb/tui/tui-layout.c | 5 +- gdb/tui/tui-regs.c | 11 +- gdb/tui/tui-win.c | 28 +- gdb/unittests/lookup_name_info-selftests.c | 110 ++ gdb/utils.c | 382 ++++- gdb/utils.h | 49 +- gdb/valprint.c | 17 +- gdb/value.c | 17 +- gdb/value.h | 3 +- gdb/xcoffread.c | 11 +- 114 files changed, 10826 insertions(+), 2838 deletions(-) create mode 100644 gdb/filename-seen-cache.c create mode 100644 gdb/filename-seen-cache.h create mode 100644 gdb/testsuite/gdb.base/complete-empty.exp create mode 100644 gdb/testsuite/gdb.linespec/cpcompletion.exp create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.cc create mode 100644 gdb/testsuite/gdb.linespec/cpls-abi-tag.exp create mode 100644 gdb/testsuite/gdb.linespec/cpls-hyphen.cc create mode 100644 gdb/testsuite/gdb.linespec/cpls-ops.cc create mode 100644 gdb/testsuite/gdb.linespec/cpls-ops.exp create mode 100644 gdb/testsuite/gdb.linespec/cpls.cc create mode 100644 gdb/testsuite/gdb.linespec/cpls2.cc create mode 100644 gdb/testsuite/lib/completion-support.exp create mode 100644 gdb/unittests/lookup_name_info-selftests.c -- 2.5.5