Падение QUIK с General Protection Fault

Страницы: 1
RSS
Падение QUIK с General Protection Fault, DestroyTable() и Clear() при вызове из функции обратного вызова для обработки событий в таблице
 
Обнаружил ситуацию, которая изредка приводит к аварийному завершению Квика.

Стояла задача: при клике по строке таблицы-1 требуется таблицу-1 закрыть, а вместо неё открыть новую таблицу-2 (например, провалиться глубже по дереву).
Хоть это мне сразу и показалось не очень красиво, но попробовал сделать эти действия прямо из коллбэка Таблицы-1.
В нём вызывается DestroyTable(1) и создаётся CreateWindow(2)
Написал, потестировал - работает.
Но работает не на 100% хорошо. Через пол-года обнаружилось, что изредка, примерно в 1-2% случаях Квик падает.

(см. рис)


Долго искал, в чём причина.
Решил, что дело в том, что в каких-то редких случаях коллбэк после отработки пытается зачем-то вернуться к своей родительской таблице, которую он сам же только-что уничтожил.
Переписал скрипт так, что коллбэк только создаёт новую таблицу-2, а для старой таблицы-1 делается пометка, по которой уже после отработки коллбэка в основном цикле уничтожается происходит  DestroyTable(1).
Теперь ошибка не проявляется.

Также плохо иногда может заканчиваться вызов из коллбэка  функции Clear(1) для родительской таблицы.

Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable()  и  Clear()  
 
У меня кстати тоже иногда стали появляться такие ошибки!
Но я никак не мог понять , из-за чего, потому что у меня таблицы пересоздаются очень редко, и без моего нажатия на какие-либо кнопки.
Послежу, в каких случаях это происходит. Спасибо за мысль!  
 
Но в версиях до 7.6 ничего подобного никогда не происходило, хотя макрос в части пересоздания таблиц никак не менялся.  
 
Цитата
Антонио написал:
Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable()  и  Clear()

Надо не в документации писать, а разбираться с причинами падения.
В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
По нему мы сможем провести анализ.
 
Причина интересна, но как временное решение может попробовать не уничтожать/создавать таблицу, а скрывать/показывать, очищая/меняя содержимое?
 
Цитата
Sergey Gorokhov написал:
Цитата
Надо не в документации писать, а разбираться с причинами падения.
В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
dmp-файл отправил.

Цитата
Sergey Denegin написал:
Но в версиях до 7.6 ничего подобного никогда не происходило, хотя макрос в части пересоздания таблиц никак не менялся.
Почти согласен: для моего случая до версии 7.6 падение происходило крайне редко - нельзя сказать, что его не было вообще, а с версией 7.6 - это стало действительно проблемой, которую надо решать.
Цитата
vgi написал:
как временное решение может попробовать не уничтожать/создавать таблицу, а скрывать/показывать, очищая/меняя содержимое?
Я нашёл для себя решение - оно меня устраивает. Закрываемая таблица исчезает не мгновенно перед созданием новой, а с небольшой задержкой не более секунды (в основнов цикле стоит Sleep на 1 секунду).
Что касается "очищая/меняя содержимое" - то
1)  вызов Clear() из колбэка также иногда ведёт к падению
2) новая таблица-2 у меня должна иметь другой состав колонок, и, может я не до конца разобрался, но в уже созданной таблице поменять состав колонок возможности нет и нужно только уничтожать и создавать новую
 
Цитата
Антонио написал:
В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
Помню один раз потратил время и по просьбе службы поддержки отправлял целую копию квика (уже не помню по какой проблеме), но ответа так и не получил. А прошло наверно больше года.
так что веры в то, что стоит тратить время на отправку дампа тоже нет.  
 
Цитата
Sergey Denegin написал:
Цитата
Антонио   написал:
В сообщении, скриншот которого Вы приводите, сказано о необходимости отправить нам dmp файл.
Помню один раз потратил время и по просьбе службы поддержки отправлял целую копию квика (уже не помню по какой проблеме), но ответа так и не получил. А прошло наверно больше года.
так что веры в то, что стоит тратить время на отправку дампа тоже нет.
Добрый день.

Проверьте свой почтовый ящик, при попытке отправки на него приходит ответ что превышена некая квота.
 
Разобрались в этом вопросе по почте.
Вот сегодня у меня случился как раз перезагруз квика по такой ошибке.
Отправил файл info_20170220_140947.dmp на почту quiksupport@arqatech.com
Надеюсь поможет разобраться в проблеме.  
 
Цитата
Sergey Gorokhov написал:
Цитата
Антонио   написал:
Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable()  и  Clear()
Надо не в документации писать, а разбираться с причинами падения.

Гы.. Начиная с 7.10 в документацию-таки добавили:
Цитата
SetTableNotificationCallback

Задание функции обратного вызова для обработки событий в таблице.

ВАЖНО! Недопустим вызов функций Clear и DestroyTable для t_id внутри функции обратного вызова f_cb, назначенной на таблицу с данным t_id.

Всегда использовал шаблон:
Код
SetTableNotificationCallback(t_id, function(t_id, msg, par1, par2)
  if msg == QTABLE_CLOSE then
     DestroyTable(t_id)
  end
end
и тут на тебе: чё-то поломали и "недопустимо"..
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель написал:
Цитата
Sergey Gorokhov   написал:
Цитата
Антонио   написал:
Наверное, если я прав, имеет смысл в документации указать, что не надо из коллбэка вызывать DestroyTable()  и  Clear()
Надо не в документации писать, а разбираться с причинами падения.
Гы.. Начиная с 7.10 в документацию-таки добавили:
Цитата
 SetTableNotificationCallback  

Задание функции обратного вызова для обработки событий в таблице.

ВАЖНО! Недопустим вызов функций Clear и DestroyTable для t_id внутри функции обратного вызова f_cb, назначенной на таблицу с данным t_id.
Всегда использовал шаблон:
Код
   SetTableNotificationCallback (t_id,  function (t_id, msg, par1, par2)
   if  msg  =  =  QTABLE_CLOSE  then 
      DestroyTable (t_id)
   end 
 end   
и тут на тебе: чё-то поломали и "недопустимо"..
а чему тут удивляться? Идёт вызов колбека и внутри него вы разрушаете его контекст. Конечно нельзя.

использование команды format c: /y внутри командного файла windows тоже приведет к проблеме с дальнейшим выполнением команд из этого командного файла. Правда в последних версиях windows система откажется от суицида )
www.bot4sale.ru

Пасхалочка для Алексея Иванникова: https://forum.quik.ru/messages/forum10/message63088/topic7052/#message63088
 
А точно требуется вызывать DestroyTable для таблицы, связанной с окном, которое и так закрывается?
Я думал таблица при этом автоматически уничтожится.
Или это не так?
 
Цитата
swerg написал:
А точно требуется вызывать DestroyTable для таблицы, связанной с окном, которое и так закрывается?
Я думал таблица при этом автоматически уничтожится.

Часть данных остаётся в памяти, что демонстрирует данный скрипт:
Код
function main()
  t_id = AllocTable()
  message(tostring(t_id))
  AddColumn(t_id, 1, 'Колонка1', true, QTABLE_STRING_TYPE, 20)
  AddColumn(t_id, 2, 'Колонка2', true, QTABLE_STRING_TYPE, 20)
  CreateWindow(t_id)
  while t_id do
    if IsWindowClosed(t_id) then CreateWindow(t_id) end
    sleep(100)
  end
end
Поэтому, если таблица более не нужна, я её Destroy
Надо делать так, как надо. А как не надо - делать не надо.
Страницы: 1
Читают тему
Наверх