4

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?

Community
  • 1
  • 1
Richard Corden
  • 21,389
  • 8
  • 58
  • 85
  • It sounds like you're trying to do this without a disassembly listing. If true, your first step should be to run the compiler with (can't remember the flag right now, -s?). But I have to ask: is a temporary variable really that bad? Yes, you have a memory store/retrieve, but an optimizer should remove even that. Oh yeah, what's your optimization level? For debugging it should be very low. – kdgregory Sep 04 '09 at 11:47
  • In the real situation, the function in question is a template using some boost constructs. It's called form several places, so it's actually faster to add the breakpoing and repeatidly to "finish" until I see the value I'm looking for. I was hoping I could "automate" this though. Regarding optimisation, it should be off completely: -O0. – Richard Corden Sep 04 '09 at 11:58

2 Answers2

4

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
  • 533
  • 3
  • 12
0

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
  • 23,773
  • 22
  • 96
  • 162
  • 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 Sep 04 '09 at 13:34
  • 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 Sep 04 '09 at 14:08