2011-07-27

vak: (Default)
Рыться в древних исходниках - увлекательное занятие. На днях исправил забавную ошибку в /bin/sh (из Unix версии 2.11BSD). Свободная память хранится в виде односвязного списка, проход по которому включал следующий фрагмент:
struct blk {
    struct blk *word;
} *p, *q;

#define busy(x) ((int)(x)->word & 1)

p = ...;
while (! busy (q = p->word)) {
    p->word = q->word;
}
Прелесть в том, что конец списка может быть нулём. В цикле - хотя это не очевидно из текста - по нулевому указателю будет извлечено слово и проверен младший разряд. Если там окажется единица - нам повезло, иначе система зацикливается. На PDP-11 по нулевому адресу располагалась инструкция SETD с кодом 0170011, и шелл прекрасно работал. На симуляторе MIPS32 тоже работал первое время, пока конфигурация не изменилась.