Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Manipulating C++ member variables that begin with $ in GDB

I'm working with a C++ code base with a very peculiar coding style, including prefixing member variables in classes with '$'. For anyone who's never come across this before, it's not formally part of C++ standards, but lurks around for backwards compatibility.

As an example of what I'm talking about:

#include <iostream>

class T { public: int $x; int y; };

int main()
{
  T *t = new T();
  t->$x = t->y = 42;
  std::cout << "t->$x = " << t->$x << std::endl;
  delete t;
  return 0;
}

This introduces a problem in GDB. GDB normally uses $ prefixed variables as a magic convenience variable (such as referring to previous values). Fire up GDB, set a breakpoint at the cout statement, and try to print t->$x.

p t runs fine. p *t runs fine. p t->y runs fine. p t->$x returns a syntax error, presumably expecting the $ to refer to a convenience variable.

Ideally, I'd strip the $s out entirely and spend the rest of my days hunting down whoever thought that was a good idea (especially for a modern codebase). That's not realistic, but I still need to be able to use GDB for debugging.

I'm hoping there's a magic escape character, but nothing I've searched for or tried has worked.

Examples:

  • p this->'\044descriptor'
  • p this->'$descriptor'
  • p this->'$'descriptor
  • p this->\$descriptor
  • p this->\\$descriptor
  • p this->'\$descriptor'
  • p this->'\\044descriptor'
  • p this->$$descriptor
  • p this->'$$descriptor'

and so on.

In this particular case, I can run the getter function (p this->getDescriptor()). An uglier workaround is to print the entire class contents (p *this). I'm not sure I can rely on both of those indefinitely; some of the classes are fairly large, and most member variables don't have getters.

This could potentially be classified as a bug in GDB, depending on whether it's a good idea to rip up input to support this. However, even if it was fixed, I'm stuck on GDB 7.2 for the given architecture/build environment.

Any ideas?

UPDATE: python import gdb; print (gdb.parse_and_eval("t")['$x']) as suggested in the comment works if you have python builtin (which I don't have, unfortunately).

like image 998
SirNuke Avatar asked May 13 '15 19:05

SirNuke


People also ask

How do I change a variable value in gdb?

Use the set variable (gdb) and the assign (dbx) commands to change the value associated with a variable, memory address, or expression that is accessible according to the scope and visibility rules of the language. The expression can be any expression that is valid in the current context.

What does @entry mean in gdb?

The @entry form refers to the value of the parameter when the function was entered. This isn't always available, but sometimes it is -- there is a DWARF extension for it, and GCC emits this when possible. There's some information here: https://sourceware.org/gdb/onlinedocs/gdb/Variables.html.

Which command is used in gdb to find the type of variable in C?

The ptype [ARG] command will print the type. Show activity on this post. This question may be related: vtable in polymorphic class of C++ using gdb: (gdb) help set print object Set printing of object's derived type based on vtable info.

How do I get the value of a variable in gdb?

you can examine and use the variable a whenever your program is executing within the function foo , but you can only use or examine the variable b while your program is executing inside the block where b is declared. These uses of ' :: ' are very rarely in conflict with the very similar use of the same notation in C++.


1 Answers

If you got the gdb version with python extensions, maybe the "explore" feature will help.

See https://sourceware.org/gdb/onlinedocs/gdb/Data.html#Data


  (gdb) explore cs
     The value of `cs' is a struct/class of type `struct ComplexStruct' with
     the following fields:

       ss_p = 
        arr = 

     Enter the field number of choice:

Since you don't need the variable name, you should be able to step around the '$' issue.

like image 191
narz Avatar answered Nov 16 '22 02:11

narz