2016-07-11 3 views
1

Nicht einfach zu sagen, was meine Programmierfrage ist, da ich nicht wirklich sehe, wo das Problem liegt. Tatsächlich habe ich einen Laufzeitfehler irgendwo in der Boost Spirit Karma Library verloren. Ich denke, ich vermisse hier eine Debugging-Technik.Welche Debugging-Technik für einen Karma-Generator mit Laufzeitfehler

habe ich, dass das Makro BOOST_SPIRIT_DEBUG_NODE (S) für Parser hilft sehr zu sehen, obwohl ich nicht einen Hinweis auf mich im Handbuch finden. Für Generatoren scheint es, dass dies nicht funktioniert und ich (ehrlich gesagt) nicht den Mut habe (sollte ich?), Den Code dieser Bibliothek zu durchforsten, um zu verstehen, wo das Problem liegt.

Ich habe versucht, die drei Arten meiner unionartigen Struktur allein in einer Grammatik ohne irgendein Problem zu erzeugen. Also ich vermute der Fehler kommt von der Besetzung der U-Struktur in eine Boost-Variante, nochmal (siehe Casting attribute to boost::variant) aber ich habe keinen Beweis.

Für diejenigen, die es mit einem einfachen Code-Inspektion lösen könnte, hier ist die minimale Beispiel meiner Frage:

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <iterator> 

//#define BOOST_SPIRIT_DEBUG 
#include <boost/spirit/include/karma.hpp> 
#include <boost/variant/variant.hpp> 

namespace ka = boost::spirit::karma; 

typedef std::back_insert_iterator<std::string> iterator; 
typedef enum {A, B, C } E; 
typedef enum {FOO, BAR, POINTER } K; 

struct U /* Union like */ 
{ 
    K kind; 
    double foo; 
    E bar; 
    unsigned int * p; 
}; 

class EName : public ka::symbols<E, std::string> 
{ 
public: 
    EName() 
    { 
     add (A,"A") (B,"B") (C,"C"); 
    } 
}; 

typedef boost::variant<E, double, unsigned int *> UVariant; 

namespace boost { namespace spirit { namespace traits { 
    template<> 
    struct transform_attribute<const U,UVariant,ka::domain> 
    { 
     typedef UVariant type; 
     static type pre(const U & u) { 
      switch (u.kind) 
      { 
      case FOO: 
       return type(u.foo); 
      case BAR: 
       return type(u.bar); 
      case POINTER: 
       return type(u.p); 
      } 
      return type(A); 
     } 
    }; 
}}} 

class grm: public ka::grammar<iterator, U()> 
{ 
public: 
    grm():grm::base_type(start) 
    { 
     start = ka::attr_cast<UVariant >(bar | foo | pointer); 
     bar = b; 
     foo = ka::double_; 
     pointer = ka::hex; 
    } 
private: 
    ka::rule<iterator,U()> start; 
    ka::rule<iterator,double()> foo; 
    ka::rule<iterator,E()> bar; 
    ka::rule<iterator,unsigned int *()> pointer; 
    EName b; 
}; 

int main(int argc, char * argv[]) 
{ 
    grm g; 
    U u; 
    //unsigned int a; 
    u.kind = BAR; 
    //u.foo = 1.0; 
    u.bar = B; 
    //u.p = &a; 

    std::string generated; 
    std::back_insert_iterator<std::string> sink(generated); 
    ka::generate(sink,g,u); 
    std::cout << generated; 

    return 0; 
} 

UPDATE: Compiler: Visual C++ Express-Version 11 und 12. Die Call-Stack Anschläge an:

  // If you are seeing a compilation error here stating that the 
      // third parameter can't be converted to a karma::reference 
      // then you are probably trying to use a rule or a grammar with 
      // an incompatible delimiter type. 
      if (f(sink, context, delim)) // <--- call stack stops here (last boost spirit reference) 

auch habe ich herausgefunden, dass die Definition des _SCL_SECURE_NO_WARNINGS Makro die folgende Compiler-Warnung beschattete:

Warnung C4996: ‚std :: _ Copy_impl‘: Funktionsaufruf mit Parametern, die unsicher sein könnte - dieser Aufruf stützt sich auf den Anrufer zu überprüfen, ob die gebenen Werte korrekt sind. Verwenden Sie -D_SCL_SECURE_NO_WARNINGS, um diese Warnung zu deaktivieren. Siehe Dokumentation, wie Visual C++ verwenden 'aktiviert Iteratoren'

Diese Warnung unter Bezugnahme auf mehrere Boost-Geist-Dateien:

  • Geist \ home \ Karma \ Detail \ output_iterator.hpp (242)
    Geist \ home \ Karma \ Detail \ output_iterator.hpp (577)
    Geist \ home \ Karma \ Detail \ output_iterator.hpp (574)
    Geist \ home \ Karma \ Detail \ alternative_function.hpp (170)
    Geist \ home \ karma \ detail \ alternative_funktion.hpp (162)
    spirit \ home \ karma \ Operator \ alternative.hpp (122)
    spirit \ Home \ karma \ Hilfs \ attr_cast.hpp (85)
    spirit \ home \ karma \ nicht terminale \ Detail \ generator_binder.hpp (43)
    Geist \ home \ Karma \ Nicht-End \ Detail \ generator_binder.hpp (52)
    Geist \ home \ Karma \ Nicht-End \ rule.hpp (193)
    Geist \ home \ Karma \ Nicht-End \ rule.hpp (230)
+0

"Ich habe einen Laufzeitfehler" - was ist das? Ich kann das nicht reproduzieren. Debugging-Technik # 1 ist die verfügbaren Fakten zu beobachten. – sehe

+0

Ich denke, ich habe gerade eine glückliche Gehirnwelle, siehe meine Antwort – sehe

Antwort

1

Ich kann den Fehler nicht reproduzieren.

Ich kann es auch nicht von einer kleinen Code-Inspektion "lösen".Ich kann jedoch zwei Dinge tun:

  • Ich kann bestätigen, dass Debug-Makros werden nicht für Karma

  • Ich kann auf einem Bein gehen umgesetzt werden und sagen, dass vielleicht bar|foo|pointer Bedürfnisse werden tief kopiert:

    start = ka::attr_cast<UVariant >(boost::proto::deep_copy(bar | foo | pointer)); 
    

ich habe versucht, mit UB-sanitizer und Adress-sanitizer aktiviert, aber sie beide nicht Repo rt irgendwelche Probleme.


UPDATE In der Tat sieht es aus wie ich kann "lösen" es von einer kleinen Code-Inspektion (und Glück brainwave) schließlich:

In der Tat zeigen DOES unter valgrind laufen a problem und tatsächlich geht es weg, wenn Sie die deep_copy hinzufügen.

Ich werde ein paar Referenzen hinzufügen, wie ich diese Dinge die Hypothese aufgestellt:

+0

Live-Demo: [Live On Coliru] (http://coliru.stacked-crooked.com/a/ab18b21d259da5df) – sehe

+0

Es löst den Laufzeitfehler, aber nicht die Warnung (siehe meine Updates), die ziemlich "gruselig" (?) ist. Ich werde morgen Ihre Referenzen lesen und berichten, wenn etwas noch unklar ist. – Heyji

+0

Vielen Dank, dass Sie Ihrer Frage ein paar Informationen zu den tatsächlichen Symptomen hinzugefügt haben. Das macht es viel einfacher, dir zu helfen. – sehe