Приложение wxWidgets аварийно завершает работу в Arch Linux, но не в Windows

Я пытался создать приложение wxWidgets C++ под своей EndeavourOS (по своей сути это должен быть Arch Linux).

Моя среда рабочего стола — KDE Plasma (Wayland). Но те же проблемы возникают и в GNOME, и в XFCE.

Мне уже удалось скомпилировать C++-приложение wxWidgets под Windows.

Но в Linux моя скомпилированная простая программа:

// g++ main.cpp -o prog `wx-config --cppflags --libs`
#include <wx/wx.h>

class MyFrame: public wxFrame{
    public:
    MyFrame() : wxFrame(nullptr, wxID_ANY, "WxWidgets Linux Program") {
        wxPanel* mainPanel = new wxPanel(this);
        wxButton* cancel = new wxButton(mainPanel, wxID_ANY, "Cancel");
        SetClientSize(500, 50); // it seems that this makes the program crash
        Center(); // and this also
    }
};

class App : public wxApp {
public:
    bool OnInit() {
        MyFrame* w = new MyFrame();
        w->Show();

        return true;
    }
};

wxIMPLEMENT_APP(App);

...вылетает:

./prog: /usr/lib/libwx_gtk3u_core-3.2.so.0: no version information available (required by ./prog)
./prog: /usr/lib/libwx_baseu-3.2.so.0: no version information available (required by ./prog)
./prog: Symbol `_ZTV8wxButton' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV9wxControl' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV12wxButtonBase' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV11wxAnyButton' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV11wxPanelBase' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV7wxPanel' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV17wxMDIClientWindow' has different size in shared object, consider re-linking
./prog: Symbol `_ZTV7wxFrame' has different size in shared object, consider re-linking
Speicherzugriffsfehler (Speicherabzug geschrieben)
// english translation: Memory access error (memory dump written)

Program terminated with signal SIGSEGV, Segmentation fault.

Это трассировка стека, которую я получаю с помощью GDB:

User
(gdb) bt
#0  0x00006e6f74747562 in ??? ()
#1  0x00007ffff7950f43 in wxWindow::PreCreation (this=this@entry=0x55555566ef80, parent=parent@entry=0x555555724500, pos=..., size=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/gtk/window.cpp:2953
#2  0x00007ffff79533f3 in wxWindow::Create (this=0x55555566ef80, parent=0x555555724500, id=-1, pos=..., size=..., style=2621440, name=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/gtk/window.cpp:2841
#3  0x00007ffff77abf16 in wxPanelBase::Create (this=0x55555566ef80, parent=<optimized out>, id=<optimized out>, pos=<optimized out>, size=<optimized out>, style=<optimized out>, name=...) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/common/panelcmn.cpp:98
#4  0x0000555555564da0 in wxPanel::wxPanel(wxWindow*, int, wxPoint const&, wxSize const&, long, wxString const&) ()
#5  0x0000555555565b84 in MyFrame::MyFrame() ()
#6  0x0000555555565da0 in App::OnInit() ()
#7  0x0000555555563e79 in wxAppConsoleBase::CallOnInit() ()
#8  0x00007ffff70f1452 in wxEntry (argc=<optimized out>, argv=<optimized out>) at /usr/src/debug/wxwidgets/wxWidgets-3.2.4/src/common/init.cpp:481
#9  0x000055555556354b in main ()

Странно то, что следующий код работает нормально (за исключением того, что масштабирование окна иногда приводит к зависанию программы)

#include <wx/wx.h>

class App : public wxApp {
public:
    bool OnInit() {
        
        wxFrame* window = new wxFrame(NULL, wxID_ANY, "GUI Test", wxDefaultPosition, wxSize(600, 400));
        wxBoxSizer* sizer = new wxBoxSizer(wxHORIZONTAL);
        wxStaticText* text = new wxStaticText(window, wxID_ANY, "Well Done!\nEverything seems to be working",
            wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE_HORIZONTAL);
        text->SetFont(wxFont(20, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL));
        sizer->Add(text);
        window->SetClientSize(300, 300);
        window->SetSizer(sizer);
        window->Show();
        return true;
    }
};

