10

How can I print the value of static const class members in gdb?

Say I have:

#include <iostream>

struct foo {
    static const int bar = 5;
};

int main() { 
    std::cout << foo::bar;
    return 0; 
}

How do I examine the contents foo::bar in gdb?

I tried:

(gdb) p foo::bar
No symbol "foo" in current context.
(gdb) p 'foo::bar'
No symbol "foo::bar" in current context.
Gillespie
  • 5,780
  • 3
  • 32
  • 54
  • Could be related to [this](https://stackoverflow.com/questions/9110487/undefined-reference-to-a-static-member). If you add a definition or make it inline, does it work then? – NathanOliver Aug 05 '21 at 20:37
  • 1
    Hmm, not even if I add a constructor and set a breakpoint in it does it think that `bar` or `foo::bar` exists in the current context. – Ted Lyngmo Aug 05 '21 at 20:52
  • 2
    It could well be that you can not. Such name doesn't have linkage, and `gdb` so it doesn't exist as a symbol for `gdb`. And `gdb` is not a compiler, so it can not extract this information from the C++ code itself. It is just a limitation of the toolchain. – SergeyA Aug 05 '21 at 20:52
  • @TedLyngmo no instance was created, why would it think otherwise? it would inline the value of static member, that's all. – Swift - Friday Pie Aug 05 '21 at 22:04
  • @Swift-FridayPie I added a constructor and set a breakpoint in it and created an instance to see if that would help - it did not. – Ted Lyngmo Aug 05 '21 at 22:06
  • Have you checked the disassembly for `main`? The code would be optimized, then the variable doesn't exist. – prehistoricpenguin Aug 06 '21 at 02:08
  • ODR-use `bar` might help. – Jarod42 Aug 06 '21 at 08:39
  • 1
    If I add an instance of `foo`, then `p foo::bar` works for me in gdb. – ssbssa Aug 06 '21 at 14:07
  • @ssbssa - you're right. If I just do `foo f;` as the first line of `main()` I'm able to print the value of it. Even though `-O0` is passed, I'm wondering if GCC is still doing a slight optimization by not creating a symbol if an instance is never created. – Gillespie Aug 06 '21 at 18:35

2 Answers2

1

You can't because gcc does not resolve this to a symbol but to an actual value in the assembly so gdb has nothing to look at. If you needed to you might be able to add the volatile keyword to prevent the compiler from performing this optimization.

0

As @ssbssa pointed out, as long as one instance of the class is created, it works. Doesn't matter where, instance could even be created in an unused function. For example:

#include <iostream>

struct foo {
    static const int bar = 5;
};

void unused() {
    foo f;
}

int main() { 
    return 0; 
}

And in gdb:

gdb) info variables
All defined variables:
...
File test.cpp:
4:  const int foo::bar;
...
(gdb) p foo::bar
$1 = 5

You can see that as long as there is one instance of foo somewhere, there is a symbol for it in .debug_info section of the binary, i.e.:

user@krypton:~$ readelf -w a.out | grep foo
    <28ee>   DW_AT_name        : foo
    <2901>   DW_AT_linkage_name: (indirect string, offset: 0xcfa): _ZN3foo3barE

Note that the same symbol is missing if the compiler detects that no instances of the class are ever created. Seems to be some quirk/optimization of GCC that can't be disabled.

Gillespie
  • 5,780
  • 3
  • 32
  • 54