3. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
M˚l
a
M˚let er 100% korrekt programmel - lettere sagt end gjort
a
Kan ikke generelt bevise korrekthed
Inputdomænet er ofte meget stort, ikke alle input er lige
vigtige/sandsynlige
Nogle output er meget uacceptable (hvis de f.eks. giver en
angriber mulighed for at afvikle arbitrær kode p˚ ens server)
a
Sæt ind, hvor det giver mest mening
Michael Rasmussen
Dynamiske analysatorer til C/C++
5. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Metoder til automatisk fejlsøgning/tilsikring af
programkorrekthed
Statiske analyse
Lad oversætteren hjælpe! Oversæt altid med
tilsvarende)!
-Wall -Wextra
Unit-, system-, stress- og regressionsafprøvninger
, køretidskontrol af invarianter (eksempelvis af
iteratorgyldighed)
assert
Dynamisk analyse
Michael Rasmussen
Dynamiske analysatorer til C/C++
(eller
7. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Hvad er dynamisk analyse?
Programafviklingen inspiceres under køretid for forskellige
fejlsituationer og mistænkelig opførsel
Normalt automatisk uden ekstra programmørarbejde
Giver øjeblikkelig feedback - tættere p˚ fejlkilden (som oftest)
a
Virker ved at programmet afvikles i en virtuel maskine, kendte
funktioner opsnappes eller programkoden udvides automatisk
med ekstra køretidscheck
Michael Rasmussen
Dynamiske analysatorer til C/C++
8. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Ulemper
Kun afviklet kode + input kontrolleres
Programafvikling bliver normalt markant langsommere
Programmet afvikles ikke under ”rigtige”forhold (debug build,
ændret timing, o.s.v.)
Falske negativer/positiver (programforhold kan maskere
rigtige fejl, korrekt programmel kan give udslag)
Kan ofte ikke kombineres, anden debugging kan blive
besværliggjort
Beviser ikke fravær af fejl
Michael Rasmussen
Dynamiske analysatorer til C/C++
9. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Eksempler p˚ dynamiske analysatorer
a
Valgrind (http://valgrind.org/)
CodeGuard (Embarcadero RadStudio/C++Builder)
BoundsChecker (Borland/Microfocus BoundsChecker)
Purify (IBM Rational Purify)
*sanitizer Clang 3.2/GCC 4.8
Michael Rasmussen
Dynamiske analysatorer til C/C++
10. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Instrumenterede dynamiske analysatorer
Programkoden udvides af oversætteren til at indeholde diverse
check
Har potentielt mere information end en stand-alone analysator
Kan anskues som automatisk tilføjede
Michael Rasmussen
s
assert
Dynamiske analysatorer til C/C++
11. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Hvad er AddressSanitizer?
Alle hukommelsestilgange instrumenteres af oversætteren
* address = ...; // or : ... = * address ;
// Omskrives til
if ( IsPoisoned ( address ) ) {
ReportError ( address , kAccessSize , kIsWrite ) ;
}
* address = ...; // or : ... = * address ;
Afdækker flere klasser af hukommelsesfejl
Over- og underløb
Brug af dynamisk allokeret hukommelse efter frigivelse
Tilgang til ugyldige hukommelsesomr˚der (findes sædvaneligvis
a
ogs˚ ved normal afvikling)
a
Desværre ikke alle hukommelsesfejl (off-by-one fejl findes let,
off-by-4K er straks sværere)
Michael Rasmussen
Dynamiske analysatorer til C/C++
12. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo 1
// 01. cpp
# include < string .h >
int main () {
char x [8];
strcpy (x , " 01234567 " ) ;
}
$ g ++ -4.8 - Wall - Wextra - std = c ++11 -g 01. cpp
$ ./ a . out
$ valgrind ./ a . out
<<<< klip >>>>
==4587== ERROR SUMMARY : 0 errors from 0 contexts ( suppressed : 2 from 2)
Michael Rasmussen
Dynamiske analysatorer til C/C++
13. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo 1 (fortsat)
$ g ++ -4.8 - Wall - Wextra - std = c ++11 -g - fsanitize = address 01. cpp
$ ./ a . out
=================================================================
==4601== ERROR : AddressSanitizer : stack - buffer - overflow on address
0 x7fff8e4c6b58 at pc 0 x40099d bp 0 x7fff8e4c6b20 sp 0 x7fff8e4c6b18
WRITE of size 1 at 0 x7fff8e4c6b58 thread T0
#0 0 x40099c (/ home / mras / Dropbox / Pres / asan /01/ a . out +0 x40099c )
#1 0 x7fb64b80ede4 (/ lib / x86_64 - linux - gnu / libc -2.17. so +0 x21de4 )
#2 0 x4007b8 (/ home / mras / Dropbox / Pres / asan /01/ a . out +0 x4007b8 )
Address 0 x7fff8e4c6b58 is located at offset 40 in frame < main > of T0 ’ s stack :
This frame has 1 object ( s ) :
[32 , 40) ’x ’
<<<< klip >>>>
Michael Rasmussen
Dynamiske analysatorer til C/C++
14. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo 2
// 02. cpp
char g [8];
int main () {
return g [8];
}
$ g ++ -4.8 - Wall - Wextra - std = c ++11 -g - fsanitize = address 02. cpp
$ ./ a . out
==4637== ERROR : AddressSanitizer : global - buffer - overflow on address
0 x0000006010e8 at pc 0 x4007e6 bp 0 x7fff13416e10 sp 0 x7fff13416e08
READ of size 1 at 0 x0000006010e8 thread T0
#0 0 x4007e5 (/ home / mras / Dropbox / Pres / asan /02/ a . out +0 x4007e5 )
#1 0 x7f04d84fbde4 (/ lib / x86_64 - linux - gnu / libc -2.17. so +0 x21de4 )
#2 0 x4006e8 (/ home / mras / Dropbox / Pres / asan /02/ a . out +0 x4006e8 )
0 x0000006010e8 is located 0 bytes to the right of global variable ’g (02. cpp ) ’
(0 x6010e0 ) of size 8
’g (02. cpp ) ’ is ascii string ’’
Michael Rasmussen
Dynamiske analysatorer til C/C++
15. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Hvad er ThreadSanitizer?
Værktøj til at p˚vise datakapløb i programmet
a
Hukommelsestilgange (der ikke er beviseligt kapløbsfri) i
programmet instrumenteres og sendes til en tilstandsmaskine
Tilstandsmaskinen gemmer en begrænset liste af
hukommelsestilgange og sammenholder dem for at afdække
datakapløb
Fejl kan slippe igennem, men fundne problemer har høj
sandsynlighed for at være reelle
Kender til atomiske variable og efterh˚nden det meste af
a
C++11 standardbiblioteket
Michael Rasmussen
Dynamiske analysatorer til C/C++
16. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo
// 01. cpp
# include < pthread .h >
int g ;
void * f ( void *) {
g ++;
return NULL ;
}
int main () {
pthread_t t1 , t2 ;
pthr ead_create (& t1 , NULL , f , NULL ) ;
pthr ead_create (& t2 , NULL , f , NULL ) ;
pthread_join ( t1 , NULL ) ;
pthread_join ( t2 , NULL ) ;
return g ;
}
Michael Rasmussen
Dynamiske analysatorer til C/C++
17. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo (fortsat)
$ g ++ -4.8 - Wall - Wextra - std = c ++11 -g - fsanitize = thread - pie - fPIC 01. cpp
-Wl , - - no - as - needed - ltsan - pthread - lpthread && ./ a . out
WARNING : ThreadSanitizer : data race ( pid =14413)
Read of size 4 at 0 x7ff7cd0e609c by thread T2 :
#0 f ( void *) / home / mras / Dropbox / Pres / tsan /01/01. cpp :6 ( exe +0 x000000000b8d )
#1 _ _ t sa n _w ri t e_ ra n ge ??:0 ( libtsan . so .0+0 x00000001b1c9 )
Previous write of size 4 at 0 x7ff7cd0e609c by thread T1 :
#0 f ( void *) / home / mras / Dropbox / Pres / tsan /01/01. cpp :6 ( exe +0 x000000000ba8 )
#1 _ _ t sa n _w ri t e_ ra n ge ??:0 ( libtsan . so .0+0 x00000001b1c9 )
Thread T2 ( tid =14415 , running ) created by main thread at :
#0 pt hread_create ??:0 ( libtsan . so .0+0 x00000001eccb )
#1 main / home / mras / Dropbox / Pres / tsan /01/01. cpp :13 ( exe +0 x000000000c13 )
Thread T1 ( tid =14414 , running ) created by main thread at :
#0 pt hread_create ??:0 ( libtsan . so .0+0 x00000001eccb )
#1 main / home / mras / Dropbox / Pres / tsan /01/01. cpp :12 ( exe +0 x000000000bf6 )
SUMMARY : ThreadSanitizer : data race / home / mras / Dropbox / Pres / tsan /01/01. cpp :6 f (
void *)
Michael Rasmussen
Dynamiske analysatorer til C/C++
18. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Demo (fortsat)
Retfærdigvis skal det nævnes at helgrind ogs˚ finder datakapløbet:
a
$ g ++ -4.8 - Wall - Wextra - std = c ++11 -g 01. cpp -Wl , - - no - as - needed
- pthread - lpthread && valgrind -- tool = helgrind ./ a . out
<<<< klip >>>>
==14397== Possible data race during read of size 4 at 0 x60105C by thread #3
==14397== Locks held : none
==14397==
at 0 x400785 : f ( void *) (01. cpp :6)
==14397==
by 0 x4C2EA06 : ??? ( in / usr / lib / valgrind / vgpreload_helgrind - amd64 linux . so )
==14397==
by 0 x4E3DF6D : start_thread ( pthread_create . c :311)
==14397==
by 0 x596B9CC : clone ( clone . S :113)
==14397==
==14397== This conflicts with a previous write of size 4 by thread #2
==14397== Locks held : none
==14397==
at 0 x40078E : f ( void *) (01. cpp :6)
==14397==
by 0 x4C2EA06 : ??? ( in / usr / lib / valgrind / vgpreload_helgrind - amd64 linux . so )
==14397==
by 0 x4E3DF6D : start_thread ( pthread_create . c :311)
==14397==
by 0 x596B9CC : clone ( clone . S :113)
<<<< klip >>>>
Michael Rasmussen
Dynamiske analysatorer til C/C++
19. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Andre sanitizers
MemorySanitizer - Læsning af uintialiseret hukommelse
IntegerSanitizer - Heltalsoverløb
UndefinedSanitizer - Finder udefineret opførsel, der er
”billig”at have køretidscheck for
Flere p˚ vej
a
Michael Rasmussen
Dynamiske analysatorer til C/C++
20. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Omkostninger
Falsk tryghedsfølelse - et fravær af konstaterede fejl betyder
ikke at programmet er korrekt eller fejlfrit
Forøget køretid og hukommelsesforbrug (b˚de rigtig og virtuel
a
hukommelse)
Ændring af timing
Kan ikke bruges sammen - afprøvning med b˚de Thread- og
a
AddressSanitizer nødvendig
Falske positiver
Kun afprøvet kode/input checkes
Michael Rasmussen
Dynamiske analysatorer til C/C++
21. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Hvordan kommer man i gang?
Alle unittests og særlige stresstests kører under Thread- og
AddressSanitizer (gerne altid)
Gør et hjørne af koden klar - brug evt. supressions
N˚ til et punkt, hvor alle detekterede problemer er værd at
a
undersøge
Husk: Overvej en ekstra gang om koden er korrekt inden en
potentiel falsk positiv afvises
Michael Rasmussen
Dynamiske analysatorer til C/C++
22. Indledning
Dynamisk analyse
AddressSanitizer
ThreadSanitizer
Praktisk brug
Konklusion
Mere information
Konklusion
Sanitizers kan hjælpe til at automatisk at afdække flere
klasser af fejl
Garanterer ikke korrekthed, men giver en bedre
”mavefornemmelse”
Det bør være et m˚l at ens program er ”clean”under afvikling
a
i valgrind og med Thread- og AddressSanitizer
Bør bruges i kombination med andre teknikker (herunder
statisk programanalyse)
Det betaler sig, at finde fejl tidligt (ment b˚de som tæt p˚ at
a
a
fejlen blev introduceret og tæt p˚ fejlkilden i programkoden)
a
Michael Rasmussen
Dynamiske analysatorer til C/C++