[Powered by Google Translate] [Valgrind] [Nate Hardison, Hārvarda universitātes] Tas ir CS50, CS50.TV] Daži no visgrūtākajiem bugs C programmu nāk no piesavināšanos atmiņas. Ir daudz veidu, kādos skrūvējamu lietām augšu, tostarp piešķirot nepareizu atmiņas apjomu, aizmirstot inicializēt mainīgie, rakstiski pirms vai pēc tā beigām bufera, un atbrīvojot saglabāt atmiņas vairākas reizes. Simptomi svārstās no intermitējošām avārijām līdz noslēpumaini pārrakstīti vērtībām, bieži vietās un laikos ir tālu no sākotnējās kļūdas. Tracing novēroto problēmu atpakaļ uz bāzes cēloni var apstrīdēt, bet par laimi tur ir noderīga programma, ko sauc Valgrind kas var darīt daudz, lai palīdzētu. Palaižot programmu ar Valgrind lai ļautu plaša pārbaude kaudze atmiņas sadalījumu un piekļuves. Kad Valgrind atrod problēmu, tas dod jums tūlītēju, tieša informācija, kas ļauj vieglāk atrast un novērst problēmu. Valgrind arī atskaites par mazāk nāvīga atmiņas jautājumiem, piemēram, atmiņas noplūde, piešķirot kaudze atmiņu, un aizmirstot, lai atbrīvotu to. Patīk mūsu kompilators, šķindēt, mūsu debugger, GDB, Valgrind ir bezmaksas programmatūra, un tā ir uzstādīta uz ierīces. Valgrind darbojas uz binārā izpildāmā, nav jūsu C vai.. h pirmkods failus, tāpēc, ka Jums ir apkopojusi up-to-date kopiju jūsu programmā izmantojot šķindēt vai Make. Tad, rādīt savu programmu saskaņā Valgrind var būt tik vienkārši, kā tikai apzīmētāju standarta programmu komandu ar vārdu Valgrind, kas sākas līdz Valgrind un palaiž programmu iekšpusē no tā. Kad sākas, Valgrind dara dažas sarežģītas jiggering konfigurēt izpildāmo atmiņas pārbaudēm, lai tā varētu veikt mazliet piecelties un darbojas. Programma pēc tam izpildīt normāli, tas būtu daudz lēnāk, un kad tā ir pabeigta, Valgrind būs drukāt kopsavilkumu par savu atmiņas izmantošanu. Ja viss noritēs labi, tas izskatās kaut kas līdzīgs šim: Šajā gadījumā / clean_program. ir ceļš uz programmu es gribu, lai palaistu. Un, kamēr tas viens neveic nekādus argumentus, ja tas tā man vienkārši sadiegšana tos uz beigām, komandu, kā ierasts. Tīrs programma ir tikai dumjš maz programmu es radīju kas sadala telpu bloka Ints uz kaudzes, likts dažas vērtības iekšpusē no viņiem, un atbrīvo visu bloku. Tas ir tas, ko jūs šaušana, bez kļūdām un nav noplūdes. Vēl viens svarīgs rādītājs ir kopējais skaits piešķirto baitu. Atkarībā no programmas, ja jūsu piešķīrumi ir Jo megabaiti vai augstāka, jūs, iespējams, dara kaut ko nepareizi. Vai tu nevajadzīgi glabāšanai dublikātus? Vai jums, izmantojot kaudze glabāšanai, kad labāk būtu izmantot kaudze? Tātad, atmiņas kļūdas var būt patiesi ļauns. Jo vairāk redzami tie rada iespaidīgu avāriju, bet pat tad tas joprojām var būt grūti precīzi noteikt ko tieši noveda pie avārijas. Vairāk iekšēji, programma ar atmiņas kļūda joprojām var sastādīt tīri un vēl var šķist strādāt pareizi jo jums izdevās iegūt laimīgs lielāko daļu laika. Pēc vairāku "veiksmīgu rezultātu," Jūs varētu vienkārši domāju, ka avārija ir parazīts no datora, bet dators nekad nepareizi. Darboties Valgrind var palīdzēt jums izsekot cēloni redzamu atmiņas kļūdas kā arī atrast lurking kļūdas jums nav pat vēl zināt. Katru reizi Valgrind atrod problēmu, tas drukā informāciju par to, ko tā ir norādījusi. Katra vienība ir diezgan kodolīgs - avots līnija pārkāpēja instrukciju, kāda problēma ir, un maz informācijas par iesaistītā atmiņu - bet bieži vien tas ir pietiekami daudz informācijas, lai jūsu uzmanību uz pareizo vietu. Šeit ir par Valgrind piemērs darbojas buggy programmu kas dara nederīgu palasīt kaudze atmiņu. Mēs redzam nekādas kļūdas vai brīdinājumus apkopošanai. Uh-oh, kļūda kopsavilkums saka, ka ir divas kļūdas - 2 nederīgs lasījumi 4 izmēra - baiti, kas ir. Ļaunus skan radās galvenā funkcija invalid_read.c, pirmais uz līnijas 16 un par 19 līnijā. Pieņemsim apskatīt kodu. Izskatās pēc pirmā uzaicinājuma uz printf mēģina lasīt vienu int garām beigās mūsu atmiņas bloku. Ja mēs atskatāmies uz Valgrind produkcijai, mēs redzam, ka Valgrind mums teica tieši tā. Adrese mēs cenšamies lasīt sākas 0 baiti pagātnes beigām bloka izmērs 16 baiti - četri 32-bitu Ints ka mēs faktori. Tas nozīmē, ka adrese mēs cenšamies lasīt sākas tieši gada beigās mūsu bloku, tāpat kā mēs redzam mūsu sliktā printf zvanu. Tagad, nederīgs lasījumi varētu šķist, ka liels ir galā, bet, ja jūs izmantojat, ka dati, lai kontrolētu plūsmu jūsu programmā - Piemēram, kas ir daļa no, ja paziņojums vai cilpa - tad lietas var klusi iet slikti. Skaties kā es varu palaist invalid_read programmu un nekas neparasts notiek. Biedējošu, vai ne? Tagad, pieņemsim apskatīt dažas vairāku veidu kļūdas, kas jums varētu rasties jūsu kodu, un mēs redzēsim, cik Valgrind atklāj tos. Mēs tikko redzējām piemēru par invalid_read, tāpēc tagad pieņemsim izbraukšana invalid_write. Atkal, nekādas kļūdas vai brīdinājumi apkopošanas. Labi, Valgrind saka, ka ir divas kļūdas šajā programmā - un invalid_write un invalid_read. Pieņemsim pārbaudīt šo kodu. Izskatās, ka mēs esam ieguvuši gadījums klasiskās strlen plus viens bug. Kodeksā nav malloc papildu baitu telpas par / 0 raksturu, tāpēc, kad str kopiju devās rakstīt to ssubstrlen "CS50 akmeņiem!" tā rakstīja 1 baits garām beigās mūsu bloku. The invalid_read nāk, kad mēs padarītu mūsu zvanu uz printf. Printf nonāks lasījumā nederīgu atmiņu, kad tas skan / 0 rakstzīmi kā tas izskatās beigās šajā E virknes tā drukāšanu. Bet neviens no tā izbēguši Valgrind. Mēs redzam, ka tas nozvejotas invalid_write kā daļu no str kopijas uz galveno 11 līnijas, un invalid_read ir daļa no printf. Rock, Valgrind. Atkal, tas varētu šķist liels darījumu. Mēs varam palaist šo programmu vairāk un vairāk ārpus Valgrind un neredzu nevienu kļūdu simptomus. Tomēr, aplūkosim nedaudz variācijas, lai redzētu kā lietas var iegūt patiešām slikti. Tātad, kas piešķirts, mēs ļaunprātīgi lietas vairāk nekā tikai mazliet šajā kodu. Mēs esam tikai piešķirot vietu uz kaudzes uz divām stīgām garums CS50 akmeņiem, šoreiz, atceroties / 0 raksturu. Bet tad mēs iemest super garumā virknes uz atmiņas bloku ka S ir vērsta uz. Kādas sekas būs, kas ir par atmiņas bloku ka T norāda uz? Nu, ja T norāda uz atmiņu, kas ir tikai blakus S, nāk tikai pēc tam, tad mēs varētu būt rakstīts vairāk nekā daļu no T. Pieņemsim palaist šo kodu. Paskaties, kas notika. Stīgas mēs glabājas mūsu kaudze blokus gan varot būt izdrukāt pareizi. Nekas, šķiet nepareizi vispār. Tomēr, iesim atpakaļ uz mūsu kodu un komentēt līniju, kur mēs kopēt CS50 ieži uz otro atmiņas bloku, norādīja uz t. Tagad, kad mēs palaist šo kodu mēs būtu redzēt tikai tās pirmās atmiņas bloku saturs izdrukāt. Paga, lai gan mēs neesam ielā kopija Par jebkuru otro kaudze bloku rakstzīmes, viens norādīja uz pa T, mēs izdrukāt. Patiešām, stīgu mēs iepildīta mūsu pirmajā blokā ieņēma pirmo bloku un vienā otrā bloka, padarot viss šķiet normāli. Valgrind, lai gan, stāsta mums patieso stāstu. Tur mums iet. Visiem tiem nederīgs lasa un raksta. Apskatīsim piemēru cita veida kļūdas. Te mēs kaut ko diezgan žēl. Mēs paķert vietu int uz kaudzes, un mēs sāktu int rādītāju - p - lai norādītu uz šo vietu. Taču, kamēr mūsu rādītājs ir inicializēts, dati, ka tas norāda uz tikko ir kāds junk ir, ka daļa no kaudzes. Tātad, kad mēs slodze ka datus int i, mēs tehniski inicializēt I, bet mēs tik ar junk datiem. Aicinājumu aizstāvēt, kas ir ērts atkļūdošanas makro definēts trāpīgi nosaukts aizstāvēt bibliotēkas, tiks apturēta programma, ja tās testa apstākļos neizdodas. Tas ir, ja es nav 0. Atkarībā no tā, kāda bija kaudze telpā, norādīja uz P, Šī programma varētu strādāt reizēm un nespēj citos laikos. Ja tas darbojas, mēs esam tikai kļūst laimīgs. Kompilators nesapratu šo kļūdu, bet Valgrind pārliecināts gribu. Tur mēs redzam kļūdas, kas izriet no mūsu izmantošanu ka junk datiem. Kad jūs piešķirt kaudze atmiņu, bet nav deallocate to vai to atbrīvotu, ka sauc noplūde. Par nelielu, īslaicīgu programma, kas darbojas un uzreiz izejām, noplūde ir diezgan nekaitīgi, bet par projektu lielāka izmēra un / vai ilgmūžību, pat neliela noplūde var pagatavot kaut ko lielu. Par CS50, mēs sagaidām, ka jūs rūpēties par atbrīvojot visu kaudze atmiņas, kas jums piešķirt, jo mēs vēlamies, lai jūs veidot prasmes, lai pareizi rīkotos manuālo procesu pieprasa C. Lai to izdarītu, jūsu programma būtu precīza viens pret vienu sarakste starp malloc un bezmaksas zvanus. Par laimi, Valgrind var jums palīdzēt ar atmiņas noplūdes pārāk. Šeit ir caurs programma, ko sauc leak.c kas iedalīti Vieta uz kaudzes, raksta tā, bet ne to atbrīvotu. Mēs apkopotu to ar Marka un palaist to zem Valgrind, un mēs redzam, ka, lai gan mums nav atmiņas kļūdas, mums ir viena noplūde. Ir 16 baiti galīgi zaudējis, kas nozīmē, ka rādītājs uz šo atmiņu nebija joma, kad programma iziet. Tagad, Valgrind nedod mums ton informāciju par noplūdi, bet, ja mēs šo nedaudz piezīmi, ka tas dod atpakaļ uz leju par savu ziņojumu lai uzsāktu ar - noplūdes pārbaudīt = pilna lai redzētu pilnu informāciju par noplūda atmiņa, mēs iegūtu vairāk informācijas. Tagad, kaudze kopsavilkumā, Valgrind stāsta mums, kur atmiņas, kas tika zaudēta sākotnēji tika piešķirti. Tāpat kā mēs zinām no skatoties pirmkodu, Valgrind informē mūs, ka mēs noplūda atmiņu piešķirtas ar aicinājumu malloc uz leak.c 8 Line galvenajā funkciju. Diezgan švītīgs. Valgrind categorizes noplūdi, izmantojot šos terminus: Galīgi zaudējis - tas ir kaudzes piešķirti atmiņa uz kurām programma vairs nav rādītājs. Valgrind zina, ka jūs reiz bija rādītāju, bet kopš tā laika ir zaudējis dziesmu no tā. Šī atmiņa ir noteikti noplūdis. Netieši zaudējis - tas ir kaudzes piešķirti atmiņa ar kuriem vienīgais norādes uz to arī tiek zaudēti. Piemēram, ja esat pazaudējis savu rādītāju uz pirmo mezgla saistītajā sarakstā, tad pirmais mezgls pati būtu galīgi zaudējis, bet visus turpmākos mezgli būtu netieši zaudēts. Iespējams zaudējis - tas ir kaudzes piešķirti atmiņa uz kuru Valgrind nevar būt pārliecināts, vai ir rādītājs, vai ne. Joprojām sasniedzama ir kaudze piešķirti atmiņa uz kuru programma vēl ir rādītāju pie izejas, kas parasti nozīmē, ka globālā mainīgā norāda uz to. Lai pārbaudītu šo noplūdes, jūs arī ir jāiekļauj iespēja - Joprojām-sasniedzams = jā Jūsu piesaukšana no Valgrind. Šie dažādie gadījumi varētu prasīt dažādas stratēģijas, lai tīrīšanas tos, bet noplūde būtu jālikvidē. Diemžēl, nosaka noplūdes var būt grūti to darīt, jo nepareizi zvani uz bezmaksas var uzspridzināt savu programmu. Piemēram, ja mēs skatāmies uz invalid_free.c, mēs redzam piemēru slikti atmiņas deallocation. Kas būtu viens zvans, lai atbrīvotu visu bloku atmiņas, ko uzrādīja int_block, ir nevis kļuvis mēģinājums atbrīvot katru int izmēra sadaļu no atmiņas individuāli. Tas nebūs katastrofāli. Bums! Kas kļūda. Tas noteikti nav laba. Ja jūs esat iestrēdzis ar šāda veida kļūdas, lai gan, un jūs nezināt, kur meklēt, krist atpakaļ uz savu jauno labāko draugu. Jūs uzminējāt - Valgrind. Valgrind, kā vienmēr, zina, ko tieši ir atkarīgs. Ar alloc un bezmaksas skaits nesakrīt augšu. Mēs esam ieguvuši 1 alloc un 4 atbrīvo. Un Valgrind arī stāsta mums, kur pirmo slikto bezmaksas zvans - viens, kas izraisīja blowup - nāk no - līnija 16. Kā jūs redzat, slikti zvani uz bezmaksas ir patiešām slikti, tāpēc mēs iesakām ļaujot jūsu programma noplūdi kamēr jūs strādājat par iegūt funkcionalitāti pareizs. Sākt meklēt noplūdes tikai pēc jūsu programma darbojas pareizi, bez jebkādām citām kļūdām. Un tas ir viss, ko mēs esam ieguvuši par šo video. Tagad, ko jūs gaida? Iet palaist Valgrind par savām programmām tiesības tagad. Mans vārds ir Nate Hardison. Tas ir CS50. [CS50.TV]