----------------------------------------------------------------------------------
@MSGID: 2:5015/46 65bbb3ae
@REPLY: 2:5034/10.1 f950b269
@CHRS: CP866 2
@TZUTC: 0300
@TID: hpt/lnx 1.9.0-cur 2021-05-15
Hello, Sergey!
Thursday February 01 2024 10:14, from Sergey Anohin -> Nil A:
SA> Если ты читал историю эхи, там были всякие вопросы от меня касаемо
SA> memcpy, так что тут без дядей программистов никуда.
Нашёл письмо от 14го года, привожу ниже.
Таких багов с memcpy() мы недавно выправили в golded тоже.
Memcpy() копирует быстро, берёт байты из одного места, и копирует в
другое, но главное, чтобы эти буфера не пересекались.
Функция memmove() не накладывает ограничений, чтобы буфера не
пересекались, но и работает медленнее.
Где такие буфера с наложением встречаются в коде?
Вот выдуманный пример, есть текстовая строчка
(abc=123;bce=234;cde=345;def=456), делаем её char buf[256]. Задача удалить из серидины ";bce=234".
Заводим char *dst указывающий на ;bce=... и char *src на ;cde=...
Делаем копирование схлопывая эту дырку. memcpy(dst, src, strlen(src));
И потом `\0` закрываем новый конец строки.
Тут при копирование произойдёт наложение - где-то с def=.. мы уже
будем переписывать байтики на которые изначально указывал src.
Что случится? Правильный ответ - UB, или undefined behavior, значит
всё что угодно, любая комбинация или мусор может оказаться в строчке.
Заменить тут memcpy на memmove и поведение становится определённым, и
всё работает.
Как такие места найти?
а). Во время код-ревью внимательно вникать
б). Запустить под valgrind - он такие вещи отловит, но программа
выполняется оооочень медленно, потому что там виртуальная машина работает
в). Собрать с санитайзером адресов, gcc -fsanitize=address, замедление
программы будет небольшое, но будет, и тоже покажет проблемные места во время
выполнения программы
Я голдед собирал с пачкой санитайзеров разных
-fsanitize=address -fsanitize=leak -fsanitize=undefined
-fno-sanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow
-fsanitize=null
= ru.qico (2:5015/46) =========================================================
Msg : 12 of 258
From : Semen Panevin 2:5025/121 29 Nov 14 12:05:36
To : All
Subj : починил страшный баг
===============================================================================
Доброго здоровьица тебе, All!
После очередного апдейта компилятора и пересборки qico-xe в qcc появился
странный баг, по любому чиху (например создание poll или старт новой сессии)
открывались новые окна, а логи в них оказывались битые (например вместо 11 Nov
2014 писалось что-то типа 11 Nvvv2014)
Давно дело было, год а может и два назад, кажется я тут даже об этом писал.
Долго не мог понять что портит жизнь, и вот наконец дошли руки покопаться в
коде и поставить несколько следственных экспериментов.
Два дня ковыряния - и я таки выловил ошибку.
Там используется unsafe memcpy, с перекрытием буфферов, причём не только в
qcc-related коде, а это значит что аффектится не только морда, но вероятны
глюки и в работе самого мейлера.
Замена memcpy на memmove которая судя по документации safe решила эту проблему.
Последнюю известную мне версию qico-0.57.1-xe с этим фиксом по-прежнему можно
взять с svn
http://icelan.ru/svn/qicoxe/trunk
С наилучшими пожеланиями, Семён.
... Если человек родился, то это уж на всю жизнь... (c)...
+++ GoldED+/LNX 1.1.5-b20130910 (Linux 3.10.17-gentoo iF6M10)
- Origin: IceLAN (2:5025/121)
Best Regards, Nil
--- GoldED+/LNX 1.1.5
* Origin: Linux 2.6.32-042stab145.3 (2:5015/46)
SEEN-BY: 50/109 240/1120 301/1 341/66 455/19 463/68
467/888 4500/1 5001/100
SEEN-BY: 5005/49 5010/352 5015/42 46 255 5020/113
545 715 830 846 848 1042
SEEN-BY: 5020/4441 12000 5022/128 5030/49 115 1081
1900 5036/26 5053/51 58
SEEN-BY: 5054/8 5058/104 5061/133 5083/1 444
@PATH: 5015/46 5020/1042 4441