Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[QT] Występowanie random'owego błędu segmentacji.

Ostatnio zmodyfikowano 2017-10-09 22:46
Autor Wiadomość
dlakin95
Temat założony przez niniejszego użytkownika
[QT] Występowanie random'owego błędu segmentacji.
» 2017-10-09 09:34:38
Cześć,

Mam problem z występowaniem błędu segmentacji w miejscach, gdzie nie powinien występować. Występuje głównie przy usuwaniu pamięci. Wydaje mi się, że problemem są meta-objecty.

Kod błędu przy wywalaniu programu:

Podpis problemu:
  Nazwa zdarzenia problemu: APPCRASH
  Nazwa aplikacji: DyplomProject.exe
  Wersja aplikacji: 0.0.0.0
  Sygnatura czasowa aplikacji: 59db225d
  Nazwa modułu z błędem: Qt5Widgetsd.dll
  Wersja modułu z błędem: 5.9.0.0
  Sygnatura czasowa modułu z błędem: 59282cff
  Kod wyjątku: c0000005
  Przesunięcie wyjątku: 00018418
  Wersja systemu operacyjnego: 6.1.7601.2.1.0.256.1
  Identyfikator ustawień regionalnych: 1045
  Dodatkowe informacje 1: c0ca
  Dodatkowe informacje 2: c0ca69c687f1c5b36e9eb00188c8eb87
  Dodatkowe informacje 3: f6fd
  Dodatkowe informacje 4: f6fd73168cc772d019ad9688ef171b7f

Przykłady błedów działania:
1) Błąd nie wystąpił, ale nie sconnectowało mi Widgeta, który należy do zupełnie innej klasy.

Proszę o szybką odpowiedź.
Z góry. Dzięki.

EDIT. Dodatkowo dla porównania umieszczam przykładowy inny błąd.
Różnice są jedynie:
-Sygnatura czasowa modułu z błędem
- Przesunięcie wyjątku
- Dodatkowe informacje

Podpis problemu nr.2 :
Nazwa zdarzenia problemu: APPCRASH
  Nazwa aplikacji: DyplomProject.exe
  Wersja aplikacji: 0.0.0.0
  Sygnatura czasowa aplikacji: 59db225d
  Nazwa modułu z błędem: Qt5Cored.dll
  Wersja modułu z błędem: 5.9.0.0
  Sygnatura czasowa modułu z błędem: 59282824
  Kod wyjątku: c0000005
  Przesunięcie wyjątku: 002cb9fc
  Wersja systemu operacyjnego: 6.1.7601.2.1.0.256.1
  Identyfikator ustawień regionalnych: 1045
  Dodatkowe informacje 1: cbee
  Dodatkowe informacje 2: cbeecd5dd0f5e18304591e448c9ff263
  Dodatkowe informacje 3: 442a
  Dodatkowe informacje 4: 442a08a511c9002ead9bfd44a1795e77
P-165563
YooSy
» 2017-10-09 10:38:36
Frazy, które należy wpisać w wyszukiwarkę google:
https://pl.wikipedia.org/wiki​/Naruszenie_ochrony_pami%C4%99ci
P-165564
dlakin95
Temat założony przez niniejszego użytkownika
» 2017-10-09 10:50:29
Rozumiem, czyli prawdopodobnie następuję przepełnienie stosu, ale czy można w jakiś sposób przechwycić ten błąd i sprawdzić co jest faktycznym powodem błędu?
P-165565
YooSy
» 2017-10-09 11:42:08
Bez kodu można tylko zgadywać.
Należy nauczyć się korzystać z debuggera. Zwrócić uwagę czy jest zwracany lokalny wskaźnik,
lub wyjście poza zakres tablicy lub jak już zwrócona została uwaga, przepełnienie stosu.
P-165566
mateczek
» 2017-10-09 11:45:02
Występuje głównie przy usuwaniu pamięci.
 Czyli są to miejsca gdzie może wystąpić, jeśli się to zrobi źle. Na 99% Masz błąd w kodzie. Ale po szczegóły do wróżbity macka :)
 