какая у тебя версия wx? У вас такая же версия в винде? Вы сами собирали библиотеку или устанавливали ее из репозитория? Можете ли вы успешно собрать и запустить образец minimal, предоставленный вам библиотекой?

Igor 25.04.2024 21:37

Мое первое подозрение заключалось в том, что вы комбинируете разные заголовки и библиотеки (т.е. они могут не совпадать).

Christian Stieber 25.04.2024 21:42

@Igor Я использую версию 3.2.4.0 (согласно wx-config --version-full). ДЛЯ библиотеки - я установил wxwidgets через консоль, но это привело к ошибкам, которые я написал выше. Затем я сам собрал библиотеку (скачал самую последнюю версию с официального сайта wxWidgets), что привело к тем же проблемам. У меня та же версия wxwidgets в Windows, но это не имеет значения, поскольку предоставленный мной код запускался изолированно, в новом каталоге под Linux. К сожалению, я не очень понимаю, как собрать минимальный образец. По крайней мере, я нашел его сам (новичок здесь).

tbone 26.04.2024 18:20

@ChristianStieber, судя по другим комментариям ниже, я сам теперь в это верю. Но как я могу проверить, где я ссылаюсь на неправильные библиотеки? Я очень озадачен тем, почему каждое руководство yt, в котором показано, как скомпилировать простую программу wxwidgets, не работает только на моей машине.

tbone 26.04.2024 18:22

