programing

Valgrind에 의해 아직 도달 가능한 누출이 감지됨

copyandpastes 2022. 7. 17. 21:18
반응형

Valgrind에 의해 아직 도달 가능한 누출이 감지됨

이 블록에 기재되어 있는 기능은 모두 라이브러리 기능입니다.이 메모리 누수를 수정하려면 어떻게 해야 합니까?

"Still reachable"(아직 도달 가능) 카테고리에 나열됩니다(매우 유사하지만 크기가 다른 4개가 더 있습니다).

 630 bytes in 1 blocks are still reachable in loss record 5 of 5
    at 0x4004F1B: calloc (vg_replace_malloc.c:418)
    by 0x931CD2: _dl_new_object (dl-object.c:52)
    by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
    by 0x92EFB6: _dl_map_object (dl-load.c:2251)
    by 0x939F1B: dl_open_worker (dl-open.c:255)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0x9399C5: _dl_open (dl-open.c:584)
    by 0xA64E31: do_dlopen (dl-libc.c:86)
    by 0x935965: _dl_catch_error (dl-error.c:178)
    by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
    by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
    by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)

주의: 프로그램을 실행하면 메모리 누수는 발생하지 않았지만 Valgrind 출력에 이전에는 없었던 추가 행이 하나 더 있었습니다.

munmap()으로 인해 /lib/libgcc_s-4.4.4-20100630.so.1의 0x5296fa0-0x52af438에 있는 syms를 폐기합니다.

누수를 수정할 수 없는 경우, munmap() 회선으로 인해 Valgrind가 "아직 도달 가능한" 누수를 0으로 보고하는 이유를 적어도 설명할 수 있습니까?

편집:

다음은 최소 테스트 샘플입니다.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *runner(void *param) {
    /* some operations ... */
    pthread_exit(NULL);
}

int n;

int main(void) {

    int i;
    pthread_t *threadIdArray;

    n=10; /* for example */

    threadIdArray = malloc((n+n-1)*sizeof(pthread_t));  

    for(i=0;i<(n+n-1);i++) {
        if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
            printf("Couldn't create thread %d\n",i);
            exit(1);
        }
    }


    for(i=0;i<(n+n-1);i++) {
        pthread_join(threadIdArray[i],NULL);
    }

    free(threadIdArray);

    return(0);
}

실행 대상:

valgrind -v --leak-check=full --show-reachable=yes ./a.out

「메모리 누전」을 정의하는 방법은 여러 가지가 있습니다.특히 프로그래머들 사이에서 공통적으로 사용되는 "메모리 누수"에는 두 가지 주요 정의가 있습니다.

"메모리 누수"의 첫 번째 일반적인 정의는 "메모리는 할당되어 프로그램이 종료되기 전에 해방되지 않았습니다."입니다.그러나 많은 프로그래머들은 (적당히) 이 정의에 맞는 특정 유형의 메모리 누수는 실제로 아무런 문제가 되지 않으므로 진정한 "메모리 누수"로 간주해서는 안 된다고 주장합니다.

"메모리 누전"에 대한 보다 엄격한 정의(더 유용한 정의)는 "메모리는 할당되었으며 프로그램에는 할당된 메모리 블록에 대한 포인터가 더 이상 없기 때문에 나중에 해방될 수 없습니다."입니다.즉, 포인터가 없는 메모리는 해방할 수 없습니다.따라서 이러한 메모리는 "메모리 리크"입니다.Valgrind는 "메모리 누수"라는 용어의 보다 엄격한 정의를 사용합니다.이는 특히 장기간의 프로세스에서 중대한 힙 고갈의 원인이 될 수 있는 누출 유형입니다.

Valgrind의 리크 보고서 내의 "still reachable" 카테고리는 "memory leak"의 첫 번째 정의에만 맞는 할당을 나타냅니다.이들 블록은 해방되지 않았지만 프로그램이 메모리 블록에 대한 포인터를 계속 추적하고 있었기 때문에 해방될 수 있었다.

