Cannot Evaluate Function -- May Be Inlined

Cannot evaluate function -- may be in-lined error in GDB for STL template container

This is because amap.begin() does not exist in resulting binary. This is how C++ templates work: if you don't use or explicitly instantiate some template method it is not generated in resulting binary.

If you do want to call amap.begin() from gdb you have to instantiate it. One way to do it is to instantiate all methods of std::map:

#include <map>

template class std::map<int,int>;

int main()
{
std::map<int,int> amap;
amap.insert(std::make_pair(1,2));
}

gdb session:

(gdb) p amap.begin()
$1 = {first = 1, second = 2}

gdb stl functions still show as inlined after disabling optimizations

My question is why are the functions showing up as inlined even after Disabling optimizations with -O0 options?

g++ will only instantiate templates that are actually used by your program, and your program doesn't actually use the size method.

You can check this using nm:

$ nm -C q|grep size
$

If I change your program to use return ivec.size(), then I can:

(gdb) p ivec.size()
$1 = 0

This whole situation with inlining and non-instantiation is why the gdb xmethod support was written. And, libstdc++ has some xmethods (though I didn't check if it specifically has this one). I recommend using that.

Possible to call inline functions in gdb and/or emit them using GCC?

One way to get the compiler to generate a callable version of an inline function is to include code that takes the address of the function. There is also an option you can give to gcc. From the gcc documentation on inline functions:

When a function is both inline and static, if all calls to the function are
integrated into the caller, and the function's address is never used, then the
function's own assembler code is never referenced. In this case, GCC does not
actually output assembler code for the function, unless you specify the option
-fkeep-inline-functions
.

Inspecting standard container (std::map) contents with gdb

I think there isn't, at least not if your source is optimized etc. However, there are some macros for gdb that can inspect STL containers for you:

http://sourceware.org/ml/gdb/2008-02/msg00064.html

However, I don't use this, so YMMV

Call an overloaded operator from GDB

The issue is not that the operator() is being inlined, but the linker is just removing the function, since is not called anywhere in your program.

On my machine, if I change main to:

int main()
{
Test t = Test(10);
t(42); // some call, result can be ignored
return 0;
}

then running the command gives:

(gdb) call (int)t.operator()((int)10)
$1 = 20

Also, when compiling the program, use -ggdb3 (for better debugging symbols) and -O0 (so that function calls don't get inlined, etc).

How can I tell gcc not to inline a function?

You want the gcc-specific noinline attribute.

This function attribute prevents a
function from being considered for
inlining. If the function does not
have side-effects, there are
optimizations other than inlining that
causes function calls to be optimized
away, although the function call is
live. To keep such calls from being
optimized away, put
asm ("");

Use it like this:

void __attribute__ ((noinline)) foo() 
{
...
}


Related Topics



Leave a reply



Submit