Как быть с ошибками вида "function: 94A71D38"

Страницы: 1
RSS
Как быть с ошибками вида "function: 94A71D38"
 
В моих скриптах реализован перехват ошибок и печать информации об их причинах следующим образом:

Код
local status, errMessage = xpcall(function()
...
end, function(err)
  logger:error(tostring(err))
  logger:error(debug.traceback())
end)
if not status and errMessage ~= nil then
  logger:error(errMessage)
end

В обычных ситуациях возникновения ошибок по вине программиста в лог печатается информация об ошибке и трасса стека типа:

Код
2015-09-01 12:00:00.123 [ERROR] D:\Quik\lua\ScriptName.lua:123: Attempt to call method 'MethodName' (a nil value).
2015-09-01 12:00:00.123 [ERROR] stack traceback:
.....

Иногда (скажем, раз в неделю) скрипты падают с сообщениями вида:

Код
2015-09-01 12:00:00.123 [ERROR] function: 94A71D38
Поскольку трассы стека нет и сообщение об ошибке весьма краткое, полагаю, что это внутренняя ошибка QUIK. Как быть с ошибками такого вида? В идеале хотелось бы понять, что их вызывает и как быть, чтобы их больше не было.

Воспроизведение таких ошибок, по-видимому, весьма проблематично.

Разработчики QUIK могут как-нибудь помочь в этом деле?
 
по-моему это ошибка не квик, а луа скрипта, либо ,в крайнем случае , луа машины.
у меня так не падает, поэтому делаю вывод, что  проблема в Вашем скрипте.
 
Цитата
Николай Камынин пишет:
по-моему это ошибка не квик, а луа скрипта, либо ,в крайнем случае , луа машины.
у меня так не падает, поэтому делаю вывод, что проблема в Вашем скрипте.
Похоже, что это ошибка луа-машины. Выяснить бы, что является причиной: ошибки в самой луа-машине или недоработки в реализации связки QUIK + LUA. Во втором случае можно было бы надеяться на то, что такие недоработки будут исправлены. Жаль, что разработчики QUIK молчат по первому вопросу этой темы. Наверное, действительно, ничем не могут помочь.
 
Добрый день.
Для понимания нужен пример кода и версия терминала, на которой повторяется проблема.
 
Версия терминала 6.17.3.6. Ошибка возникла при торговле на десятке счетов при параллельной работе порядка 8 скриптов. Пример кода я предоставить не могу: реально эксплуатирующуюся систему показать невозможно, а модельного кода, где воспроизводится ошибка, у меня нет.
 
Реальный кусок кода с xpcall, который возвращает такую диагностику, можете привести ?
 
В первом сообщении темы написан фрагмент функции main(). В скрипте только один xpcall, перехватывающий ошибки на самом последнем уровне. Вместо многоточия идут вызовы инициализации скрипта, цикл while is_running, закрытие ресурсов. Поэтому предоставить содержательный код не могу.

Было бы неплохо при таком как у меня падении скрипта, создавать что-то типа dump-файла с внутренним состоянием lua-машины, чтобы разработчики могли хоть как-то понять, что пошло не так.
 
В скрипте используются какие-то сторонние библиотеки?
Так при использовании сторонних библиотек, скрипты в QUIK иногда могут падать с ошибкой "Unknown error."
Надо делать так, как надо. А как не надо - делать не надо.
 
попробуйте убрать  свой перехват ошибок.
возможно тогда ошибка вывалится в dump,
либо получите больше сообщений из перехвата луа машины.
 
еще можно попытаться найти function: 94A71D38 в таблицах луа машины:
 
Цитата
Николай Камынин пишет:
еще можно попытаться найти function: 94A71D38 в таблицах луа машины:
Полагаю ID функций меняется при каждом новом запуске скрипта.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
Старатель пишет:
В скрипте используются какие-то сторонние библиотеки?
Так при использовании сторонних библиотек, скрипты в QUIK иногда могут падать с ошибкой "Unknown error."
Применяется только gettime() из библиотеки Socket. Остальное всё самописное.
Цитата
Николай Камынин пишет:
попробуйте убрать свой перехват ошибок.
возможно тогда ошибка вывалится в dump,
либо получите больше сообщений из перехвата луа машины.
Такой вариант не удобен, т.к. свои ошибки тоже нужно контролировать с подробностями (трасса стека не пишется в окно об ошибках скриптов).

Вряд ли без помощи разработчиков QUIK и сохранения ошибок луа-машины в некий дамп можно что-то конструктивное сделать. (В Java, например, если виртуальная машина по какой-то причине падает с внутренней ошибкой, пишется некий err-файл, где хоть какие-то подробности приводятся.)
 
Цитата
_sk_ пишет:
Применяется только gettime() из библиотеки Socket. Остальное всё самописное.
Самописное в Lua-коде?
Цитата
Николай Камынин пишет:
попробуйте убратьсвой перехват ошибок.
возможно тогда ошибка вывалится в dump,
либо получите больше сообщений из перехвата луа машины.
Возможно действительно без xpcall получите больше информации об ошибке, и будет понимание, где искать.
Цитата
_sk_ пишет:
Такой вариант не удобен, т.к. свои ошибки тоже нужно контролировать с подробностями (трасса стека не пишется в окно об ошибках скриптов).
Код всё ещё модифицируется? Или не все "блохи отловлены"?
В любом случае, после того, как найдёте причину возникновения ошибки, вернёте xpcall.
Надо делать так, как надо. А как не надо - делать не надо.
 
