crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Выяснение причины падения приложения, при переключении вкладок
AD
  опции профиля:
сообщение 17.6.2009, 11:10
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Приложение имеет такой вид:

Вкладка имитации работы с пульта управления
[attachment=670:picture1.JPG]

Вкладка имитации работы с внешних устройств
[attachment=671:picture2.JPG]

Первая вкладка отличается от остальных 3-x передаваемым и принимаемым пакетом данных! Если сделать следующее действие: открыть порт (текущая вкладка - 1), переключиться на другую вкладку - то в 70% случаев приложение падает. Не могу найти причину падения. Как правило в отладчике выпадает в следующую функцию (мне неясно что там может упасть):

/// Проверка пакета, принятого от прожектора
void ManualControl::checkPacket()
{
    int value1 = VALFROMBYTES(inf_from_ed_packet.high_azim, inf_from_ed_packet.low_azim) / 10;
    sliderFactAzimuth -> setValue(value1);
    int value2 = VALFROMBYTES(inf_from_ed_packet.high_angle_elev, inf_from_ed_packet.low_angle_elev) / 10;
    sliderFactAngleElevation -> setValue(value2);

    QString pStrAzimuth(lblFactAzimuth -> text()), pStrAngleElev(lblFactAngleElevation -> text());
    pStrAzimuth = pStrAzimuth.simplified().section(QRegExp("[-0-9]"), 0, 0).simplified();
    pStrAzimuth += "                     ";
    pStrAzimuth += QString::number(value1);
    lblFactAzimuth -> setText(pStrAzimuth);
    pStrAngleElev = pStrAngleElev.simplified().section(QRegExp("[-0-9]"), 0, 0).simplified();
    pStrAngleElev += "     ";
    pStrAngleElev += QString::number(value2);
    lblFactAngleElevation -> setText(pStrAngleElev);

    readStateSpotlight();
}

По какой-то неизвестной мне причине падает либо на первой строчке c pStrAzimuth, либо на предпоследней.

А последний раз упало на функции readSpotlight
/// Чтение и разбор состояния прожектора
void ManualControl::readStateSpotlight()
{
    chkPwrIRNozzle -> setChecked(TESTBIT(inf_from_ed_packet.spotlight_state, 0));
    chkPwrLamp -> setChecked(TESTBIT(inf_from_ed_packet.spotlight_state, 1));
    chkSuccSpotlight -> setChecked(!TESTBIT(inf_from_ed_packet.spotlight_state, 2));
    chkSuccCoolSys -> setChecked(!TESTBIT(inf_from_ed_packet.spotlight_state, 3));
    chkStwPos -> setChecked(TESTBIT(inf_from_ed_packet.spotlight_state, 4));
    chkOrigPos -> setChecked(TESTBIT(inf_from_ed_packet.spotlight_state, 5));
    lblCtrlMode -> setText(TESTBIT(inf_from_ed_packet.spotlight_state, 6) ? "Man" : "Auto");
}


Сообщение отредактировал AD - 17.6.2009, 11:11
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 17.6.2009, 11:38
Сообщение #2


Старейший участник
****

Группа: Участник
Сообщений: 601
Регистрация: 2.2.2009
Пользователь №: 523

Спасибо сказали: 101 раз(а)




Репутация:   9  


В консоли при падении что-нибудь пишется?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 17.6.2009, 12:27
Сообщение #3


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Kagami @ 17.6.2009, 12:38) *
В консоли при падении что-нибудь пишется?

Про что именно? В дебаге сваливается в отладчик на гуишные кнопки и прочее, неясно при чем здесь они...

Первый пользовательский код, на который я выхожу с помощью стека еще и такой бывает временами:
[attachment=672:picture2.JPG]

А вот стек вызовов:
[attachment=673:picture1.JPG]
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 17.6.2009, 12:45
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Похоже на падение при отрисовке окна вызванной сменой state в checkbox'ах. Проверь с другими стилями. Библиотека Qt собиралась на той машине, где ты её тестируешь?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 17.6.2009, 13:14
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(SABROG @ 17.6.2009, 13:45) *
Библиотека Qt собиралась на той машине, где ты её тестируешь?

Да.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 17.6.2009, 14:59
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Ого... ошибка очень глубоко сидела!

Вот ошибочный код:
/// Циклическое чтение из COM-порта, пока не соберем пакет данных
INFO_FROM_EXTERN_DEVICE* ImitatorTSL::readCyclic()
{
    BYTE buffer[1] = {0}, finded_byte;
    BYTE *_buffer = new BYTE[INFO_FROM_EXTERN_DEVICE().length], *ch_buf = new BYTE[LED_PACKET().length];
    memset(_buffer, 0, INFO_FROM_EXTERN_DEVICE().length);
    memset(ch_buf, 0, LED_PACKET().length);

    _buffer[0] = INFO_FROM_EXTERN_DEVICE().header;
    register int i = 1, j = 0;
    QTime begining_time(QTime::currentTime());
    do {
        unsigned long len_result;
        ::ReadFile(COMPort::instanceCOM() -> comHandle(), buffer, sizeof(buffer), &len_result, 0);
        if(!len_result) break;
        finded_byte = findHeader(buffer, len_result, INFO_FROM_EXTERN_DEVICE().header);
        if(!finded_byte)
        {
            _buffer[i] = buffer[0];
            ch_buf[j] = buffer[0];
            ++i;    ++j;
        }
        int secs = begining_time.secsTo(QTime::currentTime());
        if(secs > 10) break;
        if(ch_buf[0] == LED_PACKET().header && ch_buf[1] == LED_PACKET().length &&
            ch_buf[2] == LED_PACKET().command_code)
            break;
    } while(finded_byte == 0);
    return (INFO_FROM_EXTERN_DEVICE*)_buffer;
}


В функции вначале выделяется память под буферы, в которых собираются пакеты при чтении из COM-порта данных. Чтение идет посимвольно.
В цикле идет чтение до тех пор, пока не встретиться заголовок след. пакета (условие выхода из цикла в while).
break-выходы из цикла происходят в 2 случаях:
1) если прочитывается не тот пакет;
2) если нет символа заголовка в течение 10 секунд.

Ошибка в следующем коде:
_buffer[i] = buffer[0];
            ch_buf[j] = buffer[0];
            ++i;    ++j;

Нет проверки на то, что i, j не выходят за пределы выделенных байт. В итоге, начинается чтение в чужую память -> рушится система выделения памяти.
В этом и была ошибка.

Сообщение отредактировал AD - 17.6.2009, 14:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 17.6.2009, 15:49
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

Спасибо сказали: 229 раз(а)




Репутация:   34  


Удивительно как ты вообще это нашел.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 17.6.2009, 15:50
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Подсказал сотрудник - мой начальник!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 30.12.2024, 14:55