programing

C malloc 어설션 실패가 발생하는 이유는 무엇입니까?

firstcheck 2022. 7. 5. 00:17
반응형

C malloc 어설션 실패가 발생하는 이유는 무엇입니까?

할 수 OpenCL을 얻을 수 malloc프로그램을 실행하면 이 프로그램을 할당해 주고, 이 프로그램을 실행하면 이 프로그램을 통해 '이러다', '이러다', '이러다', '이러다', '이러다', '이러다', '이러다', '이러다'를 보내 줍니다.size/2알고리즘에 대응합니다. 내가 리 the가를 때malloc을 하다

malloc.c:3096: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted

문제의 행은 다음과 같습니다.

int *mult(int size, int *a, int *b) {
    int *out,i, j, *tmp1, *tmp2, *tmp3, *tmpa1, *tmpa2, *tmpb1, *tmpb2,d, *res1, *res2;
    fprintf(stdout, "size: %d\n", size);

    out = (int *)malloc(sizeof(int) * size * 2);
}

했습니다.fprintf그리고 이것은 양의 정수(보통 그 시점에서는 50)입니다.malloc★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★나는 그저 무슨 일이 일어나고 있는지 막막할 뿐이고, 지금까지 구글에서 찾은 어떤 것도 도움이 되지 않는다.

무슨 일인지 짐작 가는 거 없어?컴파일러 에러에 대비하여 새로운 GCC를 컴파일하는 방법을 찾고 있습니다만, 매우 의심스럽습니다.

메모리가 파손되었을 가능성이 99.9%(버퍼 오버 또는 언더 버퍼, 해방 후 포인터에 쓰기, 같은 포인터로 2회 프리 콜 등)

Valgrind에서 코드를 실행하여 프로그램이 잘못된 부분을 확인합니다.

이런 일이 일어나는지 이해하기 위해 @r-samuel-klatchko의 답변을 조금 더 자세히 말씀드리겠습니다.

했을 때malloc실제로 일어나고 있는 일은 단순히 가지고 놀 수 있는 메모리 덩어리를 주는 것보다 조금 더 복잡합니다.에는 ★★★★★★★★★★★★★★★★★★.malloc, 에서는 메모리의 한 것은, 그 사이즈)가되고 있기 에, 가 「」에 전화를 때에, 「」(가장 중요한 것은 「사이즈」)가 됩니다.free메모리를 얼마나 해방시킬지 알고 있습니다.는 일반적으로 됩니다.malloc보다 상세한 정보는 인터넷™에서 확인할 수 있지만, 기본적인 생각은 다음과 같습니다.

+------+-------------------------------------------------+
+ size |                  malloc'd memory                +
+------+-------------------------------------------------+
       ^-- location in pointer returned by malloc

으로 ( 단순화해서) 이 할 때malloc사용 가능한 메모리의 다음 부분에 대한 포인터가 필요합니다. 방법 중 하나는 비트의 하는 것입니다.size네..p1,p2 ★★★★★★★★★★★★★★★★★」p3:

+------+----------------+------+--------------------+------+----------+
+ size |                | size |                    | size |          +
+------+----------------+------+--------------------+------+----------+
       ^- p1                   ^- p2                       ^- p3

그럼, 무엇이 당신의 오류를 야기합니까?

할당한 메모리 용량을 초과하여 코드가 잘못 입력되었다고 가정해 보십시오(문제 발생 시 필요량보다 적게 할당했거나 코드 내 어딘가에서 잘못된 경계 조건을 사용하고 있기 때문입니다).에 데이터가 있다고 가정해 .p2한다고 합니다.p3의 »size에 드드를 호출할 때. 음음음음음음음malloc크기 필드를 보고 크기 로 이동합니다p3 + size이치노가 되었기 size 이 된 memorydisposition이 아닌 "memory.disposition"이 됩니다.

말할 필요도 없이, 이것은 대혼란을 일으킬 수 있습니다!의 실장자malloc따라서 님은 이 문제(및 기타 문제)가 발생할 경우 이를 파악하기 위해 건전성 체크를 여러 번 실시하려고 하는 '의견' 또는 체크(체크)를 여러 개 투입하고 있습니다.당신의 특별한 경우, 이러한 주장은 위반되고, 따라서malloc당신의 코드가 하지 말아야 할 일을 하려고 한다고 말하는 거죠

앞서 말한 바와 같이, 이것은 지나친 단순화이지만, 요점을 설명하기에 충분하다.glibc의 실장malloc5k 회선이 넘고, 다이나믹 메모리 할당 메카니즘을 구축하는 방법에 대해서는, 많은 연구가 행해지고 있기 때문에, SO답변으로 모든 것을 커버하는 것은 불가능합니다.이것으로 문제의 진짜 원인이 무엇인지 알 수 있기를 바랍니다!

Valgrind를 사용하는 대체 솔루션:

나는 내 친구가 프로그램을 디버깅하는 것을 도와줘서 매우 기쁘다.그의 프로그램에는 바로 이런 문제가 있었다.malloc()중단의 원인)을 나타냅니다.GDB에서 같은 에러 메시지가 표시됩니다.

주소 삭제 프로그램을 컴파일해서

gcc -Wall -g3 -fsanitize=address -o new new.c
              ^^^^^^^^^^^^^^^^^^

그리고 도망쳤다.gdb new. 프로그램이 종료될 때SIGABRT후속으로 야기되다malloc(), 많은 유용한 정보가 인쇄되어 있습니다.

