Russian Qt Forum
Апрель 26, 2024, 18:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1] 2 3 ... 39
1  Qt / Многопоточное программирование, процессы / Re: Ошибка "Segmentation fault" : Апрель 04, 2024, 15:23
Крах программы наблюдается, когда я перед загрузкой новой конфигурации удаляю старые объекты контроллеров, использующих протоколы modbus rtu по протоколу TCP/IP. Это мой компонент (QModbusRtuClient), я сделал его на основе уже имеющихся в составе qtserialbus, исходники я публиковал где-то здесь. Ключевые фрагменты кода (не существенные части я пропускаю, отмечено '...'):

Код
C++ (Qt)
CModbusInterface::CModbusInterface(...) {
...
       //
       modbusDevice = new QModbusRtuClient(this);
...
}
 
CModbusInterface::~CModbusInterface(){
   if (modbusDevice) {
       modbusDevice->deleteLater();
   }
}
 

Фрагмент кода не должен приводить к краху по рассматриваемой причине.
Код в деструкторе лишний, так как при конструировании modbusDevice указан родитель this, который и управляет его временем жизни.

после чего сокетом формируется сигнал ошибки и отправляется уже удаленному modbusDevice. И программа валится.

Все сигнал слот соединения разрываются и все сообщения для modbusDevice удаляются из очереди обработки при его удалении.
Поэтому ситуации "сокетом формируется сигнал ошибки и отправляется уже удаленному modbusDevice" при корректной реализации быть не может.

Здесь на лицо проблема конкурентного доступа к экземпляру объекта. Обработка сообщений происходит в одном потоке, удаление объекта в другом.
Можно проверить это с помощью определения своего типа производного QModbusRtuClient, например, и вывода и сравнении информации о потоке в деструкторе и обработчиках сигналов.

Вариантов управления временем жизни не так уж и много:

  • объект на стеке - удалиться при потере области видимости в том же потоке, где был создан, независимо от потока обработки событий
  • член класса - удалиться вместе с экземпляром агрегата, независимо от потока обработки событий
  • умный указатель - удалиться вместе удаления умного указателя, независимо от потока обработки событий
  • Qt parent-child отношение - удалиться вместе с экземпляром родителя, независимо от потока обработки событий
  • new/delete - удалиться в вместе вызова delete, независимо от потока обработки событий
  • deleteLater - удалиться в потока обработки событий, независимо от других способов владения (кроме Qt parent-chaild)


Основное, вроде, перечислил.
Почти любая суперпозиция способов владения - крах программы с похожей проблемой, как здесь.

Удаление, изменение и т.д. конфигурации не должно приводить в краху программы. Решение задачу с помощью "отложенное удаление старой конфигурации ...", лишь усугубит ситуацию, так как проблема никуда не денется, а частота её появления уменьшиться.



2  Qt / Многопоточное программирование, процессы / Re: Ошибка "Segmentation fault" : Апрель 04, 2024, 08:21
Код
C++ (Qt)
QObject::connect(&archivingThread, &QThread::finished, archiving, &CServiceArchives::deleteLater);
 

Цитировать
If deleteLater() is called after the main event loop has stopped, the object will not be deleted.

Что-то подсказывает мне, что archiving никогда не удалиться), цикл обработки событий уже не работает.
Одна морока с этим moveToThread  В замешательстве

Конечно, хотелось бы увидеть весь проект или тестовый пример, или хотя бы стек вызовов по всем потокам.
3  Qt / Многопоточное программирование, процессы / Re: Ошибка "Segmentation fault" : Апрель 03, 2024, 15:21
И ещё... Если иcпользовался moveToThread, то удалять нужно через deleteLater(), чтобы удаление произошло в правильном потоке.
4  Qt / Многопоточное программирование, процессы / Re: Ошибка "Segmentation fault" : Апрель 03, 2024, 14:56
Или может сигнал слот взаимодействие через обычный AutoConnection, а потом используется moveToThread()?
А это имеет значение? Если да, то позор мне...  Грустный

Такие ошибки чаще всего связаны именно с этим. Значение имеет огромное.

