El lenguaje de programación Cyclone fue pensado para ser un dialecto seguro del lenguaje C. [ 2] Evita desbordamientos de buffer y otras vulnerabilidades que son posibles en los programas C por diseño, sin perder la potencia y conveniencia de C como herramienta para la programación de sistemas . Ya no es soportado por sus desarrolladores originales, con las herramientas de referencia no soportando plataformas de 64 bits . El lenguaje Rust es mencionado por los desarrolladores originales por haber integrado muchas de las mismas ideas que tenía Cyclone. [3]
El desarrollo de Cyclone comenzó como un proyecto conjunto de Trevor Jim de AT&T Labs Research y el grupo de Greg Morrisett en la Universidad de Cornell en 2001. La versión 1.0 se lanzó el 8 de mayo de 2006. [4]
Características del lenguaje
Cyclone intenta evitar algunos de los problemas más comunes de C , manteniendo al mismo tiempo su aspecto y rendimiento. Para ello, Cyclone impone los siguientes límites a los programas:
NULLSe insertan controles para evitar fallos de segmentación.- La aritmética de punteros es limitada
- Los punteros deben inicializarse antes de su uso (esto se aplica mediante el análisis de asignación definida )
- Los punteros colgantes se evitan mediante el análisis de la región y los límites en
free() - Sólo se permiten uniones y moldes “seguros”
gotoNo se permite el acceso a ámbitosswitchNo se permiten etiquetas en diferentes ámbitos- Las funciones que devuelven punteros deben ejecutarse
return setjmpylongjmpno son compatibles
Para mantener el conjunto de herramientas al que están acostumbrados los programadores de C, Cyclone proporciona las siguientes extensiones:
- Nunca:
NULLlos punteros no requierenNULLcomprobaciones - Los punteros "gordos" admiten la aritmética de punteros con verificación de límites en tiempo de ejecución
- Las regiones ampliables admiten una forma de gestión de memoria manual segura
- Recolección de basura para valores asignados al montón
- Las uniones etiquetadas admiten argumentos que varían según el tipo
- Las inyecciones ayudan a automatizar el uso de uniones etiquetadas para programadores
- El polimorfismo reemplaza algunos usos de
void * - Los varargs se implementan como punteros fat
- Las excepciones reemplazan algunos usos de
setjmpylongjmp
Para una mejor introducción de alto nivel a Cyclone, el razonamiento detrás de Cyclone y la fuente de estas listas, consulte este documento.
Cyclone se parece, en general, mucho a C, pero debería considerarse un lenguaje similar a C.
Tipos de punteros
Cyclone implementa tres tipos de puntero :
*(el tipo normal)@(elNULLpuntero que nunca apunta), y?(el único tipo con aritmética de punteros permitida, punteros "gordos" ).
El objetivo de introducir estos nuevos tipos de punteros es evitar problemas comunes al utilizar punteros. Tomemos como ejemplo una función llamada fooque toma un puntero a un int:
int foo ( int * );
Aunque la persona que escribió la función foopodría haber insertado NULLcontroles, supongamos que por razones de rendimiento no lo hizo. La llamada foo(NULL);dará como resultado un comportamiento indefinido (normalmente, aunque no necesariamente, se envía una señal SIGSEGV a la aplicación). Para evitar este tipo de problemas, Cyclone introduce el tipo de puntero, que nunca puede ser . Por lo tanto, la versión "segura" de sería:
@NULLfoo
int foo ( int @ );
Esto le dice al compilador Cyclone que el argumento to foonunca debe ser NULL, evitando el comportamiento indefinido mencionado anteriormente. El simple cambio de *to @ahorra al programador tener que escribir NULLcomprobaciones y al sistema operativo tener que atrapar NULLdesreferencias de punteros. Sin embargo, este límite adicional puede ser un gran obstáculo para la mayoría de los programadores de C, que están acostumbrados a poder manipular sus punteros directamente con aritmética. Aunque esto es deseable, puede conducir a desbordamientos de búfer y otros errores de tipo "desfase de uno". Para evitar esto, el ?tipo de puntero está delimitado por un límite conocido, el tamaño de la matriz. Aunque esto agrega sobrecarga debido a la información adicional almacenada sobre el puntero, mejora la seguridad. Tomemos como ejemplo una strlenfunción simple (e ingenua), escrita en C:
int strlen ( const char * s ) { int i = 0 ; si ( s == NULL ) devuelve 0 ; mientras ( s [ i ] != '\0' ) { i ++ ; } devuelve i ; }
Esta función supone que la cadena que se pasa termina en '\0'. Sin embargo, ¿qué sucedería si se pasara a esta cadena? Esto es perfectamente legal en C, pero provocaría iteraciones a través de la memoria no necesariamente asociada con la cadena . Hay funciones, como que se pueden usar para evitar tales problemas, pero estas funciones no son estándar en todas las implementaciones de ANSI C . La versión Cyclone de no es tan diferente de la versión C:
char buf[6] = {'h','e','l','l','o','!'};strlensstrnlenstrlen
int strlen ( const char ? s ) { int i , n = s . tamaño ; si ( s == NULL ) devuelve 0 ; para ( i = 0 ; i < n ; i ++ , s ++ ) si ( * s == '\0' ) devuelve i ; devuelve n ; }
Aquí, strlense limita a sí mismo por la longitud de la matriz que se le pasa, por lo que no supera la longitud real. Cada uno de los tipos de puntero se puede convertir de forma segura a cada uno de los otros, y ?el compilador convierte automáticamente matrices y cadenas. (La conversión de ?to *invoca una comprobación de límites , y la conversión de ?to @invoca tanto una NULLcomprobación como una comprobación de límites. La conversión de *to ?no produce ninguna comprobación; el ?puntero resultante tiene un tamaño de 1).
Punteros colgantes y análisis de regiones
Considere el siguiente código, en C:
char * itoa ( int i ) { char buf [ 20 ]; sprintf ( buf , "%d" , i ); devolver buf ; }
La función itoaasigna una matriz de caracteres bufen la pila y devuelve un puntero al inicio de buf. Sin embargo, la memoria utilizada en la pila para bufse libera cuando la función retorna, por lo que el valor devuelto no se puede usar de manera segura fuera de la función. Si bien GNU Compiler Collection y otros compiladores advertirán sobre este tipo de código, lo siguiente generalmente se compilará sin advertencias:
char * itoa ( int i ) { char buf [ 20 ], * z ; sprintf ( buf , "%d" , i ); z = buf ; devolver z ; }
GNU Compiler Collection puede generar advertencias para dicho código como un efecto secundario de la opción -O2o -O3, pero no hay garantías de que se detecten todos esos errores. Cyclone realiza un análisis regional de cada segmento de código, lo que evita punteros colgantes, como el que devuelve esta versión de itoa. Todas las variables locales en un ámbito determinado se consideran parte de la misma región, separadas del montón o de cualquier otra región local. Por lo tanto, al analizar itoa, el compilador Cyclone verá que zes un puntero a la pila local y reportará un error.
Véase también
Referencias
- ^ "Revistas de acceso abierto de Cyclone (lenguaje de programación) · OA.mg". oa.mg . Archivado desde el original el 30 de octubre de 2022 . Consultado el 30 de octubre de 2022 .
- ^ Jim, Trevor; Morrisett, J. Greg; Grossman, Dan; Hicks, Michael W.; Cheney, James; Wang, Yanling (10 de junio de 2002). "Ciclón: un dialecto seguro de C". Actas de la Conferencia Técnica Anual de la Conferencia Anual de USENIX . ATEC '02. EE. UU.: Asociación USENIX: 275–288. doi :10.5555/647057.713871 (inactivo el 1 de noviembre de 2024). ISBN 978-1-880446-00-3.
{{cite journal}}: Mantenimiento de CS1: DOI inactivo a partir de noviembre de 2024 ( enlace ) Mantenimiento de CS1: errores de DOI ignorados ( enlace ) - ^ "Ciclón". cyclone.thelanguage.org . Archivado desde el original el 21 de mayo de 2006 . Consultado el 11 de diciembre de 2023 .
- ^ "Ciclón". Universidad de Cornell . Archivado desde el original el 15 de octubre de 2022. Consultado el 30 de octubre de 2022 .
Enlaces externos
- Página de inicio de Cyclone
- Sitio web antiguo
- Cyclone - repositorios de código fuente
- Ciclón - Preguntas frecuentes
- Cyclone para programadores en C
- Manual de usuario del ciclón
- Cyclone: a Type-safe Dialect of C (Ciclón: un dialecto de C con seguridad de tipos) por Dan Grossman, Michael Hicks, Trevor Jim y Greg Morrisett (publicado en enero de 2005)
Presentaciones:
- Ciclón: un dialecto de C con seguridad de tipos
- Cyclone: un lenguaje de programación de nivel C que no daña la memoria