conditional breakpoints in gdb (c++)

D

digz

Hi,
I am having a lot of trouble setting conditional breakpoints in gdb,
here is a simple example...

#include<string>
#include<iostream>
using namespace std;

void func(string& s){
cout << s << endl;
}

int main()
{
string a[] ={ "A", "B", "C" };
for (int i=0; i < 3 ; i++)
func(a);
}
~
I am trying to break at the cout (line # 6)
in func(string&) only if s == "C", but gdb disregards it no matter
what i try to do, here it goes

(gdb) b 6 if s == "C" //does not work breaks for "A", "B", "C"
(gdb) b 6 if ( (s== "C") > 0) //breaks for all "A", "B", "C"

(gdb) b 6 if s.operator==("C") > 0
(gdb) b 6 if s.operator==(s,"C") > 0
Error in testing breakpoint condition:
There is no member or method named operator.

(gdb) b 6 if (strcmp(s.c_str() , "C") == 0 )
No symbol "strcmp" in current context.

The only way i can possibly think of is to add source lines and clean
them up later like
if ( s == "C" ) break;
and set a breakpoint at that line!!!
There has to be a better way to do this...what am i missing here..

Thx
Digz
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Hi,
I am having a lot of trouble setting conditional breakpoints in gdb,
here is a simple example...

#include<string>
#include<iostream>
using namespace std;

void func(string& s){
cout << s << endl;
}

int main()
{
string a[] ={ "A", "B", "C" };
for (int i=0; i < 3 ; i++)
func(a);
}
~
I am trying to break at the cout (line # 6)
in func(string&) only if s == "C", but gdb disregards it no matter
what i try to do, here it goes

(gdb) b 6 if s == "C" //does not work breaks for "A", "B", "C"
(gdb) b 6 if ( (s== "C") > 0) //breaks for all "A", "B", "C"

(gdb) b 6 if s.operator==("C") > 0
(gdb) b 6 if s.operator==(s,"C") > 0
Error in testing breakpoint condition:
There is no member or method named operator.

(gdb) b 6 if (strcmp(s.c_str() , "C") == 0 )
No symbol "strcmp" in current context.

The only way i can possibly think of is to add source lines and clean
them up later like
if ( s == "C" ) break;
and set a breakpoint at that line!!!
There has to be a better way to do this...what am i missing here..


This is off-topic here since it concerns 1) debugging, which is not
defined in the C++ standard and 2) a specific implementation, next time
try a group for your debugger, gnu.gdb comes to mind.

I've no personal experience with this kind of stuff under gdb, but in
VS2005 I notices a severe performance degradation when trying to set a
condition on a breakpoint, my guess is that the debugger braked on the
specific line each time it was executed, performed the check and if it
was false resumed execution. So I would insert a bit of code that
performed the check if I were you.
 
A

Adrian Hawryluk

digz said:
Hi,
I am having a lot of trouble setting conditional breakpoints in gdb,
here is a simple example...

#include<string>
#include<iostream>
using namespace std;

void func(string& s){
cout << s << endl;
}