Когда осуществляется connect по AutoConnection выбирается способ соединения в соответствии с потоками обработки событий объектов.
Если потоки одинаковые, то AutoConnection == DirectConnection.

После moveToThread объект меняет поток обработки событий, а соединения остаются связанными через DirectConnection.
События в одном потоке, сигнал слот в другом, отсюда следует UB в случае конкурентного доступа к полям экземпляра объекта.
И программа может упасть не обязательно из-за деструктора, а в любой момент в процессе работы.
А уж если деструктор вызвался, то практически гарантировано упадет (но есть случаи, когда может и не упасть)). UB оно такое).
5  Qt / Многопоточное программирование, процессы / Re: Ошибка "Segmentation fault" : Апрель 01, 2024, 08:37
Такое впечатление, что receiver не живой или почти не живой.
Базовый тип QObject выглядит подозрительно.

Нет ли сигнал слот взаимодействия через DirectConnection для объектов, связанных с разными потоками?
Или может сигнал слот взаимодействие через обычный AutoConnection, а потом используется moveToThread()?
6  Qt / Qt Quick / Re: Найти и выделить слово в TextArea : Март 28, 2024, 14:39
TextArea отображает разметку html, выделяемые слова можно поместить в теги, определяющие формат выделения.
7  Qt / Работа с сетью / Re: tcp proxy server. Только на berkley sockets (select/poll/epoll) : Январь 31, 2024, 11:10
И еще момент, лучше разделять запросы по ';' не смотря на 'SELECT'.
В SQL есть и другие команды, кроме выборки данных (SELECT). Улыбающийся

По хорошему да.., но ';' не обязателен в конце запроса. Поэтому про пример трафика и пишу.
Если явных признаков начала и конца нет, то парсер придется писать)).
8  Qt / Работа с сетью / Re: tcp proxy server. Только на berkley sockets (select/poll/epoll) : Январь 31, 2024, 10:58
При подключении нового клиента, выполняем подключение к серверу и после этого имеем пару сокетов client-proxy и proxy-server, вот все что приходит по первому сокету, нужно отправить во второй и наоборот. Если один из сокетов закрывается, то нужно закрыть и второй.
Как правило эти два сокета хранятся в объектах, которые называют session. Улыбающийся

Я тоже к такой схеме пришёл). Назвал объект только proxy_client.

Цитировать
Как мне узнать, что ответ получен не полностью и ожидается продолжение?

Нужно реальный трафик смотреть. В общем случае никак. Если в сети текст, то надеяться, что есть разделитель ";", либо по слову "SELECT" или другим косвенным признакам.
Если бинарный протокол, то его нужно знать, скорее всего, где-то длина пакета должна быть.
9  Qt / Работа с сетью / Re: tcp proxy server. Только на berkley sockets (select/poll/epoll) : Январь 30, 2024, 17:04
С сетью работал оочень давно). Похоже, что должно работать.

Цитировать
Необходимо распарсить сетевые пакеты, проходящие через
прокси, в которых содержатся SQL запросы, извлечь эти запросы из пакетов и записать их
в файл в виде текста (по одному запросу в строке, структура неважна)

Вот этой части не нашел. В обработчике только вывод в cout.

По идее SQL запросы необходимо собирать из сетевых пакетов.
При этом пакеты могут неожиданно разрываться и слипаться между собой.
Должен быть какой-то признак окончания запроса (м.б. символ";").
10  Разное / Говорилка / Re: Регистрация программы в Росреестре : Январь 19, 2024, 09:50
Коллеги,
прошло много времени, появиличь ли прецеденты регистрации программ на Qt в росреестре?

Да, мы регистрировали несколько продуктов в 2021-2023.
По моему, мы нанимали консалтинговую фирму для подготовки документов.
11  Qt / Вопросы новичков / Re: как правильно работать с Qt, чтобы не было утечек памяти? : Декабрь 11, 2023, 16:24
Проблема владения не редкий вопрос на форуме), например, Про деревянный айтем )). Паттерн parent-child, как раз про отношение часть-целое, отношение владения.

