[Powered by Google Translate] [Valgrind]
[Nate Hardison, Harvardo universitetas]
Tai CS50, CS50.TV]
Kai kurie iš sunkiausių C programos klaidas
kilę iš atminties netinkamo administravimo.
Yra daugybė būdų, kaip viską suknisti,
įskaitant neteisingą sumą paskirstant atminties,
nepamirštant inicijuoti kintamuosius,
raštu prieš arba po buferio pabaigos,
ir atlaisvinti išsaugoti atminties kelis kartus.
Simptomai svyruoti nuo pertrūkiais avarijų
paslaptingai perrašyti vertybėms,
dažnai toli nuo originalo klaida vietose ir įvairiose epochose.
Sekti pastebėtą problemą su pagrindine priežastimi
gali būti sudėtinga,
tačiau, laimei, yra naudinga programa, vadinama Valgrind
, kad galima padaryti daug padėti.
>> Jums paleisti pagal Valgrind programą, kad būtų galima
Platus tikrinimas Heap atminties paskirstymas ir prieigomis.
Kai Valgrind aptinka problemą, ji suteikia jums iš karto,
tiesioginė informacija, kuri leidžia jums
lengviau rasti ir išspręsti problemą.
Valgrind ataskaitas apie mažiau mirtinų atminties klausimais,
pavyzdžiui, atminties nutekėjimas, skiriant krūvos atminties,
ir pamiršta jį išlaisvinti.
Kaip mūsų kompiliatorių, Apsukite metalinis garsas, mūsų debugger, gdb,
Valgrind yra nemokama programinė įranga, ir jis yra įrengtas ant prietaiso.
Valgrind veikia jūsų failus vykdomais
ne tavo c arba H kodą failus,
todėl, kad jūs turite surinkti up-to-data kopiją savo programą
Apsukite metalinis garsas ar Markė.
Tada, veikia savo programą, pagal Valgrind gali būti
taip paprasta, kaip tik prasideda standartinės programos komandą su žodžiu Valgrind,
, kuris prasideda Valgrind ir paleidžia programą viduje ji.
Paleidus Valgrind kai sudėtinga
jiggering konfigūruoti vykdomąjį atminties patikrinimus,
todėl tai gali užtrukti šiek tiek gauti ir veikia.
Tada programa bus vykdyti paprastai, tai būtų daug lėčiau,
ir kai ji nesibaigė, Valgrind bus atspausdinti savo atminties naudojimo santrauką.
Jei viskas vyks gerai, tai atrodys maždaug taip:
Šiuo atveju. / Clean_program
yra kelias į programą, aš noriu paleisti.
Ir nors tai vienas nesiima jokių argumentų,
jei ji aš tiesiog pakeisti halsą juos kaip įprasta komanda pabaigos.
Švarus programa yra tik kvailas mažai programa, aš sukūriau
, kad skiria erdvės bloko int krūvos,
įdėti keletą reikšmių viduje iš jų, ir išlaisvina visą bloką.
Tai yra tai, ką jūs šaudymo, be klaidų ir be jokių nuotėkių.
>> Kitas svarbus rodiklis yra bendras skiriamų baitų skaičius.
Priklausomai nuo programos,, jei jūsų asignavimai yra megabaitų ar aukštojo
jūs tikriausiai tai kažkas negerai.
Jūs be reikalo saugoti dublikatus?
Ar jūs naudojate krūvą laikymo, kada būtų geriau naudoti kamino?
Taigi, atminties klaidos gali būti tikrai blogis.
Akivaizdžių tie sukelti įspūdingų avarijų,
bet net ir tada jis vis dar gali būti sunku tiksliai
kas tiksliai buvo į avariją.
Nepastebimai, su atminties klaidų programa
vis dar gali sudaryti švariai
ir gali vis dar atrodo, dirbti teisingai
nes jums pavyko gauti pasisekė didžiąją laiko dalį.
Po kelių sėkmingų rezultatų "
galite tiesiog manote, kad kritimo iš kompiuterio FLUKE,
bet kompiuteris niekada neklysta.
>> Veikia Valgrind gali padėti jums sekti matomų atminties klaidų priežastis
taip pat rasti pasiklysti klaidų jums net nereikia dar žinoti.
Kiekvieną kartą, kai Valgrind aptinka problemą, jis spausdina informaciją apie tai, ką pastebėjo.
Kiekvienas elementas yra gana trumpas ir atžarus -
šaltinis linija neteisėto instrukcijų, kokia yra problema,
ir šiek tiek informacijos apie atminties dalyvauja
bet dažnai tai pakankamai informacijos, kad nukreipti savo dėmesį į tinkamą vietą.
Čia yra pavyzdys Valgrind veikia Buggy programą
tai daro negaliojantį paskaityti krūvos atminties.
Mes nematome kompiliavimo klaidų ar įspėjimų.
Uh-oh, klaida santrauka sako, kad yra dvi klaidas -
dviejų negalioja skaityta dydžio 4 - baitų, kad yra.
Blogus skaito įvyko invalid_read.c pagrindinė funkcija,
16 on-line ir on line 19 2. pirmas.
Pažvelkime pateiktą kodą.
Atrodo, kad pirmojo kvietimo į printf bando skaityti vieną int pro mūsų atminties bloko pabaigos.
Jei pažvelgsime atgal Valgrind produkcijos,
matome, kad Valgrind būtent tai mums pasakė,.
Adresas, kuriuo bandote skaityti prasideda 0 baitų
praeityje dydis 16 baitų paketo pabaigos -
keturi 32-bit int, kad mes skiriamos.
Tai reiškia, kad mes stengiamės skaityti adresas prasideda mūsų bloko pabaigos,
kaip mes matome mūsų blogą printf skambučio.
Dabar, neteisingas skaityta gali ne atrodo, kad spręsti didelis,
bet jei jūs naudojate, kad duomenys kontroliuoti savo programą srautas
Pavyzdžiui, dalis, jei pareiškimas arba kilpiniai
tada viskas gali tyliai pūti.
Žiūrėti, kaip aš galiu paleisti invalid_read programą
ir niekas iš paprastų atsitinka.
Baisu, ar ne?
>> Dabar pažvelkime šiek tiek daugiau rūšių klaidų, kad jūs gali susidurti savo kodą,
ir mes pamatyti, kaip Valgrind aptinka juos.
Mes tik pamačiau apie invalid_read pavyzdys
todėl dabar galime patikrinti invalid_write.
Vėlgi, jokių klaidų ar įspėjimų rengimo.
Gerai, Valgrind sako, kad yra dvi klaidos šioje programoje -
ir invalid_write invalid_read.
Leiskite patikrinti šį kodą.
Atrodo, kad mes gavome iš klasikinių strlen pridėjus vieną klaidą egzempliorių.
Kodas nėra malloc papildomą baitas vietos
/ 0 pobūdžio,
g kopija nuėjo rašyti jį ssubstrlen "CS50 uolų!"
jis parašė 1 baitas praeityje mūsų blokas pabaigoje.
Invalid_read ateina, kai mes darome mūsų raginimą printf.
Printf baigiasi skaityti neteisingą atmintį, kai jis skaito / 0 pobūdį
, kaip jis žiūri į šią interneto eilutės pabaigoje, tai spauda.
Bet visa tai pabėgo Valgrind.
Matome, kad sugauti invalid_write STR kopijos
pagrindinis 11 eilutėje, ir invalid_read printf dalis.
Rock on, Valgrind.
Vėlgi, tai gali ne atrodo baisi.
Mes galime paleisti šią programą daugiau ir daugiau už Valgrind
ir nematau jokių klaidų simptomus.
>> Tačiau pažvelkime šiek tiek variacijos
kaip ką gali gauti tikrai blogai.
Taigi, suteiktas, mes piktnaudžiauja dalykų daugiau nei tik šiek tiek šio kodekso.
Mes tik patalpų skyrimo krūvos dvi eilutes
CS50 uolų ilgis,
šį kartą, prisiminti / 0 charakterį.
Bet tada mes mesti super ilgą eilutę į atminties bloką
kad S yra nukreipta į.
Kokį poveikį, kad į atminties bloką, kad T atkreipia dėmesį į?
Na, jei T į atmintį, kad tik šalia S
tik po to,
tada mes galime turėti raštu per T.
Leiskite paleisti šį kodą.
Pažvelgti į tai, kas atsitiko.
Stygos mes saugomi mūsų Heap blokų abiejų išspausdinti teisingai.
Nieko atrodo neteisinga.
Tačiau grįžkime į mūsų kodą ir
komentaras iš linijos, kur mes kopijuojate CS50 uolų
į antrąjį atminties bloko, atkreipė dėmesį į t.
Dabar, kai mes paleisti šį kodą, turėtume
matyti tik pirmojo atminties bloko turinys atsispausdinti.
Oho, net jei mes ne g kopija
bet į antrąjį krūvos blokas simbolių, vienas nurodė, kad T
mes gauname atspausdinti.
Iš tiesų, eilutė įspraustas į mūsų pirmojo bloko
išplito pirmąjį bloką ir į antrojo bloko,
todėl viskas atrodo normalu.
Valgrind, nors pasakoja tikra istorija.
Čia mes eiti.
Tiems negalioja skaito ir rašo.
>> Pažvelkime kitos klaidos natūra pavyzdys.
Čia mes kažką daryti, o gaila.
Mes patraukti vietos už krūvą int,
ir mes inicijuoti int žymeklį - P - rodytų tos vietos.
Tačiau, nors mūsų žymeklis yra rengiami,
duomenys, kad ji nukreipta į visų šiukšlių yra tos krūvos.
Taigi, kai mes įkelti į int i, kad duomenys,
mes techniškai inicijuoti i,
tačiau mes tai darome su junk duomenų.
Skambutis tvirtinti, kuris yra patogus derinimo makro
apibrėžta taikliai pavadino teigti, bibliotekoje,
bus nutrauktas programą, jei jos ir bandymų nepavyko.
Tai reiškia, kad, jei aš yra ne 0.
Priklausomai nuo to, kas buvo krūvos erdvėje, atkreipė dėmesį į P,
ši programa gali dirbti kartais ir nepavyksta kitu metu.
Jei jis veikia, mes tiesiog gauti pasisekė.
Kompiliatorių bus ne sugauti šią klaidą, bet Valgrind tikrai bus.
Ten mes matome klaidą, kylančią iš mūsų, kad šiukšlių duomenų naudojimo.
>> Kai jums skirti krūvos atminties, bet ne deallocate arba jį išlaisvinti,
, kuris yra vadinamas nuotėkio.
Mažos, trumpaamžių programa, kuri veikia ir nedelsiant išėjimus,
nutekėjimas yra gana nekenksmingi,
bet didesnio dydžio ir / arba ilgaamžiškumą projekto,
net nedidelis nutekėjimas gali dar labiau padidinti pagrindinių į kažką.
CS50, mes tikimės, kad jūs
atlaisvinti visi krūvos atminties, kad jums paskirti rūpintis,
nes mes norime, kad jūs statyti įgūdžius, kad galėtų tinkamai tvarkyti rankiniu būdu
reikalaujama pagal C.
Norėdami tai padaryti, jūsų programa turėtų būti tiksli
"vienas su vienu" korespondencija tarp malloc ir nemokami vietiniai skambučiai.
Laimei, Valgrind gali padėti jums su atminties nutekėjimas.
Čia yra spinduliuojamieji programa, vadinama leak.c, kad skiria
vieta ant krūvos, rašo prie jo, bet jis neatleidžia.
Mes kaupia jį Markė ir veikti pagal Valgrind
ir matome, kad, o mes neturime jokių atminties klaidų,
mes turime vieną nutekėjimą.
Yra 16 baitų neabejotinai prarado,
tai reiškia, kad rodyklė į tos atminties nebuvo taikymo sritį, kai išėjo programa.
Dabar Valgrind nėra suteikti mums informacijos apie nuotėkio toną,
bet jei mes tai mažai dėmesį į tai, kad ji suteikia į savo ataskaitą, apačioje
Pakartotinas - nuotėkio patikrinti = visas
pamatyti pilną informaciją apie nutekėjo atminties,
mes gauti daugiau informacijos.
Dabar krūvos santraukoje,
Valgrind mums sako, kur iš pradžių buvo skirta atminties, kad buvo prarasta.
Lygiai taip pat, kaip mes žinome iš šaltinio kodą,
Valgrind informuoja mus, kad mes nutekėjo atmintį
skiriama su skambučio į malloc linija 8 iš leak.c
pagrindinės funkcijos.
Gana madingas.
>> Valgrind skirsto nutekėjimas per šiuos terminus:
Neabejotinai prarado - tai krūva skirta atmintis
kuriuos programa nebeturi rodyklę.
Valgrind žino, kad jūs kažkada buvo žymeklį, tačiau nuo to laiko neteko stebėti jį.
Ši atmintis yra tikrai nutekėjo.
Netiesiogiai prarado - tai krūva skirta atmintis
tik patarimų, į jį taip pat gali būti prarasti.
Pavyzdžiui, jei jūs praradote savo žymiklį į susietą sąrašą pirmojo mazgo,
tada pati pirmą mazgas būtų neabejotinai prarado,
, o visus vėlesnius mazgai netiesiogiai prarasti.
Galbūt prarado - tai krūva skirta atmintis
į kurią Valgrind negali būti tikras, ar yra žymeklis, arba ne.
Vis dar pasiekiamas yra krūva skirta atmintis
programa dar turi išvežimo žymeklį,
kuris paprastai reiškia, kad pasaulinį kintamąjį atkreipia dėmesį į tai.
Norėdami patikrinti, ar šių sandarumą, jūs taip pat turėsite galimybę
- Vis dar pasiekiamas = taip
į savo pritaikymo Valgrind.
>> Šie skirtingi atvejai gali reikalauti skirtingas strategijas valyti, kvėpinti,
bet nutekėjimas turėtų būti pašalintos.
Deja, nustatantis nutekėjimas gali būti sunku padaryti,
nuo neteisingų skambučiai į nemokamai gali susprogdinti savo programą.
Pavyzdžiui, jei mes žiūrime invalid_free.c
matome, netinkamą atminties deallocation pavyzdys.
Koks turėtų būti vienas kvietimas išlaisvinti visą bloką
atminties nurodė į int_block
vietoj to bandoma išlaisvinti kiekvieną int dydžio skyrių
atminties atskirai.
Žlugs katastrofiškai.
Boom! , Kas yra klaida.
Tai tikrai nėra gerai.
Jei esate pakimba su tokios klaidos, nors ir jūs nežinote, kur ieškoti,
patenka atgal į jūsų naujas geriausias draugas.
Jūs atspėjote - Valgrind.
Valgrind, kaip visada, tiksliai žino, ko iki.
Dėl ALLOC ir be skaičius nesutampa.
Mes turime 1 ALLOC ir 4 išlaisvina.
Ir Valgrind taip pat pasakoja, kur pirmas blogas skambutis nemokamas
vienas, kuris sukėlė Išsiplėtus tiekiamos iš
linija 16.
Kaip matote, blogas ragina NEMOKAMAI tikrai blogai,
taigi mes rekomenduojame leisti savo programos nutekėjimą
, o jūs dirbate gauti funkcionalumas teisinga.
Pradėti ieškoti sandarumą tik po to, kai jūsų programa veikia tinkamai,
be jokių kitų klaidų.
>> Ir tai viskas, mes turime šį vaizdo įrašą.
Dabar, ką jūs laukiate?
Bėgti, dabar Valgrind jūsų programoje.
Mano vardas yra Nate Hardison. Tai CS50. [CS50.TV]