@tbone, используйте менеджер репозитория, который использует ваш дистрибутив, для удаления установленной вами библиотеки. Избавьтесь от него полностью. (Скорее всего, он находится внутри /usr/lib{64}/wx. Если вы запускали make install, запустите make distclean из каталога сборки. Или, если хотите, переустановите ОС. Загрузите исходные коды и соберите ее вручную. Дон не запускаю make install. Теперь выполните - "g++ *.cpp -o test ``/full/path/to/wx-config --cxxflags --libs`"

Igor 26.04.2024 20:16

@tbone, идея состоит в том, чтобы на машине была только одна копия wxWidgets. В ответе я постараюсь дать вам пошаговые инструкции по сборке библиотеки и образца.

Igor 26.04.2024 20:18
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
6
154
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я согласен с анализом, что, скорее всего, имеет место нарушение ODR. Скорее всего (с этим воспроизводителем) это вызвано конфликтом версий библиотек во время сборки и выполнения.

На моем компьютере NixOs я построил простую оболочку nix:

NixOs отлично справляется с разделением зависимостей, но в обычном Linux пути не будут уникальными, и вместо этого вы можете увидеть что-то вроде /usr/lib/x86_64/libwx_gtk...-.so, связанное с определенной версией. Если это не та версия, которую вы используете, вы рискуете UB из-за нарушения ODR.

Обратите внимание, что речь не обязательно идет о версиях Wx/GTK. Это может быть любая зависимость компоновщика во время выполнения.

Примечание:

  • interactive Gnome3/Wayland demo

  • interactive KDE Plasma5/Wayland demo

ПС. Я управляю Hyprland/Wayland. Также протестирую под Gnome/Wayland на случай, если помешает какая-нибудь странная ошибка Wx.

sehe 25.04.2024 21:57

Нет проблем в Gnome/Wayland imgur.com/a/D7mybFT

sehe 25.04.2024 22:02

Также нет проблем на Plasma5/Wayland imgur.com/a/D7mybFT . Я отмечаю, что жестко закодированный размер (500, 50) кажется меньше минимальной высоты в соответствии с интерактивным изменением размера Plasma5 (см. сами в видео). Вполне возможно, что это как-то связано с этим. Моя плазменная оболочка — v5.27.11. Возможно, в этой области уже исправлена ​​ошибка GTK или оконного менеджера?

sehe 25.04.2024 22:20

Почему вы игнорируете предупреждения о несовместимости ABI, которые вы получаете и которые явно указывают на проблему?

Вы ничего не говорите о том, как вы создаете свое приложение, но эти сообщения недвусмысленно показывают, что оно использует библиотеки, не соответствующие заголовкам, с которыми оно было скомпилировано. Вам необходимо исправить это, гарантируя, что вы связываетесь с правильными библиотеками и что во время выполнения обнаруживаются одни и те же библиотеки (а не какой-то другой вариант).

Уважаемый ВЗ., хм, кажется, сноску на моих вопросах "я во всем этом чертов новичок" удалили. Я не игнорировал предупреждения. Я просто не понимаю таких. Зачем быть таким токсичным? Как я могу обеспечить правильное связывание - как мне вообще узнать, какой файл библиотеки вызывает проблему?

tbone 26.04.2024 18:24

@tbone VZ не токсичен. Он однозначно говорит, в чем проблема. Вместо того, чтобы обижаться, примите, что он прямо ответил на ваш заданный вопрос. Если вам нужна помощь в понимании ответа, просто попросите об этом.

Dúthomhas 26.04.2024 20:46
Ответ принят как подходящий

Чтобы собрать библиотеку и минимальный образец:

cd wxWidgets 
mkdir buildGTK
cd buildGTK
../configure --enable-debug --with-gtk && make -j4
cd samples/minimal
make
./minimal

Это должно собрать библиотеку и минимальный образец.

Сообщите нам, если во время этого процесса возникнут какие-либо ошибки.

Помните - это должно быть сделано в "чистой среде" - без установленной версии wxWidgets.

Затем, когда все будет завершено и у вас будет запущен минимальный образец, выполните:

g++ *.cpp -o test `/full/path/to/wx-config --cxxflags --libs`

Невероятно – это сработало! Что я еще сделал, так это удалил остатки других установок wx, но я просто использовал путь к папке buildGTK, когда дело дошло до части wx-config, и — бум! Однако собрать минимальный образец с помощью последней команды g++ не удалось, но, тем не менее, мой пример кода заработал! Я до сих пор не понимаю, что я мог сделать не так, установив wxwidgets, как указано во всех видео на YouTube. Что ж, думаю, теперь мне придется удалить все предыдущие wxwidgets и попытаться установить wxWidgets buildGTK где-нибудь на моем диске :)

tbone 29.04.2024 20:49

@tbone, пожалуйста, поймите - я не предлагал создавать сэмплер minimal с помощью g++. Все, что я сделал, это посоветовал вам перейти в каталог buildGTK/samples/minimal и ввести команду make. Команда g++, на которую вы ссылаетесь, предназначена для вашего собственного кода. Но вам больше не нужно создавать образец. Просто сохраните библиотеку, которую вы собрали, и все будет в порядке.

Igor 29.04.2024 21:48

@tbone, также имейте в виду, что создание образцов - это всегда хорошая идея: они покажут вам, на что способна текущая версия, и помогут вам проверить функциональность, если вам понадобится воспроизводитель для чего-то, что не удалось.

Igor 29.04.2024 21:50

Ах, теперь я также вижу, что неправильно понял последнюю часть, где я думал, что мне нужно/можно использовать g++, чтобы снова построить минимальный образец. Но я знаю — мне не нужен минимальный пример для моих проектов. Вчера я взял вашу команду g++ и поместил ее в свой проект, и вуаля, она сработала :D Теперь я также понял важность этих примеров. Большое спасибо :)

tbone 30.04.2024 08:28

@tbone, да, вот оно. Единственная причина, по которой я упоминаю инструкцию по сборке minimal, заключается в том, что люди путают Makwdile в каталоге примеров и каталоге сборки на nox. Но вам это не нужно, так как все работает.

Igor 01.05.2024 02:28

Другие вопросы по теме