[Powered by Google Translate] [Valgrind]
[Nate Hardison, Harvard University]
Ez CS50, CS50.TV]
Néhány a legnehezebb hibákat a C programok
származnak hűtlen emlékezet.
Van egy hatalmas számos módon rontani a dolgokat,
beleértve kiosztása a rossz memória,
felejtés változók inicializálása,
írás előtt vagy után a végén egy puffer,
és felszabadítja tartsa memória többször.
A tünetek terjedhet váratlan összeomlások
A titokzatos felülíródnak értékek,
gyakran olyan helyeken és időkben távol az eredeti hibát.
Követése a megfigyelt problémát vissza a mögöttes kiváltó ok
nagy kihívás lehet,
de szerencsére van egy hasznos program neve Valgrind
hogy sokat tehetnek, hogy segítsen.
>> Ehhez egy programot futtatsz alapján Valgrind hogy
kiterjedt ellenőrzése heap memóriakiosztás és hozzáférések.
Ha Valgrind problémát észlel, akkor ad azonnali,
közvetlen információt, amely lehetővé teszi, hogy
könnyebben megtalálni és kijavítani a problémát.
Valgrind is jelentéseket kevesebb halálos memória problémák,
mint például a memória szivárgás, elosztásának kupac memória,
és megfeledkezve arról, hogy kiszabadítsa azt.
Mint a fordító, csenget a mi debugger, GDB,
Valgrind szabad szoftver, és telepítve van a készülékre.
Valgrind fut a bináris végrehajtható,
nem az. c vagy. h forráskód fájlokat,
úgyhogy győződjön meg róla, hogy összeállított egy up-to-date másolatot a program
használatával csenget vagy Gyártmány.
Ezután fut a program keretében Valgrind is lehet
olyan egyszerű, mint csak raksz a standard program parancsot a szót Valgrind,
amely elindul Valgrind és futtatja a programot belsejébe.
Indításakor, Valgrind nem valami bonyolult
jiggering beállítani végrehajtható a memória ellenőrzések
így hogy egy kicsit, hogy kelj fel és működik.
A program ezután végre rendesen, legyen sokkal lassabban,
és amikor befejezi, Valgrind kiírja összefoglalót a memória használat.
Ha minden jól megy, akkor valahogy így néz ki:
Ebben az esetben a. / Clean_program
a program elérési útja szeretnék futtatni.
És amíg ez nem kerül semmilyen érvet,
ha mégis Én csak tack őket, hogy a végén a parancs a szokásos módon.
Clean program csak egy buta kis program általam létrehozott
hogy osztja helyet egy blokk ints a halom,
egy kis értékei bennük, és felszabadítja az egész blokk.
Ez az, amit a forgatás, nem hiba és nem szivárog.
>> Egy másik fontos metrika a bájtok számát különítettek el.
Attól függően, hogy a program, ha a juttatások vannak a megabájt vagy magasabb,
akkor valószínűleg csinál valamit rosszul.
Ön feleslegesen ismétli tárolására?
Ön használja a halom, a tárolás, amikor jobb lenne használni a stack?
Szóval, memória hiba lehet igazán gonosz.
Minél több nyilvánvaló is okoznak látványos összeomlik,
de még akkor is még mindig nehéz pontosan
hogy pontosan mi vezetett az összeomláshoz.
Több alattomosan, a program a memória hiba
még fordítani tisztán
és továbbra is úgy tűnik, hogy működik helyesen
mert sikerült szerencsés a legtöbb időt.
Miután több "sikeres eredmények,"
talán csak úgy gondolja, hogy egy baleset a szerencse a számítógép,
de a számítógép soha nem téved.
>> Futás Valgrind segítségével nyomára az oka a látható memória hiba
valamint találta lappangó hibát nem is még tudni.
Minden alkalommal, amikor Valgrind problémát észlel, akkor kiírja, hogy milyen is megfigyelhető.
Minden elem meglehetősen tömör -
a sornak a jogsértő utasítás, mi a kérdés,
és egy kis információ a memóriában érintett -
de gyakran elég információt irányítani a figyelmet, hogy a megfelelő helyre.
Íme egy példa a Valgrind futó buggy programra
amely nem érvénytelen olvasható a heap memória.
Nem látjuk hibák és figyelmeztetések összeállítása.
Uh-oh, a hiba összegzés azt mondja, hogy van két hiba -
2 érvénytelen olvasás mérete 4 - bytes, hogy van.
Mindkettő rossz beolvassa történt a fő funkciója invalid_read.c,
Az első on line 16 és a második sorban 19.
Nézzük meg a kódot.
Úgy néz ki, mint az első hívást printf próbál olvasni egy int az elmúlt vége a memória blokk.
Ha megnézzük vissza Valgrind kimeneti,
azt látjuk, hogy Valgrind elmondta nekünk, hogy pontosan.
A cím próbálunk olvasni kezdi 0 bájt
múlt a végét a blokk méret 16 byte -
4 32-bit ints hogy különítettek el.
Ez azt jelenti, a cím igyekeztünk olvasni kezd jobbra a végén a mondat,
ahogy látjuk, a mi rossz printf hívást.
Most, érvénytelen olvasás talán nem tűnik olyan nagy üzlet,
de ha használja ezeket az adatokat áramlását kontrollálják a program -
Például részeként if vagy loop -
akkor a dolgok csendben megy rossz.
Nézd meg, hogyan lehet futtatni a programot invalid_read
és semmi szokatlan történik.
Ijesztő, mi?
>> Most nézzük meg néhány fajta hiba, amit esetleg felmerülő a kódot,
, és majd meglátjuk, hogyan Valgrind észleli őket.
Most láttam egy példa egy invalid_read,
így most nézzük meg egy invalid_write.
Ismét nem hibák vagy figyelmeztetések összeállítása.
Oké, Valgrind azt mondja, hogy van két hiba ebben a programban -
és invalid_write és invalid_read.
Nézzük meg ezt a kódot.
Úgy néz ki, most már van egy példány a klasszikus strlen plusz egy bug.
A kód nem malloc extra byte helyet
A / 0 karaktert,
így amikor str másolatot elment írni azt ssubstrlen "CS50 sziklák!"
azt írta, 1 byte az elmúlt vége a blokk.
A invalid_read jön, amikor tesszük hívás printf.
Printf végül olvasás érvénytelen memória, ha elolvassa a / 0 karakter
mivel úgy néz ki, a végén az E húr ez nyomtatást.
De mindez nem szökött Valgrind.
Látjuk, hogy elkapta a invalid_write részeként str másolat
on line 11 fő, és a invalid_read része printf.
Rock, Valgrind.
Ismét, ez talán nem tűnik nagy dolognak.
Mi lehet futtatni ezt a programot, újra és újra kívül Valgrind
és nem látok semmilyen hibát tüneteket.
>> Azonban nézzük meg egy kis módosítás e látni
hogy a dolgok nagyon rossz.
Így biztosított, hogy visszaélnek a dolgokat több, mint egy kicsit ezt a kódot.
Mi csak felosztásának a heap két húrok
a hossza CS50 kőzetek,
Ekkor eszébe jutott a / 0 karaktert.
De aztán dobni egy szuper-hosszú string a memória blokk
hogy az S mutat.
Milyen hatása lesz, amelyek a memória blokk, hogy a T pontot?
Nos, ha a T rámutat memória, amely csak szomszédos S,
jön csak azt követően,
akkor volna felülírni része T.
Fussunk ezt a kódot.
Nézd meg, mi történt.
A húrok mi nálunk tárolt kupac blokkok mind úgy tűnt, hogy kinyomtatott helyesen.
Úgy tűnik, semmi baj egyáltalán.
Azonban, menjünk vissza a kódot, és
megjegyzésbe a sort, ahol bemásolod CS50 sziklák
a második memória blokk által mutatott t.
Most, amikor ezt a kódot meg kellene
csak látni a tartalmát az első memóriablokk kinyomtatni.
Hú, még akkor is, nem str másolat
karaktereket a második halom blokk, az egyik által mutatott T,
kapunk egy nyomtatott ki.
Valóban, a húr azt töltve az első mondatban
lerohanták az első blokk, és a második mondatban,
hogy mindent úgy tűnik normális.
Valgrind, bár azt mondja, az igaz történet.
Ott vagyunk.
Minden e helytelenül olvas és ír.
>> Nézzünk egy példát egy másik fajta hiba.
Itt nem teszünk valamit, hanem szerencsétlen.
Mi megragad hely int a halom,
és mi inicializálni egy int pointer - p -, hogy pont ezt a helyet.
Azonban, míg a mutató-ra,
Az adatok, hogy ez a mutató csak a szemét, amit abban a része a kupac.
Így, amikor betölti az adatokat figyelembe int i,
mi technikailag initialize i,
de mi ezt a szemét adatokat.
A hívás állítani, ami egy praktikus hibakereső makró
meghatározott, a találóan elnevezett állítják könyvtár,
megszakítja a program, ha a vizsgált feltétel nem teljesül.
Azaz, ha i nem 0.
Attól függően, hogy mi volt a heap space, mutatott a p,
ez a program is működik, és néha nem máskor.
Ha ez működik, mi csak most szerencsés.
A fordító nem fogja elkapni ezt a hibát, de a Valgrind biztos akaratát.
Itt látjuk a hibát fakadó mi ezzel a junk adatok.
>> Ha kiosztani heap memóriát, de nem deallocate, vagy szabad azt,
hogy hívják a szivárgás.
Egy kis, rövid életű program fut, és azonnal kilép,
szivárgás meglehetősen ártalmatlan,
de a projekt nagyobb méretű és / vagy hosszú élettartam,
még egy kis szivárgás összetett valami nagy.
A CS50, mi várjuk, hogy
vigyázni felszabadítása összes halom memória, hogy osztja,
mert azt akarjuk, hogy építeni a készséggel, hogy megfelelően kezelni a manuális folyamat
által előírt C.
Ehhez a program kell egy pontos
one-to-one közötti levelezés malloc és free hívásokat.
Szerencsére Valgrind tud segíteni memóriavesztés is.
Itt van egy lyukas nevű program leak.c azt juttatja
hely a heap, írja rá, de nem szabad azt.
Mi fordítani azt gyártmánya és fuss ez alatt Valgrind,
és látjuk, hogy míg nincs memória hiba,
mi van egy szivárgás.
Jelenleg 16 bájt egyértelműen elveszett,
azt jelenti, hogy a mutatót, hogy a memória nem volt hatálya alá, amikor a program kilép.
Most Valgrind nem ad nekünk egy csomó információt a szivárgás,
, de ha követjük ezt a kis megjegyzést, hogy ez ad le alja felé jelentésének
futtatni, a - szivárgás-check = teljes
hogy a teljes részleteket szivárogtatott memória,
szerzünk több információt.
Most, a kupac összefoglaló
Valgrind azt mondja, ha a memória, hogy elveszett az eredetileg kiosztott.
Ahogy tudjuk, keresi a forráskódot,
Valgrind tájékoztat bennünket, hogy kiszivárgott a memória
kiosztott egy hívás malloc on line 8 A leak.c
a fő funkciója.
Elég klassz.
>> Valgrind kategorizálja szivárgások használja ezeket a kifejezéseket:
Mindenesetre vereség - ez a kupac memóriát
amely a program már nem egy mutatót.
Valgrind tudja, hogy egyszer volt a mutató, de azóta elvesztette követheti azt.
Ez a memória határozottan kiszivárgott.
Közvetetten vereség - ez a kupac memóriát
, melyre a mutató azt is elvesznek.
Például, ha elvesztetted a mutatót az első csomópont egy láncolt lista,
akkor az első csomópont önmagában kell véglegesen elveszett,
míg minden későbbi csomópontoknak közvetve elveszett.
Valószínűleg vereség - ez a kupac memóriát
amely Valgrind nem lehet biztos abban, hogy van egy mutató, vagy sem.
Még mindig elérhető a kupac memóriát
amely a programot még egy mutató a kijárat,
ami általában azt jelenti, hogy egy globális változó mutat rá.
Ahhoz, hogy ellenőrizze ezeket a szivárgás, akkor is tartalmaznia kell a lehetőséget
- Még mindig elérhető = yes
az Ön hívása Valgrind.
>> Ezek a különböző esetekben szükség lehet különböző stratégiákat tisztító őket,
de a szivárgást meg kell szüntetni.
Sajnos rögzítéséről szivárog nehéz lehet csinálni,
mivel a téves hívások ingyenesen lehet felrobbantani a program.
Például, ha egy pillantást vetünk invalid_free.c,
látunk példát rossz memória felszabadítás.
Milyen legyen egy hívást, hogy kiszabadítsa az egész blokk
memória által mutatott int_block,
e helyett vált kísérletet, hogy kiszabadítsa az egyes int méretű szakasz
a memória külön-külön.
Ez nem fog sikerülni katasztrofálisan.
Boom! Mi a hiba.
Ez határozottan nem jó.
Ha ragadt ilyen hiba, bár, és nem tudja, hol keresse,
esik vissza az új legjobb barátja.
Te találtad ki - Valgrind.
Valgrind, mint mindig, pontosan tudja, hogy mi a helyzet.
A alloc és ingyenes számít nem egyeznek meg.
Van 1 alloc és 4 felszabadított.
És Valgrind is elmondja, ha az első rossz ingyenes hívás -
az egyik, hogy elindította a robbanás - jön -
16 vezetéken.
Amint látod, a rossz hívások felszabadítani nagyon rossz,
ezért javasoljuk, bérbeadása a program szivárgás
munka közben a szerzés a funkcionalitás helyes.
Indítsa el a keresett szivárog után a program megfelelően működik,
anélkül, hogy bármilyen más hibákat.
>> És ez minden megvan ehhez a videóhoz.
Most mit vársz?
Tovább fut Valgrind a programokban most.
A nevem Nate Hardison. Ez CS50. [CS50.TV]