[Powered by Google Translate] [Valgrind] [Nate Hardison, Chuo Kikuu cha Harvard] Hii ni CS50, CS50.TV] Baadhi ya mende ngumu zaidi katika mipango ya C kuja kutoka usimamiaji mbovu wa kumbukumbu. Kuna idadi kubwa ya njia ya kufaidika mambo up, ikiwa ni pamoja na kugawa kiasi ya makosa ya kumbukumbu, kusahau initialize vigezo, kuandika kabla au baada ya mwisho wa buffer, na kumkomboa kutunza kumbukumbu mara nyingi. dalili mbalimbali kutoka shambulio vipindi kwa maadili ya mysteriously overwritten, mara nyingi katika sehemu na nyakati mbali kuondolewa kutoka katika makosa ya awali. Hazieleweki tatizo aliona nyuma sababu ya msingi mzizi inaweza kuwa changamoto, lakini bahati nzuri kuna mpango kusaidia aitwaye Valgrind ambayo inaweza kufanya mengi kusaidia. Wewe kukimbia chini ya mpango Valgrind ili kuwawezesha kina kuangalia ya mgao wa kumbukumbu chungu na wanapata. Wakati Valgrind hutambua tatizo, anakupa haraka, moja kwa moja habari kwamba utapata zaidi kupata urahisi na kurekebisha tatizo. Valgrind pia taarifa juu ya masuala ya chini mauti kumbukumbu, kama vile kumbukumbu uvujaji, kugawa lundo kumbukumbu, na kusahau ya bure yake. Kama compiler yetu, Clang, katika debugger yetu, GDB, Valgrind ni programu za bure, na ni imewekwa kwenye appliance. Valgrind anaendesha binary executable yako, si yako c. au. files chanzo h kificho, hivyo kuwa na uhakika kuwa compiled nakala up-to-date ya mpango wako kutumia Clang au kufanya. Kisha, mbio programu yako chini ya Valgrind inaweza kuwa rahisi kama tu prefixing kiwango mpango amri na Valgrind neno, ambayo kuanza juu Valgrind na anaendesha programu ndani yake. Wakati wa kuanza, Valgrind gani baadhi tata jiggering configure executable kwa hundi kumbukumbu, hivyo inaweza kuchukua kidogo kuamka na kukimbia. Mpango huo basi nitafanya kawaida, kuwa ni taratibu zaidi, na wakati atamaliza, Valgrind itakuwa magazeti muhtasari wa kumbukumbu matumizi yake. Kama yote inakwenda vizuri, itakuwa kuangalia kitu kama hii: Katika kesi hii, /. Clean_program ni njia ya mpango nataka kukimbia. Na wakati mmoja hii haina kuchukua hoja yoyote, kama alivyofanya mimi d tu tack yao ya mwisho wa amri kama kawaida. Mpango safi ni tu silly kidogo mpango nilianzisha kwamba kutenga nafasi kwa block ya ints juu ya chungu, kuweka maadili baadhi ndani yao, na frees block nzima. Hii ni nini ni risasi kwa, makosa hakuna uvujaji na hakuna. Mwingine metric muhimu ni jumla ya idadi ya ka zilizotengwa. Kutegemea mpango, kama mgao yako ni katika megabaiti au ya juu, pengine wewe kufanya kitu kibaya. Je unnecessarily hifadhi marudio? Je, unatumia chungu kwa ajili ya kuhifadhi, wakati itakuwa bora kutumia stack? Hivyo, kumbukumbu makosa unaweza kuwa kweli maovu. ndio zaidi overt kusababisha shambulio kuvutia, lakini hata basi bado unaweza kuwa vigumu pinpoint nini hasa ulisababisha ajali. Zaidi hila na njama zilizotengenezwa, mpango na makosa kumbukumbu bado anaweza kukusanya cleanly na bado anaweza kuonekana kazi ipasavyo kwa sababu wewe imeweza kupata bahati zaidi ya muda. Baada ya kadhaa "matokeo ya mafanikio," unaweza tu kufikiri kwamba ajali ni fluke ya kompyuta, lakini kompyuta ni kamwe makosa. Mbio Valgrind inaweza kukusaidia kufuatilia chini sababu ya makosa inayoonekana kumbukumbu kama vile kupata lurking makosa huna hata bado kujua juu. Kila wakati Valgrind hutambua tatizo, ni Prints taarifa kuhusu ni nini aliona. Kila kipengele ni uungwana terse - line chanzo cha mafundisho offending, nini suala hilo ni, na info kidogo juu ya kumbukumbu wanaohusika - lakini mara nyingi ni ya kutosha habari kuelekeza mawazo yako mahali pa haki. Hapa ni mfano wa Valgrind mbio juu ya mpango Buggy kwamba hana kusoma batili ya kumbukumbu chungu. Sisi kuona makosa hakuna maonyo au katika mkusanyiko. Uh-oh, muhtasari kosa anasema kuwa kuna makosa mawili - mbili batili wasomaji wa kawaida 4 - ka, kwamba ni. Wote mbaya anasoma ilitokea katika kazi kuu ya invalid_read.c, kwanza katika mstari wa 16 na ya pili juu ya mstari 19. Hebu tuangalie code. Inaonekana kama ya kwanza mwito kwa printf inajaribu kusoma moja int zamani mwisho wa kumbukumbu block yetu. Kama sisi kuangalia nyuma katika pato la Valgrind, tunaona kwamba Valgrind alituambia hasa ile. anuani ya sisi ni kujaribu kusoma kuanza ka 0 nyuma mwisho wa block ya kawaida 16 ka - nne ya 32-bit ints kwamba sisi zilizotengwa. Hiyo ni, anuani tulikuwa kujaribu kusoma kuanza kulia katika mwisho wa kuzuia yetu, tu kama sisi kuona katika wito wetu mbaya printf. Sasa, batili wasomaji wanaweza kuonekana kama kwamba kubwa ya mpango huo, lakini kama wewe ni kutumia data kwamba kudhibiti mtiririko wa mpango wako - kwa mfano, kama sehemu ya kama maelezo au kitanzi - mambo yanaweza kwenda mbaya kimya. Kuangalia jinsi naweza kuendesha programu invalid_read na chochote nje ya kawaida hutokea. Inatisha, huh? Sasa, hebu tuangalie baadhi ya aina zaidi ya makosa ambayo unaweza kukutana katika code yako, na tutaweza kuona jinsi Valgrind hutambua yao. Sisi tu aliona mfano wa invalid_read, hivyo sasa hebu angalia invalid_write. Tena, hakuna makosa au maonyo katika mkusanyiko. Okay, Valgrind anasema kwamba kuna makosa mawili katika mpango huu - na invalid_write na invalid_read. Hebu angalia hii code. Inaonekana kama sisi tumepewa mfano wa strlen classic plus moja mdudu. code haina malloc Byte ziada wa nafasi kwa tabia / 0, hivyo wakati nakala str akaenda kuandika katika ssubstrlen "miamba cs50!" ni aliandika 1 Byte zamani mwisho wa kuzuia yetu. invalid_read inakuja wakati sisi kufanya wito wetu kwa printf. Printf mwisho juu ya kusoma kumbukumbu batili wakati anasoma / 0 tabia kama inaonekana katika mwisho wa kamba hii E ni uchapishaji. Lakini hakuna hii alitoroka Valgrind. Tunaona kwamba hawakupata invalid_write kama sehemu ya nakala str kwenye mstari wa 11 kuu, na invalid_read ni sehemu ya printf. Rock juu, Valgrind. Tena, hii inaweza kuonekana kama mpango kubwa. Tunaweza kuendesha programu hii tena na tena nje ya Valgrind na wala kuona dalili zozote makosa. Hata hivyo, hebu angalia tofauti kidogo ya hii kuona jinsi mambo wanaweza kupata mbaya kweli kweli. Hivyo, nafasi, sisi ni abusing mambo zaidi kuliko kidogo tu katika kanuni hii. Sisi ni tu kugawa nafasi kwenye chungu kwa masharti mawili urefu wa miamba cs50, wakati huu, wakikumbuka / 0 tabia. Lakini basi sisi kutupa katika string super-muda mrefu ndani ya kuzuia kumbukumbu S ni kwamba akizungumzia. Nini athari itakuwa kwamba kuwa juu ya kuzuia kumbukumbu kwamba Simu pointi? Naam, kama T pointi kwa kumbukumbu kwamba tu karibu na S, kuja tu baada ya hayo, kisha sisi tupate kuwa imeandikwa juu ya sehemu ya T. Hebu kukimbia hii code. Kuangalia nini kilitokea. masharti sisi kuhifadhiwa katika vitalu yetu lundo wote alionekana kuwa na kuchapishwa kwa usahihi. Hakuna inaonekana vibaya wakati wote. Hata hivyo, hebu kwenda nyuma katika kanuni zetu na maoni nje mstari ambapo sisi nakala miamba cs50 katika block pili kumbukumbu, alisema kwa t. Sasa, wakati sisi kukimbia hii code tunapaswa tu kuona yaliyomo ya kuzuia kwanza kumbukumbu magazeti nje. Ho, ingawa hatukuwa str nakala yoyote wahusika katika block pili chungu, alisema kwa moja na T, sisi kupata magazeti nje. Hakika, kamba sisi stuffed katika block wetu wa kwanza akaivamia block kwanza na katika block ya pili, kufanya kila kitu kuonekana ya kawaida. Valgrind, ingawa, inatuambia hadithi ya kweli. Kuna sisi kwenda. Wote wa wale batili anasoma na anaandika. Hebu tuangalie mfano wa aina nyingine ya ufisadi. Hapa sisi kufanya kitu bahati mbaya. Sisi kunyakua nafasi kwa int juu ya chungu, na sisi initialize pointer int - p - kwa uhakika na nafasi hiyo. Hata hivyo, wakati pointer yetu ni initialized, data kwamba ni akizungumzia tu ina chochote Junk ni katika sehemu hiyo ya chungu. Hivyo wakati sisi mzigo data kwamba katika int i, sisi kitaalam initialize i, lakini sisi kufanya hivyo pamoja na data Junk. wito kwa kudai, ambayo ni Handy debugging jumla inavyoelezwa katika maktaba aptly aitwaye kudai, mapenzi abort mpango kama mtihani wake hali inashindwa. Hiyo ni, kama i si 0. Kutegemea juu ya nini alikuwa katika nafasi chungu, alisema kwa p, mpango huu inaweza kufanya kazi wakati mwingine na kushindwa mara kwa mara nyingine. Kama ni kazi, sisi ni kupata tu bahati. compiler si kukamata kosa hili, lakini Valgrind mapenzi uhakika. Kuna sisi kuona makosa yanayotokana na matumizi yetu ya data kwamba Junk. Wakati wewe kutenga chungu kumbukumbu lakini si deallocate au huru yake, kiitwacho leak. Kwa wadogo, muda mfupi mpango kwamba anaendesha na mara exits, uvujaji ni uungwana wapole, lakini kwa ajili ya mradi wa ukubwa kubwa na / au longevity, hata leak ndogo inaweza kuzidisha katika kitu makubwa. Kwa CS50, hatuwezi kutarajia wewe utunzaji wa kumkomboa yote ya kumbukumbu chungu kwamba wewe kutenga, tangu tunataka kujenga stadi vizuri kushughulikia mchakato mwongozo inavyotakiwa na C. Kwa kufanya hivyo, mpango wako awe kamili moja kwa moja ya mawasiliano kati ya malloc na wito bure. Bahati nzuri, Valgrind inaweza kukusaidia na uvujaji kumbukumbu pia. Hapa ni mpango leaky kuitwa leak.c kwamba inatenga nafasi kwenye chungu, anaandika kwa hilo, lakini haina huru yake. Sisi ni pamoja na kukusanya Matokeo na kukimbia chini ya Valgrind, na sisi kuona kwamba, wakati tuna makosa kumbukumbu hakuna, sisi kufanya kuwa moja ya uvujaji. Kuna 16 ka dhahiri waliopotea, maana kwamba pointer kumbukumbu ambayo haikuwa katika wigo wakati mpango exited. Sasa, Valgrind hautupatii tani ya taarifa kuhusu leak, lakini kama sisi kufuata kumbuka hii kidogo kwamba anatoa chini kuelekea chini ya ripoti yake kwa rerun na - leak-kuangalia = kamili kuona maelezo kamili ya kumbukumbu kuvuja, tutaweza kupata habari zaidi. Sasa, katika muhtasari wa chungu, Valgrind inatuambia ambapo kumbukumbu aliyepotea awali zilizotengwa. Tu kama sisi kujua kutoka kuangalia katika chanzo code, Valgrind inatufahamisha ya kwamba sisi kuvuja kumbukumbu zilizotengwa kwa mwito wa malloc kwenye mstari 8 ya leak.c katika kazi kuu. Pretty nifty. Valgrind categorizes uvujaji kwa kutumia sheria hizi: Dhahiri waliopotea - hii ni chungu zilizotengwa kumbukumbu ambayo mpango tena ina pointer. Valgrind anajua kwamba wewe mara moja alikuwa pointer lakini tangu waliopotea track yake. Kumbukumbu hii ni dhahiri kuvuja. Moja kwa moja walipoteza - hii ni chungu zilizotengwa kumbukumbu ambayo kuyatumia tu kwa hiyo pia ni kupotea. Kwa mfano, kama wewe waliopotea pointer yako na nodi ya kwanza ya orodha wanaohusishwa, kisha nodi kwanza yenyewe itakuwa dhahiri waliopotea, wakati nodes yoyote baadae itakuwa moja waliopotea. Uwezekano waliopotea - hii ni chungu zilizotengwa kumbukumbu ambayo Valgrind haiwezi kuwa na uhakika kama kuna pointer au la. Bado ni reachable lundo zilizotengwa kumbukumbu ambayo bado ina mpango pointer katika exit, ambayo kwa kawaida ina maana kwamba kimataifa variable pointi hiyo. Ili kuangalia kwa uvujaji hizi, itabidi pia kuwa ni pamoja na chaguo - Bado-reachable = ndiyo katika sala yako ya Valgrind. Hizi kesi mbalimbali wanaweza kuhitaji mikakati mbalimbali kwa ajili ya kusafisha yao juu, lakini uvujaji wanapaswa kuondolewa. Kwa bahati mbaya, fixing uvujaji inaweza kuwa vigumu kufanya, tangu sahihi wito kwa bure wanaweza kulipua programu yako. Kwa mfano, kama sisi kuangalia invalid_free.c, tunaona mfano wa deallocation mbaya kumbukumbu. Kile lazima wito moja kwa huru block nzima ya kumbukumbu alisema kwa int_block, ina badala kuwa jaribio la kumwondolea kila sehemu int ukubwa ya kumbukumbu mmoja mmoja. Hii kushindwa catastrophically. Boom! Nini kosa. Hii ni dhahiri si nzuri. Kama wewe ni kukwama kwa aina hii ya makosa, ingawa, na huwezi kujua wapi kuangalia, kuanguka nyuma rafiki yako mpya bora. You guessed it - Valgrind. Valgrind, kama siku zote, anayejua hasa nini juu. makosa na alloc bure hayaoani up. Sisi tumepewa 1 alloc na 4 frees. Na Valgrind pia inatuambia ambapo kwanza mbaya bure wito - moja kwamba yalisababisha blowup - anakuja kutoka - mstari 16. Kama unaweza kuona, mbaya wito kwa huru ni mbaya kweli kweli, hivyo sisi kupendekeza kuruhusu mpango wako leak wakati wewe kazi kupata utendaji sahihi. Kuanza kuangalia kwa uvujaji tu baada ya mpango wako ni kazi vizuri, bila makosa yoyote nyingine. Na kwamba wote sisi tumepewa kwa video hii. Sasa ni wewe kusubiri? Nenda kukimbia Valgrind juu ya mipango yako sasa hivi. Jina langu ni Nate Hardison. Hii ni CS50. [CS50.TV]