=================================================================
==407==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6060000000b4 at pc 0x7ffffe49ed1a bp 0x7ffffffedc20 sp 0x7ffffffed3c8
WRITE of size 104 at 0x6060000000b4 thread T0
    #0 0x7ffffe49ed19  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x5ed19)
    #1 0x8001dab in CreatHT2 /home/wsl/Desktop/hash/new.c:59
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #4 0x8001679 in _start (/mnt/d/Desktop/hash/new+0x1679)

0x6060000000b4 is located 0 bytes to the right of 52-byte region [0x606000000080,0x6060000000b4)
allocated by thread T0 here:
    #0 0x7ffffe51eb50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50)
    #1 0x8001d56 in CreatHT2 /home/wsl/Desktop/hash/new.c:55
    #2 0x80031cf in main /home/wsl/Desktop/hash/new.c:209
    #3 0x7ffffe061b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)

출력, 특히 스택트레이스에 대해 살펴보겠습니다.

첫 번째 부분에는 다음 위치에 잘못된 쓰기 작업이 있다고 나와 있습니다.new.c:59이 행은 다음과 같습니다.

memset(len,0,sizeof(int*)*p);
             ^^^^^^^^^^^^

두 번째 부분에서는 잘못된 쓰기가 발생한 메모리가 다음 위치에서 생성된다고 합니다.new.c:55이 행은 다음과 같습니다.

if(!(len=(int*)malloc(sizeof(int)*p))){
                      ^^^^^^^^^^^

바로 그겁니다.몇 시간 동안 친구를 혼란스럽게 했던 버그를 찾는 데 30분도 채 걸리지 않았습니다.그는 그 실패의 위치를 알아냈지만, 그것은 그 이후가 될 것이다.malloc()콜이 실패했지만 이전 코드에서 이 에러를 검출할 수 없었습니다.

요약: 테스트해 보세요.-fsanitize=addressGCC 또는 Clang.메모리 문제를 디버깅할 때 매우 유용합니다.

당신과 비슷한 메시지를 받았습니다.


프로그램: malloc.c:2372:sysmalloc:Assertion `(old_top ==(((mbinptr)(((차))&((av)->, bins[((1)-1)*2]))-__builtin_offsetof(structmalloc_chunk, fd))))&&, old_size== 0||(old_size)을(( 긴 부호 없는), =( 긴 부호 없는)((((__builtin_offsetof(structmalloc_chunk, fd_nextsize))+((2*((size_tsizeof)))-1))&~((2*((size_tsizeof)))-1)))&&((o.Ld_top)->, 크기&0x1)&&(( 가로지르죠.igned long) old_end & pagemask) == 0'이(가) 실패했습니다.

이전에 malloc을 사용할 때 메서드 호출을 잘못했습니다.부호 없는 문자 배열에 필드를 추가할 때 sizeof()-operator 뒤에 계수를 업데이트할 때 곱셈 기호 '*'에 '+'를 잘못 입력한다.

내 경우 오류의 원인이 되는 코드는 다음과 같습니다.


UCHAR* b=(UCHAR*)malloc(size of(UCHAR)+5);b[INTB]ITS]=(일부 계산);
b[BUFSPC]=(일부 계산);
b[BUFOVR]=(일부 계산);
b[BUFMEM]=(일부 계산);
b[MATCHB]ITS]=(일부 계산);

나중에 다른 방법으로 malloc을 다시 사용해보니 위와 같은 에러 메시지가 나타납니다.문의는 (충분히) 간단했습니다.


UCHAR* b=(UCHAR*)malloc(size of(UCHAR)*50);

첫 번째 콜에서 +' 기호를 사용하면 (어레이에 할당되지 않은 메모리를 덮어쓰기) 직후 어레이 초기화와 조합하여 계산이 잘못될 수 있습니다.이 malloc의 메모리 맵에 혼란을 줍니다.그 때문에 두 번째 콜이 잘못되었다.

1개의 애플리케이션을 Visual C에서 gcc over Linux로 포팅하고 있었는데 같은 문제가 있었습니다.

malloc.c:3096: sYSMARTOc: UBUNTU 11에서 gcc를 사용한 어설션.

같은 코드를 Suse 디스트리뷰션(다른 컴퓨터)으로 옮겼는데 문제 없습니다.

나는 그 문제가 우리의 프로그램이 아니라 자신의 libc에 있다고 생각한다.

할당된 메모리를 초과하여 실행 중일 수 있습니다.malloc을 호출할 때까지 기본 SW는 수신하지 않습니다.

malloc에 의해 포착된 가드 값이 있을 수 있습니다.

edit...한계 확인 도움말을 위해 추가했습니다.

http://www.lrde.epita.fr/~akim/ccmp/doc/http-checking.http://http://www.lrde.epita.fr/

크기(int)를 곱하는 것을 잊었기 때문에 이 오류가 발생했습니다.malloc(..) 인수는 바이트 수이지 기계어 등의 수가 아닙니다.

동일한 문제가 발생하였고, 새로운 문자 *문자열 데이터를 추가하기 위해 루프에서 malloc over n을 다시 사용했습니다. 같은 문제에 직면했지만, 출시된 후 할당된 메모리 문제는 해결되었습니다.

언급URL : https://stackoverflow.com/questions/2987207/why-do-i-get-a-c-malloc-assertion-failure

반응형