Aula 22 Instrumentação - Parte 2 - Departamento de Informática...
Transcript of Aula 22 Instrumentação - Parte 2 - Departamento de Informática...
1
Aula 22Instrumentação - Parte 2
Alessandro Garcia
Eduardo Fernandes (assistente)
Alessandro Garcia © LES/DI/PUC-Rio
Junho 2018
Aula passada...
• O que é instrumentação? Para que serve?
• Quais os tipos de instrumento?
• Quais são exemplos de assertivas executáveis que podem
ser incluídas para instrumentar o módulo LISTA?
• O que é o módulo CONTA?
• Como utilizar CONTA para realizar a contagem de passagens
em um módulo segundo algum critério de cobertura dos
testes?
2 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
2
3 / 40
Especificação
• Objetivo dessa aula
– Tipos de instrumentação
• módulo CESPDIN: controlador de espaço de dados
• estruturas auto-verificáveis
– verificadores
• deturpadores
• Referência básica:
– Capítulo 14
Alessandro Garcia © LES/DI/PUC-RioJun 2018
4 / 40Alessandro Garcia © LES/DI/PUC-Rio
Controle de espaços dinâmicos
• Em linguagens que não possuem garbage collection pode 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 collection pode 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 depois, o espaço seja alocado para
satisfazer uma nova requisição de alocação
Jun 2018
3
5 / 40Alessandro Garcia © LES/DI/PUC-Rio
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
Jun 2018
6 / 40Alessandro Garcia © LES/DI/PUC-Rio
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
• queremos que se tornem falhas sólidas caso possam ocorrer,
que ocorram sempre
• como testar falta de memória? como testar coisas que tenham um
comportamento não previsível (não determinístico)?
• Precisamos de instrumentos para controlar esses erros
Jun 2018
4
Jun 2018 7 / 40Alessandro Garcia © LES/DI/PUC-Rio
Módulo de instrumentação: CESPDIN
• O módulo CESPDIN monitora o uso de memória dinâmica
– é essencialmente um módulo de instrumentação para as
funções malloc e free
• ver CESPDIN.H em autotest\arcabouc
pProx pAnttamValor
ControleAntes Valor
ControleApos
tam Valor
tamTotal
pOrgLista
Ponteiro retornado
idTipoValor
Onde foialocado
Ehativo
idespaço
Impressãodigital
tamTotal
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 8 / 40Alessandro Garcia © LES/DI/PUC-Rio
Controle de tipos
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
...
Módulo ÁRVORE
• A função CED_DefinirTipoEspaco(Ponteiro, idTipo) permite
definir o tipo do espaço alocado
– Ponteiro: ponteiro para o valor (espaço útil) do espaço
– idTipo: novo identificador de tipo a ser dado ao espaço
• Funções-clientes podem controlar a consistência entre o tipo
implicitamente associado ao ponteiro e o tipo real do espaço
5
Nov 2009 9 / 40Alessandro Garcia © LES/DI/PUC-Rio
Controle de tipos
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
Nov 2009 10 / 40Alessandro Garcia © LES/DI/PUC-Rio
Modo de uso (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" ;
...
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 */
...
Módulo ÁRVORE
6
Funções do CESPDIN permitem:
• simular ter-se atingido o limite de memória disponível
• controlar o vazamento de memória
– CED_ExibirTodosEspacos
=verficarmemoria
– 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
11 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
12 / 40Alessandro Garcia © LES/DI/PUC-Rio
Tipos de instrumentos
• Internos ao programa
– assertivas executáveis
– controladores de espaços de dados
– estruturas auto-verificáveis
• redundâncias e funções verificadoras
– deturpadores de estruturas de dados
– contadores de passagem
• Externos ao programa
– arcabouço e módulos de teste
Jun 2018
7
13 / 40Alessandro Garcia © LES/DI/PUC-Rio
Estruturas auto-verificáveis
• Uma estrutura de dados é auto-verificável se for possível
verificar completamente a sua corretude estrutural através de
informação interna adicional à contida na própria estrutura
• Para tornar auto-verificável uma estrutura de dados, deve-se
assegurar que:
– existam suficientes redundâncias que permitam controlar a
consistência de todos os elementos da estrutura
• as assertivas estruturais executáveis estejam implementadas e
envolvam as redundâncias requeridas
– se possa examinar todos os espaços alocados no âmbito da
estrutura sendo verificada
• Passos para transformar uma estrutura em auto-verificável de
modo que se insiram as redundâncias necessárias
Jun 2018
14 / 40Alessandro Garcia © LES/DI/PUC-Rio
Tabela de randomização
• Exemplo:
função de hashing H
retorno da função H é o
Índice do vetor de
randomização:
A = 0
B = 1
C = 2
...
universo
de dados
listas
de colisão
chave
K
Jun 2018
8
Tabela de randomização: Modelo físico
pEsq Id Simbolo pDir
Vetor
de
randomizção
Listas de colisão
n
Modelo
Exemplo
Vt26
v[0]
v[1]
v[2]
...
v[26]
Antonia Álvaro
char[150]
Zilda
pTabela
Randomizacao
pLista
Exemplos de modelo físico e exemplo físico
pEsq Id Simbolo pDir
Vetor
de
randomizção
Listas de colisão
n
Modelo
Exemplo
Vt26
v[0]
v[1]
v[2]
...
v[25]
Antonia Álvaro
char[150]
Zilda
pTabela
Randomizacao
pLista
9
17 / 40Alessandro Garcia © LES/DI/PUC-Rio
Exemplo de transformação
• Vamos considerar uma tabela de
símbolos genérica que utiliza
randomização (hashing) e resolução
de colisões através de listas de
colisão
• O vetor de randomização contém
um número fixo N de referências
para listas de colisão.
– Exemplo: N = 26 (letras do
alfabeto)
• A função H(chave) calcula um
índice K do vetor de randomização,
tal que 0 <= K <= N – 1.
• As listas de colisão são listas
duplamente encadeadas:
pEsq Id pDir
Vetor
de
randomizção
Listas de colisão
n
Modelo
Exemplo
Vt
Simbolo
Tabela
Jun 2018
Jun 2018 18 / 40Alessandro Garcia © LES/DI/PUC-Rio
Exemplo de transformação
Seja Ref uma referência para um espaço qualquer
• Passo: Deve ser possível determinar o tipo do espaço
referenciado por Ref, ou seja, deve ser possível realizar o
controle dinâmico de tipos
– todos os espaços iniciam com um int que contém o
identificador do tipo do espaço: idTipoXXX τ
10
Jun 2018 19 / 40Alessandro Garcia © LES/DI/PUC-Rio
Módulo de instrumentação: CESPDIN
• O módulo CESPDIN monitora o uso de memória dinâmica
– é essencialmente um módulo de instrumentação para as
funções malloc e free
• ver CESPDIN.H em autotest\arcabouc
pProx pAnttamValor
ControleAntes Valor
ControleApos
tam Valor
tamTotal
pOrgLista
Ponteiro retornado
idTipoValor
Onde foialocado
Ehativo
idespaço
Impressãodigital
tamTotal
Exemplo de transformação
• Passo: não esquecer de atualizar as informações
redundantes da estrutura auto-verificável
– exemplo: informar tipo...
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
...
Módulo ÁRVORE
Jun 2018 Alessandro Garcia © LES/DI/PUC-Rio 20 / 40
11
21 / 40Alessandro Garcia © LES/DI/PUC-Rio
Exemplo de transformação
Seja Ref uma referência para um espaço qualquer
• Passo: Deve ser possível determinar o tipo do espaço
referenciado por Ref, ou seja, deve ser possível realizar o
controle dinâmico de tipos
– todos os espaços iniciam com um int que contém o
identificador do tipo do espaço: idTipoXXX τ
• Passo: Deve ser possível determinar o tamanho em uso e
tamanho alocado do elemento apontado por Ref
Atributos de
dimensão variável,
ver aula passada
Jun 2018
22 / 40Alessandro Garcia © LES/DI/PUC-Rio
Tabela
nVtn
vtRandomização
pEsq
Simbolo
Valor
Id pDirpSimb
ElemTabela
inxHashvtRand
Exemplo de transformação
• Passo: deve ser possível verificar completamente todas as
referências a espaços adjacentes ao espaço referenciado por
Ref
– para tal é necessário dispor de uma referência inversa
• acessar todos outros elementos da estrutura de dados
– ex. a partir do ElemTabela, acessar o ponteiro para lista de colisão e o
vetor de randomização
– deve incluir novos campos na declaração das estruturas
• nenhum suporte do CESPDIN
referênciaponteiro
ponteiro
Jun 2018
12
23 / 40Alessandro Garcia © LES/DI/PUC-Rio
Exemplo de transformação
• Passo: deve ser possível caminhar para todos os espaços
adjacentes ao espaço referenciado por Ref, independente-
mente da direção desta adjacência
– são adjacentes
• todos os espaços referenciados por Ref
• todos os espaços que referenciam o espaço Ref
– as estruturas devem sempre ter antecessores para cada
sucessor
– na realidade trata-se de uma verificação do passo anterior
• Passo: deve ser possível identificar espaços alocados e não
ativos
Jun 2018
24 / 40Alessandro Garcia © LES/DI/PUC-Rio
Lista de âncoras
• Passo: cria-se uma lista de âncoras (como a do CESPDIN)
– sempre que for dado um malloc, uma âncora é adicionada à
lista
– é possível agora verificar o conjunto de todos os espaços ativos
a partir da lista de âncoras usando o CESPDIN
lista de âncoras
Jun 2018
13
25 / 40Alessandro Garcia © LES/DI/PUC-Rio
Último passo: Verificador da estruturas de dados
• Um verificador de estruturas de dados é um conjunto de
uma ou mais funções especificamente desenvolvidas para
verificar se as estruturas de dados satisfazem as suas
assertivas estruturais
– as funções de verificação pertencem necessariamente ao
módulo em que foram definidos os dados a serem verificados
• idealmente, deveria ser implementada uma função para cada tipo
de elemento
– pode ser fazer uso das redundâncias
– Ex. de verificações:
• tipo dos elementos: CED_ObterTipoEspaco
• quantidade de elementos está correta?
• encadeamento correto de elementos da estrutura
• verifica integridade do espaço (ex. extravasão, etc...):
CED_VerificarEspaco
Jun 2018
26 / 40Alessandro Garcia © LES/DI/PUC-Rio
• Passo: redija um verificador para checar as assertivas
estruturais usando as redundâncias
Exemplos de assertivas?
Exemplo de transformação
Tabela
nVtn
vtRandomização
pEsq
Simbolo
Valor
Id pDirpSimb
ElemTabela
inxHashvtRand
Jun 2018
14
27 / 40Alessandro Garcia © LES/DI/PUC-Rio
• Passo: redija um verificador para checar as assertivas
estruturais usando as redundâncias
pTabela->idTipo == idTipoTabela
pTabela->vtRand->idTipo == idTipoVtRandomizacao
pTabela->vtRand->n >= 2 e n <= 26
...
Exemplo de transformação
Tabela
nVtn
vtRandomização
pEsq
Simbolo
Valor
Id pDirpSimb
ElemTabela
inxHashvtRand
Jun 2018
• Passo: redija (verifique) as assertivas estruturais
pTabela->idTipo == idTipoTabSimb
pTabela->vtRand->idTipo == idTipoTabRand
pTabela->vtRand->pTabela == pTabela
pTabela->vtRand->n >= 2 e n <= 26
inxElem | 0 <= inxElem < pTabela->vtRand->n :
pTabela->vtRand[ inxElem ]->idTipo == idTipoElem
VerificarLista( pTabela->vtRand[ inxElem ] )
pElem Lista{ pTabela->vtRand[ inxElem ] } :
pElem->inxHash == inxElem
pElem->pSimb->idTipo == idTipoVal
Exemplo de transformação
Tabela
nVtn
vtRandomização
pEsq
Simbolo
Valor
Id pDirpSimb
ElemTabela
inxHashvtRand
Jun 2018 Alessandro Garcia © LES/DI/PUC-Rio 28 / 40
15
Verificador – outro exemplo
ARV_tpCondRet ARV_VerificarArvore( void * pArvoreParm ) {
tpArvore * pArvore = NULL ;
if ( ARV_VerificarCabeca( pArvoreParm ) != ARV_CondRetOK )
{
return ARV_CondRetErroEstrutura ;
} /* if */
[...]
pArvore = ( tpArvore * ) ( pArvoreParm ) ;
return VerificarNo( pArvore->pNoRaiz ) ;
} /* Fim função: ARV &Verificar uma árvore */
29 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
Verificador - exemplo
ARV_tpCondRet ARV_VerificarCabeca( void * pArvoreParm ) {
} /* Fim função: ARV &Verificar uma árvore */
30 / 40Alessandro Garcia © LES/DI/PUC-Rio
?Jun 2018
16
Verificador - exemplo
ARV_tpCondRet ARV_VerificarCabeca( void * pArvoreParm ) {
se...
cabeça inexistente?
tipo do espaço não é tipo cabeça?
TST_CompararInt( ARV_TipoEspacoCabeca ,
CED_ObterTipoEspaco( pCabecaParm )...)!=TST_CondRetOK
árvore vazia tem nó corrente não NULL?
uso da redundância: número de elementos
nó raiz não aponta para cabeça?
uso da redundância: ponteiro para cabeça
algum erro no uso do espaço, tais como extravasão de espaço?
CED_VerificarEspaco( pCabecaParm ...)
então
return ARV_CondRetErroEstrutura ;
}
} /* Fim função: ARV &Verificar uma árvore */
31 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
32 / 40Alessandro Garcia © LES/DI/PUC-Rio
Verificador de estruturas de dados
• Uma função verificadora nada mais é do que um um
conjunto de assertivas que detectam erros (exceções)
durante a execução do programa
– aumento da confiabilidade (fidedignidade) do programa
• E se o verificador estiver incorreto?
Jun 2018
17
33 / 40Alessandro Garcia © LES/DI/PUC-Rio
Verificador de estruturas de dados
• E se o verificador estiver incorreto?
– se a implementação da estrutura de dados está correta o
verificador, mesmo completo e o mais rigoroso possível, jamais
encontrará uma falha, consequentemente não se sabe se o
verificador está correto ou não
– pode erroneamente retornar true para dados errados
– pode deixar de verificar algumas condições relevantes
• faltou uma assertiva no conjunto
• uma assertiva foi mal formulada
• Como testar o verificador?
Jun 2018
34 / 40Alessandro Garcia © LES/DI/PUC-Rio
Deturpador de estruturas de dados
• Deturpadores são funções especificamente projetadas para
danificar estruturas de dados
– podem requerer conhecimento da organização dos dados
• neste caso as funções serão internas ao módulo que contém os
dados a serem deturpados
– evitar perda de encapsulamento
• facilita a escolha do que deve ser danificado bastando fornecer o
nome, ou id, do atributo e o seu novo valor
– podem ser funções que alteram um sub-espaço do espaço
dado, baseando-se no deslocamento relativo à origem desse
espaço, na dimensão do espaço a deturpar e no valor a inserir
• neste caso o deturpador pode ser externo ao módulo em teste
• porém torna o deturpador sensível à plataforma e a parâmetros de
compilação
Jun 2018
18
35 / 40Alessandro Garcia © LES/DI/PUC-Rio
Deturpador de estruturas de dados
• Deturpadores devem sempre ser desativados quando o
módulo for compilado para produção
– deturpadores intrinsecamente abrem uma brecha de
insegurança
– deturpadores podem fazer com que o construto em teste “voe”.
Por exemplo, ao substituir um ponteiro por algum outro ilegal.
• sugestão: criar espaços de dados lixo e somente deturpar com
ponteiros ilegais que estejam apontando para estes espaços
• o módulo ARVORE em autotest\instrum\fontes do
arcabouço de apoio aos testes ilustra verificadores e
deturpadores
Jun 2018
36 / 40Alessandro Garcia © LES/DI/PUC-Rio
Deturpador de estruturas de dados
• Deturpador é uma função especificamente projetada para
danificar a estrutura de dados
void ARV_Deturpar( void * pArvoreParm , int ModoDeturpar )
{
...
switch ( ModoDeturpar ) {
/* Modifica o tipo da cabeça */
case DeturpaTipoCabeca :
CED_DefinirTipoEspaco( pArvore , CED_ID_TIPO_VALOR_NULO ) ;
break ;
/* Anula ponteiro raiz */
case DeturpaRaizNula :
pArvore->pNoRaiz = NULL ;
break ;
/* Anula ponteiro corrente */
case DeturpaCorrenteNulo :
pArvore->pNoCorr = NULL ;
break ;
...Jun 2018
19
Dicas – T4
• Criação de um comando de teste: =deturpar <ação>
<ação> = 1 atribui tipo diferente a cabeça de lista
<ação> = 2 atribui NULL ao ponteiro para a raiz
<ação> = 3 atribui NULL ao ponteiro para o corrente
• Deturpadores devem sempre ser desativados quando o
módulo for compilado para produção
• Trabalho: vão entregar
– 1) versão com funções verificadoras e deturpação, e
respectivos testes
– 2) versão sem funções verificadoras e deturpação, e
respectivos testes
• o módulo ARVORE em autotest\instrum\fontes do
arcabouço ilustra verificadores, deturpadores e testes
37 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
38 / 40Alessandro Garcia © LES/DI/PUC-Rio
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
• 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)
• Usar CESPDIN no módulo LISTA e/ou BARALHO
– simular falta de memória e verificar se módulo funciona corretamente
– assertivas que checam acesso correto quanto a tipagem
– Opção: função verificadora que checam se há vazamento de memória
(ex. espaço ativo após a destruição do grafo)
Jun 2018
20
Cronograma
• Aula – 13/6:
– Exercício do T3 relativo a:
• critérios de cobertura de teste caixa-branca
• instrumentação para análise de cobertura dos testes (uso do
módulo CONTA)
• Aulas 18 a 25/6 – dúvidas trabalho T4
• Prova P2 – 27/6 (quarta)
• Entrega do T4 – 29/6 (sexta)
39 / 40Alessandro Garcia © LES/DI/PUC-RioJun 2018
Aula 22Instrumentação - Parte 2
Alessandro Garcia
Eduardo Fernandes (assistente)
Alessandro Garcia © LES/DI/PUC-Rio
Junho 2018