2016-06-14 24 views
2

Ich habe ein Problem mit großen verschachtelten Datenstrukturen (von JSON Spirit). Beim Debuggen beginnt Eclipse, wenn diese Struktur mit Daten gefüllt ist, sehr langsam zu arbeiten, nach jedem Schritt wartet es auf gedruckte Daten von GDB. Die Sache ist, dass Eclipse viele Informationen über lokale Variablen sammelt, auch wenn ich diese Datenstruktur nicht erweitere. Wenn der hübsche Ausdruck aus ist, funktioniert es, aber ich kann natürlich nichts in STL-Containern sehen.Eclipse CDT (4.5.1) arbeitet langsam mit hübschen Drucken

Ich bin mit Druckern von GDB SVN

hier ein kleines Stück Code, die ähnliche Probleme machen kann:

#include <iostream> 
#include <string> 
#include <map> 

int main() { 
    std::map<std::string, std::map<std::string, std::map<std::string, std::string>>> mega_map; 

    const int factor = 50; 
    for (int c = 0; c < factor; ++c){ 
     std::map<std::string, std::map<std::string, std::string>> b_map; 
     for (int b = 0; b < factor; ++b){ 
      std::map<std::string, std::string> a_map; 
      for (int a = 0; a < factor; ++a){ 
       std::string a_str = "a"; 
       a_str += (std::to_string(a)); 
       auto a_pair = std::make_pair("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + a_str, "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"); 
       a_map.insert(a_pair); 
      } 
      std::string b_str = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; 
      b_str += (std::to_string(b)); 
      b_map[b_str] = a_map; 
     } 
     std::string c_str = "cccccccccccccccccccccccccccccccccccccccc"; 
     c_str += (std::to_string(c)); 
     mega_map[c_str] = b_map; 
    } 
    return 0; 
} 

Nur eine Bremse bei ‚Rückkehr‘ machen, und Sie werden sehen, dass es dauert, viel Zeit, um etwas im 'Variablen' Fenster zu bekommen. Während dieser Zeit können Sie nicht debuggen.

Es gibt ein Flag in GDB set print elements number-of-elements, das die Anzahl der Elemente in den zu druckenden Containern begrenzen kann. Obwohl diese verschachtelten Strukturen mich nicht interessieren, wirkt sich diese Einstellung auf andere Container aus, die ich untersuchen möchte.

Irgendwelche Ideen, wie man es repariert?

Danke.

Antwort

0

Wir (Kollegen und ich) haben dieses Problem heute getroffen und untersucht, und hier ist unsere Schlussfolgerung. Leider haben wir keine Möglichkeit gefunden, dieses Problem mit einigen Einstellungen zu lösen, aber einige Änderungen in CDT und GDB gefunden, die helfen könnten, dieses Problem zu beheben. Wenn Sie Ihr eigenes CDT oder GDB erstellen können, kann es Ihnen helfen.

CDT fragt GDB nach den Einheimischen, die -stack-list-locals verwenden, mit dem Argument, um ihre Werte auch zu erhalten. Für eine ziemlich bedruckten Behälter endet GDB die Kinder darunter bis:

std::vector of length 20, capacity 20 = {<children here>} 

für verschachtelte Datenstrukturen, kann es bis riesige beenden. Eine Lösung ist, dass CDT diese Werte nicht fragt. Es wird Variablenobjekte korrekt verwenden und beim Erweitern der Datenstrukturen nach den erforderlichen Werten fragen. Hier ist der Unterschied:

diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIStack.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIStack.java 
index c319eb8..23bbb8a 100644 
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIStack.java 
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/mi/service/MIStack.java 
@@ -859,7 +859,7 @@ implements IStack, ICachingService { 
      fMICommandCache.execute(
        // Don't ask for value when we are visualizing trace data, since some 
        // data will not be there, and the command will fail 
-     fCommandFactory.createMIStackListLocals(frameDmc, !fTraceVisualization), 
+     fCommandFactory.createMIStackListLocals(frameDmc, false), 
        new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), rm) { 
         @Override 
         protected void handleSuccess() { 
@@ -988,7 +988,7 @@ implements IStack, ICachingService { 
       // the result without the values 
       // Don't ask for value when we are visualizing trace data, since some 
       // data will not be there, and the command will fail 
-    fCommandFactory.createMIStackListLocals(frameDmc, !fTraceVisualization), 
+    fCommandFactory.createMIStackListLocals(frameDmc, false), 
       new DataRequestMonitor<MIStackListLocalsInfo>(getExecutor(), countingRm) { 
        @Override 
        protected void handleSuccess() { 

Es gibt andere Fälle, in denen CDT Anfragen werden ausgeben, die GDB machen ausspucken die volle rekursive Datenstruktur, das heißt, wenn Sie die Variable in der Variablen ausgewählt haben anzuzeigen oder wenn Sie es schweben. Dann werden Sie den vollständigen erweiterten Wert im Abschnitt "Details" bemerken. Wenn Sie diese Variable jedoch nicht als Schritt auswählen, wird sie schnell ausgeführt.

Die mögliche Korrektur in GDB ist es, es nicht hübsch gedruckte Datenstrukturen rekursiv auszugeben. Dieser Hack zum Beispiel schränkt sie auf eine Ebene der Kinder:

diff --git a/gdb/python/py-prettyprint.c b/gdb/python/py-prettyprint.c 
index 66929bf..b213699 100644 
--- a/gdb/python/py-prettyprint.c 
+++ b/gdb/python/py-prettyprint.c 
@@ -700,7 +700,7 @@ gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, 
    /* Print the section */ 
    print_result = print_string_repr (printer.get(), hint.get(), stream, 
        recurse, options, language, gdbarch); 
- if (print_result != string_repr_error) 
+ if (print_result != string_repr_error && recurse == 0) 
    print_children (printer.get(), hint.get(), stream, recurse, options, 
      language, print_result == string_repr_none); 

Ein Beitrag GDB aufwärts könnte in Betracht gezogen werden, wenn diese Rekursion Grenze eine Einstellung mit einem reasonnable Wert ist.

+0

Dies sieht sehr ähnlich zu https://bugs.eclipse.org/bugs/show_bug.cgi?id=519561 und ich schätze die Analyse, die Sie getan haben. Können Sie dem Fehler bitte die gleichen Details hinzufügen, besonders wenn Sie glauben, dass es derselbe ist. Vielen Dank! –