简体   繁体   中英

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 .

pt 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']) 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).

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM