Alessandro Garcia LES/DI/PUC-Rio Novembro 2016
Aula 19
Instrumentação – Parte 1
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 2 /41
Hoje... Especificação
• Objetivo dessa aula
– Motivar instrumentação de programas
• Necessidade do controle de espaços dinâmicos
– características dos erros de uso de espaços dinâmicos
• Módulo de instrumentação CESPDIN
– funcionalidade 1: simulação de memória insuficiente – funcionalidade 2: controle dinâmico de tipos
• Referência básica:
– Capítulo 14 – Monografia
• Slides adaptados de: Staa, A.v. Notas de Aula em Programação Modular; 2008.
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 3 /41
Sumário
• Propriedades desejáveis de programas fidedignos • Tipos de instrumentação
• Módulo CESPDIN
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 4 /41
Qualidade do software em execução
Dados Produtor cria elemento Erro ? ? ? ? Observador de erros Defeito Elemento Sistema a b c d e f g h i j k Usuário Lesão (conseqüência de erro não observado) Falha Resultados Engano do produtor
introduz defeito Causa exógena
provoca um erro
Causa endógena
provoca um erro
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 5 /41
Qualidade do software em execução
• O exercício do defeito pode provocar um erro de execução
– esse é um erro de causaendógena(gerado internamente) – devido a algum engano do produtor(humano, ferramenta) um
elemento pode conter um defeito(falta, fault)
• O erro é propagadode elemento a elemento até que:
– ou seja observado, neste momento passa a ser uma falha (failure)
– ou o usuário seja afetado pelo erro, provocando uma lesão
• o usuário pode nem se dar contaque ocorreu o dano
• o usuário pode saber que ocorreu um dano, mas não saber por quê ocorreu
• Além de causas endógenas, erros podem ter causas
exógenas (gerado externamente)
– hardware, plataforma, outro software – mau uso
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 6 /41
Tolerância a falhas: conceitos
• Para ser um software fidedigno, este deve ser robusto e ou tolerante a falhas
• Um programa robustoobserva a ocorrência de erros endógenos ou exógenos (detectabilidade)
– intercepta a execução quando observa um erro
– mantém confinado o possível dano decorrente da falta
• Um programa tolerante a falhas(fault tolerant)
– é um programa robusto
– possui mecanismos de recuperação, habilitando-o a continuar operando confiavelmente (fidedignamente) após ter detectado uma falha
• Deterioração controlada(graceful degradation)
– é a habilidade de um programa continuar operando
corretamente após uma falha, embora com alguma perda de funcionalidade
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 7 /41
Tolerância a falhas: conceitos
• Um programa intolerante a falhas não observa a ocorrência de erros endógenos ou exógenos
– não é robusto
– pode provocar lesões substanciais
– exemplo 1: programas que não verificam a corretude dos
dados e comandos fornecidos pelo usuário
– exemplo 2: programas que contêm defeitos mas não contêm
código de controle faltam assertivas executáveis
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 8 /41
Sistemas corretos fidedignos
•
Um sistema correto é fidedigno se...
– de que posso justificavelmente depender em que posso confiar digno de fé (fidedigno)
• que não provoca lesõesnem falha de forma imprevisível
•
Logo, para ser um software correto fidedigno, tais
propriedades
são
desejáveis
...
– capacidade de detectaro correspondente erro para evitar possíveis lesões
• detectabilidade
– a partir da informação relativa ao erro precisamos diagnosticar a falta que provocou o erro: descobrir as causas
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 9 /41
Instrumentação: o que é
• A instrumentação
– monitora o comportamentodo programa em execução
• Ex. assertivas executáveis
– é formada por fragmentos inseridosno código – pode estabelecer e explorar redundâncias
• exemplo: N-Version Programming
– deve poder ser inseridae mais tarde retiradasem que isto afete a funcionalidade do programa
• não contribui para o serviçoa que se destina o programa
• entretanto, ao monitorar a corretude pode interceptara execução ao detectar uma falha
– leva a custos adicionais...
• requer tempo e custo adicionais de desenvolvimento
• consome recursos de execução
– porém, benefícios vem a curto, médio e longo prazo…
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 10 /41
Instrumentação: inserção no código
• A instrumentação deve permanecer no código
– deve poder ser ativada ou desativada
• compilação condicional
– pode ser útil ao alterar um programamais tarde
• Esquema de inclusão de instrumentos no código em C/C++
#ifdef _DEBUG
• código do instrumento
• funções e dados de uso exclusivo em instrumentos #endif
• Para que a instrumentação seja compilada o comando de compilação deve conter o parâmetro /D_DEBUG
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 11 /41
Instrumentação - objetivos
• Objetivos - controlar a corretude durante a execução – detectarerros, isto é, identificar falhas:
• o mais cedo possível
• de forma automática, i.e. sem necessitar da intervenção humana – impedirque erros
• propaguem lesões para outras partes do programa ou de outros sistemas
– simular e monitorar propriedades dinâmicasdo programa
• cobertura dos testes
– quanto do código foi exercitado durante os testes
• simular mau funcionamento para fins de teste – ocorrências de falta de memória
– deturpadores
• ...
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 12 /41
Tipos de Instrumentos
• Internosao programa
– assertivas executáveis – contadores de passagem
– controladores de espaços de dados – deturpadores de estruturas de dados
• Externosao programa
– armaduras de teste – depuradores
Nov 2009 LES/DI/PUC-Rio 13 / 41
Assertivas executáveis
• Assertivas executáveis contribuem para
– aumentar a detectabilidade: identifica erro imediatamente – aumentar a diagnosticabilidade: reduz o esforço de diagnose
• É possível traduziruma parcela considerável das assertivas
para código executável. Exemplo:
∀ ∀ ∀
∀ pElem ∈∈∈∈ Lista { pLista } : pElem->pProx != NULL => pElem->pProx->pAnt == pElem
AE: pLista aponta para a cabeça da lista a ser controlada numErros = 0 ;
for ( pElem = pLista->pOrigem ; pElem != NULL ; pElem = pElem->pProx ) { if (pElem->pProx != NULL) { if (pElem->pProx->pAnt != pElem)) numErros ++ ; } }
AS: se numErros != 0 a lista contém erros estruturais.
todos nós posteriores apontam corretam. para o anterior
Nov 2009 LES/DI/PUC-Rio 14 / 41
Exemplo de assertivas executáveis
A
A
B
B
pElemCorr
pElemCorr
InserirApos( pElemCorr , pElemNovo )
pElemNovo
pElemNovo
C
C
Antes
Após
Nov 2009 LES/DI/PUC-Rio 15 / 41
Exemplo de assertivas executáveis
void InserirElemApos( tpElem * pElemCorr , tpElem * pElemNovo ) { //Assertivas de entrada #ifdef _DEBUG tpElem * pElemAux ; tpElem * pElemCorrEntra ; if ( ( pElemCorr == NULL ) || ( pElemNovo == NULL )) {
TratarErro( "InserirElem: Argumentos nulos") ; }
if ( ( pElemNovo->pProx != NULL ) || ( pElemNovo->pAnt != NULL )) {
TratarErro("InserirElem: Novo elem esta encadeado") ; } pElemCorrEntra = pElemCorr ; pElemAux = pElemCorr->pProx ; if ( pElemAux != NULL ) { if ( pElemAux->pAnt != pElemCorr ) {
TratarErro("InserirElem: Encadeamento do elem corrente da lista") ; }
} #endif
checa se o próximo elemento do elem corrente aponta para o nó corrente
Nov 2009 LES/DI/PUC-Rio 16 / 41
Exemplo de assertivas executáveis
// Efetuar a inserção// Assertivas de saída
#ifdef _DEBUG
if ( !(( pElemNovo == pElemCorr ) && ( pElemNovo->pAnt == pElemCorrEntra ) && ( pElemNovo->pProx == pElemAux ) && ( pElemCorrEntra->pProx == pElemNovo ))) {
TratarErro( "InserirElem: Encadeamento antes") ; }
if ( pElemAux != NULL ) {
if ( !( pElemAux->pAnt == pElemNovo )) {
TratarErro( "InserirElem: Encadeamento apos"); } } #endif } // Fim da função checar se ponteiros do novo elemento estão corretos checar se ponteiro do elemento à seguir aponta com pAnt para novo elemento
Experimentos com sistemas reais…
• … demonstram os benefícios constantes de instrumentação (assertivas executáveis) à longo prazo
Fonte: Minds @ Work, Dr. João Magalhães Todos sistemas são
Implementados em C
Jun 2009 Alessandro Garcia - LES/DI/PUC-Rio 18 /41
Tipos de Instrumentos
• Internosao programa
– assertivas executáveis – contadores de passagem
– controladores de espaços de dados
– verificadores de estruturas de dados – deturpadores de estruturas de dados
• Externosao programa
– armaduras de teste – depuradores
Nov 2009 LES/DI/PUC-Rio 19 / 41
Controle de espaços dinâmicos
• Em linguagens que não possuem garbage collectionpode ocorrer vazamento de memória
– ocorre quando um espaço de memória deixa de ser acessível • exemplo: variável local; ao final da execução não é dado um ‘free’ • qualquer espaço não ativo é um espaço vazado
• Em linguagens que não possuem garbage collectionpode ocorrer acesso a espaços já desalocados
– podem existir vários ponteiros ativos para um mesmo espaço
– um desses ponteiros pode ser usado para desalocar o espaço, enquanto os demais continuam apontado para área de memória real onde se encontrava o espaço desalocado
– ao desalocar um espaço, o valor nele contido não é alterado • portanto, um programa com esse tipo de erro pode continuar operando
corretamente!!! até que, muito tempo mais tarde, o espaço seja alocado para satisfazer uma nova requisição de alocação
Nov 2009 LES/DI/PUC-Rio 20 / 41
Controle do uso de espaços
• Várias linguagens permitem que se atribua valores a índices de elementos de um vetor além do final ou aquém do início do espaço declarado ou alocado
– este tipo de erro pode interferir no funcionamento de outros componentes do programa
– pode ocorrer de forma intermitente Espaço alocado
para módulo A Espaço alocado para módulo B
Parcela do vetor de A que extravasou e invadiu B
Os espaços alocados são espalhados pela memória real e pode ocorrer que o espalhamento seja diferente de uma instância de uso para outra
Nov 2009 LES/DI/PUC-Rio 21 / 41
Possível estado do controle de memória
e8
e7
e1 e2 e3 e4 e5 e6 e9 e10 e11 e12 e13 e14 e15 e16 e17 e18 e19 e20
Fronde Raiz
Os espaços alocados são espalhados pela memória real e pode ocorrer que o espalhamento seja diferente de uma instância de uso para outra
Nov 2009 LES/DI/PUC-Rio 22 / 41
Característica de erros de uso de espaços
• Erros de uso de espaços de dados são
– difíceis de provocar ao testar
• difíceis de detectar
• difíceis de diagnosticar
– frequentemente intermitentes
• como testar falta de memória? como testar coisas que tenham um comportamento não previsível(não determinístico)
• queremos que se tornem falhas sólidas caso possam ocorrer, que ocorram sempre
Nov 2009 LES/DI/PUC-Rio 23 / 41
Módulo de instrumentação: CESPDIN
• O módulo CESPDIN monitora o uso de memória dinâmica
– é essencialmente um módulo de instrumentaçãopara as funções malloc e free
• ver CESPDIN.H em autotest\arcabouc
pProx pAnt tamValor ControleAntes Valor ControleApos tam Valor
tamTotal pOrgLista
Ponteiro retornado idTipo
Valor Onde foialocado Eh
ativo id
espaço Impressão
digital Totaltam
Lista de todos os espaços dinâmicos alocados sob controle de CESPDIN. Para ser controlado o módulo precisa incluir CESPDIN.H
Nov 2009 LES/DI/PUC-Rio 24 / 41
Módulo de instrumentação: CESPDIN
• ImpressaoDigital– o valor contido neste campo é sempre o mesmo. Tem por objetivo informar que o espaço de dados corresponde a um espaço controlado. Caso este valor não exista neste campo as operações de manipulação de espaço controlado serão inibidas.
• struct tgElemListaControle * pAnt • struct tgElemListaControle * pProx • idEspaco
– identificador único do espaço alocado. Permite verificar se o espaço sendo manipulado é o espaço desejado, ou comparar se dois ponteiros apontam para o mesmo espaço.
• ehAtivo
– chave indicadora de se o espaço é ativo ou não. Permite o
desenvolvimento de funções que verificam as regras de vazamento de memória
Nov 2009 LES/DI/PUC-Rio 25 / 41
Módulo de instrumentação: CESPDIN
• idTipoValor
– identificador do tipo do dado contido no espaço. Permite verificar a coerência dos tipos dos dados e dos ponteiros para eles.
• int tamValor
– número de bytes solicitados no malloc correspondente
• numLinhaFonte
• NomeArquivoFonte[ DIM_NOME_ARQ_FONTE ]
– informam onde no código fonte está o comando malloc que alocou o espaço. Facilita determinar o defeito que fez um espaço vazar
• char Valor[ DIM_VALOR ]
– o espaço útil. O tamanho deste campo é estabelecido dinamicamente
Nov 2009 LES/DI/PUC-Rio 26 / 41
Como funciona?
• Em módulos controlados, são instrumentados função implementado por
malloc CED_Malloc
free CED_Free
• Para o módulo cliente a instrumentação é transparente – o código é alterado pelo pre-processador de C/C++
Nov 2009 LES/DI/PUC-Rio 27 / 41
Modo de usar
• Para ativar o controle de espaços dinâmicos, basta incluir a definição do módulo de instrumentação CESPDIN.H
#ifdef _DEBUG
#include CESPDIN.H #endif
• São disponibilizadas diversas funções de instrumentação – recomenda-se que o uso dessas funções esteja sempre dentro
de um controle #ifdef _DEBUG
• O módulo INTRPCEDdisponibiliza diversos comandos de testeque executam funções de CESPDIN
– na realidade INTRPCED é um módulo de teste específico parcial para o módulo CESPDIN
– vocês podem utilizar tais comandos nos scripts
Funções do CESPDIN permitem:
• simular ter-se atingido o limite de memória disponível
• controlar o vazamento de memória – CED_ExibirTodosEspacos
=verficar memoria – CED_EhEspacoAtivo
• controlar a extravasão de espaços de dados alocados ao usuário
– CED_ObterTamanhoValor (em bytes) – CED_VerificarEspaco
• controlar o acesso a espaços já desalocados – CED_EhEspacoAtivo
– Percorrer a lista
• controlar a consistência entre o tipo implícito de um ponteiro e o tipo do espaço por ele apontado
Nov 2009 LES/DI/PUC-Rio 29 / 41
Modo de Usar: Exemplo... TSTARV.C
Controlador de teste específico do módulo ÁRVORE (/instrum)
/* Tabela dos nomes dos comandos de teste específicos */ const char CRIAR_ARV_CMD [ ] = "=criar" ;
const char INS_DIR_CMD [ ] = "=insdir" ; ...
const char VER_CABECA_CMD[ ] = "=verificarcabeca" ; const char VER_ARVORE_CMD[ ] = "=verificarelem_arvore" ; const char VER_MEMORIA_CMD[ ] = "=verificarmemoria" ;
usados na definição dos casos de teste nos arquivos script
ARV_tpCondRet ARV_CriarArvore( void ** ppArvoreParm ) { tpArvore * pArvore ;
pArvore = ( tpArvore * ) malloc( sizeof( tpArvore )) ; if ( pArvore == NULL )
{
return ARV_CondRetFaltouMemoria ; } /* if */
#ifdef _DEBUG
CED_DefinirTipoEspaco( pArvore , ARV_TipoEspacoCabeca ) ; #endif ... verifica se realmente é um nó cabeça Módulo ÁRVORE Nov 2009 LES/DI/PUC-Rio 30 / 41
Modo de Usar: Exemplo... TSTARV.C
Controlador de teste específico do módulo ÁRVORE (/instrum)
/* Tabela dos nomes dos comandos de teste específicos */ const char CRIAR_ARV_CMD [ ] = "=criar" ;
const char INS_DIR_CMD [ ] = "=insdir" ; ...
const char VER_CABECA_CMD[ ] = "=verificarcabeca" ; const char VER_ARVORE_CMD[ ] = "=verificarelem_arvore" ; const char VER_MEMORIA_CMD[ ] = "=verificarmemoria" ;
usados na definição dos casos de teste nos arquivos script
ARV_tpCondRet ARV_VerificarCabeca(void * pCabecaParm ) { /* Verifica o tipo do espaço */
if ( TST_CompararInt( ARV_TipoEspacoCabeca ,CED_ObterTipoEspaco( pCabecaParm ) , "Tipo do espaço de dados não é cabeça de árvore." ) != TST_CondRetOK ) {
return ARV_CondRetErroEstrutura ; } /* if */ ... verifica se realmente é um nó cabeça Módulo ÁRVORE espaço deve ser “inicializado” com tal tipo quando criado
Nov 2009 LES/DI/PUC-Rio 31 / 41
Modo de usar: memória insuficiente
• Para simular falta de memória podem ser utilizados os comandos de teste:
• =limitarmemoriadisponivel <numBytes>
– estabelece o limite em número de bytesdisponíveis para a alocação dinâmica
• =limitarnumeroespacos <numEspaços>
– estabelece o limite de número de espaçosalocados
• =limitarfrequenciaNULL <freqüência alloc>
– estabelece a freqüência de sucessodas alocações. É um valor dado em milésimos: 999 indica que 99,9% das vezes
CED_Malloc ou CED_CAlloc alocarão memória
• =eliminarlimitesespaco
– elimina todos os controles porventura ativos
ver o módulo INTRPCED.C
Nov 2009 LES/DI/PUC-Rio 32 / 41
Trabalho 4
• Ler seções 9 e 10 da Monografia do Arcabouço
• Estudar o módulo CESPDIN para controle de espaço dinâmico
– entender as funcionalidades providas (*.h) – entender também o módulo INTRPCED
• Usar CESPDIN no módulo LISTACIRCULAR
– E eventualmente em outros módulos para quais você pode necessitar do CESPDIN para tratar uma ou mais das 3 exceções que o grupo escolheu
• Estude o exemplo contido na pasta “Instrum” do arcabouço
– vide controlador de teste e scripts de teste de “Árvore”
•
Estudar outros exemplos (
disponíveis no sítio do
curso – aba Software
)
Alessandro Garcia LES/DI/PUC-Rio Novembro 2016