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
Alias: None
Product: gdb
Classification: Unclassified
Component: c++ (show other bugs)
Version: 7.7
: P2 critical
Target Milestone: ---
Assignee: patrick
Depends on:
Reported: 2014-04-25 08:06 UTC by Richard Biener
Modified: 2017-06-21 08:46 UTC (History)
6 users (show)

See Also:
Last reconfirmed:

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:
Find the GDB manual and other documentation resources online at:
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

(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:
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)
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)

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


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

namespace { int foo (void) { return 0; } }
int bar(void);
int main() { return foo () + bar (); }

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

You can find it in the users/palves/cxx-breakpoint-improvements branch meanwhile, if you want to give it a try.