2015-05-13 5 views
9

Ich arbeite mit einer C++ - Codebasis mit einem sehr speziellen Codierungsstil, einschließlich der Vorsilbe von Elementvariablen in Klassen mit '$'. Für alle, die nie zuvor darauf gestoßen sind, ist es nicht formal Teil von C++ - Standards, sondern lurks around for backwards compatibility.

Als ein Beispiel von dem, was ich spreche:

#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; 
} 

Dies führt zu einem Problem in GDB. GDB verwendet normalerweise $ Präfix-Variablen als eine magische Bequemlichkeitsvariable (wie zum Beispiel Bezug auf vorherige Werte). Starten Sie GDB, legen Sie einen Haltepunkt bei der Anweisung cout fest, und versuchen Sie, t->$x zu drucken.

p t läuft gut. p *t läuft gut. p t->y läuft gut. p t->$x gibt einen Syntaxfehler zurück und erwartet vermutlich, dass $ auf eine Convenience-Variable verweist.

Im Idealfall würde ich die $ s ganz ausziehen und den Rest meiner Tage damit verbringen, jemanden zu jagen, der das für eine gute Idee hielt (besonders für eine moderne Codebasis). Das ist nicht realistisch, aber ich muss trotzdem GDB zum Debuggen verwenden können.

Ich hoffe, es gibt eine magische Flucht Charakter, aber nichts, was ich gesucht oder ausprobiert hat funktioniert.

Beispiele:

  • 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'

und so weiter.

In diesem speziellen Fall kann ich die Getter-Funktion (p this->getDescriptor()) ausführen. Eine hässlichere Problemumgehung ist das Drucken des gesamten Klasseninhalts (p *this). Ich bin mir nicht sicher, ob ich mich auf beide auf unbestimmte Zeit verlassen kann; Einige der Klassen sind ziemlich groß, und die meisten Membervariablen haben keine Getter.

Dies könnte möglicherweise als ein Fehler in GDB klassifiziert werden, abhängig davon, ob es eine gute Idee ist, Eingabe zu rippen, um dies zu unterstützen. Aber selbst wenn es behoben wurde, bleibe ich bei GDB 7.2 für die gegebene Architektur/Build-Umgebung hängen.

Irgendwelche Ideen?

UPDATE: python import gdb; print (gdb.parse_and_eval("t")['$x']) wie in dem Kommentar vorgeschlagen funktioniert, wenn Sie Python eingebaut haben (die ich leider nicht habe).

+1

Rückwärts Kompabilität ist böse, nicht wahr? – user463035818

+0

Wird die Codebasis aktiv in einem Repository wie github verwaltet? Könnte dies im Quellcode bereinigt werden, vielleicht im Repository aktualisiert werden, oder könnten Sie es aufteilen und es dort bereinigen? Wenn Sie mit GDB stolpern, ist das vielleicht die beste Option .... aber zählen Sie die Kosten in Stunden, um dies zu tun. –

+0

Haben Sie versucht mit '$$' zu entkommen? – sehe

Antwort

1

Wenn Sie die gdb-Version mit Python-Erweiterungen haben, hilft Ihnen vielleicht die "explore" -Funktion.

Siehe 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: 

Da Sie die Variablennamen nicht benötigen, sollten Sie rund um das ‚$‘ Problem Schritt können.

Verwandte Themen