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
|
|
YooSy |
» 2017-10-09 10:38:36 |
|
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?
|
|
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. |
|
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 :) |
|
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. 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 ); 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 ) ); configFile->seek( *( configDataPosition->getPackNamePosition() + 1 ) + 12 ); { uint diff = counter - *( configDataPosition->getPackNamePosition() + 1 ); if( diff != 0 ) { configDataPosition->setPackNamePositionAt( *( configDataPosition->getPackNamePosition() + 1 ) + diff, 1 ); diff = 0; } 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(); } ( * numbOfProjects ) ++; 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; ConfigFileStat * configFileStat = new ConfigFileStat; ProjectsParamNames * projectsParamNames = nullptr; * configFileStat = SEARCHING; 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; }
|
|
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 ?? prosto !!! QFile tempfile( "plik.txt" );
to niżej to już przegięcie :) 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)!!! |
|
dlakin95 Temat założony przez niniejszego użytkownika |
» 2017-10-09 12:32:51 Czyli pisanie delete nullptr może coś zrobić? |
|
« 1 » 2 |