[Powered by Google Translate] [Valgrind]
[네이트 Hardison, 하버드 대학교]
이 CS50.TV, CS50입니다]
C 프로그램에서 가장 어려운 버그 중 일부
메모리의 그릇된 관리에서 왔습니다.
엉망으로하는 방법에는 거대한 숫자가있다
메모리의 잘못된 양을 할당 포함
변수를 초기화 잊어하면,
버퍼의 끝에 전이나 후에 쓰기,
메모리를 여러 번 계속 자유롭게.
증상은 간헐적 인 충돌에 이르기까지 다양한
신비 덮어 값으로,
자주 멀리 원래 오류에서 제거 장소 및 시간에.
기본 근본 원인으로 다시 관찰 문제를 추적
도전 할 수 있습니다,
그러나 다행스럽게도 Valgrind라는 유용한 프로그램이
그 도움이 많이 작업을 수행 할 수 있습니다.
>> 당신은 활성화 Valgrind 아래 프로그램을 실행
힙 메모리 할당 및 액세스 광범위하게 확인하지 않습니다.
Valgrind 문제를 감지하면, 당신에게 즉각적인을 제공합니다
작업을 수행 할 수 있습니다 직접 정보를
더 쉽게 찾아 문제를 해결할 수 있습니다.
또한 적은 치명적인 메모리 문제에 대한 보고서를 Valgrind
이러한 메모리 누수와 같은, 힙 메모리를 할당,
하고 해방 잊고 있어요.
우리 디버거에서의 컴파일러, 꽝, GDB를 좋아
Valgrind는 무료 소프트웨어이며,이 기기에 설치되어 있습니다.
Valgrind는 여러분의 바이너리 실행 파일에서 실행
네. C 나. H 소스 코드 파일,
그럼 당신은 프로그램의 최신 복사본을 컴파일해야합니다
꽝를 사용하거나합니다.
그런 다음, Valgrind 아래에 프로그램을 실행하는 것은 할 수
그냥 단어 Valgrind로 표준 프로그램 명령을 prefixing 간단,
이는 Valgrind까지 시작하고 그것의 내부 프로그램을 실행합니다.
시작할 때, Valgrind 일부 복잡한 아는
메모리 검사의 실행을 구성 할 수 jiggering,
그래서 설치하고 실행하기 위해 비트를 취할 수 있습니다.
이 프로그램은 다음 훨씬 더 천천히, 일반적으로 실행 그것을됩니다
하고 완료하면 Valgrind는 메모리 사용량의 요약을 인쇄합니다.
모든 것이 잘되면, 그것은 다음과 같이합니다 :
이 경우. / clean_program
제가 실행하려는 프로그램의 경로입니다.
그리고이 어떤 인수를하지 않습니다 반면,
만약 그랬다면 나는 평소와 같이 명령의 끝에, 그냥 압정으로 고정을 물었다.
클린 프로그램은 내가 만든 좀 멍청 프로그램입니다
즉, 힙에 ints의 블록을위한 공간을 할당
일부 값 중 내부를 놓고, 전체 블록을 만듭니다.
이렇게하면 오류없이 누출 아니,에 촬영하신 거죠.
>> 또 다른 중요한 측정 항목은 할당 된 바이트의 총 수입니다.
귀하의 할당이 메가바이트 이상에있는 경우, 프로그램에 따라,
당신은 아마 뭔가 잘못을 다하고 있습니다.
당신은 불필요하게 중복 저장을하는거야?
이 스택을 사용하는 것이 더 효과적 때, 저장을 위해 힙을 사용하고 있습니까?
따라서, 메모리 오류가 진정한 악마가 될 수 있습니다.
더 명백한 사람은 멋진 충돌을 일으킬
이지만 아직도 정확하게하기 어려울 수 있습니다
정확히 어떤 충돌로했다.
메모리 오류가 더 insidiously, 프로그램
여전히 깨끗하게 컴파일 할 수
아직도 제대로 작동 할 수
당신은 대부분의 시간을 행운 관리 because.
여러 후 "성공 결과"
당신은, 충돌 컴퓨터의 우연이라고 생각할 수
하지만 컴퓨터는 절대 틀리지 않습니다.
>> Valgrind를 실행하면 볼 수 메모리 오류의 원인을 추적 할 수 있습니다
뿐만 아니라 오류가 숨어 발견으로 아직 모르는.
Valgrind 문제를 감지 할 때마다, 그것이 관찰에 대한 정보를 인쇄합니다.
각 항목은 매우 간결한입니다 -
저작권을 침해하는 명령어의 소스 라인,이 문제는 무엇이며,
관련 메모리에 대한 약간의 정보 -
하지만 종종이 올바른 위치에주의를 기울여 주시기하기에 충분한 정보입니다.
다음은 버그가 프로그램을 실행 Valgrind의 예입니다
그 힙 메모리의 잘못된 읽기를하지 않습니다.
우리는 컴파일에 오류 또는 경고를 볼 수 없습니다.
어 - 오, 오류 요약은 두 오류가 있다고 -
크기 4의 두 잘못된 읽기 - 바이트입니다.
모두 나쁜는 invalid_read.c의 주요 기능에서 발생 읽고
라인 16 라인 (19)의 두 번째에서 첫 번째.
가 코드를 보자.
printf의 메모리 블록의 끝을 지났 한 정수를 읽으려고하는 최초의 호출 것 같습니다.
우리는 Valgrind의 출력에서​​ 다시 만난다면
우리는 Valgrind 정확히 그게 우리에게 말하는 것을 참조하십시오.
우리가 읽을하려는 주소는 0 바이트를 시작
- 크기 16 바이트의 블록의 끝을 지났습니다
우리가 할당하는 4 개의 32 비트 ints.
즉, 우리가 읽는 된 주소는, 그렇지 블록의 끝에서 시작
우리는 우리의 나쁜 printf 전화에서 볼 것처럼.
이제 잘못된 읽기, 거래의 큰처럼 들릴 수
하지만 당신은 프로그램의 흐름을 제어하기 위해 데이터를 사용하는 경우 -
예를 들어,의 일환으로 if 문 또는 루프 -
그리고 일이 자동으로 나쁜 이동할 수 있습니다.
나는 invalid_read 프로그램을 실행 할 수있는 방법보기
그리고 보통의 아무 아웃이 발생하지 않습니다.
무서운, 그렇지?
>> 이제, 귀하가 귀하의 코드에서 발생할 수있는 오류를 좀 더 가지 살펴 보자
우리는 그들을 감지하는 방법 Valgrind가 표시됩니다.
우리는, invalid_read의 예를 본
그래서 지금의이 invalid_write을 확인 해보자.
다시 컴파일에 오류 또는 경고.
좋아요, Valgrind이 프로그램에서 두 오류가 있다는 것을 말해 -
그리고 invalid_write 및 invalid_read.
가이 코드를 확인 해보자.
우리가 고전 나 strlen 플러스 벌레의 인스턴스가 생긴 것 같은데.
코드는 malloc 공간의 추가 바이트를하지 않습니다
/ 0 문자를 들면,
그래서 str을 복사 ssubstrlen에서를 작성했을 때 "cs50 바위!"
우리 블록의 끝을 지났 1 바이트를 썼습니다.
우리가 printf 우리의 통화를 할 때 invalid_read 온다.
가 / 0 문자를 읽을 때 Printf가 잘못 메모리를 읽고 종료
이렇게 E 문자열의 끝 부분에 보이는대로 인쇄입니다.
그러나이 중 아무 것도 Valgrind를 탈출하지 않습니다.
우리는으로 str 복사의 일환으로이 invalid_write을 잡은 것을 알
메인 행 11과 invalid_read는 printf의 일부입니다.
Valgrind, 신난다.
다시 말하지만,이 큰 문제 같아 보이지 않을 수도 있습니다.
우리는 Valgrind의 외부 계속해서이 프로그램을 실행할 수 있습니다
및 오류 증상을 볼 수 없습니다.
>> 그러나 볼이 약간의 변화를 살펴 보자
어떻게 일이 진짜 나쁜받을 수 있습니다.
자, 부여, 우리는이 코드에서 조금만보다 더 일을 남용하고 있습니다.
우리는 두 개의 문자열의 힙 공간을 할당하고
cs50 바위의 길이,
이 시간, / 0 문자를 기억.
하지만 우리는 메모리 블록에 슈퍼 - 긴 문자열에 던져
그 S는를 가리키고 있습니다.
어떤 영향을하면 메모리 블록에이됩니다 거기에 T 포인트?
음, 만약 S 바로 인접 메모리로 T 포인트
단지 이후에 오는
그러면 우리는 T.의 일부를 통해 서면으로 수도
가이 코드를 실행할 수 있습니다.
무슨 일이 있었는지 좀 봐.
우리는 힙 블록 모두에 저장된 문자열이 제대로 출력 한 것으로 나타났다.
아무것도 전혀 잘못된 것 없습니다.
그러나,이 우리의 코드로 돌아 가게하고
우리가 cs50 바위를 복사 어디에 줄을 주석으로
두 번째 메모리 블록에, t에 의해 지적했다.
자, 우리는이 코드를 실행할 때 우리는해야
첫 번째 메모리 블록의 내용이 인쇄를 참조하십시오.
우와, 우리는 str을 복사 한 경우에도
두 번째 힙 블록에 모든 문자는 하나, T 의해 지적
우리는 인쇄를 나가.
사실, 문자열 우리는 우리의 첫번째 블록에 박제
첫 번째 블록 두 번째 블록에를 지나쳤
모든 정상적인 것 같습니다 만들기.
Valgrind하지만, 우리에게 진실을 이야기 알려줍니다.
우리는 간다.
그 무효의 모든 읽고 씁니다.
>> 의 오류의 또 다른 종류의 예를 살펴 보도록하겠습니다.
여기보다 불행한 일을.
우리는 힙에 정수를위한 공간을 잡아
P - - 그 공간을 가리 키도록 우리는 정수 포인터를 초기화합니다.
그러나, 우리 포인터가 초기화되는 동안,
가 가리키는 있다는 데이터는 힙의 해당 부분에 있던 정크이기도.
그래서 우리는 INT 전으로 데이터를로드 할 때,
우리는 기술적으로, 전을 초기화
우리는 정크 데이터를 이렇게.
전화는 편리한 디버깅 매크로입니다, 주장
aptly라는 이름의 주장 라이브러리에서 정의
중지는 테스트 조건이 실패 할 경우 프로그램 것이다.
나는이 0이 아닌 경우 즉,이다.
힙 공간에 어떤 건지에 따라, P 의해 지적
이 프로그램은 때로는 작동하고 다른 시간에 실패 할 수 있습니다.
작동하는 경우, 우리는 운이지고있어.
컴파일러는이 오류를 잡을 만, 확인 의지를 Valgrind하지 않습니다.
이 우리는 정크 데이터의 사용에서 형태소 분석 오류를 참조하십시오.
>> 당신이 힙 메모리를 할당 있지만 할당을 취소하거나 확보되지 않는 경우
그는 누출이라고합니다.
종료를 실행하고 즉시 작은 수명이 짧은 프로그램,
누출은 매우 해롭지,
하지만, 큰 크기 및 / 또는 장수의 프로젝트,
심지어 작은 누출은 주요 식으로 조합 할 수 있습니다.
CS50를 들어, 우리는 당신을 기대
당신이 할당 된 힙 메모리를 모두 자유롭게, 알아서
우리는 당신이 수동 프로세스를 제대로 처리 기술을 구축하고자부터
C.에 필요한
이렇게하려면, 당신의 프로그램이 정확하게 있어야합니다
malloc과 무료 통화 사이의 일대일는 통신.
다행히도, Valgrind도 메모리 누수를 할 수 있습니다.
여기 leak.c라는 새는 프로그램입니다 할당
힙의 공간, 거기에 기록하지만, 그것을 확보하지 않습니다.
우리는 확인하고 Valgrind 아래 실행과 컴파일
우리는보고, 우리는 메모리 오류도이없는 반면, 그
우리가 한 누출을 가지고 있습니다.
확실히 손실 16 바이트이 있습니다
프로그램이 종료되면 그 메모리 포인터가 범위에 존재하지 않았을 의미합니다.
지금, Valgrind는 우리에게 누설에 대한 정보의 톤을 제공하지 않습니다
하지만 우리는 그 보고서의 하단으로 내려주는이 작은 노트를 수행하는 경우
을 다시 실행 - 누출 확인 = 전체
누수 된 메모리의 전체 내용을 보려면
우리는 더 많은 정보를 얻을 수 있습니다.
이제 힙 요약,
분실 된 메모리가 처음 할당 된 곳 Valgrind 우리를 알려줍니다.
우리가 소스 코드에서 찾고에서 알고있는 것처럼,
Valgrind는 우리가 메모리를 유출 우리에게 알려
leak.c의 8 호선에서 malloc를 호출로 할당 된
main () 함수 인치
아주 멋진.
>> Valgrind는 이러한 용어를 사용하는 누수 분류 :
물론 분실 -이 힙 할당 된 메모리입니다
어떤 프로그램은 더 이상 포인터가 없습니다.
Valgrind를 사용하면 포인터를 가지고 있지만, 이후의 자취를 잃었 것으로 알고 있습니다.
이 메모리는 확실히 유출된다.
간접적 손실 -이 힙 할당 된 메모리입니다
어떤 거기에 유일한 포인터도 손실됩니다 수 있습니다.
예를 들어, 연결리스트의 첫 번째 노드에 포인터를 분실하는 경우
다음 첫 번째 노드 자체는 분명히 손실 될
후속 노드는 간접적으로 손실 될 것입니다 동안.
가능 잃었 어 -이 힙 할당 된 메모리입니다
어떤에 Valgrind는 포인터 여부가 있는지 확신 할 수 없습니다.
그래도 연결할 수는 힙 할당 된 메모리입니다
프로그램이 여전히 출구에서 포인터를 가지고있는에,
이는 일반적으로 의미합니다 거기에 전역 변수를 가리 킵니다.
이러한 누수를 확인하려면, 당신은 또한 옵션을 포함해야합니다
- 아직도 도달 = 예
Valgrind의 호출 인치
>> 이 다른 경우는, 그들을 청소에 대해 서로 다른 전략을 필요로 할 수
하지만 누수가 제거해야합니다.
불행하게도, 누수를 해결하는 것은 힘들 수 있습니다
무료로 잘못된 통화 프로그램을 날려 버릴 수 있기 때문에.
예를 들어, 우리가 invalid_free.c 보면,
우리는 나쁜 기억 반납의 예를 참조하십시오.
전체 블록을 확보 할 수있는 하나의 호출해야하는 것은 무엇입니까
메모리, int_block 의해 지적
대신 각 정수 크기 섹션을 확보하기 위해이되었습니다
개별적으로 메모리가 부족합니다.
이 catastrophically 실패합니다.
꽝! 어떤 오류가 발생했습니다.
이 확실히 좋지 않습니다.
당신은 오류의 종류와 붙어있어,하지만 당신은, 어디를 봐야할지 모를 경우
당신의 친한 친구에 귀환한다.
당신은 그것을 짐작 - Valgrind.
Valgrind, 언제나이야, 정확히 알고 있습니다.
alloc과 무료 카운트가 일치하지 않습니다.
우리는 하나 alloc과 4 해방있어.
그리고 Valgrind는 또한 어디에서 처음으로 나쁜 무료 통화 우리에게 말해줍니다 -
확대를 게재 한 사람은 -에서 오는 -
라인 16.
당신이보다시피, 해방하는 나쁜 전화, 정말 나쁜
그래서 우리는 프로그램 누수를 보내는 것이 좋습니다
당신은 기능이 올바른 받고 작업을하는 동안.
프로그램이 제대로 작동 후에 만​​ 누출을 찾고 시작,
다른 오류없이.
>> 그리고 우리가이 동영상에 대한 가진 전부입니다.
이제 뭘 기다리는거야?
지금 프로그램에 Valgrind 실행 이동합니다.
내 이름은 네이트 Hardison입니다. 이 CS50입니다. [CS50.TV]