P-165567
dlakin95
Temat założony przez niniejszego użytkownika
» 2017-10-09 12:01:26
Jeśli było by to wyjście poza zakres tablicy, czy odniesienie się do złego adresu czy do nullptr, to bym to z łatwością wykrył. Kod jest wywoływany przeze mnie ten sam i raz wywali za 1, raz za 6, a raz za 20 razem. Ale błąd wywala mi głównie w funkcjach QT ( kod w asemblerze) i to za każdym razem w innym miejscu. Raz w QHash, raz przy disconnectowaniu, raz przy QMetaObject. I to nie jest tak, że wrzucam komuś kod do zrobienia za mnie, bo póki co już 6 godzin (od wykrycia problemu) siedzę i myślę.

Kodu myślę, że nie ma sensu wysyłać, bo jest rozległy ( ponad 7k linii kodu). Ale jak bardzo chcecie mogę wrzucić, tylko za dużo się z niego nie dowiecie.

C/C++
bool Config::addNewProject( bool defaultProject ) {
    QFile * configFile = new QFile( CONFIG_FILE );
    if( configFile->open( QIODevice::ReadOnly | QIODevice::Text ) ) {
        QFile * tempFile = new QFile( TEMP_FILE );
        if( tempFile->exists() )
             tempFile->remove();
       
        if( tempFile->open( QIODevice::WriteOnly | QIODevice::Text ) ) {
            unsigned long long counter = 0;
            QTextStream stream( tempFile );
            // Zapisywanie paczki danych [General]
            stream << "[General]\n";
            stream << "defaultPath=\"";
            stream << * defaultPath + "\"\n";
            stream << "numbOfProj=" + QString::number( * numbOfProjects + 1 ) + "\n";
            stream << "numbOfRec=" + QString::number(( * numbOfRecentProjects != 20 ) ?( * numbOfRecentProjects + 1 )
                : * numbOfRecentProjects ) + "\n";
            stream << "sort=" + QString::number(( uint ) sortingType ) + "\n";
            counter += CALCULATE_GENERAL_PACK_NAME_SIZE( 1,(( * numbOfRecentProjects != 20 ) ? 1
                : 0 ) );
           
            // Ustawianie pliku konfiguracyjnego (odczytywanego) na pierwszy projekt
            configFile->seek( *( configDataPosition->getPackNamePosition() + 1 ) + 12 );
           
            // Dostosowanie pozycji paczek danych + Dostosowanie pozycji projektów oraz recentów
            {
                uint diff = counter - *( configDataPosition->getPackNamePosition() + 1 );
                if( diff != 0 ) {
                    // Dostosowanie pozycji paczek danych
                    configDataPosition->setPackNamePositionAt( *( configDataPosition->getPackNamePosition() + 1 ) + diff, 1 );
                   
                    diff = 0;
                }
               
                // Zapisywanie nowego projektu z paczki danych [Projects]
                stream << "[Projects]\n";
                stream << "projectNumb=1\n";
                configDataPosition->addNewProjectPos( counter + 12 );
                configDataPosition->addNewRecentPos( counter + 27 );
                stream << "recentNumb=1\n";
                stream << "name=\"" + *( *( parent->getProjectInfo() ) )->getProjectName() + "\"\n";
                if(( *( parent->getProjectInfo() ) )->getObjectName() != nullptr )
                     stream << "fullscalePlantName=\"" + *(( *( parent->getProjectInfo() ) )->getObjectName() ) + "\"\n";
               
                stream << "path=\"" + *(( * parent->getProjectInfo() )->getPath() ) + "\"\n";
                stream << "default=" + QString::number((( * parent->getProjectInfo() )->isDefaultProj() ) ? 1
                    : 0 ) + "\n";
                counter += 70 +((( * parent->getProjectInfo() )->getObjectName() != nullptr ) ?( 23 +( * parent->getProjectInfo() )->getObjectName()->length() )
                    :( 0 ) );
                counter +=( * parent->getProjectInfo() )->getProjectName()->length() +( * parent->getProjectInfo() )->getPath()->length();
            }
            // Zwiększenie ilości projektów o 1
            ( * numbOfProjects ) ++;
           
            // Zwiększenie ilości recentów o 1, jeśli mniej niż 20
            if( * numbOfRecentProjects < 20 )
                ( * numbOfRecentProjects ) ++;
           
            char * tempChar = nullptr;
            tempChar = new char;
            * tempChar = '\0';
            QString * tempStr = new QString();
            unsigned long long * pos = new unsigned long long;
            uint projectsCounter = 1;
            bool rewrite = false;
            ushort recentCounter = 1;
           
            // Inicjowanie zmiennych sterujących
            ConfigFileStat * configFileStat = new ConfigFileStat;
            ProjectsParamNames * projectsParamNames = nullptr;
            * configFileStat = SEARCHING;
           
            // Odczyt pliku
            while( !configFile->atEnd() ) {
                if( configFile->getChar( tempChar ) )
                if( * tempChar == '\n' )
                     counter += 2;
                else
                     counter++;
                else
                     continue;
               
                switch(( uint ) * configFileStat ) {
                    case( uint ) SEARCHING
                        : switch(( uint ) * tempChar )
                    {
                        case( uint ) '\n'
                            : * configFileStat = SEARCHING;
                        stream << '\n';
                        break;
                        default:
                        * pos = counter - 1;
                        * configFileStat = READING_PARAMS;
                        tempStr->append( * tempChar );
                        break;
                    }
                    break;
                    case( uint ) READING_PARAMS
                        : if( * tempChar == '=' )
                    {
                        if( projectsParamNames == nullptr )
                             projectsParamNames = new ProjectsParamNames;
                       
                        if(( uint )( * projectsParamNames = checkProjectParamName( tempStr ) ) == UINT_MAX ) {
                            if( resetAndRestoreConfig( configFile ) ) {
                                configFile->setFileName( CONFIG_FILE );
                                configFile->open( QIODevice::ReadOnly | QIODevice::Text );
                                * configFileStat = SEARCHING;
                                tempStr->clear();
                                break;
                            } else {
                                delete projectsParamNames;
                                projectsParamNames = nullptr;
                                delete tempStr;
                                tempStr = nullptr;
                                delete tempChar;
                                tempChar = nullptr;
                                delete configFileStat;
                                configFileStat = nullptr;
                                delete pos;
                                pos = nullptr;
                                return false;
                            }
                        }
                        tempStr->append( * tempChar );
                        stream << * tempStr;
                        tempStr->clear();
                        * configFileStat = READING_VALUE;
                       
                       
                    } else {
                        tempStr->append( * tempChar );
                    }
                    break;
                    case( uint ) READING_VALUE
                        : delete tempStr;
                    tempStr = readValueAtStart( configFile, tempChar, & counter );
                    switch(( uint ) * projectsParamNames ) {
                        case( uint ) PROJECT_NUMB
                            :
                        {
                            projectsCounter++;
                            if( projectsCounter % 20 == 0 || projectsCounter == 1 ) {
                                if( projectsCounter > * numbOfProjects ) {
                                    uint size =( projectsCounter - * numbOfProjects ) * 0.05 + 1;
                                    unsigned long long * temp = new unsigned long long[ size ];
                                    for( uint i = 0; i < size - 1; i++ )
                                         *( temp + i ) = *( configDataPosition->getProjectsPosition() + i );
                                   
                                    *( temp + size - 1 ) = * pos;
                                    configDataPosition->setProjectsPosition( temp );
                                    rewrite = true;
                                    parent->getMainWin()->setProgressBarSLMaxReady( false );
                                    temp = nullptr;
                                } else {
                                    configDataPosition->setProjectsPositionAt( * pos, projectsCounter * 0.05 );
                                }
                            }
                            counter -= tempStr->length();
                            stream << projectsCounter;
                            counter += QString::number( projectsCounter ).length();
                            stream << * tempChar;
                        }
                        break;
                        case( uint ) RECENT_NUMB
                            :
                        {
                            ushort number = tempStr->toUShort();
                            if( number == 20 ) {
                                counter -= tempStr->length();
                                stream << "0";
                                counter++;
                                stream << * tempChar;
                            } else {
                                if( number != 0 ) {
                                    recentCounter++;
                                    if( number > * numbOfRecentProjects ) {
                                        unsigned long long * temp = new unsigned long long[ number ];
                                        for( uint i = 0; i < * numbOfRecentProjects; i++ )
                                             *( temp + i ) = *( configDataPosition->getRecentProjectsPosition() + i );
                                       
                                        *( temp + number - 1 ) = * pos;
                                        configDataPosition->setRecentProjectsPosition( temp );
                                        * numbOfRecentProjects = number;
                                        rewrite = true;
                                        temp = nullptr;
                                    } else {
                                        number++;
                                        counter -= tempStr->length();
                                        stream << number;
                                        counter += QString::number( number ).length();
                                        stream << * tempChar;
                                        configDataPosition->setRecentProjectsPositionAt( * pos, number - 1 );
                                    }
                                   
                                } else {
                                    stream << * tempStr;
                                    stream << * tempChar;
                                }
                            }
                           
                        }
                        break;
                    case NAME:
                        stream << "\"" + * tempStr + "\"";
                        break;
                    case FULLSCALE_PLANT_NAME:
                        stream << "\"" + * tempStr + "\"";
                        break;
                    case PATH:
                        stream << "\"" + * tempStr + "\"";
                        break;
                    case DEFAULT:
                        stream << * tempStr + "\n";
                        break;
                    }
                    * configFileStat = SEARCHING;
                    tempStr->clear();
                }
            }
            * configFileStat = SEARCHING;
            if( projectsCounter > * numbOfProjects ) {
                rewrite = true;
                * numbOfProjects = projectsCounter;
            }
            tempFile->close();
            configFile->close();
            if( rewrite )
                 rewriteGeneral();
           
            QFile backUpFile( CONFIG_BACK_UP_FILE );
            backUpFile.remove();
            configFile->copy( CONFIG_BACK_UP_FILE );
            delete tempChar;
            tempChar = nullptr;
            delete tempStr;
            tempStr = nullptr;
            delete pos;
            pos = nullptr;
            delete configFileStat;
            configFileStat = nullptr;
            delete projectsParamNames;
            projectsParamNames = nullptr;
        } else {
            QMessageBox::critical( nullptr, ERROR_CANT_OPEN_TEMP_FILE_TITLE, ERROR_CANT_OPEN_TEMP_FILE_DESCRIPTION, QMessageBox::NoButton, QMessageBox::Ok );
            delete tempFile;
            tempFile = nullptr;
            configFile->close();
            delete configFile;
            configFile = nullptr;
            return false;
        }
        configFile->remove();
        delete configFile;
        configFile = nullptr;
        tempFile->rename( CONFIG_FILE );
        delete tempFile;
        tempFile = nullptr;
    } else {
        QMessageBox::critical( nullptr, ERROR_CANT_OPEN_CONFIG_FILE_TITLE, ERROR_CANT_OPEN_CONFIG_FILE_DESCRIPTION, QMessageBox::NoButton, QMessageBox::Ok );
        delete configFile;
        configFile = nullptr;
        return false;
    }
    return true;
}
P-165568
mateczek
» 2017-10-09 12:15:48
tego co wkleiłeś rzecz jasna skompilować się nie da
ale skoro używasz kilka razy delete na tym samym obiekcje to sam prosisz się o problemy

po co ci te wskaźniki ??
C/C++
prosto !!!
QFile tempfile( "plik.txt" );

to niżej to już przegięcie :)
C/C++
char * tempChar = nullptr;
tempChar = new char;
* tempChar = '\0';
deklarujesz dynamicznie pamięć na jeden znak ??
Jestem prawie pewny, że w którymś momencie wywołujesz dwa razy delete na wskaźniku lub piszesz do skasowanego wskaźnika.

moim zdaniem kod do refaktoryzacji (przepisania na nowo)!!!
P-165569
dlakin95
Temat założony przez niniejszego użytkownika
» 2017-10-09 12:32:51
Czyli pisanie delete nullptr może coś zrobić?
P-165570
« 1 » 2
  Strona 1 z 2 Następna strona