Sistemas Criticos: Como Desenvolver Software
Quando o software falha num app de delivery, o usuario ve uma mensagem de erro. Quando falha num sistema de controle de aviao ou num marcapasso, as consequencias
Carregando
Quando o software falha num app de delivery, o usuario ve uma mensagem de erro. Quando falha num sistema de controle de aviao ou num marcapasso, as consequencias
Sistemas Criticos: Como Desenvolver Software. Quando o software falha num app de delivery, o usuario ve uma mensagem de erro. Quando falha num sistema de controle de aviao ou num marcapasso, as consequencias sao diferentes. As normas e tecnicas que a industria usa para minimizar esse risco sao menos conhecidas do que deveriam.
Mais devs estao trabalhando em sistemas que tem consequencias reais de falha: saude digital, infraestrutura critica, veiculos autonomos, financas. Conhecer as tecnicas de engenharia de software critico nao e so para quem trabalha em aviaçao. E um conjunto de ferramentas mentais que melhora qualquer software onde falha tem custo alto.
Um sistema e critico quando sua falha pode causar morte, lesao grave, dano ambiental significativo ou perda financeira catastrofica. A classificacao nao e binaria: existe um espectro de criticidade que as normas organizam em niveis de Design Assurance Level (DAL) ou Safety Integrity Level (SIL), dependendo da industria. O nivel mais alto exige que a probabilidade de falha catastrofica seja inferior a 10 elevado a -9 por hora de operacao. Isso e equivalente a uma falha em mais de 100.000 anos de operacao continua.
Atingir esses numeros nao e possivel apenas com mais testes. Exige abordagem sistematica que comeca nos requisitos, passa pelo design, implementacao, verificacao e integracao, com rastro documentado entre cada etapa. Qualquer mudanca no codigo, por menor que seja, precisa ter impacto avaliado e reverificar as etapas afetadas. Esse processo e custoso e lento por design: a velocidade de desenvolvimento em sistemas criticos e deliberadamente menor porque o custo de um bug em producao e incomparavel.
Como um bug de integer overflow destruiu um foguete de 370 milhoes de dolares em 37 segundos.
Como fazer code review que realmente previne bugs criticos, com checklist e uso de IA.
O DO-178C e o padrao de certificacao de software para aviaçao civil, publicado pelo RTCA e adotado pela FAA nos EUA e pela EASA na Europa. Ele define cinco niveis de criticidade, do nivel A ao nivel E, onde A e o mais critico. Software nivel A, como o sistema de controle de voo primario, precisa de cobertura MC/DC em todos os testes: cada condicao booleana em cada decisao deve ser mostrada como tendo um impacto independente no resultado da decisao.
O DO-178C tambem exige independencia entre as equipes de desenvolvimento e verificacao para o nivel A: a equipe que escreve o codigo nao pode ser a mesma que verifica se o codigo esta correto. Isso elimina o vies de confirmacao onde o desenvolvedor testa seus proprios assunções. A certificacao de um aviao comercial pode envolver dezenas de milhoes de linhas de documentacao de verificacao alem do codigo em si.
Uma das adicoes mais importantes na versao C, publicada em 2011, foram os suplementos para Model-Based Development e Object-Oriented Technology. A versao anterior tratava software orientado a objetos com desconfianca porque polimorfismo e despacho dinamico tornam dificil garantir que todos os caminhos de execucao foram cobertos pelos testes. Os suplementos definem como tratar esses casos de forma que a certificacao ainda seja valida.
A IEC 62304 e o padrao internacional para software de dispositivos medicos, incluindo marcapassos, equipamentos de imageamento, bombas de infusao e sistemas de monitoracao de pacientes. Ela define tres classes de segurança: classe A para software onde falha nao apresenta risco de lesao, classe B para risco de lesao nao grave, e classe C para risco de morte ou lesao grave.
Um aspecto especifico da IEC 62304 que diferencia de outros padroes e o tratamento de software de prateleira, como bibliotecas open source usadas em dispositivos medicos. A norma exige que o fabricante do dispositivo documente o historico de bugs conhecidos da biblioteca, avalie se esses bugs podem afetar a seguranca do dispositivo e mantenha um processo de monitoramento continuo para novas vulnerabilidades. Usar uma biblioteca open source num dispositivo medico sem esse processo e uma nao-conformidade que pode impedir a aprovacao regulatoria.
MISRA C e um conjunto de diretrizes de codificacao em C desenvolvido originalmente para a industria automotiva britanica e hoje usado em aviaçao, defesa e outras areas criticas. O MISRA C restringe ou proibe construcoes da linguagem C que sao definidas como comportamento indefinido ou que historicamente causaram bugs dificeis de detectar. Entre as regras mais conhecidas: proibicao de uso de funcoes de alocacao dinamica de memoria como malloc em codigo critico, restricao de ponteiros para funcoes, e exigencia de que toda variavel seja inicializada antes do uso.
A logica por tras dessas restricoes e eliminar classes inteiras de bug ao custo de algumas capacidades da linguagem. Codigo sem alocacao dinamica de memoria e mais facil de analisar estaticamente e tem comportamento de memoria mais previsivel em tempo de execucao. Codigo sem ponteiros para funcoes e mais facil de verificar com analise de fluxo de controle. A restricao de algumas features poderosas da linguagem e o preco para tornar o comportamento do sistema verificavel.
Verificacao formal e o processo de provar matematicamente que um programa satisfaz uma especificacao. Ferramentas como Coq, Isabelle e TLA+ sao usadas para isso. A NASA usa verificacao formal para partes criticas de software de controle de missao. O sistema de controle do Mars Rover tem partes verificadas formalmente. E um processo muito mais lento do que desenvolvimento convencional, mas o nivel de confianca que proporciona e qualitiativamente diferente de qualquer quantidade de testes empiricos.
Fuzzing estruturado e outra tecnica que vai alem do que a maioria dos projetos usa: em vez de gerar inputs aleatorios, o fuzzer usa o grafo de controle de fluxo do programa para gerar inputs que exploram especificamente os caminhos menos testados. American Fuzzy Lop e seus derivados como libFuzzer tornaram essa tecnica mais acessivel, e encontram classes de bugs que testes unitarios manuais raramente cobrem.
Analise de modos de falha e efeitos, conhecida como FMEA, e um processo sistematico para enumerar cada modo de falha possivel de cada componente do sistema e avaliar o efeito de cada falha no sistema como um todo. Nao e um processo de software: e uma analise de engenharia de sistemas que envolve toda a equipe. Para software critico, a FMEA e feita antes do codigo existir, influenciando o design para minimizar o impacto de cada modo de falha identificado.
Mais do que a maioria dos devs imagina. Analise de modos de falha e util para qualquer sistema distribuido onde falha parcial e possivel: identificar o que acontece quando cada componente falha antes de construir o sistema evita surpresas desagradaveis em producao. Cobertura MC/DC de testes e excessivamente rigorosa para a maioria dos projetos, mas o principio de testar cada condicao booleana independentemente e uma boa pratica geral para logica de negocio critica. Restricoes de codigo ao estilo MISRA fazem sentido em qualquer ambiente embarcado com recursos limitados. A questao e calibrar o nivel de rigor de acordo com o custo real de falha do sistema especifico.
A maioria das empresas de aviaçao e saude digital contrata devs com background convencional e os treina nos padroes especificos. O que ajuda na candidatura e familiaridade com os conceitos gerais: saber o que e DO-178C, o que distingue niveis de criticidade, e ter experiencia com praticas que sao subconjuntos das exigencias das normas, como cobertura de testes alta, analise estatica sistematica, e documentacao de decisoes de design. Certificacoes como o exame de Software Requirements do IEEE podem ajudar a sinalizar seriedade, mas a maioria do conhecimento especifico de normas se adquire na pratica.