wxWidgets + linux + многопоточность(std) = ошибка сегментирования

Это русская секция форума wxWidjets. В этой секции вы можете обсуждать любые вопросы, связанные с wxWidgets на вашем родном языке.
Post Reply
p001
Earned a small fee
Earned a small fee
Posts: 18
Joined: Sun Aug 28, 2022 9:24 am

wxWidgets + linux + многопоточность(std) = ошибка сегментирования

Post by p001 »

Здравствуйте.

Имеем:
1. wxWidgets 3.2.2;
2. windows 10 x64;
3. debian 11.5 (virtualBox);
4. многопоточность (std );
5. socket tcp\ip.

Что не так:
1. В Win10 работает, в debian нет;
2. В debian при запуске через терминал выдает ошибку "ошибка сегментирования"

Что делал:
1. Пересматрел циклы с массивами и векторами. Вроде все нормально;
2. В конструкторе в самом конце создал цикл, в котором создаются события нажатия на кнопку "присоединиться", далее после обработки этого события вызывается метод, в котором создается соединение, включаются\отключаются кнопки и устанавливается текст:
Говнокод этого метода:

Code: Select all

void Class::makeConnection (int aI) {
 
    m_darrayDisconnectButton [aI] ->Enable (true);
 
    this->changeStatusConnect (aI);
 
    #ifdef windows1
        SOCKET socket1 = socket (AF_INET, SOCK_STREAM, 0);
        m_arraySocket [aI] = socket1;
    #endif // windows1
 
    #ifdef linux1
        int socket1 = socket (AF_INET, SOCK_STREAM, 0);
        m_arraySocket [aI] = socket1;
    #endif // linux1
 
    std::string stringIp = (m_darrayTextCtrlIp [aI] ->GetLineText (0)).ToStdString();
    std::string stringPort = (m_darrayTextCtrlPort [aI] ->GetLineText(0)).ToStdString();
 
    sockaddr_in addr1;
    addr1.sin_family = AF_INET;
    addr1.sin_addr.s_addr = inet_addr (stringIp.c_str());
    int intPort = stoi (stringPort);
    addr1.sin_port = htons (intPort);
 
    wxString wxStringResult (wxEmptyString);
    wxString wxStringResultPart1 (wxT ("111"));
    int attempt = 1;
    int codeCheck = 0;
 
    while (attempt < 4) {
        wxString wxStringAttempt = wxString::Format (wxT ("%i"), attempt);
        wxString wxStringResultPart2 (wxT ("/3"));
        wxStringResult = wxStringResultPart1 + wxStringAttempt
                                    + wxStringResultPart2;
 
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxStringResult);
        wxStringResult.clear();
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
 
        codeCheck = connect (m_arraySocket [aI], (sockaddr*)&addr1, sizeof (addr1));
 
        ++attempt;
 
        if (codeCheck == 0) {
            break;
        }
 
        if ( ! m_darrayDisconnectButton [aI] ->IsEnabled()) {
            codeCheck == -1;
            break;
        }
    } // while (attempt).
 
    if (codeCheck != 0) {
        #ifdef windows1
            closesocket (m_arraySocket [aI]);
        #endif // windows1
 
        #ifdef linux1
            close (m_arraySocket [aI]);
        #endif // linux1
 
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
 
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
        m_darrayConnectButton [aI] ->Enable (true);
        m_darrayDisconnectButton [aI] ->Enable (false);
 
        if (m_numberOfConnection == 0) {
            m_disconnectAllButton ->Enable (false);
            m_connectAllButton->Enable (true);
        }
        else if ( (m_numberOfConnection > 0)
                    | (m_numberOfConnection < m_numberOfMoxa) ) {
            m_disconnectAllButton ->Enable (true);
            m_connectAllButton->Enable (true);
        }
        else if (m_numberOfConnection == m_numberOfMoxa) {
            m_disconnectAllButton ->Enable (true);
            m_connectAllButton->Enable (false);
        }
    }
    else if (codeCheck == 0) {
        m_arraySendingError [aI] = false;
        m_arrayReceived [aI] = false;
        m_arrayReconnect [aI] = false;
 
        m_mutex1.lock();
            ++m_numberOfConnection;
        m_mutex1.unlock();
 
        m_arrayStatusStop [aI] = true;
        m_arrayStatusPause [aI] = false;
 
        if (m_darrayCheckBoxGeneralParameters [aI] ->IsChecked() ) {
            this->copyGenerallSettings (aI);
        }
 
        wxString wxStringPart1 (wxT ("111"));
        this->markTime ( (*m_darrayNameEquipments [aI] + wxStringPart1), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
 
        this->switchOnAcDc (aI);
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
        m_Graph->setColorGraph (aI, *m_darrayWxColor
                                                        [
                                    m_darrayChoiceColour [aI] ->GetSelection ()
                                                        ]);
 
        std::thread t1 (&Ses21::sendPackage, this, aI);
        t1.detach ();
 
        m_Graph->setCurrentGraph (aI);
 
        wxCommandEvent event1 (wxEVT_RADIOBUTTON,
                                        (m_darrayRadioButton [6])->GetId() );
        event1.SetEventObject (this);
        ProcessWindowEvent (event1);
 
        this->markTime (wxT ("111"), aI);
        m_matrixInstructionLog [aI] [m_arrayIndexInstructionLog [aI] ] = 1;
        ++m_arrayIndexInstructionLog [aI];
        m_darrayStatTextInfoBook2 [aI] ->SetLabel (wxT ("111"));
        m_darrayStatTextInfoBook1 [aI] ->SetLabel (m_darrayStatTextInfoBook2 [aI] ->GetLabelText() );
 
        this->markSettings (aI);
 
        this->enableParameters (true);
        this->enableParameters (true, aI);
 
        wxCommandEvent event2 (wxEVT_CHECKBOX,
                                    (m_darrayCheckBoxGeneralParameters [aI])->GetId() );
        event2.SetEventObject (this);
        ProcessWindowEvent (event2);
 
        this->enableButtons (m_buttonChange->GetId(), true);
        this->enableButtons (m_buttonStop->GetId(), true);
        this->enableButtons (m_buttonPause->GetId(), true);
        this->enableButtons (m_buttonStart->GetId(), true);
 
        this->enableButtons ( (m_darrayPingButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayStartButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayChangeButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayStopButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayPauseButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayDisconnectButton [aI])->GetId(), true);
        this->enableButtons ( (m_darrayConnectButton [aI])->GetId(), false);
 
        this->enableButtons (m_disconnectAllButton->GetId(), true);
        }
    }
}
3. Если закомментировать все строки у "else if (codeCheck == 0)" то прога запускается;
4. Если раскомментировать в "else if (codeCheck == 0)" 3 строки, в которых происходит установка значений в массиве, а остальные не раскомментировать, то прога стабильно не запускается и пишет "ошибка сегментирования". Видимо я неправильно понял как использовать многопоточность...

