[gelöst] QXmlSchemaValidator::validate() verursacht SegFault

Alles rund um die Programmierung mit Qt
Antworten
shinji
Beiträge: 23
Registriert: 28. Juli 2010 19:01

[gelöst] QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von shinji »

Hallo!

ich weiß ich nerve so ganz langsam... aber ich habe schon wieder ein Problem *lol*

Nachdem ich jetzt die Schemavalidierung in meinem anderen Thread zum Laufen bekommen habe wollte ich jetzt eine Methode implementieren, der ich ein QByteArray mit XML-Daten übergebe und in der Methode sollen die Daten dann gehen das Schema geprüft werden. Soweit alles super toll ;)

Folgendes Problem tritt auf:
Ich bekomme die Daten über einen TCP-Socket als QByteArray. So wie die Daten sind schicke ich diese an die folgende Methode meiner XMLValidator-Klasse:

Code: Alles auswählen

void XmlValidator::validate(const QByteArray xml)
{
    qWarning() << "Bekommen: " << xml;
    if ( schema.isValid() )
    {
        qWarning()  << "A";
        QXmlSchemaValidator validator( schema );

         qWarning()  << "B";

        if ( validator.validate( xml ) )
        {
            qWarning()  << "C1";
            qDebug() << "Instanz ist gueltig";
        } else
        {
            qWarning()  << "C2";
            qDebug() << "Instanz ist ungueltig";
        }
    } else
    {
        qWarning()  << "D";
        qDebug() << "Schema ist ungueltig";
    }
}
schema ist als Membervariable definiert. Wenn ich folgendes an die Methode schicke geht alles:

Code: Alles auswählen

<?xml version="1.0" encoding="UTF-8"?>
  <p>Hello World</p>
Durch Zufall habe ich aber die folgenden Daten gesendet:

Code: Alles auswählen

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  <p>Hello World</p>
Das fühert sofort in der Zeile

Code: Alles auswählen

validator.validate( xml ) 
zu folgenden Fehler:

Code: Alles auswählen

Bekommen:  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
  <p>Hello World</p>

" 
A 
B 
ASSERT failure in QMutexLocker: "QMutex pointer is misaligned", file ..\..\include\QtCore/../../../../../../ndk_buildrepos/qt-desktop/src/corelib/thread/qmutex.h, line 100
Invalid parameter passed to C runtime function.
Invalid parameter passed to C runtime function.
Erwartet hätte ich jetzt das der Validator mir lieb sagt, dass die XML-Daten falsch sind. Er hätte echt nicht gleich abstürzen müssen ;)

--edit--
Der stürzt übrigens auch dann ab, wenn ich ein "Hallo" als XML hinsende. :(
Was mache ich da bitte wieder falsch? :(

--edit2--
Selbst wenn ich es so mache wie in der Qt Reference Doku stürzt das dumme Ding ab! :

Code: Alles auswählen

void XmlValidator::validate(QByteArray xml)
{
    QByteArray data("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                    "<test></test>");

    QBuffer buffer(&data);
    buffer.open(QIODevice::ReadOnly);

    if ( schema.isValid() )
    {
        qWarning()  << "A";
        QXmlSchemaValidator validator( schema );

         qWarning()  << "B";

        if ( validator.validate( &buffer ) )
...
--edit3--
Es liegt wohl irgendwie am als Member angelegtem Schema in der Klasse. Wenn ich in der Methode selber statt des globalen 'schema' eine lokales anlege stürzt mein Programm nicht ab. Dies hier geht also:

Code: Alles auswählen

void XmlValidator::validate(QByteArray xml)
{
    QXmlSchema tmp_schema;
    file.reset();

    if (tmp_schema.load( &file, QUrl::fromLocalFile(file.fileName()) ))
    {
        file.reset();

        // Temp. Laden erfolgreich. Jetzt richtig
        tmp_schema.load(&file, QUrl::fromLocalFile(file.fileName()));
    }

    if ( tmp_schema.isValid() )
    {
        qWarning()  << "A";
        QXmlSchemaValidator validator( tmp_schema );

         qWarning()  << "B";

        if ( validator.validate( xml ) )
...
Woran liegt das? Ich möchte das ungern so machen. Meine Idee war halt, dass ich am Anfang 1x das Schemata einlese und dann immer wieder damit arbeiten kann. Wieso muss ich davon bei jedem mal ein neues Objekt anlegen? :shock:
Zuletzt geändert von shinji am 15. September 2011 14:46, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von Christian81 »

Und wie im vorigen Thread - ein minimales kompilierbares Beispiel (das hast Du uns imm vorigen Thread auch nicht gegeben sondern auch nur Codefragmente) und wir können uns das mal anschauen. Wenn es in der Qt-Doku so steht dann funktioniert das auch zu nahezu 100%. Also muss es an Dir liegen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
shinji
Beiträge: 23
Registriert: 28. Juli 2010 19:01

Re: QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von shinji »

Hallo!

Ich weiß, es liegt oft zu 99,9% an mir wenn was nicht geht :)
Aber es ist schwer ein kompilierfähiges Beispiel zu posten. Habe hier eine Konsolenapplikation die nur eine main() und meine Klasse enthält. Da läuft das alles super toll. Irgendwie scheint es daran zu liegen, dass ich das XmlValidator::validate() aus der MainWindow heraus aufrufe. Rufe ich das validate() innerhalb der XmlValidator::importXsdFile() Methode auf funktioniert das fehlerfrei.

Habe doch nichts anders gemacht als sonst:

1) mainwindow.h

Code: Alles auswählen

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
...
    XmlValidator *xml;
...
2) mainwindow.cpp

Code: Alles auswählen

MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
{
...
    xml = new XmlValidator();
...
Und dann habe ich in zwei Membermethoden jeweils das Schema laden lassen und dann Daten validiert:

Code: Alles auswählen

void MainWindow::laden()
{
    xml->importXsdFile("PFAD_ZUR_DATEI.xsd");
}

...

void MainWindow::validiere()
{
    QByteArray test("HAHGAGHFAGFGAHFGAHF");
    xml->validate(test);
}
Und ZACK... Absturz... :/
SirTwist
Beiträge: 3
Registriert: 15. Mai 2007 02:47

Re: QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von SirTwist »

Hi,

also ich habs nun versucht in einem Beispiel programm so zu bauen wie du das oben meinst und bei mir läufts super. Kannst du das tool bitte so anpassen das es so abstürzt wie bei dir?

die foo.xsd nach /tmp/ schieben oder den pfad im programm anpassen nicht vergessen.

Alternativ, sollte dein Programm über mehrere Threads verfügen, könnte es ein Problem mit einem Threadsprung sein, also du bist in einem Thread in dem xml noch nicht initialisiert ist. Könntest du das daher mal im debugger checken?

Cheers
Simon
Dateianhänge
foo.tar
Programmversuch um obiges nachzustellen
(1.88 KiB) 179-mal heruntergeladen
shinji
Beiträge: 23
Registriert: 28. Juli 2010 19:01

Re: QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von shinji »

Hallo Simon!

Wenn das so einfach wäre :(
Dein Programm funktioniert... außer das 2x false angezeigt wird.

Ich selber habe keine Threads angelegt. Was Qt intern macht weiß ich natürlich nicht.
Gibt mir noch mal deine private Mailadresse... eventuell kann ich dir mein Projekt ja mal zusenden und du schlägst mich dann wegen dem Anfängerfehler *lol*
shinji
Beiträge: 23
Registriert: 28. Juli 2010 19:01

Re: QXmlSchemaValidator::validate() verursacht SegFault

Beitrag von shinji »

Huhu!

Es geht jetzt. Klar war es mein Fehler. :roll:

In der importXsdFile() Methode hatte ich ein Objekt einer MessageHandler Klasse angelegt und den Message Handler über schema.setMessageHandler(&messagehandler) mit dem Schema verbunden. Innerhalb der importXsdFile() funktionierte das super. Allerdings hatte ich in der validate() Methode dann auf das Schema zugegriffen. Der Zugriff auf den Message Handler konnte da aber natürlich nicht mehr gelingen. Der war ja nach dem Verlassen der importXsdFile() nicht mehr verfügbar.

Das Problem trat dann deswegen auch nur in dem Fall auf, als die XML-Daten nicht valide waren.
Dann nämlich wird versucht, eine Fehlermeldung über das nicht mehr vorhandene Objekt abzusetzen und es knallt.

Daher war die Lösung sehr simpel: Der Message Handler wird jetzt als Member der Klasse angelegt und alles läuft super. ;)

Ich "liebe" diese Art von Fehlern. :P
Antworten