From: "Martin Schröder" <gschroeder@onlinehome.de>
To: <gdb@sourceware.org>
Subject: Breakpoint troubles on typedefs
Date: Thu, 18 Nov 2010 19:47:00 -0000 [thread overview]
Message-ID: <C2489EECC5ED4C33ACE3F0164C8BEC5E@igor> (raw)
Hello everyone.
I seem to have found a bug / feature in GDB 7.2 for C++. The problem is that
typedefs are not converted to their base type when one tries to set a
breakpoint into a function that has a typedef'd type as parameter.
Here's a simple program that triggers this bug:
main.cpp
- - - - - - - - - - - - - - - - - - - - - - - - -
#include <string>
typedef std::string foo;
void calltest(foo val) {}
int main() {
calltest(foo(""));
}
- - - - - - - - - - - - - - - - - - - - - - - - -
Compiled with: "g++ -O0 -g main.cpp -o a.out"
Now, when you start the program with gdb 7.2, you'll get the following
whatis replies:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) whatis foo
type = std::string
(gdb) whatis calltest
type = void (foo)
- - - - - - - - - - - - - - - - - - - - - - - - -
But now, try to set a breakpoints. Once with "foo" and once with
"std::string"; which should be equal, as whatis has just told us.
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) break calltest(foo)
Breakpoint 1 at 0x80485e7: file main.cpp, line 5.
(gdb) break calltest(std::string)
Can't find member of namespace, class, struct, or union
named "calltest(std::string)"
Hint: try 'calltest(std::string)<TAB> or
'calltest(std::string)<ESC-?>
(Note leading single quote.)
Make breakpoint pending on future shared library load? (y or [n]) n
- - - - - - - - - - - - - - - - - - - - - - - - -
So, you might try to see the expansion. This is what GDB returns on Tab:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) break calltest<TAB>
[...]
calltest(foo)
calltest(std::basic_string<char, std::char_traits<char>,
std::allocator<char> >)
[...]
- - - - - - - - - - - - - - - - - - - - - - - - -
So, among the massiv amounts of text, we find both foo, and the full
"std::string" typedef-expansion. Okay, so we try to set the breakpoint
accordingly:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) whatis calltest(std::string)
type = void (foo)
(gdb) whatis calltest(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)
type = void (foo)
(gdb) break calltest(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)
Can't find member of namespace, class, struct, or union named
[...]
Make breakpoint pending on future shared library load? (y or [n]) n
- - - - - - - - - - - - - - - - - - - - - - - - -
So ... what this tells me is that "whatis" reads the symbol table correctly,
but break somehow doesn't.
But wait, it gets even better. Now quit GDB and restart it. This is what you
get when you issue the "break" as the very first command:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) break calltest(foo)
Function "calltest(foo)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) whatis foo
type = std::string
(gdb) break calltest(foo)
Breakpoint 1 at 0x80485e7: file main.cpp, line 5.
- - - - - - - - - - - - - - - - - - - - - - - - -
Interesting, isn't it? Do note that you can substitute the "whatis" with a
range of commands; for example "break main", or "list" and the second call
will still work. But not all commands, observe:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) break calltest(foo)
Function "calltest(foo)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) break calltest(foo)
Function "calltest(foo)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
- - - - - - - - - - - - - - - - - - - - - - - - -
Furthermore, starting with a fresh GDB will also change what the
tab-expansion shows. Instead of lots and lots of types, it shows only the
two "calltest" function entries; but it shows "std::string" instead of the
full typedef-expansion for std::string in the second entry.
Anyway, here's the platform and program versions I used for testing:
OS: Ubuntu 10.10
gdb: 7.2-ubuntu
g++: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
I've tested the same program with an older, self-compiled GDB 7.1, and there
I get this:
- - - - - - - - - - - - - - - - - - - - - - - - -
(gdb) break calltest(foo)
Function "calltest(foo)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) whatis foo
type = std::string
(gdb) break calltest(foo)
Function "calltest(foo)" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
(gdb) break calltest(std::string)
Breakpoint 1 at 0x8048627: file main.cpp, line 5.
- - - - - - - - - - - - - - - - - - - - - - - - -
Basically, I have no clue what could trigger this strange behaviour. It
almost seems to me as if GDB 7.2 added support for typedef'd variables, but
broke the "break" statement in a way that causes it to not read the
symbol-table correctly anymore, but I could be a mile off with that
suspicion.
Any help would be appreciated, thanks,
Martin Schröder.
next reply other threads:[~2010-11-18 19:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-18 19:47 Martin Schröder [this message]
2010-11-23 21:15 ` Tom Tromey
2010-11-24 0:25 ` Martin Schröder
2010-11-25 10:29 ` Martin Schröder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=C2489EECC5ED4C33ACE3F0164C8BEC5E@igor \
--to=gschroeder@onlinehome.de \
--cc=gdb@sourceware.org \
--cc=lionhead@onlinehome.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox