Author Topic: get return value of a call while debugging  (Read 5346 times)

Offline MoonKid

  • Almost regular
  • **
  • Posts: 180
get return value of a call while debugging
« on: April 16, 2006, 12:32:02 pm »
Where can I see the return value of a function/methode that is called while debugging.

I step on each line with F7. I want to see each(!) return value. Where can I see it?

Here is an example (I know the code is wrong!):
Code: [Select]
wxString strSubDest = strDestination_ + dirname.Right(dirname.Find(wxFILE_SEP_PATH, true));

I want to see two values if I step over this line.
Return value of Right() and of Find().
« Last Edit: April 16, 2006, 12:33:51 pm by MoonKid »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: get return value of a call while debugging
« Reply #1 on: April 16, 2006, 03:27:03 pm »
You cannot, since there is no symbol for it. If you want to see them, you have to assign them to a variable first.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline MoonKid

  • Almost regular
  • **
  • Posts: 180
Re: get return value of a call while debugging
« Reply #2 on: April 16, 2006, 03:41:26 pm »
You cannot, since there is no symbol for it.

Why does the MSVC debugger can do this?

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: get return value of a call while debugging
« Reply #3 on: April 16, 2006, 03:53:59 pm »
Quote
Why does the MSVC debugger can do this?
Obviously by secretly creating a symbol.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline MoonKid

  • Almost regular
  • **
  • Posts: 180
Re: get return value of a call while debugging
« Reply #4 on: April 16, 2006, 04:42:06 pm »
by secretly creating a symbol.

You mean the MSVC compiler restruct code like this

Code: [Select]
functioncall();

to

Code: [Select]
long rc = functioncall();

?

And then the debugger can handle it?
Nice! Why does GCC and GDB does not allow this?

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: get return value of a call while debugging
« Reply #5 on: April 17, 2006, 06:44:54 pm »
Shouldn't be that hard to implement really (at least in the debugger). The common implementation is to save the return value in eax (x86), or save there a pointer to where it's stored if it cannot be saved there, etc. Anyway, the return value is there. If it's a long all you'd need to do is to check eax's value. Haven't tested though :)

[edit]
I just did a quick test and it works, but this'sn't really the best way to do it. I wonder if the plugin could be modified to play with those "internals".

In the meanwhile just be sure to have the "CPU Registers" window enabled or modify your code to save the return value in a temporary.
[/edit]
« Last Edit: April 17, 2006, 06:52:41 pm by Ceniza »

Offline MoonKid

  • Almost regular
  • **
  • Posts: 180
Re: get return value of a call while debugging
« Reply #6 on: April 17, 2006, 06:59:47 pm »
Shouldn't be that hard to implement really (at least in the debugger).

Should I have to patch the hole world? ;)

Patching a debugger is to hard for me. I am not a code hacker.

The common implementation is to save the return value in eax (x86), or save there a pointer to where it's stored if it cannot be saved there, etc. Anyway, the return value is there. If it's a long all you'd need to do is to check eax's value.
I just did a quick test and it works, but this'sn't really the best way to do it. I wonder if the plugin could be modified to play with those "internals".

Where did you test it? You patched gdb? :)

Which plugin do you mean?

You confuse me! ;)

sethjackson

  • Guest
Re: get return value of a call while debugging
« Reply #7 on: April 17, 2006, 07:07:22 pm »
He didn't mean patch GDB.  :shock: :lol:
He meant make a patch (feature addition) to the Code::Blocks debugger plugin.

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: get return value of a call while debugging
« Reply #8 on: April 17, 2006, 07:19:54 pm »
First, just ignore the fact of patching GDB.

This is what I did:
* Created a new console project.
* Created a main.cpp ('cause I created the project totally empty).
* Added this little test program:

Code: C++
  1. #include <iostream>
  2.  
  3. long function(long n)
  4. {
  5.   return n * 7 + 2;
  6. }
  7.  
  8. int main()
  9. {
  10.   long x;
  11.  
  12.   std::cin >> x;
  13.   function(x);
  14.  
  15.   std::cin >> x;
  16.   function(x);
  17. }

* In the build options enabled debugging symbols [-g].
* In the debugger toolbar I enabled the "CPU Registers" window.
* Added a breakpoint at line 13 (first call to function).
* Started debugging.

It'll show you a console and will be waiting for a long value. I typed 8 just for fun. When I hit enter the program is interrupted by the debugger.

The current value of eax is before calling function, so I just click on "Next line" button (it's in the debugger toolbar). Now check eax's value: 58 (8 * 7 + 2).

"Next line". It'll ask for another number. I typed 3. "Next line". Once again it's eax's value before the function is called. "Next line". Now eax's value is 23 (3 * 7 + 2).

The plugin I was talking about is the debugger plugin, but I really wonder if Don Corleone would be interested in doing so, or anyone else in writing a patch.

Once again, it's kinda a hack, but works :P

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: get return value of a call while debugging
« Reply #9 on: April 17, 2006, 07:46:26 pm »
Another trick, if someone is really feeling like creating a patch for the debugger plugin (sorry if no one is) :)

Howto when the return value is a struct

This is basically the same example, but now everything is evaluated as long and double, stored in a struct and returned.

Code: C++
  1. #include <iostream>
  2.  
  3. struct longdouble
  4. {
  5.   long l;
  6.   double d;
  7. };
  8.  
  9. longdouble function(longdouble n)
  10. {
  11.   longdouble r;
  12.  
  13.   r.l = r.d = n.l * 7 + 2;
  14.  
  15.   return r;
  16. }
  17.  
  18. int main()
  19. {
  20.   longdouble x;
  21.  
  22.   std::cin >> x.l;
  23.   x.d = x.l;
  24.   function(x);
  25.  
  26.   std::cin >> x.l;
  27.   x.d = x.l;
  28.   function(x);
  29. }

The breakpoint goes now in line 24 (first call to function).

I just did the same: typed 8, the program was interrupted and clicked on "Next line". Because it's a struct, eax stores a pointer to a temporary struct where the result is saved. In my machine it's 0x22ff50 in hex (eax's value).

If you want the value of l (the long inside struct longdouble): Debug -> Send user command to debugger:

Code: [Select]
output ((struct longdouble *)0x22ff50)->l
The result will be shown in the Debugger thingy in the Messages pane.

I hope all of this be of any use, but once again: sorry.

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: get return value of a call while debugging
« Reply #10 on: April 17, 2006, 11:36:58 pm »
Although this clearly works as you have pointed out, I fear that there may be quite a few pitfalls, it may not be that easy in the end.

For example, how can the debugger plugin know a function's return type without either querying the code completion plugin or demangling the C++ function name? Both is problematic in some way.

One could argue that this functionality is only ever needed for bool and int values as well as pointers. You don't usually do something like if(ReturnsAnObject()) (and with most object types, that won't compile, either).
But anyway, bool and int may have different sizes (normally, but not necessarily sizeof(bool) == sizeof(char)), and you don't really know what kind of tampering the compiler does (and what may be the upper 24/56 bits of a bool), so simply reading the whole register might give random nonsense (or might work fine, who knows...).

And then we have non-stdcall functions, and inline functions, register variables, all that kind of stuff. According to the GCC documentation, it is quite possible and valid to debug optimized code, so we cannot expect everything to be nice and easy.

Life is a lot easier if you do have a symbol, since then you just *ask* GDB for the value, and it is not your problem where it comes from :)
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline Ceniza

  • Developer
  • Lives here!
  • *****
  • Posts: 1442
    • CenizaSOFT
Re: get return value of a call while debugging
« Reply #11 on: April 18, 2006, 12:45:55 am »
Quote from: thomas
For example, how can the debugger plugin know a function's return type without either querying the code completion plugin or demangling the C++ function name? Both is problematic in some way.

Quote from: GDB
(gdb) whatis function
type = longdouble (longdouble)
(gdb) whatis main
type = int (void)

bool: eax is 0 for false and != 0 (1 in GCC) for true.

Inlined functions wouldn't work and all in all the implementation would become architecture specific, GCC only and a whole hack.

Anyway, there you have tricks for some of your needs, but just like thomas said: "Life is a lot easier if you do have a symbol".

Offline MoonKid

  • Almost regular
  • **
  • Posts: 180
Re: get return value of a call while debugging
« Reply #12 on: April 18, 2006, 03:30:28 pm »
but just like thomas said: "Life is a lot easier if you do have a symbol".

Ok, I will submit a feauter request for gcc and/or gdb. ;)