G++4.8: internal compiler error: Segmentation fault (program cc1plus)



  • Ich habe ein Problem mit G++4.8 und es würde mich entzücken wenn ich das Problem schnellstmöglich lösen könnte da ich an diesem Punkt nicht weiter programmieren kann.

    Ich habe eine Header-Datei namens title.hpp. In dieser Headerdatei gibt es eine Title-Klasse, die es ermöglichen soll einen Titel (o wunder) auszugeben. Dazu schrieb ich mir auch den entsprechenenden operator<< um ihn direkt mit std::cout << mytitle; auszugeben. Sobald ich jedoch den Operator kompiliere kriegt der G++ nen Segfault 😑

    Und ich wüsste mir grad echt nicht zu helfen - außer den Vorgänger von G++4.8 zu benutzen, aber dann muss ich einiges in meinem Programm neu umschreiben, weil ich die C++11-Features benutze (unter anderem auch inherited constructors).

    Hier der Code, der das Segfault auslöst sobald ich in der main-Funktion die Header-Datei einbinde.

    #ifndef TITLE_HPP
    #define TITLE_HPP
    
    ...
    
    namespace fast{
        namespace io{
    
            /*** CLASS FOR THE TITLE ***/
    
            class title{
    ...
            };
    
        }
    }
    
    inline std::ostream& operator<< (std::ostream& out, const fast::io::title& title){
        return out << title.get_name() << '\n' << title.get_line();
    }
    
    #endif
    

    Sobald ich operator<< auskommentiere funktioniert alles glatt.
    Und nun? 😞



  • *[...]sobald ich in der main.cpp (nicht main-Funktion, pardon) die Header-Datei einbinde.[...]



  • Tja, irgendwo hantierst du mit Pointern herum, die auf ungünstigen Speicher zeigen.
    Das geht zufälligerweise beim Aufruf der operator << Funktion schief.
    Es muss aber nicht heißen, dass der Fehler da liegt.
    Er könnte IRGENDWO sein. In irgendeiner Funktion.



  • Tja, irgendwo hantierst du mit Pointern herum, die auf ungünstigen Speicher zeigen

    Ach, dadurch stuerzt aber der Kompiler nicht ab. Dennoch sollte das bei einem korrekten C++-Programm nicht passiere.

    Loesung clang nehmen und schauen ob er Fehlermeldungen ausspuckt.



  • Nathan schrieb:

    Tja, irgendwo hantierst du mit Pointern herum, die auf ungünstigen Speicher zeigen.

    Raw Pointers und C++? Igitt, niemals.

    knivil schrieb:

    Loesung clang nehmen und schauen ob er Fehlermeldungen ausspuckt.

    I will try.



  • hohe-berge-saftige-wiesen schrieb:

    Raw Pointers und C++? Igitt, niemals.

    Und jetzt reden wir ueber Dogmen ... Rohe Zeiger sind in C++ nicht verpoent.



  • Vollständigen Code bitte. Erfahrungsgemäß hat die Stelle, an der Compiler aussteigt, meistens nichts mit dem zugrundeliegenden Problem zu tun.

    Der nächste Schritt wäre die Verwendung eines Debugbuilds von gcc.



  • knivil schrieb:

    Tja, irgendwo hantierst du mit Pointern herum, die auf ungünstigen Speicher zeigen

    Ach, dadurch stuerzt aber der Kompiler nicht ab. Dennoch sollte das bei einem korrekten C++-Programm nicht passiere.

    Oh, mein Fehler.
    Der Compiler hat nen SegFault, nicht das Programm.
    Schande über mich.



  • Ich brings net auf die Reihe Clang 3.3 zu installieren 😑

    Ich mach alles wie hier beschrieben, jedoch ab dem Punkt

    ../llvm/configure --prefix=/usr/clang_3_3 --enable-optimized --enable-targets=host
    

    bekomme ich folgendes gegen den Kopf geworfen:

    configure: error: Selected compiler could not find or parse C++ standard library headers.  Rerun with CC=c-compiler CXX=c++-compiler ./configure ...
    

    Und selbst wenn ich die Variablen CC und CXX setze, kommt immer noch die gleiche Fehlermeldung. Auch das hier hab ich vergeblich befolgt.

    Betrübt vorm Rechner sitzend,
    Hohe Berge und saftige Wiesen.



  • Also unter Fedora/Linux habe ich einfach nur yum install clang gemacht.



  • knivil schrieb:

    Also unter Fedora/Linux habe ich einfach nur yum install clang gemacht.

    Klar, ich auch, jedoch gibts bei meinem Ubuntu da nur die clang Version 3.0, und die versteht ein Haufen C++11-Features nicht - unter anderem kennt die den <type_traits> -Header nicht, von dem ich intensiv Gebrauch nehme.



  • Auch schon mal mit den "Clang Binaries for Ubuntu-12.04/x86 (67M)" von der Downloadseite probiert?



  • binni schrieb:

    Auch schon mal mit den "Clang Binaries for Ubuntu-12.04/x86 (67M)" von der Downloadseite probiert?

    Ja, jetzt eben, aber da muss ich die gesamte libc++ kompilieren und da weiß ich jetzt nicht genau wie ich das anstellen soll... Abgesehen davon bezweifle ich, dass clang3.2 das C++11-Feature "Inheriting Constructors" unterstützt was wiederum nach einem großen Umschreiben meines Programmes riecht.

    Abgesehen davon habe ich operator<< Mal auskommentiert und die Klasse so benutzt und das letzte bisschen Funktionalität rausgekitzelt - alles hat glatt funktioniert, bis ich dann den Operator mitkompiliere, dann krachts.

    Neben der title.hpp gibts auch noch eine entry.hpp (für einen Menüeintrag), bei dem die gleiche Leier vorliegt. Mit operator<< machts Bum und ohne läufts absolut einwandfrei.

    *schnief*
    Grüße.



  • btw, wenn ich (grad aus purer Freude mal getestet) operator>> statt operator<< verwende, funktionierts ganz prächtig.

    Nur dass std::cout >> mytitle; echt das allerletzte ist 😃



  • Tjo, nachdem ich nun weiß womit der G++ nicht klar kommt und es ausgerechnet von der is_printable<> -Klasse stammt muss ich nun wohl oder über meine Identität verraten 😃 (tu ich immer um potenziellem Flaming aus dem Weg zu gehen [falls ich denke, dass ich ne dumme Frage stellen muss]).

    Nun, in diesem Thread wurden mir bessere Implementierungen für die is_printable<> -Klasse vorgeschlagen, die ich dann so sehr ich konnte umgeändert und dann verwendet habe (Danke nochmals an einself und camper). Meine is_printable<> -Implementation sieht wie folgt aus:

    template<typename Type, typename = std::ostream&>
    class is_printable : public std::false_type {};
    
    template<typename Type>
    class is_printable<Type, decltype(std::declval<std::ostream&>() << std::declval<Type>())> : public std::true_type {};
    

    Jedoch scheint der Compiler nicht damit klarzukommen, wenn ich die Klasse wie folgt in meiner Title-Klasse (im Konstruktor) verwende:

    template<typename TitleType, typename LineType = std::string,
              typename = typename std::enable_if<is_printable<TitleType>::value && is_printable<LineType>::value>::type>
    title(const TitleType& title_name, const LineType& title_line = LineType())
        : ... {}
    

    Wenn ich jedoch folgendes mache...

    template<typename TitleType, typename LineType = std::string,
              typename = typename std::enable_if<true /*is_printable<TitleType>::value && is_printable<LineType>::value*/>::type>
    title(const TitleType& title_name, const LineType& title_line = LineType())
        : ... {}
    

    ...kommt der G++ damit klar.

    Um mir auch ganz sicher zu sein, dass der interne Compiler-Bug auch wirklich davon entsteht, habe ich diesen Prozess oftmals wiederholt, d.h. ich habe rund 10 - 20 Mal is_printable<TitleType>::value && is_printable<LineType>::value auskommentiert und durch true ersetzt und jedes Mal als ich das Zeug auskommentiert habe, war nichts mehr vom Compiler-Bug zu sehen. Jedes Mal wo ich die Kommentare wieder entfernt habe, tauchte der Bug wieder auf.

    Was ich komisch finde, ist, dass ich die is_printable<> -Klasse nicht nur in diesem Konstruktor verwende. Beispielsweise hat meine Title-Klasse eine Methode die wie folgt aussieht:

    template<typename Type, typename = typename std::enable_if<is_printable<Type>::value>::type>
    void set_name(const Type& title_name){
        name = nothrow_cast<std::string>(title_name);
    }
    

    Wobei hier kein Compiler-Bug zustande kommt.
    Ich kann sehr schlecht auf meine is_printable<> -Klasse verzichten, und möchte, dass das nun doch noch irgendwie damit funktioniert. Irgendwelche Vorschläge?

    Wer noch mehr Informationen braucht, muss einfach Bescheid sagen.
    Grüße.



  • Schritt 1: Aktuelle GCC-Version aus dem VCS auschecken und bauen (wenn du das nicht schon längst machst). Versuchen das Problem zu reproduzieren.

    Schritt 2: Wenn Problem immer noch vorhanden, Bugreport erstellen.



  • Schritt 0: den exakten Quelltext posten.



  • Eigentlich wollte ich dir zeigen, wie du dein typename enable_if<is_printable<A>::value && is_printable<B>::value>::type zu enable_if_printable<A, B> vereinfachen kannst, aber dann hat der Segmentation-fault auch mich heimgesucht.

    #include <type_traits>
    #include <tuple>
    
    template <typename T, typename... U>
    using all_same = std::is_same<std::tuple<T, U...>, std::tuple<U..., T> >;
    template <template<typename>class P, typename... T>
    using enable_if_all = typename std::enable_if<all_same<std::integral_constant<bool, P<T>::value>...>::value>::type;
    template <typename... T>
    using enable_if_printable = enable_if_all<std::is_arithmetic, T...>;
    
    template<typename A, typename B, typename = enable_if_printable<A, B> >
    void f(A,B){}
    
    int main(){f(1,1.1);}
    

    LC_ALL=C g++ -Wall -Wextra -pedantic -std=c++11 mwe.cc -o mwe
    mwe.cc:5:73: internal compiler error: Segmentation fault
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See <file:///usr/share/doc/gcc-4.7/README.Bugs> for instructions.
    Preprocessed source stored into /tmp/ccKCPEgY.out file, please attach this to your bugreport.

    Leider ist LWS gerade down, deshalb kann ich das nicht auf anderen GCCs testen. Mit clang gehts.



  • gcc hat noch ein Paar bekannte Probleme, im Zusammenhang mit variablen Templates und using.
    gcc 4.8. produziert hier normale Fehlermeldungen

    test.cpp: In substitution of ‘template<class T, class ... U> using all_same = std::is_same<std::tuple<_El0, _El ...>, std::tuple<U ..., T> > [with T = std::integral_constant<bool, P<T>::value>...; U = {U ...}]’:
    test.cpp:8:16:   required from here
    test.cpp:5:73: error: template argument 2 is invalid
     using all_same = std::is_same<std::tuple<T, U...>, std::tuple<U..., T> >;
                                                                             ^
    test.cpp:8:24: error: template argument 1 is invalid
     P<T>::value>...>::value>::type;
                            ^
    test.cpp:10:29: error: expected type-specifier before ‘enable_if_all’
     using enable_if_printable = enable_if_all<std::is_arithmetic, T...>;
                                 ^
    test.cpp:12:45: error: expected type-specifier before ‘enable_if_printable’
     template<typename A, typename B, typename = enable_if_printable<A, B> >
                                                 ^
    test.cpp:12:45: error: expected ‘>’ before ‘enable_if_printable’
    test.cpp: In function ‘int main()’:
    test.cpp:15:19: error: no matching function for call to ‘f(int, double)’
     int main(){f(1,1.1);}
                       ^
    test.cpp:15:19: note: candidate is:
    test.cpp:13:6: note: template<class A, class B, class> void f(A, B)
     void f(A,B){}
          ^
    test.cpp:13:6: note:   template argument deduction/substitution failed:
    

    Das ist zwar immer noch falsch, aber nicht das gesuchte Problem.



  • camper schrieb:

    Schritt 0: den exakten Quelltext posten.

    Klick

    alterbernd schrieb:

    Schritt 1: Aktuelle GCC-Version aus dem VCS[...]

    Nun... Ich hab noch nie was von der Abkürzung "VCS" gehört, könntest Du vielleicht noch schnell erläutern was das ist?

    einself schrieb:

    Leider ist LWS[...]

    Ich habs echt nicht so mit Abkürzungen 😃



  • Eine Abwandlung bringt bei mir sogar clang (3.2) zum Absturz. Während gcc (4.3.6, 4.4.7, 4.5.4, 4.6.3) ebenfalls mit ICE aussteigen, beschweren sich gcc 4.7.2 und 4.8.0 über Überschreitung der Instantiierungstiefe. Da könnte sogar etwas dran sein.

    template <bool, typename = void> struct enable_if {};
    template <typename T> struct enable_if<true,T> { typedef T type; };
    
    struct A {};
    
    template<typename T, typename = A&>
    struct trait
    { static const bool value = false; };
    
    template<typename T>
    struct trait<T, decltype(fun( (A()), (T()) ))>
    { static const bool value = true; };
    
    struct foo
    {
        foo() {}
        template<typename T>
        foo(const T&, typename enable_if<trait<T>::value>::type* =0)
        {}
    };
    
    A& fun(A, foo);
    A& fun(A, int);
    
    int main()
    {
        int x;
        foo y(x);
    }
    

Anmelden zum Antworten