int main()
{
string a[] ={ "A", "B", "C" };
for (int i=0; i < 3 ; i++)
func(a);
}
~
I am trying to break at the cout (line # 6)
in func(string&) only if s == "C", but gdb disregards it no matter
what i try to do, here it goes

(gdb) b 6 if s == "C" //does not work breaks for "A", "B", "C"
(gdb) b 6 if ( (s== "C") > 0) //breaks for all "A", "B", "C"

(gdb) b 6 if s.operator==("C") > 0
(gdb) b 6 if s.operator==(s,"C") > 0
Error in testing breakpoint condition:
There is no member or method named operator.


IIRC, the function needs to be put in quotes, or the gdb parser will not
parse it in the way you expect:

b 6 if s."operator=="("C")

but you must have used that operator or it would not have been put in
the resulting executable. Also, I'm not sure if gdb will generate "C"
(an array of two bytes) on the fly.
(gdb) b 6 if (strcmp(s.c_str() , "C") == 0 )
No symbol "strcmp" in current context.

The only way i can possibly think of is to add source lines and clean
them up later like
if ( s == "C" ) break;

The break keyword doesn't cause the gdb to break. Actually, I'm not
sure what it would do in this context. Maybe go out one scope level?
Dunno.

If you want to do something like you are suggesting, IMHO, it would
'easier' to do like this:

BREAK(s == "C");

then have in a header file somewhere:
#if !defined BREAK_NO_CHECK
# define BREAK(x) ((void)((x)?(brk()):0))
#else
# define BREAK(x) ((void)0)
#endif

and in a source file somewhere:
#if !defined BREAK_NO_CHECK
// Need something so that it doesn't get optimised out if optimisation
// are on.
// Not sure if you can make inline as I don't know what gdb will be
// able to break on the call then.
int brk() { int a=0; ++a; return a; }

#endif

and then use the gdb command:

b brk

Once the break has been tripped, use gdb 'finish' command to let the
brk() function finish and return to the caller.

NOTE: the way I defined BREAK() allows for you to use it pretty much
anywhere, though these would be a bit obscure, such as:


int a=3, b=(BREAK(a=3), 3);

// NOTE: BREAK() always returns a non-zero (i.e. TRUE) value.
for (int i=3; i<9, BREAK(i==4); ++i) {
//...
}

fn(3, (BREAK(b==3),b), 3);

Though usually, you would use it in a more normal statement syntax as I
initially described.

Hope this helps.


Adrian
--
_____________________________________________________________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ _---_ Q. What are you doing here? _---_ /
\ / | A. Just surf'n the net, teaching and | \ /
\__/___\___ learning, learning and teaching. You?_____/___\__/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
 
A

Adrian Hawryluk

Adrian said:
digz said:
Hi,
I am having a lot of trouble setting conditional breakpoints in gdb,
here is a simple example...

#include<string>
#include<iostream>
using namespace std;

void func(string& s){
cout << s << endl;
}

int main()
{
string a[] ={ "A", "B", "C" };
for (int i=0; i < 3 ; i++)
func(a);
}
~
I am trying to break at the cout (line # 6)
in func(string&) only if s == "C", but gdb disregards it no matter
what i try to do, here it goes

(gdb) b 6 if s == "C" //does not work breaks for "A", "B", "C"
(gdb) b 6 if ( (s== "C") > 0) //breaks for all "A", "B", "C"

(gdb) b 6 if s.operator==("C") > 0
(gdb) b 6 if s.operator==(s,"C") > 0
Error in testing breakpoint condition:
There is no member or method named operator.


IIRC, the function needs to be put in quotes, or the gdb parser will not
parse it in the way you expect:

b 6 if s."operator=="("C")

but you must have used that operator or it would not have been put in
the resulting executable. Also, I'm not sure if gdb will generate "C"
(an array of two bytes) on the fly.
(gdb) b 6 if (strcmp(s.c_str() , "C") == 0 )
No symbol "strcmp" in current context.

The only way i can possibly think of is to add source lines and clean
them up later like
if ( s == "C" ) break;

The break keyword doesn't cause the gdb to break. Actually, I'm not
sure what it would do in this context. Maybe go out one scope level?
Dunno.

If you want to do something like you are suggesting, IMHO, it would
'easier' to do like this:

BREAK(s == "C");

then have in a header file somewhere:
#if !defined BREAK_NO_CHECK
# define BREAK(x) ((void)((x)?(brk()):0))
#else
# define BREAK(x) ((void)0)
#endif

and in a source file somewhere:
#if !defined BREAK_NO_CHECK
// Need something so that it doesn't get optimised out if optimisation
// are on.
// Not sure if you can make inline as I don't know what gdb will be
// able to break on the call then.


Er, now that I think about that last comment RE inline some more,
inlineing from within a source file will probably only affect things
referring to brk() within the source file after the definition. So the
comment is moot.
int brk() { int a=0; ++a; return a; }

#endif

and then use the gdb command:

b brk

Once the break has been tripped, use gdb 'finish' command to let the
brk() function finish and return to the caller.

NOTE: the way I defined BREAK() allows for you to use it pretty much
anywhere, though these would be a bit obscure, such as:


int a=3, b=(BREAK(a=3), 3);

// NOTE: BREAK() always returns a non-zero (i.e. TRUE) value.
for (int i=3; i<9, BREAK(i==4); ++i) {
//...
}

fn(3, (BREAK(b==3),b), 3);

Though usually, you would use it in a more normal statement syntax as I
initially described.

I forgot to mention, you must define BREAK_NO_CHECK in your project to
strip out the excess code in the compiled binary. Make sure that the
condition you pass to BREAK has no side-effects, or you _will_ have trouble.


Adrian
--
_____________________________________________________________________
\/Adrian_Hawryluk BSc. - Specialties: UML, OOPD, Real-Time Systems\/
\ _---_ Q. What are you doing here? _---_ /
\ / | A. Just surf'n the net, teaching and | \ /
\__/___\___ learning, learning and teaching. You?_____/___\__/
\/______[blog:__http://adrians-musings.blogspot.com/]______\/
 
D

digz

digz said:
Hi,
I am having a lot of trouble settingconditionalbreakpointsingdb,
here is a simple example...
#include<string>
#include<iostream>
using namespace std;
void func(string& s){
cout << s << endl;
}
int main()
{
string a[] ={ "A", "B", "C" };
for (int i=0; i < 3 ; i++)
func(a);
}
~
I am trying to break at the cout (line # 6)
in func(string&) only if s == "C", butgdbdisregards it no matter
what i try to do, here it goes

(gdb) b 6 if s == "C" //does not work breaks for "A", "B", "C"
(gdb) b 6 if ( (s== "C") > 0) //breaks for all "A", "B", "C"
(gdb) b 6 if s.operator==("C") > 0
(gdb) b 6 if s.operator==(s,"C") > 0
Error in testing breakpoint condition:
There is no member or method named operator.

IIRC, the function needs to be put in quotes, or thegdbparser will not
parse it in the way you expect:

b 6 if s."operator=="("C")

but you must have used that operator or it would not have been put in
the resulting executable. Also, I'm not sure ifgdbwill generate "C"
(an array of two bytes) on the fly.
(gdb) b 6 if (strcmp(s.c_str() , "C") == 0 )
No symbol "strcmp" in current context.
The only way i can possibly think of is to add source lines and clean
them up later like
if ( s == "C" ) break;


say this is line# 7 in the sample code
The break keyword doesn't cause the gdb to break. Actually, I'm not
sure what it would do in this context. Maybe go out one scope level?
Dunno.

I meant set a breakpoint in the line number where such ifs
would be used ,it could as well be :
if ( s== "C" ) cout << "found it" ;
as in the example say the "if statement" is in line no 7 in the source
so...
(gdb) break 7
would only break if the condition s==C is satisfied ,the debug macros
you suggest seem to be an overkill..
i was essentially trying to do non intrusive debugging ,without
changing the source, but that seems not likely.
even if we had to introduce operator== somewhere so its in the symbol
table it would mean changing source recompiling etc..
Apologies for Off Topic Posting :(
Thx
Digz




Digz
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top