Bug 16874 - Setting a breakpoint on function in anonymous namespace is unnecessarily awkward
Summary: Setting a breakpoint on function in anonymous namespace is unnecessarily awkward
Status: ASSIGNED
Alias: None
Product: gdb
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.7
: P2 critical
Target Milestone: ---
Assignee: patrick
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-04-25 08:06 UTC by Richard Biener
Modified: 2017-11-29 20:29 UTC (History)
7 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments
Candidate patch (1.33 KB, patch)
2014-11-26 04:32 UTC, patrick
Details | Diff
updated patch (1.27 KB, patch)
2015-08-13 06:54 UTC, Markus Trippelsdorf
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2014-04-25 08:06:33 UTC
namespace { int foo (void) { return 0; } } int main() { return foo (); }

> gdb ./a.out
GNU gdb (GDB; devel:gcc) 7.7
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...

warning: /etc/gdbinit.d/gdb-heap.py: No such file or directory
Reading symbols from ./a.out...done.
(gdb) b foo
Function "foo" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) start
Temporary breakpoint 1 at 0x4005ec: file t.C, line 1.
Starting program: /tmp/a.out 

Temporary breakpoint 1, main () at t.C:1
1       namespace { int foo (void) { return 0; } } int main() { return foo (); }
(gdb) b foo
Function "foo" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n


so it doesn't work, not from toplevel context before starting the program
nor from a context within the TU that contains the anonymous namespace.

Breaks debugging of GCC big times - try to break on cfgexpand.c:pass_expand::execute - we want to be able to do that from a
context that is not necessarily local to that TU.
Comment 1 Richard Biener 2014-04-25 09:06:20 UTC
Err.

(gdb) b '(anonymous namespace)::foo'
Breakpoint 1 at 0x4005e1: file t.C, line 1.

this can't be really the desired way to do this ...

There is a DW_TAG_imported_module of the anon namespace in the TU context
so at least there referencing 'foo' needs to work.
Comment 2 Richard Biener 2014-04-25 09:10:48 UTC
And funnily

(gdb) b '(anonymous namespace)::pass_expand::<tab>

auto-"completes" to '(anonymous namespace)::

how useful.  All auto-completion seems to strip everything up to the
first ::.  Bah.
Comment 3 Dave Malcolm 2014-07-29 21:04:37 UTC
FWIW I've written a custom breakpoint-setting command using gdb's Python interface to try to workaround this from the gcc side:
https://gcc.gnu.org/ml/gcc-patches/2014-07/msg02011.html
Comment 4 Dave Malcolm 2014-08-06 14:12:32 UTC
Renaming.  It *is* possible to set a breakpoint on a function in an anonymous namespace, it's just way too tricky to do it right now, given that
(A) you have to type the full qualified name, and
(B) tab-completion is broken

and these make it sufficiently difficult that it's effectively not possible for a non-expert user.

So please can (A) and (B) be fixed.
Comment 5 patrick 2014-09-19 14:55:39 UTC
You can do

gdb> break *foo

or if foo is inside an anonymous namespace of another TU, you can do

gdb> break *'foo.c'::foo

Is this functionality sufficient for your use case?
Comment 6 Markus Trippelsdorf 2014-09-19 15:22:47 UTC
(In reply to patrick from comment #5)
> You can do
> 
> gdb> break *foo
No symbol "foo" in current context.

markus@x4 ~ % gdb -v
GNU gdb (GDB) 7.8.50.20140729-cvs
Comment 7 patrick 2014-09-19 15:26:47 UTC
(In reply to Markus Trippelsdorf from comment #6)
> (In reply to patrick from comment #5)
> > You can do
> > 
> > gdb> break *foo
> No symbol "foo" in current context.
> 
> markus@x4 ~ % gdb -v
> GNU gdb (GDB) 7.8.50.20140729-cvs

The program has to be running for "break *" to work, it seems.

Try:

gdb> break main
gdb> run
gdb> break *foo
Comment 8 Richard Biener 2014-09-22 07:51:11 UTC
The workaround works to some extent, but tab-completion is still broken
and for

t1.C
-----
namespace { int foo (void) { return 0; } }
int bar(void);
int main() { return foo () + bar (); }

t2.C
-----
namespace { int foo2 (void) { return 1; } }
int bar () { return foo2 (); }

it doesn't allow me to set a breakpoint on t2.C::foo2 until I enter bar().
That is, using 'b *<name>' seems to do symbol lookup from the current
scope only.

For the GCC case the workaround doesn't work in practice for this reason.

b '(anonymous namespace)::foo2'

works from any context (but is quite awkward due to tab-completion being broken).
Comment 9 patrick 2014-11-26 04:32:52 UTC
Created attachment 7974 [details]
Candidate patch

Here is a candidate patch that fixes this issue by allowing the user to omit the "(anonymous namespace)::" prefix when referencing symbols that are defined inside an anonymous namespace.  Tab completion is fixed accordingly, e.g. by allowing one to tab-complete "pass_exp" into "pass_expand" even though pass_expand is actually (anonymous namespace)::pass_expand.  This should work in breakpoint and expression context.

So the patch enables you to do

(gdb) break pass_exp<TAB>::execu<TAB>

to break on (anonymous namespace)::pass_expand::execute.
Comment 10 Markus Trippelsdorf 2015-08-13 06:54:23 UTC
Created attachment 8515 [details]
updated patch

I've updated Patrick's patch for gdb trunk.

It works fine:
Example from comment0:

 % gdb ./a.out
Reading symbols from ./a.out...done.
(gdb) b fo<tab> 
Breakpoint 1 at 0x40058a: file anon_namesp.cpp, line 1.
(gdb) run
Starting program: /home/markus/a.out 
Breakpoint 1, (anonymous namespace)::foo () at anon_namesp.cpp:1

Example from comment8:

Reading symbols from ./a.out...done.
(gdb) b fo<tab><tab>
foo()   foo2()  
(gdb) b foo2() 
Breakpoint 1 at 0x4005b3: file t2.cpp, line 1.
(gdb) run
Starting program: /home/markus/a.out 
Breakpoint 1, (anonymous namespace)::foo2 () at t2.cpp:1
1       namespace { int foo2 (void) { return 1; } }

Any chance to move this issue forward?
Comment 11 patrick 2015-08-26 01:19:04 UTC
I will try to.
Comment 12 Andrew Pinski 2016-12-13 02:49:51 UTC
I just ran into this today too while trying debug a new pass I was writing for GCC which uses anonymous namespaces :).
Comment 13 Martin Jambor 2017-06-20 16:45:33 UTC
...and so did I.
Comment 14 Pedro Alves 2017-06-21 08:46:42 UTC
This series will help with this:

 [PATCH 00/40] C++ debugging improvements: breakpoints, TAB completion, more
 https://sourceware.org/ml/gdb-patches/2017-06/msg00012.html

You can find it in the users/palves/cxx-breakpoint-improvements branch meanwhile, if you want to give it a try.
Comment 15 Pedro Alves 2017-11-29 20:04:41 UTC
The series above is finally all merged to master.  These are the related improvements that you'll find there:

* Completion improvements

  ** GDB can now complete function parameters in linespecs and
     explicit locations without quoting.  When setting breakpoints,
     quoting around functions names to help with TAB-completion is
     generally no longer necessary.  For example, this now completes
     correctly:

      (gdb) b function(in[TAB]
      (gdb) b function(int)

     Related, GDB is no longer confused with completing functions in
     C++ anonymous namespaces:

      (gdb) b (anon[TAB]
      (gdb) b (anonymous namespace)::[TAB][TAB]
      (anonymous namespace)::a_function()
      (anonymous namespace)::b_function()

  ** GDB now has much improved linespec and explicit locations TAB
     completion support, that better understands what you're
     completing and offers better suggestions.  For example, GDB no
     longer offers data symbols as possible completions when you're
     setting a breakpoint.

  ** GDB now TAB-completes label symbol names.

  ** The "complete" command now mimics TAB completion accurately.

* Breakpoints on C++ functions are now set on all scopes by default

  By default, breakpoints on functions/methods are now interpreted as
  specifying all functions with the given name ignoring missing
  leading scopes (namespaces and classes).

  For example, assuming a C++ program with symbols named:

    A::B::func()
    B::func()

  both commands "break func()" and "break B::func()" set a breakpoint
  on both symbols.

  You can use the new flag "-qualified" to override this.  This makes
  GDB interpret the specified function name as a complete
  fully-qualified name instead.  For example, using the same C++
  program, the "break -q B::func" command sets a breakpoint on
  "B::func", only.

* Breakpoints on functions marked with C++ ABI tags

  GDB can now set breakpoints on functions marked with C++ ABI tags
  (e.g., [abi:cxx11]).  See here for a description of ABI tags:
  https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/

  Functions with a C++11 abi tag are demangled/displayed like this:

    function[abi:cxx11](int)
            ^^^^^^^^^^^

  You can now set a breakpoint on such functions simply as if they had
  no tag, like:

    (gdb) b function(int)

  Or if you need to disambiguate between tags, like:

    (gdb) b function[abi:other_tag](int)

  Tab completion was adjusted accordingly as well.
Comment 16 Dave Malcolm 2017-11-29 20:19:50 UTC
(In reply to Pedro Alves from comment #15)
> The series above is finally all merged to master.  These are the related
> improvements that you'll find there:

[...]

Thanks for the improvements!

> * Breakpoints on C++ functions are now set on all scopes by default
> 
>   By default, breakpoints on functions/methods are now interpreted as
>   specifying all functions with the given name ignoring missing
>   leading scopes (namespaces and classes).
> 
>   For example, assuming a C++ program with symbols named:
> 
>     A::B::func()
>     B::func()
> 
>   both commands "break func()" and "break B::func()" set a breakpoint
>   on both symbols.

To clarify, if there is a symbol:

      (anonymous namespace)::func()

will "break func" set a breakpoint on it?  (without me having to type or tab-complete the "(anonymous namespace)" part?)

[...]
Comment 17 Pedro Alves 2017-11-29 20:29:44 UTC
(In reply to Dave Malcolm from comment #16)
> (In reply to Pedro Alves from comment #15)
> > The series above is finally all merged to master.  These are the related
> > improvements that you'll find there:
> 
> [...]
> 
> Thanks for the improvements!

My pleasure!  Making things better for GCC folks was one of my
sekrit driving forces.  :-)

> To clarify, if there is a symbol:
> 
>       (anonymous namespace)::func()
> 
> will "break func" set a breakpoint on it?  (without me having to type or
> tab-complete the "(anonymous namespace)" part?)
> 
> [...]

Yes.