일반적으로 "도달 가능한" 블록에 대해서는 걱정할 필요가 없습니다.실제 메모리 누수가 일으킬 수 있는 문제를 일으키지 않습니다.예를 들어, 일반적으로 "아직 도달 가능한" 블록에서 힙이 소진될 가능성은 없습니다.이는 이러한 블록이 일반적으로 프로세스 수명 동안 참조가 유지되는 일회성 할당이기 때문입니다.프로그램을 통해 할당된 메모리를 모두 해방할 수 있지만, 프로세스가 종료된 후에는 운영체제가 프로세스의 메모리를 모두 회수하기 때문에 일반적으로는 그렇게 함으로써 얻을 수 있는 실질적인 이점은 없습니다.이것을 실제 메모리 누전과 대조해 주세요.이러한 누전은, 고정되지 않은 채로 방치하면, 프로세스의 메모리가 부족하거나, 프로세스의 메모리 소비량이 필요이상으로 증가하는 원인이 됩니다.

모든 할당에 일치하는 "free"가 있는지 확인하는 것은 누출 검출 툴이 아직 도달 가능한 블록을 판별할 수 없는 경우(그러나 Valgrind가 이를 수행할 수 있는 경우), 또는 운영 체제가 종료 프로세스의 메모리(Valgrind가 이를 위해 이식된 모든 플랫폼)를 모두 회수하지 못하는 경우뿐일 수 있습니다.

미래의 독자들에게 "도달 가능"은 파일 같은 것을 닫는 것을 잊었다는 것을 의미할 수 있습니다.원래 질문에서는 그렇게 보이지 않지만 항상 그렇게 했는지를 확인해야 합니다.

다음은 "reachable"에 대한 적절한 설명입니다.

"Still reachable"은 글로벌 및 스태틱 로컬 변수에 할당된 누출입니다.Valgrind는 글로벌 변수와 정적 변수를 추적하기 때문에 "한 번만 잊어버리는" 메모리 할당을 제외할 수 있습니다.글로벌 변수는 할당을 한 번 할당하고 할당이 무한히 증가하지 않는다는 의미에서 일반적으로 "누출"이 아니라는 것을 재할당하지 않습니다.엄밀한 의미에서는 아직 누출이지만, 현학적이지 않으면 보통 무시할 수 있습니다.

할당이 할당되어 있고 free'd가 아닌 로컬 변수는 거의 항상 누수입니다.

여기 예가 있습니다.

int foo(void)
{
    static char *working_buf = NULL;
    char *temp_buf;
    if (!working_buf) {
         working_buf = (char *) malloc(16 * 1024);
    }
    temp_buf = (char *) malloc(5 * 1024);

    ....
    ....
    ....

}

Valgrind는 working_buf를 "reachable - 16k"로, temp_buf를 "definitionally lost - 5k"로 보고합니다.

아래에 pthread 패밀리의 루틴이 있기 때문에(그것은 잘 모르겠습니다만), 당신이 joinable로 실행이 종료된 스레드를 실행했을 가능성이 있습니다.

해당 스레드의 종료 상태 정보는 사용자가 호출할 때까지 사용 가능한 상태로 유지됩니다.pthread_join따라서, 메모리는 프로그램 종료시에 손실 레코드에 보관되지만, 를 사용할 수 있기 때문에 아직 도달 가능한 상태입니다.pthread_join액세스 할 수 있습니다.

이 분석이 맞다면 프로그램을 종료하기 전에 이러한 스레드를 분리하여 실행하거나 스레드에 가입하십시오.

편집: 샘플 프로그램을 실행했는데(몇 가지 명백한 수정 후) 오류는 없지만 다음과 같습니다.

==18933== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
--18933-- 
--18933-- used_suppression:      2 dl-hack3-cond-1
--18933-- used_suppression:      2 glibc-2.5.x-on-SUSE-10.2-(PPC)-2a

그 이후로는dl-사물은 당신이 보는 것과 매우 유사합니다. 나는 당신이 억제 파일의 관점에서 해결책을 가지고 있는 알려진 문제를 보고 있다고 생각합니다.valgrind사용하시는 시스템이 최신이 아니거나 배포판의 유지보수가 되지 않을 수 있습니다.(내 것은 ubuntu 10.4, 64비트)

은 무슨 것 같군요.still reachablemeasesdiscloss..

의 ★★★★★★★★★★★★★★★★★」still reachable누출이 아닙니다.당신은 그것에 대해 아무것도 할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/3840582/still-reachable-leak-detected-by-valgrind

반응형