Вопросы:
1. Где я допустил ошибку(а если она в этом методе, то и в других) ?
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7060
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxWidgets + linux + многопоточность(std) = ошибка сегментирования

Post by ONEEYEMAN »

Dobrogo vremeni sutok,
A mogno na backtrace posmotret?

Spasibo.
User avatar
T-Rex
Moderator
Moderator
Posts: 1247
Joined: Sat Oct 23, 2004 9:58 am
Location: Zaporizhzhya, Ukraine
Contact:

Re: wxWidgets + linux + многопоточность(std) = ошибка сегментирования

Post by T-Rex »

Такие идеи есть: если идет обращение к контролам в конструкторе, то в Linux может не работать. Там контролы фактически создаются позже и надо ловить wxWindowCreateEvent и вот там уже можно обращаться к UI.
Попробуй перенести из конструктора для начала в обработчик какой-то кнопки. Если по кнопке будет работать, то переноси в криэйт евент хендлер.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7060
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxWidgets + linux + многопоточность(std) = ошибка сегментирования

Post by ONEEYEMAN »

T-Rex,
Sudja po opisaniju, v konstruktore tolko cepljaetsja obrabotchik sobytija nagatiaj na knopku.

2OP:
A mogete minimalnyj primer? I da - backtrace iz gdb neploho bylo by?

Spasibo.
Post Reply