Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to drill down into shared_ptr [Netbeans, clang++, gdb]

I'm using

  • Netbeans C++ 8.0.2
  • clang++ (Ubuntu clang version 3.6.0-2ubuntu1 (tags/RELEASE_360/final) (based on LLVM 3.6.0))
  • gdb (GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9)

In my "C++ Simple Tests," whenever I inspect a variable that is a shared_ptr, all I see for value is:

std::shared_ptr (count 1, weak 0) 0x64d3a0

or similar. There is no way to drill down to the value of what it's actually pointing to. Even if the tree view in the variables window shows one of the expander icons, it disappears when I click it. When I try dereferencing it or calling its get() function in "expressions" window, I get an error messages:

Could not find operator*.

and

Cannot evaluate function -- may be inlined

respectively.

If I create a reference to the value in the actual program, it not only allows me to drill down into the reference, but the shared_ptr can then be drilled down as well (which seems fishy to me). I tried -g3 and -ggdb but it made no difference.

Is there a debug version of the standard library (is libcxx the default?), or a setting somewhere that might improve the situation? Or maybe a way to list the private members/raw view in the variables window, so I could dereference the underlying pointer myself?

like image 586
Brent Avatar asked Oct 20 '22 09:10

Brent


1 Answers

One flaw of gdb is that the pretty-printing code is only for printing, and can't be used to dig deeper. This flaw also affects the "varobj" feature, which is what most GUIs use when communicating with gdb about value display.

There are some possibilities that can make this better.

First, a bit of background. The reason you can't call operator* or get is that gcc does not normally emit an out-of-line copy of a function that has always been inlined. This is a space-saving optimization. (You can request that this happen but it is uncommonly done.)

So, one approach to fixing this is the new-ish gdb xmethod code. You can write some Python code in gdb to let you implement things like get, so that gdb expressions will work as expected, even though the compiler isn't cooperating. This is handy! And libstdc++ ships with some of these, though I don't know what specifically; you would have to go digging.

There are two low-tech approaches I often use.

  1. Mentioned in the comments -- copy-and-paste the pointer value, cast to the proper type. This works reliably, though as you note it is a pain. Gdb should probably have some "varobj" support for this idiom so that IDEs can do the right thing without jumping through hoops. I believe there's a gdb bug open about this.

  2. Bypass the pretty-printers and dig into the object representation directly. This can sometimes be unpleasant -- in libstdc++ in particular sometimes object representations are truly non-obvious -- but for something like a smart pointer it shouldn't be too bad. The recipe for this is just print/r, and then examine what you see. IDEs can and should provide a way to bypass pretty-printing as well, the "varobj" API exposes this capability. I don't know whether Netbeans does.

like image 168
Tom Tromey Avatar answered Nov 15 '22 09:11

Tom Tromey