Циклон язык программирования предназначен , чтобы быть безопасным диалектом языка C . Cyclone разработан, чтобы избежать переполнения буфера и других уязвимостей, которые возможны в программах на C, без потери мощности и удобства C как инструмента для системного программирования .
Разработано | AT&T Labs |
---|---|
Впервые появился | 2002 |
Окончательный релиз | 1.0 / 8 мая 2006 г . |
Веб-сайт | cyclone |
Под влиянием | |
C | |
Под влиянием | |
Ржавчина , Проект Верона |
Разработка Cyclone была начата как совместный проект AT&T Labs Research и группы Грега Моррисетта в Корнелле в 2001 году. Версия 1.0 была выпущена 8 мая 2006 года.
Особенности языка
Cyclone пытается избежать некоторых распространенных ошибок C , сохраняя при этом внешний вид и производительность. С этой целью Cyclone накладывает следующие ограничения на программы:
NULL
вставлены проверки для предотвращения ошибок сегментации- Указатель арифметики ограничен
- Указатели должны быть инициализированы перед использованием (это обеспечивается определенным анализом присваивания )
- Висячие указатели предотвращаются за счет анализа области и ограничений на
free()
- Разрешены только "безопасные" слепки и союзы.
goto
в объемах запрещеноswitch
ярлыки в разных областях запрещены- Функции, возвращающие указатель, должны выполняться
return
setjmp
иlongjmp
не поддерживаются
Для поддержки набора инструментов, к которому привыкли программисты на C, Cyclone предоставляет следующие расширения:
- Никогда-
NULL
указатели не требуютNULL
проверок - "Жирные" указатели поддерживают арифметику указателей с проверкой границ времени выполнения
- Расширяемые области поддерживают безопасное ручное управление памятью
- Сборка мусора для значений, выделенных в куче
- Помеченные объединения поддерживают аргументы, зависящие от типа
- Инъекции помогают автоматизировать использование помеченных объединений для программистов
- Полиморфизм заменяет некоторые виды использования
void *
- varargs реализованы как жирные указатели
- Исключения заменяют некоторые варианты использования
setjmp
иlongjmp
Чтобы получить более полное представление о Cyclone, обосновании Cyclone и источнике этих списков, см. Этот документ .
Cyclone в целом похож на C , но его следует рассматривать как язык C-подобный.
Типы указателей
Cyclone реализует три вида указателя :
*
(нормальный тип)@
(NULL
указатель никогда ), и?
(единственный тип с допустимой арифметикой указателей , «толстые» указатели ).
Цель введения этих новых типов указателей - избежать общих проблем при использовании указателей. Возьмем, к примеру, функцию, foo
которая принимает указатель на int:
int foo ( интервал * );
Хотя человек, написавший функцию, foo
мог вставлять NULL
проверки, предположим, что из соображений производительности они этого не сделали. Вызов foo(NULL);
приведет к неопределенному поведению (обычно, хотя и не обязательно, приложению отправляется сигнал SIGSEGV ). Чтобы избежать таких проблем, Cyclone вводит тип указателя, которого никогда не может быть . Таким образом, "безопасной" версией будет:@
NULL
foo
int foo ( int @ );
Это сообщает компилятору Cyclone, что аргумент to foo
никогда не должен быть NULL
, избегая вышеупомянутого неопределенного поведения. Простая замена *
на @
избавляет программиста от необходимости писать NULL
проверки, а операционную систему - от необходимости перехватывать NULL
разыменования указателей. Это дополнительное ограничение, однако, может быть довольно большим камнем преткновения для большинства программистов на C, которые привыкли управлять своими указателями напрямую с помощью арифметики. Хотя это желательно, это может привести к переполнению буфера и другим ошибкам в стиле «нечеткость». Чтобы избежать этого, ?
тип указателя ограничен известной границей - размером массива. Хотя это увеличивает накладные расходы из-за дополнительной информации, хранящейся об указателе, это повышает безопасность. Возьмем, к примеру, простую (и наивную) strlen
функцию, написанную на C:
int strlen ( const char * s ) { int iter = 0 ; если ( s == NULL ) вернуть 0 ; в то время как ( s [ iter ] ! = '\ 0' ) { iter ++ ; } вернуть iter ; }
Эта функция предполагает, что переданная строка завершается функцией NULL ( '\0'
). Однако что произойдет, если char buf[6] = {'h','e','l','l','o','!'};
передать эту строку? Это совершенно законно в C, но приведет strlen
к перебору в памяти, не обязательно связанной со строкой s
. Есть функции, такие как , strnlen
которые могут быть использованы , чтобы избежать подобных проблем, но эти функции не являются стандартными в каждой реализации ANSI C . Версия Cyclone strlen
не так уж и отличается от версии C:
int strlen ( const char ? s ) { int iter , n = s . размер ; если ( s == NULL ) вернуть 0 ; for ( iter = 0 ; iter < n ; iter ++ , s ++ ) { if ( * s == '\ 0' ) return iter ; } return n ; }
Здесь strlen
ограничивается длиной переданного ему массива, не превышая фактическую длину. Каждый из типов типа указателя может быть безопасно приведен к каждому из других, а массивы и строки автоматически приводятся ?
компилятором. (Преобразование из ?
в *
вызывает проверку границ , а преобразование из ?
в @
вызывает как NULL
проверку, так и проверку границ. Преобразование из *
в не ?
приводит ни к каким проверкам; ?
размер результирующего указателя равен 1.)
Висячие указатели и анализ области
Рассмотрим следующий код на C:
char * itoa ( int я ) { char buf [ 20 ]; sprintf ( buf , "% d" , i ); return buf ; }
Функция itoa
выделяет buf
в стеке массив символов и возвращает указатель на начало buf
. Однако память, используемая в стеке, buf
освобождается при возврате функции, поэтому возвращаемое значение нельзя безопасно использовать вне функции. Хотя gcc и другие компиляторы будут предупреждать о таком коде, следующий код обычно компилируется без предупреждений:
char * itoa ( int i ) { char buf [ 20 ], * z ; sprintf ( buf , "% d" , i ); z = buf ; return z ; }
gcc может выдавать предупреждения для такого кода как побочный эффект опции -O2 или -O3, но нет никаких гарантий, что все такие ошибки будут обнаружены. Cyclone выполняет региональный анализ каждого сегмента кода, предотвращая висячие указатели, такие как тот, который возвращается из этой версии itoa
. Все локальные переменные в данной области считаются частью одного и того же региона, отдельно от кучи или любого другого локального региона. Таким образом, при анализе itoa
компилятор Cyclone увидит, что z
это указатель на локальный стек, и сообщит об ошибке.
Смотрите также
Рекомендации
- Циклон Руководство пользователя
- Cyclone: Type-safe Dialect of C Дэна Гроссмана, Майкла Хикса, Тревора Джима и Грега Моррисетта - опубликовано в январе 2005 г.
Внешние ссылки
- Домашняя страница Cyclone
- Старый веб-сайт, поскольку официальный веб-сайт недоступен.
- Cyclone - Репозитории исходного кода
- Циклон - FAQ
- Циклон для программистов на C
Презентации: