Ciclone (linguagem de programação)

ImprimirCitar
Dialeto seguro de memória da linguagem de programação C

A linguagem de programação Cyclone pretende ser um dialeto seguro da linguagem C. O Cyclone foi projetado para evitar estouros de buffer e outras vulnerabilidades possíveis em programas C, sem perder o poder e a conveniência do C como ferramenta para programação do sistema.

O desenvolvimento do Cyclone foi iniciado como um projeto conjunto da AT&T Labs Research e do grupo de Greg Morrisett na Cornell University em 2001. A versão 1.0 foi lançada em 8 de maio de 2006.

Recursos de linguagem

O Cyclone tenta evitar algumas das armadilhas comuns do C, mantendo sua aparência e desempenho. Para esse fim, o Cyclone impõe os seguintes limites aos programas:

  • NULL verificações são inseridas para evitar falhas de segmentação
  • A aritmética de ponteiro é limitada
  • Os ponteiros devem ser inicializados antes do uso (isso é aplicado pela análise de atribuição definida)
  • Os ponteiros de estrangulamento são impedidos através da análise da região e dos limites free()
  • Apenas os moldes e sindicatos "seguros" são permitidos
  • goto em escopos é desalvado
  • etiquetas de interruptor em diferentes escopos são desalvados
  • Funções de retorno de ponteiros devem executar return
  • setjmp e longjmp não são suportados

Para manter o conjunto de ferramentas com o qual os programadores C estão acostumados, o Cyclone fornece as seguintes extensões:

  • Nunca...NULL ponteiros não exigem NULL verificações
  • Os ponteiros "Fat" suportam aritmética ponteiro com verificação de limites de tempo de execução
  • Regiões cultivadas suportam uma forma de gestão de memória manual segura
  • Coleta de lixo para valores heap-allocated
  • Tagged unions support type-varying arguments
  • As injeções ajudam a automatizar o uso de sindicatos marcados para programadores
  • O polimorfismo substitui alguns usos do vazio *
  • varargs são implementados como ponteiros de gordura
  • Exceções substituem alguns usos de setjmp e longjmp

Para uma melhor introdução de alto nível ao Cyclone, o raciocínio por trás do Cyclone e a fonte dessas listas, consulte este artigo.

Cyclone se parece, em geral, com C, mas deve ser visto como uma linguagem semelhante a C.

Tipos de ponteiro

O Cyclone implementa três tipos de ponteiro:

  • * (o tipo normal)
  • @ (o nunca...NULL ponteiro), e
  • ? (o único tipo com aritmética ponteiro permitido, ponteiros "fat").

O objetivo de introduzir esses novos tipos de ponteiro é evitar problemas comuns ao usar ponteiros. Tomemos, por exemplo, uma função chamada foo que leva um ponteiro para um int:

 - Não. Foo(- Não. *);

Embora a pessoa que escreveu a função foo pudesse ter inserido verificações NULL, vamos assumir que por motivos de desempenho não o fez. Chamar foo(NULL); resultará em um comportamento indefinido (normalmente, embora não necessariamente, um sinal SIGSEGV sendo enviado ao aplicativo). Para evitar tais problemas, o Cyclone introduz o tipo de ponteiro @, que nunca pode ser NULL. Assim, o "seguro" versão de foo seria:

 - Não. Foo(- Não. @);

