Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Integer overflow  (Прочитано 501 раз)

Серега

  • Старожил
  • ****
  • Сообщений: 285
    • Просмотр профиля
Integer overflow
« : 11 Марта 2026, 16:51:38 »
Добрый день!
Анализируя журнал сервера наткнулся на ошибку с текстом:
Цитировать
Ошибка в скрипте "MinutestoHours" в строке 4. Integer overflow
Переходим к скрипту и видим 5 строк:
Код
begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
      Text := SecondsToStr(AsInt*60);
end.
Согласно руководству в функции SecondsToStr аргумент является:
function SecondsToStr(ASeconds: Int64): string;
с диапазоном из руководства -9223372036854775808…9223372036854775807

Обращаем внимание, что переменную берем как AsInt с диапазоном -2147483648…2147483647

Данный скрипт применяется много где, но:
- отрицательных значений нет ни где
- везде есть значения
- самое большое 51000
Предполагаем, что именно 51000 вызывает переполнение.
Считаем
51000 * 60 = 3 060 000 что на много меньше диапазонов всех указанных типов выше.
Можете подсказать, где закралась ошибка?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3210
    • Просмотр профиля
    • Simple-Scada
Re: Integer overflow
« Ответ #1 : 11 Марта 2026, 19:10:28 »
Здравствуйте.

Какая версия скады используется? Начиная с версии 2.7.4.0 в SecondsToStr можно использовать как минимум весь диапазон Integer.

pan2000

  • Постоялец
  • ***
  • Сообщений: 225
    • Просмотр профиля
Re: Integer overflow
« Ответ #2 : 13 Марта 2026, 07:24:28 »
Здравствуйте.

для начала нужно разделить ошибки функции и аргумента
Код: (delphi)
  j := AsInt*60;   // var j: integer;
  Text := SecondsToStr(j);

Цитировать
Предполагаем, что именно 51000 вызывает переполнение.
"Кофейная гуща" не поможет выявить ошибку :D. Для отлова ошибок (особенно редких) можно изменить скрипт:
Код: (delphi)
begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
    try
      Text := SecondsToStr(AsInt*60);
    except
      AddMessageToGroup(now, mkAlarm, 1, 'ошибка: объект ' + Name + '    переменная '
           + Variable.Name + ' = ' + AsStr + ' * 60 = ' + IntToStr(int64(AsInt) * 60)
           , true, false);
    end;
end.
Сообщение об ошибке будет в журнале сервера и, в несколько более детальном виде, в выделенной группе сообщений.
Проект контроля переполнений из примера можно не подключать к БД, при просмотре группы сообщений будет выдано предупреждение, но поступающие сообщения будут отображаться.
« Изменён: 15 Марта 2026, 18:03:56 от pan2000 »

Серега

  • Старожил
  • ****
  • Сообщений: 285
    • Просмотр профиля
Re: Integer overflow
« Ответ #3 : 24 Марта 2026, 13:08:56 »
Добрый день!
Немного заболел.
Как всегда pan2000 помог в решении вопроса. Теперь стало понятно в каком объекте какая переменная вызывает переполнение.
Возможная причина и в версии ПО. Сейчас 2.7.2.0, запланирован апдейт на 2.7.5.0 на этой неделе. После будет понятно, что проблема решена. План действий подготовлен.
Всем спасибо!