Spread the love

Apple Platforms Patch для RAD Studio 10.4.1

    Компания Embarcadero выпустила второе обновление для RAD Studio 10.4.1 Sydney. Оно улучшает поддержку iOS 14, macOS 11 Big Sur (Intel) и XCode 12. Эти операционные

Читать на сайте автора.

Использование переменных среды в FireDAC

    Environment variables (переменные среды или переменные окружения) появились в 7-й версии Unix в 1979 году и с тех пор используются всеми операционными системами для хранения

Читать на сайте автора.

Добавление EurekaLog в программу вызывает Integer Overflow?

К нам обратился человек, который пожаловался на то, что его приложение работало нормально, пока он не добавил в него EurekaLog. После включения в проекте EurekaLog стало появляться исключение Integer Overflow. Исключение происходило внутри функции _UStrCatN (функция конкатенации нескольких строк в RTL).

Функция _UStrCatN написана на ассемблере, но если вникнуть в смысл проверок, то получится что-то такое:

  DestLen := {... вычисляется длина результирующей строки ...};      
if DestLen < 0 then
_IntOver;

где _IntOver — это функция RTL, которая и вызывает исключение Integer Overflow.

Что происходит? Как длина строки может быть отрицательной? Это баг в EurekaLog?

Указанная проверка внутри _UStrCatN должна ограничить строки 2 Гб памяти: если результат сложения всех строк будет больше 2 Гб, то произойдёт переполнение, и длина станет отрицательной. Таким образом, Integer Overflow при сложении строк может возникать, если результат слишком большой.

Но при чём тут тогда EurekaLog? И как проверка может срабатывать, если мы складываем небольшие строки? (клиент подтвердил это логом)

Такое «ложно-положительное» срабатывание возможно, если вы проводите операцию с уже удалённой строкой.

Посмотрите на такой код:

var
Marker: String;

function ReadLine: String;
begin
// ...
Marker := { ... };
// ...
end;

begin
// ...
Data := Data + Marker + ReadLine;
// ...
end;

Видите ли вы проблему в этом коде?

Чтобы понять проблему, нужно знать как выполняется строка «Data := Data + Marker + ReadLine;«. На псевдо-коде это выглядит как-то так:

Param0 := Pointer(Data);
Param1 := Pointer(Marker);
Param2 := Pointer(ReadLine);
_UStrCatN(Data, [Param0, Param1, Param2]);

Иными словами, оператор последовательно сохраняет указатели на аргументы, прежде чем вызвать функцию.

Вот вам и проблема: оператор сохраняет указатель на строку Marker, но строка Marker меняется внутри функции ReadLine. Это означает, что сохранённый указатель будет указывать на старую строку. Таким образом, на вход функции _UStrCatN попадёт уже удалённая строка.

Заметьте, что без EurekaLog в проекте этот баг не является «проблемой». Действительно, удалённая память просто помечается как свободная, но её содержимое не очищается. Это значит, что _UStrCatN успешно проведёт конкатенацию с уже удалённой строкой. И результат операции, скорее всего, будет корректным. Т.е. баг в коде есть, но его совершенно не видно, поскольку программа функционирует полностью правильно.

Ситуация меняется в корне, если в проект добавляется EurekaLog (или любой другой инструмент для отладки проблем с памятью). По умолчанию в EurekaLog включены проверки памяти. Это означает, что удалённая память будет очищена. Как правило, это делается шаблоном вроде DEADBEEF. Заметьте, что Integer представление DEADBEEF — отрицательно (равно -559038737). Т.е. прибавление к этому числу длин нескольких небольших строк также даст отрицательное число.

Иными словами, если в проект добавлена EurekaLog, то операция с уже удалённой строкой больше не будет успешной. Ранее скрытый баг теперь виден.

Читать на сайте автора.

Третий день DelphiCon Worldwide 2020

    Сегодня, 19 ноября, третий день DelphiCon Worldwide 2020 — официальной онлайн-конференции посвященной Embarcadero Delphi.

Читать на сайте автора.

Можно ли сэкономить набирая junior специалистов?

Дисклеймер №1: По стопам предыдущих двух статей «Эффективность по Skunk Works» и «У нас нет ресурсов для ревью кода»

Дисклеймер №2: Безусловно разделение на junior-middle-senior,

Читать на сайте автора.

Второй день DelphiCon Worldwide 2020

    17 ноября началась DelphiCon Worldwide 2020 — официальная онлайн-конференция посвященная Embarcadero Delphi. Для меня важнейшим результатом первого дня конференции была презентация Embarcadero RAD Studio, Delphi

Читать на сайте автора.

Embarcadero Delphi roadmap на 2020/2021

    Марко Канту обнародовал Delphi roadmap на 2020/2021 годы. В этом году больше релизов RAD Studio не будет. Версии RAD Studio 10.4.2 и 10.5 запланированы на

Читать на сайте автора.

DelphiCon Worldwide 2020

Сегодня, 17 ноября, стартует DelphiCon Worldwide 2020. Первые доклады: 18:00. Opening Keynote: The State of Delphi. Marco Cantù (Delphi Product Manager, Embarcadero Technologies).19:00. Delphi at

Читать на сайте автора.

Почему в выводе echo командной строки с перенаправлением появляется 1? Кто вставляет эти единицы?

Это перевод Why does my command line redirection echo with an extra 1? Who’s inserting these rogue 1s everywhere? Автор: Реймонд Чен.

Если вы оставите включённым

Читать на сайте автора.

Что делать с "W1000 Symbol ‘xyz’ is deprecated"?

    Иногда при компиляции старого проекта мы видим предупреждение компилятора «W1000 Symbol ‘xyz’ is deprecated: ‘Use NewXyz'». Что это значит, и как с этим бороться?

Читать на сайте автора.