views:

208

answers:

2

I have a more complicated version of the following:

unsigned int foo ();
unsigned int bar ();

unsigned int myFunc () {
  return foo()+bar();
}

In my case, myFunc is called from lots of places. In one of the contexts there is something going wrong. I know from debugging further down what the return value of this function is when things are bad, but unfortunately I don't know what path resulted in this value.

I could add a temporary variable that stored the result of the expression "foo()+bar()" and then add the conditional breakpoint on that value, but I was wondering if it is possible to do in some other way.

I'm working on x86 architecture.

From this and this answer I thought I could set a breakpoint at the exact location of the return from the function:

gdb> break *$eip

And then add a conditional breakpoint based on the $eax register, but at least in my tests here the return is not in this register.

Is this possible?

A: 

I don't get whether you're compiling from the command line or not, but from within Visual Studio, once you set your breakpoint, right-click it and click the "Condition..." option for a dialog to appear to let you edit the condition for your breakpoint to break.

Hope this helps! :-)

Will Marcouiller
Thanks for the reply. In my case I'm on linux and I'm using g++/gdb. However, having said that this is not about adding conditional breakpoints, it's about adding a condition for something that doesn't have a representation as a variable in your program. Does VS allow you to refer to the value that will be returned even if you don't actually have a named variable for it?
Richard Corden
I guess that you may break depending on the result returned by a function, so no variable are yet known, if I understand correctly. However, I don't know much about Linux programming. I wish I could be of better help.
Will Marcouiller
+2  A: 

Agree with previous commenter that this is probably something you don't want to do, but for me, setting a conditional breakpoint at the last instruction on $eax (or $rax if you are on 64-bit x86) works just fine.

For the code

unsigned int foo(void) { return 1; }
unsigned int bar(void) { return 4; }
unsigned int myFunc(void) { return foo()+bar(); }

using gdb ..

(gdb) disass myFunc
Dump of assembler code for function myFunc:
0x080483d8 <myFunc+0>:  push   %ebp
0x080483d9 <myFunc+1>:  mov    %esp,%ebp
0x080483db <myFunc+3>:  push   %ebx
0x080483dc <myFunc+4>:  call   0x80483c4 <foo>
0x080483e1 <myFunc+9>:  mov    %eax,%ebx
0x080483e3 <myFunc+11>: call   0x80483ce <bar>
0x080483e8 <myFunc+16>: lea    (%ebx,%eax,1),%eax
0x080483eb <myFunc+19>: pop    %ebx
0x080483ec <myFunc+20>: pop    %ebp
0x080483ed <myFunc+21>: ret    
End of assembler dump.
(gdb) b *0x080483ed if $eax==5
Breakpoint 1 at 0x80483ed
(gdb) run
Starting program: /tmp/x 
Breakpoint 1, 0x080483ed in myFunc ()
(gdb)
Olof