analizzatori di programmi in c
Post on 27-Jun-2015
748 Views
Preview:
DESCRIPTION
TRANSCRIPT
Tools di analisi di programmi sviluppati in ANSI C
Studio dei tre tools di analisi CFlow , Fjalar e Metre. Verranno messi a confronto per i loro requisiti di installazione, semplicità di utilizzo e funzionalità offerte.
Autore: Maurizio Pianfetti Esame per “Linguaggi e Traduttori”
seguito da Armando Tacchella, Jacopo Mantovani e Luca Pulina
Tools di analisi di programmi sviluppati in ANSI C : CFlow
il progetto GNU Cflow è un analizzatore di sorgenti C che restituisce come output il flusso computazionale del programma in base alle funzioni richiamate dalla funzione di partenza ( normalmente il main )
attualmente la versione stabile è la 1.2 ultimata il 29/06/2007
software rilasciato sotto licenze GPLv3, usufruibile gratuitamente
riferimenti all'applicazione:http://www.gnu.org/software/cflow/
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( funzionalità )
è possibile avere il flow del programma da due punti di vista diversi
Direct graph: partendo dalla funzione principale si elencano le chiamate e sotto chiamate in modo ricorsivo alle funzioni nel programma ( caller — callee dependencies )
Reverse graph: partendo da tutte le funzioni nel programma si risale a chi chiama la singola funzione in ordine inverso ( callee — caller dependencies )
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( funzionalità ) informazioni aggiuntive: oltre alle firme delle funzioni e
l'ordine con cui vengono chiamate è possibile avere: variabili o funzioni di tipo statico e globali ( i
simboli ), non è possibile una analisi locale tipi, parametri e valori di ritorno delle variabili e
funzioni rilevate è possibile fare una analisi di tipo PreProcessor è possibile avere l'elenco delle dichiarazioni di ogni
singolo simbolo ( cross-reference listings ) segnala le funzioni richiamate ricorsivamente
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( Output ) l'output di cflow può essere di due tipi:
POSIX: si ha l'elenco delle firme di ogni singola funzione con dei caratteri aggiuntivi per definire l'ingresso in esse, col numero progressivo di ordine di chiamata e richiamo alla riga di dichiarazione nel caso di funzione ricorsiva. Questo standard è utilizzato da ulteriori tools di analisi che utilizzati in “pipe” dopo CFLow creano grafici costruendo flow del programma [ cflow2vcg http://cflow2vcg.sourceforge.net/xvcg
http://rw4.cs.uni-sb.de/users/sander/html/gsvcg1.htmlComando: cflow --format=posix --omit-arguments \--level-indent='0=\t' --level-indent='1=\t' \--level-indent=start='\t' $* | cflow2vcg | xvcg -
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( Output )
GNU Output: si ha l'elenco delle firme di ogni singola funzione con dei caratteri di tabulazione per definire ciò che avviene all'interno di esse. L'output generato è configurabile ed è possibile:
aggiungere il numero progressivo di chiamata cambiare i caratteri di ingresso nelle funzioni omettere la firma delle funzioni
Attualmente non esiste l'estensione per un output XML o HTML , probabilmente funzione presente nelle versioni future
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( Usabilità ) può essere installato come plugin di Emacs può essere facilmente integrato come parte di
progetto facendo una configurazione opportuna nel file Makefile.am
è possibile definire delle configurazioni di default settando delle variabili di ambiente o utilizzando un file di configurazione
è possibile utilizzarlo agganciando l'analisi ad un debugger ( Es. gdd )
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Caratteristiche ( Installazione )
per l'installazione necessita soltanto delle librerie “header” del kernel Linux per poter essere compilato
l'installazione comporta l'esecuzione dei classici tre comandi:./configure; make; make install
è un programma senza interfaccia grafica command-line adatto per sistemi di automazione e punto di partenza per analisi più complesse
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Esempio#include <stdlib.h>#include <stdio.h>#include <assert.h>
int division(int dividend, int divisor) { int remainder = dividend; int quotient = 0; assert(divisor > 0); //assert(dividend > 0); while (divisor <= remainder) { remainder = remainder - divisor; ++quotient; } return quotient;}int main(int argc, char *argv []) { int dividend, divisor; if (argc != 3) { printf("Usage: div <dividend> <divisor>"); exit(EXIT_FAILURE); } dividend = atoi(argv[1]); divisor = atoi(argv[2]); //if (divisor <= 0) return 2; printf("%d", division( dividend, divisor )); return 0;}
Si consideri il seguente programma C che esegue una divisione tra due numeri
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Direct Flow
Formato di default
main() <int main (int argc,char *argv[]) at division.c:18>: printf() exit() atoi() division() <int division (int dividend,int divisor) at division.c:6>: assert()
Formato posix
1 main: int (int argc,char *argv[]), <division.c 18>2 printf: <>3 exit: <>4 atoi: <>5 division: int (int dividend,int divisor), <division.c 6>6 assert: <>
Ecco i due output possibili come flow diretto del codice d'esempio
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Reverse Flowassert():
division() <int division (int dividend,int divisor) atdivision.c:6>: main() <int main (int argc,char *argv[]) atdivision.c:18>
atoi(): main() <int main (int argc,char *argv[]) at division.c:18>
division() <int division (int dividend,int divisor) atdivision.c:6>: main() <int main (int argc,char *argv[]) at division.c:18>
exit(): main() <int main (int argc,char *argv[]) at division.c:18>
main() <int main (int argc,char *argv[]) at division.c:18>
printf(): main() <int main (int argc,char *argv[]) at division.c:18>
Viene evidenziata ogni singola funzione da chi viene richiamata
Tools di analisi di programmi sviluppati in ANSI C : CFlow
Numero di richiami e simboliassert division.c:9
atoi division.c:24atoi division.c:25division *division.c:6 int (int dividend,int divisor)division division.c:27exit division.c:22main *division.c:18 int (int argc,char *argv[])printf division.c:21printf division.c:27
1 main: int (int argc,char *argv[]), <division.c 18>
2 printf: <>3 exit: <>4 EXIT_FAILURE: <>5 atoi: <>6 division: int (int dividend,int divisor),
<division.c 6>7 assert: <>
Cflow evidenzia tutti i singoli richiami alle varie funzioni, visualizza le dichiarazioni e i simboli di compilazione
Tools di analisi di programmi sviluppati in ANSI C : CFlowVisualizzazione umana
E' anche possibile una visualizzazione ad albero
1 +-main() <int main () at division.c:18>2 +-printf()3 +-exit()4 +-atoi()5 \-division()
Tools di analisi di programmi sviluppati in ANSI C : Metre
il progetto Metre è un analizzatore di sorgenti ANSI C che restituisce come output una analisi statistica secondo alcune metriche che descrivono il livello di complessità / ottimalità di funzionamento del sorgente scritto e analizzato
attualmente la versione stabile è la 2.3 ultimata il 03/04/1995
software rilasciato con Copyright“Metre Copyright (c) 1993-1995 by Paul Long All rights reserved” . La licenza specificata è l'utilizzo gratuito per applicazioni No profit, diversamente bisogna richiedere la licenza d'uso direttamente allo sviluppatore (Paul Long)http://www.lysator.liu.se/c/metre-v2-3.html
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Metriche )vengono calcolate le seguenti metriche: McCabe's cyclomatic complexity : calcola la complessità del programma
analizzando il numero di costruttori con punti di decisione. L'antologia su questo argomento mette a confronto complessità con numero di possibili bug
Myers' extended complexity : evoluzione della metrica precedente, rileva l'effettivo numero di decisioni considerando il numero di condizioni per ogni costrutto
Cyclomatic Bug probability < 10 520 – 30 20> 50 40~100 60
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Metriche ) Halstead's program length: vengono calcolati il numero di “parole” e “operatori” del
linguaggio usate , con questi numeri vengono a loro volta calcolati i seguenti parametri: Considerando un programma di due funzioni:
operatori univoci f1 n1operatori univoci f2 n2totali operatori f1 N1totali operatori f2 N2velocità di scrittura S = 18 momenti / secondofattore di secondo all'ora f = 60 * 60
Si calcolano i segunti parametri:
Lunghezza Prog. N = N1 + N2Vocabolario n = n1 + n2Volume V = N * log2(n)Livello L^ = (2 / n1) * (n2 / N2)Effort E = V / L^Durata del programma in ore T^ = E / (S * f)Intelligenza I = L^ * VLivello del linguaggio L' = L^ * L^ * V
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Metriche ) Line Classifications: vengono calcolate le righe di codice, commenti e linee
senza testo. Nel caso in cui si analizza il programma in modalità preprocessor per avere l'analisi dei commenti bisognerà compilarlo considerando eliminazione / mantenimento dei commenti
Statement-Counting Standard: si classificano le “parole” del linguaggio utilizzate secondo l'antologia e regole descritte nel libro “Applied Software Measurement” di Capers Jone, in particolare si contano:
Executable-Statement: direttive del linguaggio utilizzato ( C ) Declaration-Statement: dichiarazioni di variabili e funzioni Preprocessor Statements: vengono contate le parole di codice per il
preprocessore ( nel caso del C le linee che iniziano con “#” ) Backfired function points: parametro empirico che descrive il rapporto tra
numero di “function points” e numero di righe di codice, utilizzato nei grandi progetti per valutarne la complessità
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Metriche )
Maximum control depth: definisce la profondità di annidiamento dei costrutti utilizzati
Identifier count and length: definisce il numero di identificatori ( nomi ) variabili e funzioni con la loro lunghezza massima
Number of functions and modules: definisce il numero di funzioni e moduli, intesi come file separati, librerie e sorgenti nell'intero progetto analizzato
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Output )Esistono due tipi di output:
standard : per ogni modulo e funzione vengono calcolate le singole metriche e viene visualizzata una lista con il totale, il minimo, il massimo e la media del valori trovati secondo il seguente formato:
per ogni funzione: Cyclomatic: total
Extended: total Halstead Length: total Vocabulary: total Volume: total Level: total Effort: total Intelligence: total Time (hours) total Lang Level: total Lines: total Code: total Comment: total Blank: total Exec Statements: total Decl Statements: total Max Depth: total Identifiers: total Length: <min >max ~avg
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Output ) per ogni modulo: -Function- Cyclomatic: <min >max ~avg Extended: <min >max ~avg Halstead Length: <min >max ~avg Vocabulary: <min >max ~avg Volume: <min >max ~avg Level: <min >max ~avg Effort: <min >max ~avg Intelligence: <min >max ~avg Time (hours) <min >max ~avg total Lang Level: <min >max ~avg Lines: <min >max ~avg total Code: <min >max ~avg total Comment: <min >max ~avg total Blank: <min >max ~avg total Exec Statements: <min >max ~avg Decl Statements: <min >max ~avg total Max Depth: <min >max ~avg
-Module- Lines: total Code: total Comment: total Blank: total Exec Statements: total Decl Statements: total PP Statements: total Function Points: total Identifiers: total Length: <min >max ~avg Functions: total
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Output ) per ogni modulo: -Function- Cyclomatic: <min >max ~avg Extended: <min >max ~avg Halstead Length: <min >max ~avg Vocabulary: <min >max ~avg Volume: <min >max ~avg Level: <min >max ~avg Effort: <min >max ~avg Intelligence: <min >max ~avg Time (hours) <min >max ~avg total Lang Level: <min >max ~avg Lines: <min >max ~avg total Code: <min >max ~avg total Comment: <min >max ~avg total Blank: <min >max ~avg total Exec Statements: <min >max ~avg Decl Statements: <min >max ~avg total Max Depth: <min >max ~avg
-Module- Lines: total Code: total Comment: total Blank: total Exec Statements: total Decl Statements: total PP Statements: total Function Points: total Identifiers: total Length: <min >max ~avg Functions: total
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Output )
CSV ( comma separated value ): viene generata una riga di output per ogni funzione, modulo o progetto analizzato. Ogni riga è composta da diversi campi divisi per “,”. E' possibile personalizzare quali metriche stampare e disabilitare i messaggi di warning che non vengono stampati nel formato standard ma come righe separate mod,insertsort.c,3,3,3,3,3,3,146,146,146,33,33,33,736,736,736,0.051,0.051,0.051,14510,14510,14510,37,37,37,0.2,0.2,0.2,0.2,1.89,1.89,1.89,33,33,33,33,32,32,32,32,0,0,0,0,1,1,1,1,26,26,26,1,1,1,1,2,2,2,86,37,42,7,26,2,12,0,46,1,6,2,1
non è supportato XML
Tools di analisi di programmi sviluppati in ANSI C : Metre
Caratteristiche ( Installazione ) per l'installazione necessita soltanto delle librerie
“header” del kernel Linux per poter essere compilato l'installazione comporta l'esecuzione del comando di
compilazione dei sorgenti. Sono disponibili due tools, metre e mtree
gcc -ansi -w -o metre metrules.c ytab.c lex_yy.c -lmgcc -ansi -w -o mtree trerules.c ytab.c lex_yy.c -lm
è un programma senza interfaccia grafica command-line adatto per sistemi di automazione
Tools di analisi di programmi sviluppati in ANSI C : Metre
Considerazioni
se un sorgente non è ANSI C, per esempio contiene righe con commenti “//” viene generato un “Fatal Error” e non viene completata l'analisi
l'autore consiglia l'analisi di sorgenti di tipo PREPROCESSED
Tools di analisi di programmi sviluppati in ANSI C : Metre
Confronto tra “Mtree” di Metre e la funzione “tree” di CFLow
Cflow - tree1 +-main() <int main ()
at division_ANSI.c:18>2 +-printf()3 +-exit()4 +-atoi()5 \-division()
Metre – Mtreeision_ANSI.c main +---printf +---exit +---atoiision_ANSI.c `---division `---assert
Table of Contentsdivision_ANSI.c division . . . . . . . . . . . 6 main . . . . . . . . . . . . . 18
#include <stdlib.h>#include <stdio.h>#include <assert.h>
int division(int dividend, int divisor) { int remainder = dividend; int quotient = 0; assert(divisor > 0); /* assert(dividend > 0); */ while (divisor <= remainder) { remainder = remainder - divisor; ++quotient; } return quotient;}intmain(int argc, char *argv []) { int dividend, divisor; if (argc != 3) { printf("Usage: div <dividend> <divisor>"); exit(EXIT_FAILURE); } dividend = atoi(argv[1]); divisor = atoi(argv[2]); /* if (divisor <= 0) return 2; */ printf("%d", division( dividend, divisor )); return 0;}
Tools di analisi di programmi sviluppati in ANSI C : Metre
EsempioModule Summary-Function-Cyclomatic: <2 >2 ~2Extended: <2 >2 ~2Halstead Length: <30 >43 ~37Vocabulary: <16 >24 ~20Volume: <120 >197 ~159Level: <0.086 >0.167 ~0.127Effort: <1182 >1400 ~1291Intelligence: <10 >33 ~22Time (hours): <0.0 >0.0 ~0.0 0.0Lang Level: <0.88 >5.47 ~3.18Lines: <10 >11 ~11 21Code: <9 >10 ~10 19Comment: <1 >1 ~1 2Blank: <0 >0 ~0 0Exec Statements: <6 >8 ~7Decl Statements: <1 >2 ~2 3Max Depth: <1 >1 ~1
-Module-Lines: 29Code: 26Comment: 2Blank: 1Exec Statements: 14Decl Statements: 3PP Statements: 3Function Points: 0Identifiers: 34Length: <4 >12 ~7Functions: 2
#include <stdlib.h>#include <stdio.h>#include <assert.h>
int division(int dividend, int divisor) { int remainder = dividend; int quotient = 0; assert(divisor > 0); /* assert(dividend > 0); */ while (divisor <= remainder) { remainder = remainder - divisor; ++quotient; } return quotient;}intmain(int argc, char *argv []) { int dividend, divisor; if (argc != 3) { printf("Usage: div <dividend> <divisor>"); exit(EXIT_FAILURE); } dividend = atoi(argv[1]); divisor = atoi(argv[2]); /* if (divisor <= 0) return 2; */ printf("%d", division( dividend, divisor )); return 0;}
mod,division_ANSI.c,2,2,2,2,2,2,30,43,37,16,24,20,120,197,159,0.086,0.167,0.127,1182,1400,1291,10,33,22,0.0,0.0,0.0,0.0,0.88,5.47,3.18,10,11,11,21,9,10,10,19,1,1,1,2,0,0,0,0,6,8,7,1,2,2,3,1,1,1,29,26,2,1,14,3,3,0,34,4,12,7,2
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
il progetto Fjalar è un framework per lo sviluppo di tools analizzatori del comportamento a compile-time e run-time di programmi C e C++, sfruttando il noto simulatore di CPU Valgrind, verificando problemi di allocazione di memoria legati alle dichiarazioni di variabili
attualmente la versione stabile è la 1.3 rilasciata il 30/08/2007
il software è rilasciato con licenza GNU General Public License e Copyright (C) 2004-2006 Philip Guo (pgbovine@alum.mit.edu), MIT CSAIL Program Analysis Grouphttp://groups.csail.mit.edu/pag/fjalar/
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Caratteristiche ( struttura )
Valgrind
Fjalar
Framework
Kvasir ( rileva strutture dati )
DynComp ( analisi dinamica distrutture astratte )
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Caratteristiche ( funzionalità ) fornisce informazioni relative all'accesso alle variabili,
tipi, indirizzi fisici, spazio allocato e visibilità (file, static, private, public)
rileva associazioni tra strutture e tipi di classe, con variabili per capire eventuali annidamenti e definizioni di strutture in modo ricorsivo
fornisce informazioni relative all'accesso alle funzioni, indirizzi, prototype, visibilità, parametri associati con valore e tipo di ritorno
crea nomi univoci per le variabili e funzioni globali per eliminare ambiguità in modo da facilitare l'analisi globale per altri ipotetici tools collegati
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Caratteristiche ( funzionalità )
offre molte informazioni Run-time basate sull'esecuzione del programma per fare analisi di crash e memory lack
è possibile analizzare solo parte del programma definendo quali funzioni analizzare
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Caratteristiche ( output )
offre diversi formati di output, derivati dai formati garantiti da Valgrind:
default output su standard error stampa su file, se ci sono più processi è possibile
fare un unico file o più files per ogni processo stampa su socket per la stampa via rete, Valgrind
offre un listener ed un client rispettivamente per ricevere e inviare messaggi
offre il formato XML per strutturare le varie informazioni in modo maggiormente interpretabile da altri tools
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Caratteristiche ( Installazione )
per l'installazione necessita soltanto delle librerie “header” del kernel Linux per poter essere compilato
l'installazione comporta l'esecuzione di alcuni comandi per la compilazione dei sorgenti.
./autogen.sh ./configure make make install
è un programma senza interfaccia grafica command-line adatto per sistemi di automazione
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Esempio
<executable-name>./select</executable-name><global-variable-declarations><variable><name><![CDATA[/arr]]></name><global-var><location>0x8049860</location><filename>./select.c</filename></global-var><static-array><num-dimensions>1</num-dimensions><upper-bound>19</upper-bound></static-array><var-type pointer-levels="1"><declared-type>D_UNSIGNED_FLOAT</declared-type><byte-size>4</byte-size></var-type></variable></global-variable-declarations>
float arr[20] = { 5, 4, 10.3, 1.1, 5.7, 100, 231, 111, 49.5, 99, 10, 150, 222.22, 101, 77, 44, 35, 20.54, 99.99, 888.88};
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Esempio<function><name><![CDATA[select]]></name><fjalar-name><![CDATA[..select()]]></fjalar-name><start-PC>0x8048364</start-PC><end-PC>0x8048640</end-PC><filename>./select.c</filename><formal-parameters><variable><name><![CDATA[k]]></name><var-type><declared-type>D_UNSIGNED_INT</declared-type><byte-size>4</byte-size></var-type></variable><variable><name><![CDATA[n]]></name><stack-byte-offset>4</stack-byte-offset><var-type><declared-type>D_UNSIGNED_INT</declared-type><byte-size>4</byte-size></var-type></variable></formal-parameters><return-value><variable><name><![CDATA[return]]></name><var-type><declared-type>D_UNSIGNED_FLOAT</declared-type><byte-size>4</byte-size></var-type></variable></return-value></function>
float select(unsigned long k, unsigned long n){ unsigned long i,ir,j,l,mid; float a,temp; int flag, flag2;
...
...
...
} return arr[k];}
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Esempio<function><name><![CDATA[main]]></name><fjalar-name><![CDATA[..main()]]></fjalar-name><start-PC>0x8048640</start-PC><end-PC>0x8048670</end-PC><filename>./select.c</filename><formal-parameters></formal-parameters><return-value><variable><name><![CDATA[return]]></name><var-type><declared-type>D_INT</declared-type><byte-size>4</byte-size></var-type></variable></return-value></function>>
main(){ select(10, 20);}
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Considerazioni è necessario compilare il programma per
poterlo analizzare e se la compilazione non termina con successo non si ha l'analisi del programma
non vengono considerate le variabili all'interno delle funzioni ma solo quelle globali, parametri e funzioni, poichè non è ingrado di avere informazioni nella fase di registry dal compilatore
se il programma non contiene un main e non si può compilare, non è possibile analizzarlo
Tools di analisi di programmi sviluppati in ANSI C
Analisi di sorgenti Benchmark Source CFLow Metre Fjalar
bisort OK KO – Many errors compile timebs OK OK OK
division OK OKdivisuin_ANSI OK OK OK
driver OK OKfibcall OK OK OKinsertsort OK OK OK
qsort-exam OK OK
select OK OK
sqrt OK OK
KO – HANDLE *handles[DFS_SIZE]; - swap.c(11): Fatal Error ME0000: Syntax error
KO - //assert(dividend > 0); - division.c(10): Fatal Error ME0000: Syntax error
KO – Many errors compile time - collec-t2: ld returned 1 exit status
KO - if (arr[l] > arr[ir]) { - qsort-exam.c(80): Fatal Error ME0000: Syntax errorKO - } - select.c(72): Fatal Error ME0000: Syntax error
KO – Many errors compile time - undefi-ned reference to `main'collect2: ld returned 1 exit status
Tools di analisi di programmi sviluppati in ANSI C : Fjalar
Considerazioni è necessario compilare il programma per
poterlo analizzare e se la compilazione non termina con successo non si ha l'analisi del programma
non vengono considerate le variabili all'interno delle funzioni ma solo quelle globali, parametri e funzioni, poichè non è ingrado di avere informazioni nella fase di registry dal compilatore
se il programma non contiene un main e non si può compilare, non è possibile analizzarlo
top related