В архитектуре QObject владение child, вроде как, передается parent, а вроде как и нет. Никто не мешает удалить child напрямую, минуя parent. Такое вот двойное управление ресурсами.

Как следствие вопросы типа должен ли я озаботится о зачистке памяти?, так как интуитивно не понятно, в каком случае Qt почистит ресурсы, а в каком нет. Постоянно нужно в доки глядеть).
Но я уверен, что >90% разработчиков этот вопрос никак не волнует и интерпретируется даже, как удобство).

Цитировать
Слышал как-то это обходится "муванием". И как тогда удалять тот же виджет (чайлд)?

Можно и с move и без него. Удалять виджет следовало бы либо с помощью API владельца (parent), либо сначала извлечь child из parent, а затем удалять.
Здесь расписан пример реализации иерархии tree-example. Отношение parent-child реализована для класса Node.
12  Qt / Вопросы новичков / Re: как правильно работать с Qt, чтобы не было утечек памяти? : Декабрь 06, 2023, 10:34
Да уж наворотили в Qt всего Подмигивающий.

Архитектура Qt закладывалась во времена без unique_ptr, shared_ptr и move семантики.
Но вопросы владения ресурсами и механизм RAII никто не отменял.

Как разработчик будет управлять  ресурсами - это его дело.
Можно new/delete использовать и сырые указатели (типа классические), но это трудоемко в плане подчистки ресурсов. Как минимум нужно в деструкторе удалить, а желательно ещё учесть возможность обработки исключений. Умные указатели unique_ptr, shared_ptr и другие решают задачу подчистки ресурсов, с ними проще.

Разработчики Qt в своей архитектуре смешали вопрос иерархии экземпляров объектов и вопрос владения, заложив правило, что верхний в иерархии объект удаляет объекты ниже в иерархии. Это привело к тому, что в Qt традиционно используют сырые указатели. Тем не менее, сами разработчики Qt рекомендуют использовать unique_ptr для управления ресурсами (стандартный почти аналог QScopedPointer).

При использовании сырых указателей классической ошибкой новичков является не указание родителя у экземпляра объекта (чаще всего this)

Код
C++ (Qt)
QObject * obj = new QObject; // должно быть QObject( this )
 

В этом случае никто не владеет объектом, куда указывает obj => потенциальные утечки ресурсов памяти.

В случае с умным указателем

Код
C++ (Qt)
unique_ptr< QObject > obj = make_unique< QObject >();
 

ресурсом владеет умный указатель, который в любом случае удалит объект, на который указывает obj.
13  Qt / Вопросы новичков / Re: Работа с ком-портом в Qt : Ноябрь 09, 2023, 14:55
Здесь имеется несоответствие входящих параметров метода write, который принимает const char * или QByteArray, и результата метода text, который возвращает QString.

Нужно явное преобразование QString в QByteArray (сериализация), например в байты формата utf8.

Код
C++ (Qt)
serialPort.write(this->ui->txtInput->text().toUtf8() );
 

При приеме байт необходимо делать обратное преобразование из байт в текст (десериализацию) с помощью метода QString::fromUtf8.
14  Компиляторы и платформы / Windows / Re: Где приложению можно хранить свои файлы если запускаем не под администратором? : Ноябрь 07, 2023, 09:47
QStandardPaths в помощь.
15  Qt / Общие вопросы / Re: помогите пожалуйста разобраться с ошибками(клас наследованый от QPainter) : Август 22, 2023, 15:47
Если закрыть глаза  Шокированный на попытку смешать теплое и зеленое, то должно быть так

Код
C++ (Qt)
class Square
   : public QObject // всегда первый
   , public QPainter
{
   Q_OBJECT
public:
  Square(QObject* parent = nullptr);
  void drawSquare(QPoint point,QPoint point2,QPoint point3,QPoint point4);
};
 

Но  В замешательстве, не нужно смешивать средство рисования QPainter и объект с поведением.
QPainter всегда можно создать на лету с указанием устройства, на котором требуется рисовать.
Страниц: [1] 2 3 ... 39

Страница сгенерирована за 0.153 секунд. Запросов: 23.