Цитата
_sk_ пишет:
В первом сообщении темы написан фрагмент функции main(). В скрипте только один xpcall, перехватывающий ошибки на самом последнем уровне. Вместо многоточия идут вызовы инициализации скрипта, цикл while is_running, закрытие ресурсов. Поэтому предоставить содержательный код не могу.

Было бы неплохо при таком как у меня падении скрипта, создавать что-то типа dump-файла с внутренним состоянием lua-машины, чтобы разработчики могли хоть как-то понять, что пошло не так.
Наверное всё-таки придется написать короткий код с провокацией ошибки. Иначе с чем разработчиками разбираться?
 
Цитата
_sk_ пишет:
Вряд ли без помощи разработчиков QUIK и сохранения ошибок луа-машины в некий дамп можно что-то конструктивное сделать. (В Java, например, если виртуальная машина по какой-то причине падает с внутренней ошибкой, пишется некий err-файл, где хоть какие-то подробности приводятся.)
Без примера кода не получится разобраться. Я, например, не смог за разумное время повторить ошибку. Можете прислать код целиком, это тоже поможет в разборе.
Сохранять "дамп" не такая тривиальная задача как кажется. Например, как быть с различными данными типа userdata? Байт-код, состояние переменных и таблиц можно сохранить самому, все средства для этого у пользователя есть.
 
Код прислать не могу, т.к. политика безопасности не позволяет. Как написать короткий провоцирующий код, мне пока неясно, т.к. источник проблемы непонятен.

Исходя из того, что пишется в лог, происходит следующее.
1) При выполнении кода ... возникает ошибка, но почему-то до обработчика ошибок дело не доходит, иначе в логе было бы как минимум две строки: причина ошибки + трасса стека.
2) Обработчик ошибок ничего не возвращает, поэтому по спецификации луа переменная errMessage должна быть nil.
3) Однако, функция xpcall возвращает в качестве результатов пару false, "function: 94A71D38", поэтому срабатывает if и в лог печатается одна строка.

Выглядит это как внутренняя ошибка луа-машины, поскольку спецификация не соблюдена, а внутри своего кода я использую только стандартный луа-код (без dll, C API и пр.) и одну библиотеку Socket для получения времени с помощью функции gettime(). Возможно, что ошибка произошла при попытке вызвать обработчик ошибок, и так проявилась. Возможно, что это какой-то компьютерный сбой, не относящийся к QUIK и луа.

Я могу парсить errMessage и если он имеет вид "function.*", то выводить в свой лог ещё какие-то подробности о внутренностях луа-машины. Только я не знаю, что именно надо выводить. Если есть предложения -- напишите.

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

Код
except = require('except')

function logger_error(str)
  message(tostring(str))
end


function bad1()
   x = except.zero_divizion()
   return x
end

function bad2()
   x = except.null_pointer()
   return x
end

function err_handler(err)
  logger_error("Logger: " .. tostring(err))
  logger_error(debug.traceback())
end
function main()
   res, msg = xpcall(bad1, err_handler)

   if not res and msg then
     logger_error("call bad1: " .. tostring(msg))
   end
   
   res, msg = xpcall(bad2, err_handler)

   if not res and msg then
     logger_error("call bad2: " .. tostring(msg))
   end
end
 
результат выполнения в QUIK (стандартная Lua.exe просто разваливается)


При выполнении xpcall первой на стек кладется функция-обработчик ошибок. При возникновении критической ошибки, в данном случае ACCESS VIOLATION, работа завершается и мы наблюдаем вот такую картину.
Попробуйте на время избавиться от использования socket, если она Вам нужна только для получения системного времени, и понаблюдать за поведением.
 
Это хорошо, что Вам удалось воспроизвести ошибку. Только я не понял, это недоработка в QUIK или ошибка в Lua.

Цитата
Попробуйте на время избавиться от использования socket, если она Вам нужна только для получения системного времени, и понаблюдать за поведением.
Мне в программе нужно получать время с точностью до миллисекунд. У луа стандартная функция os.time() не даёт миллисекунд. Если бы в QLua была функция gettime() с миллисекундами, то можно было бы обойтись и без socket.
 
Можно добавить логирование непосредственно перед вызовом функции из socket:
Код
function getTime()
  toLog("Определяем текущее время...")
  local Time = socket.gettime()
  toLog("Текущее время: "..Time)
  return Time
end
Тогда при возникновении подобной ошибки будет ясно, виноват ли в этом socket.
Ну и держите нас в курсе   ;-)  , бо я думал, что с работой функции socket.gettime у QUIK давно нет проблем.
Надо делать так, как надо. А как не надо - делать не надо.
 
напишите свою dll для получения времени с квантом в 0.1 мкс c использованием RDTSC
и не будет заморочек с socket.
Страницы: 1
Читают тему
Наверх