[Powered by Google Translate] [Valgrind] [Nate Hardison, Harvard University] Ito ay CS50, CS50.TV] Ang ilan ng ang pinaka-mahirap bug sa C programa darating mula sa masamang pamamahala ng memorya. Mayroong isang malaking bilang ng mga paraan sa magroskas ang mga bagay up, kabilang ang paglaan ng maling halaga ng memorya, forgetting upang simulan ang variable, nakasulat bago o pagkatapos ng dulo ng isang buffer, at pagbabakante panatilihin ang memorya maraming beses. Ang mga sintomas ay mula sa mga pasulput-sulpot na nag-crash sa mysteriously mapapatungan halaga, madalas sa lugar at oras na malayo inalis mula sa orihinal na error. Ang pagsunod sa naobserbahang problema pabalik sa ang kalakip na sanhi ng ugat maaaring hamon, ngunit masuwerte mayroong isang kapaki-pakinabang na programa na tinatawag na Valgrind na maaaring gawin ng maraming upang matulungan. Patakbuhin mo ang isang programa sa ilalim ng Valgrind upang paganahin malawak checking magbunton memory nakalaang at ina-access. Kapag nakita ng Valgrind isang problema, ay nagbibigay sa iyo ng agarang, direktang impormasyon na nagbibigay-daan sa iyo upang mas madaling mahanap at ayusin ang problema. Valgrind ding mga ulat sa mga mas mababa ang nakamamatay na mga isyu sa memory, tulad ng mga memory paglabas, paglaan ng magbunton memory, at forgetting magbakante ito. Gusto aming tagatala, kumalatong, sa aming debugger, GDB, Ang Valgrind ay libreng software, at ito ay naka-install sa appliance. Tumatakbo ang Valgrind sa iyong binary executable, hindi ang iyong. c o. h source code file, kaya siguraduhin na pinagsama-sama mo ang isang up-to-date na kopya ng iyong programa gamit kumalatong o Magsagawa. Pagkatapos, patakbuhin ang iyong mga programa sa ilalim Valgrind bilang simpleng bilang lamang prefixing ang standard na utos ng programa na may salita ang Valgrind, na nagsisimula hanggang Valgrind at nagpapatakbo ng programa sa loob nito. Kapag simula, ginagawa ng Valgrind ilang complex jiggering upang i-configure ang executable para sa mga tseke ng memory, sa gayon ay maaari itong tumagal ng isang bit upang makakuha ng up at pagpapatakbo. Ang programa ay isakatuparan normal, mas mabagal, at kapag natapos, Valgrind i-print ang isang buod ng paggamit ng memory nito. Kung lahat ng napupunta na rin, ito ay tumingin ng isang bagay tulad nito: Sa kasong ito,. / Clean_program ay ang path sa programa Gusto kong patakbuhin. At habang ang isang ito ay hindi gumawa ng anumang mga argumento, kung ito ginawa gusto ko lang tak ito sa dulo ng command gaya ng dati. Malinis na programa lamang ulok maliit na programa ko nilikha na allocates ng puwang para sa isang bloke ng mga ints sa magbunton, ilagay ang ilang mga halaga sa loob ng mga ito, at frees ang buong block. Ito ay kung ano ang iyong pagbaril para sa, walang mga error at hindi paglabas. Ang isa pang mahalagang panukat ay ang kabuuang bilang ng mga bytes na inilalaan. Depende sa programa, kung ang iyong mga nakalaang sa megabytes o mas mataas, marahil ikaw ay gumagawa ng mali. Mo ay hindi kinakailangan sa pag-iimbak ng mga nauulit? Ginagamit mo ba ang magbunton imbakan, kapag ito ay mas mahusay na gamitin ang stack? Kaya, ang mga error sa memorya ay maaaring maging tunay na kasamaan. Mas pantao na mga maging sanhi ng mga kamangha-manghang-crash, ngunit kahit na pagkatapos maaari pa rin itong maging mahirap upang matukoy kung ano ang eksaktong humantong sa pag-crash. Mas insidiously, isang programa na may isang error sa memorya Maaari pa rin makatipon nang malinis at maaari pa ring tila upang gumana nang tama dahil iyong mga pinamamahalaang upang makakuha ng masuwerteng karamihan ng oras. Pagkatapos ng ilang mga "matagumpay na mga kinalabasan," maaari mong isipin na ang pag-crash ay isang parasitiko ng computer, ngunit ang computer ay hindi kailanman mali. Pagpapatakbo ng Valgrind ay maaaring makatulong sa iyo na subaybayan ang sanhi ng nakikita memory error pati na rin makita nagkukubli error hindi mo pa alam tungkol sa. Sa bawat oras na nakita ng Valgrind isang problema, mga Kopya ng impormasyon tungkol sa kung ano ang obserbahan. Medyo maikli at makahulugan ang bawat item ay - ang source linya ng pagtuturo ang nakakahamak na, ano ang isyu, at isang maliit na impormasyon tungkol sa memory kasangkot - ngunit madalas itong sapat na impormasyon upang idirekta ang iyong pansin sa tamang lugar. Narito ang isang halimbawa ng Valgrind na tumatakbo sa isang programang maraming surot na ang isang di-wastong read ng magbunton memory. Nakikita namin walang mga error o babala sa compilation. Uh-oh, ang buod ng error sabi na may dalawang error - dalawang di-wastong bumabasa ng laki 4 - bytes, na. Parehong masamang bumabasa naganap sa pangunahing pag-andar ng invalid_read.c, ang unang sa linya 16 at ang pangalawang sa linya 19. Tingnan natin sa code. Mukhang ang unang tawag sa printf sinusubukang upang basahin ang isang int lagpas sa pagtatapos ng aming bloke ng memorya. Kung titingnan namin pabalik sa ng output ng Valgrind, nakikita namin na ang Valgrind Sinabi sa amin ng eksakto na. Ang address na sinusubukan naming basahin nagsisimula 0 bytes lagpas sa pagtatapos ng mga bloke ng mga bytes ng 16 laki - apat na 32-bit ints na inilalaan namin. Iyon ay, ang address namin sinusubukang basahin ay nagsisimula sa dulo ng aming block, tulad ng nakikita namin sa aming masamang printf tawag. Ngayon, di-wasto bumabasa ay hindi maaaring mukhang tulad na malaki ng isang pakikitungo, ngunit kung gumagamit ka ng data na iyon upang kontrolin ang daloy ng iyong programa - halimbawa, bilang bahagi ng isang kung pahayag o loop - pagkatapos ay mga bagay na maaari tahimik na pumunta masamang. Panoorin kung paano ang maaari kong patakbuhin ang invalid_read programa at walang pambihira mangyayari. Nakakatakot, huh? Ngayon, tingnan natin sa ilang higit pang mga uri ng mga error na maaaring nakatagpo ka sa iyong code, at kami na makita kung gaano Valgrind nakita sa kanila. Lang namin nakita ang isang halimbawa ng isang invalid_read, kaya ngayon sabihin tingnan ng invalid_write. Muli, walang mga error o babala sa compilation. Okay, Valgrind sabi na may dalawang error sa programang ito - at invalid_write at isang invalid_read. Natin tingnan ang code na ito. Mukhang kami nakakuha ng isang halimbawa ng klasikong strlen plus isang bug. Ang code ay hindi malloc ng dagdag na byte ng puwang para sa / 0 karakter, kaya kapag ang kopya STR nagpunta upang isulat ang mga ito sa ssubstrlen "cs50 bato!" sinulat ni ito ng 1 byte nakaraan ang dulo ng aming block. Invalid_read Ang na ito ay kapag ang aming tawag sa printf. Printf nagtatapos sa pagbabasa ng di-wastong memory kapag bumabasa ng / 0 character bilang ito mukhang sa dulo ang string na ito ng E-print. Ngunit wala sa mga ito ang escaped Valgrind. Nakita namin na ito nahuli ang invalid_write bilang bahagi ng kopya ng STR sa linya 11 ng pangunahing, at ang invalid_read ang bahagi ng printf. Rock sa, Valgrind. Muli, ito ay hindi maaaring mukhang tulad ng isang malaking deal. Maaari naming patakbuhin ang program na ito paulit-ulit sa labas ng Valgrind at hindi makita ang anumang mga sintomas ng error. Gayunpaman, tingnan natin sa isang bahagyang pagkakaiba-iba ng mga ito upang makita ang kung paano ang mga bagay ay maaaring makakuha ng ganap na hindi maayos. Kaya, ipinagkaloob, kami ay inaabuso bagay higit pa pa sa isang bit sa ang code na ito. Lamang namin ang paglaan ng espasyo sa magbunton para sa dalawang string ang haba ng cs50 bato, oras na ito, pagtanda / 0 character. Ngunit pagkatapos namin magtapon sa isang napaka-mahabang string sa memory block na S ay tumuturo sa. Anong effect na na may sa memory block na T punto upang? Well, kung ang T puntos sa memory na katabi lang sa S, nagmumula lamang matapos itong, maaari naming nakasulat sa paglipas ng bahagi ng T. Natin patakbuhin ang code na ito. Hanapin sa kung ano ang nangyari. Ang mga string namin na naka-imbak sa aming mga bloke ng magbunton parehong lumitaw ang na-print mo nang tama. Walang Mukhang mali sa lahat. Gayunpaman, sabihin bumalik sa aming code at magkomento ang linya kung saan kopyahin namin cs50 bato sa ikalawang bloke ng memorya, tulis sa pamamagitan ng t. Ngayon, kapag nagpatakbo namin ang code na ito ay dapat namin lamang makita ang mga nilalaman ng unang bloke ng memorya i-print. Whoa, kahit na hindi namin ginawa STR kopya anumang mga character sa ikalawang magbunton bloke, ang isang tulis sa pamamagitan ng T, makakakuha tayo ng isang print out. Sa katunayan, ang string pinalamanan namin sa aming unang bloke overran ang unang bloke at sa pangalawang block, paggawa ng lahat ng mukhang normal. Valgrind, bagaman, Sinasabi sa amin ang tunay na kuwento. Doon kami. Ang lahat ng mga di-wastong bumabasa at nagsusulat. Tingnan natin sa isang halimbawa ng isa pang uri ng error. Narito ang ginagawa namin ng isang bagay na sa halip kapus-palad. Grab namin ng espasyo para sa isang int sa magbunton, at hindi na namin simulan ang isang int pointer - p - upang tumuro sa puwang na iyon. Gayunpaman, habang ang aming pointer ay nasimulan, ang data na ito na tumuturo sa ang anumang junk ay sa na bahagi ng magbunton. Kaya kapag kami-load ang data na iyon sa int i, namin technically i initialize, ngunit ginagawa namin ito sa data ng junk. Ang tawag sa igiit, kung saan ay isang madaling-magamit na macro sa pag-debug tinukoy sa aptly na may pangalang igiit ang library, Ititigil nito ang programa kung nabigo ang pagsubok kundisyon nito. Iyon ay, kung i ay hindi 0. Depende sa kung ano ang sa espasyo magbunton, tulis sa pamamagitan ng p, Ang program na ito ay maaaring gumana minsan at mabigo sa iba pang mga oras. Kung ito gumagana, lang kami nakakakuha ng masuwerteng. Tagatala ay hindi mahuli ang error na ito, ngunit Valgrind bang kalooban. Doon namin makita ang mga error na stemming mula sa aming paggamit ng data na iyon sa junk. Kapag maglaan ka ng magbunton memory ngunit hindi ito deallocate o magbakante ito, na tinatawag na mahayag. Para sa isang maliit, maikli ang buhay na programa na tumatakbo at agad labasan, paglabas medyo hindi nakakapinsala, ngunit para sa isang proyekto ng mas malaki laki at / o kahabaan ng buhay, kahit na isang maliit na mahayag Compound sa isang bagay pangunahing. Para sa CS50, namin inaasahan mong alagaan ng pagbabakante lahat ng magbunton memory na magtalaga, dahil gusto namin sa iyo na bumuo ng mga kakayahan sa maayos na pangasiwaan ang mano-manong proseso kinakailangan ng C. Upang gawin ito, ang iyong programa ay dapat magkaroon ng isang eksaktong isa-sa-isa pagsusulatan sa pagitan ng malloc at libreng tawag. Kabutihang palad, Valgrind ay maaaring makatulong sa iyo ng mga paglabas ng memorya. Narito ang isang tumutulo na programa na tinatawag na leak.c na allocates espasyo sa magbunton, nagsusulat dito, ngunit hindi magbakante ito. Makatipon namin ito Magsagawa at patakbuhin ang mga ito sa ilalim ng Valgrind, at nakita namin na, habang wala kaming mga error sa memorya, namin ay isang mahayag. May 16 bytes talagang nawala, na nangangahulugan na ang pointer na memory ay hindi sa saklaw na kapag ang programa lumabas. Ngayon, Valgrind ay hindi nagbibigay sa amin ng isang tonelada ng impormasyon tungkol sa mahayag, ngunit kung namin sundin ang maliit na tandaan na ito ay nagbibigay patungo sa ilalim ng mga ulat sa muling palabas ng pelikula - mahayag-check = buong upang makita ang buong detalye ng leaked memory, kami makakuha ng karagdagang impormasyon. Ngayon, sa ang magbunton ng buod, Valgrind ay nagsasabi sa amin kung saan ay simula inilalaan ang memory na nawala. Tulad ng alam namin mula sa pagtingin sa source code, Informs sa amin ng Valgrind na leaked namin ang memorya inilalaan sa isang tawag sa malloc sa linya 8 ng leak.c sa pangunahing function na. Medyo nakakatawang. Valgrind kategorya paglabas paggamit ng mga term na ito: Talagang nawala - ito ay magbunton inilalaan memory na sa programa ay hindi na isang pointer. Valgrind alam na kayo kapag may pointer ngunit dahil nawala track nito. Memorya na ito ay talagang leaked. Hindi direkta nawala - ito ay magbunton inilalaan memory na lamang ang pointer dito ay mawawala. Halimbawa, kung nawala mo ang iyong pointer sa unang node ng isang naka-link na listahan, pagkatapos ang unang node mismo ay talagang nawala, habang ang anumang kasunod na node ay hindi direktang nawala. Posibleng nawala - ito ay magbunton inilalaan memory kung saan ang Valgrind hindi maaaring maging sigurado kung may isang pointer o hindi. Pa rin mapupuntahan magbunton inilalaan memory na programa ay mayroon pa ring isang pointer sa exit, na karaniwan itong nangangahulugan na ang global variable puntos dito. Upang suriin para sa mga paglabas, mayroon ka ring isama ang pagpipilian - Pa rin-mapupuntahan = yes sa iyong pananalangin ng Valgrind. Mga iba't ibang mga kaso na maaaring mangailangan ng ibang mga estratehiya para sa paglilinis up ang mga ito, ngunit paglabas ay dapat na eliminated. Sa kasamaang palad, ang pag-aayos ng paglabas ay maaaring maging mahirap na gawin, dahil ang mga tawag hindi tama sa libreng maaaring sumabog ang iyong programa. Halimbawa, kung tiningnan namin sa invalid_free.c, makita namin ang isang halimbawa ng masamang memory deallocation. Ano ang dapat ng isang tawag sa magbakante ang buong block ng memorya tulis sa pamamagitan ng int_block, sa halip ay naging isang pagtatangka upang magbakante bawat int-sized na seksyon ng memory indibidwal. Ito ay mabibigo catastrophically. Boom! Ano ang isang error. Ito ay tiyak na hindi mabuti. Kung ikaw ay natigil na may ganitong uri ng error, bagaman, at hindi mo alam kung saan upang tumingin, umasa sa iyong bagong pinakamatalik na kaibigan. Nahulaan mo - Valgrind. Valgrind, gaya ng lagi, alam eksakto kung ano ang up. Ang alloc at libreng bilang ay hindi tumutugma. Mayroon kaming 1 alloc at 4 frees. At Valgrind din nagsasabi sa amin kung saan ang unang masamang libreng tawag - ang isa na nag-trigger sa blowup - ay nagmumula sa - linya 16. Tulad ng iyong nakikita, masamang tawag sa magbakante ay ganap na hindi maayos, kaya inirerekomenda namin ang pagpapaalam ng iyong programa mahayag habang nagtatrabaho ka sa pagkuha-andar ang tamang. Simulan ang naghahanap para sa paglabas lamang pagkatapos ang iyong programa ay gumagana nang maayos, nang walang anumang iba pang mga error. At na ang lahat na nakuha namin para sa video na ito. Ngayon ano pa ang hinihintay mo? Pumunta patakbuhin Valgrind sa iyong mga programa sa ngayon. Ang pangalan ko ay Nate Hardison. Ito ay CS50. [CS50.TV]