Isso diz ao compilador Cyclone que o argumento para foo nunca deve ser NULL, evitando o comportamento indefinido mencionado anteriormente. A simples mudança de * para @ evita que o programador tenha que escrever verificações NULL e o sistema operacional de ter que interceptar NULL desreferências de ponteiro. Esse limite extra, no entanto, pode ser um grande obstáculo para a maioria dos programadores C, que estão acostumados a manipular seus ponteiros diretamente com aritmética. Embora isso seja desejável, pode levar a estouros de buffer e outros erros do estilo "off-by-one". Para evitar isso, o tipo de ponteiro ? é delimitado por um limite conhecido, o tamanho do array. Embora isso acrescente sobrecarga devido às informações extras armazenadas sobre o ponteiro, ele melhora a segurança. Tomemos, por exemplo, uma função strlen simples (e ingênua), escrita em C:

 - Não. Esforços(Não. Charlie. *S) ( - Não. Eu... = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 0; se (S - Sim. NULL) retorno 0; enquanto (SNão.Eu...] ! '') ( Eu...++; ? retorno Eu...; ?

Esta função assume que a string que está sendo passada é terminada por NULL (''). No entanto, o que aconteceria se char buf[6] = {'h','e','l','l','o',' !'}; foram passados para esta string? Isso é perfeitamente legal em C, mas faria strlen iterar através da memória não necessariamente associada à string s. Existem funções, como strnlen que podem ser usadas para evitar tais problemas, mas essas funções não são padrão em todas as implementações de ANSI C. A versão Cyclone de strlen não é tão diferente da versão C:

 - Não. Esforços(Não. Charlie. ? S) ( - Não. Eu..., n = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = S.tamanho; se (S - Sim. NULL) retorno 0; para (Eu... = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 0; Eu... < n; Eu...++, S++) ( se (*S - Sim. '') retorno Eu...; ? retorno n; ?

Aqui, strlen limita-se pelo comprimento do array passado para ele, não ultrapassando o comprimento real. Cada um dos tipos de tipo de ponteiro pode ser convertido com segurança para cada um dos outros, e arrays e strings são convertidos automaticamente para ? pelo compilador. (A conversão de ? para * invoca uma verificação de limites e a conversão de ? para @ invoca um NULL e uma verificação de limites. A conversão de * para ? resulta em nenhuma verificação; o ponteiro ? resultante tem um tamanho de 1.)

Ponteiros pendentes e análise de região

Considere o seguinte código, em C:

 Charlie. *- Sim.(- Não. Eu...) ( Charlie. O que se passa?Não.20.] Sprintf(O que se passa?,"%d",Eu...); retorno O que se passa?; ?

A função itoa aloca um array de caracteres buf na pilha e retorna um ponteiro para o início de buf. No entanto, a memória usada na pilha para buf é desalocada quando a função retorna, então o valor retornado não pode ser usado com segurança fora da função. Embora o GNU Compiler Collection e outros compiladores avisem sobre esse código, o seguinte normalmente compilará sem avisos:

 Charlie. *- Sim.(- Não. Eu...) ( Charlie. O que se passa?Não.20.] *zangão.; Sprintf(O que se passa?,"%d",Eu...); zangão. = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = O que se passa?; retorno zangão.; ?

GNU Compiler Collection pode produzir avisos para tal código como um efeito colateral da opção -O2 ou -O3, mas não há garantias de que todos esses erros serão detectados. O Cyclone faz uma análise regional de cada segmento de código, evitando ponteiros pendentes, como o retornado desta versão do itoa. Todas as variáveis locais em um determinado escopo são consideradas parte da mesma região, separadas do heap ou de qualquer outra região local. Assim, ao analisar itoa, o compilador Cyclone veria que z é um ponteiro para a pilha local e reportaria um erro.

Contenido relacionado

MU

MU, Mu ou μ podem referir-se...

Matriz de portas programável em campo

Uma matriz de portas programável em campo é um circuito integrado projetado para ser configurado por um cliente ou designer após a fabricação - daí o...

Lynx (linguagem de programação)

Lynx é uma linguagem de programação para grandes redes distribuídas, usando chamadas de procedimento remoto. Foi desenvolvido pela Universidade de...

Kevin Warwick

Kevin Warwick é um engenheiro inglês e Vice-Chanceler Adjunto da Coventry University. Ele é conhecido por seus estudos sobre interfaces diretas entre...

Computador Atanasoff-Berry

O computador Atanasoff–Berry foi o primeiro computador digital eletrônico automático. Limitado pela tecnologia da época e execução, o dispositivo...
Más resultados...
Tamaño del texto: