(gdb) l 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 void main() 5 { 6 int *arr = NULL; 7 arr = (int*)malloc(10 * sizeof(int)); 8 int idx = 0; 9 for(idx = 0; idx < 10000; idx++) 10 arr[idx] = idx; (gdb) l 10 5 { 6 int *arr = NULL; 7 arr = (int*)malloc(10 * sizeof(int)); 8 int idx = 0; 9 for(idx = 0; idx < 10000; idx++) 10 arr[idx] = idx; 11 12 // iprintf("before\n"); 13 // fflush(stdout); 14 (gdb) l 14 9 for(idx = 0; idx < 10000; idx++) 10 arr[idx] = idx; 11 12 // iprintf("before\n"); 13 // fflush(stdout); 14 15 free(arr); 16 17 printf("after\n"); 18 fflush(stdout); (gdb) b 15 Breakpoint 1 at 0x1201: file t2.c, line 15. (gdb) b No default breakpoint address now. (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000001201 in main at t2.c:15 (gdb) b main Breakpoint 2 at 0x11b5: file t2.c, line 6. (gdb) info b Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000001201 in main at t2.c:15 2 breakpoint keep y 0x00000000000011b5 in main at t2.c:6 (gdb) d Delete all breakpoints? (y or n) n (gdb) clear main Deleted breakpoint 2 (gdb) d 1 (gdb) info b No breakpoints or watchpoints. (gdb) b main Breakpoint 3 at 0x11b5: file t2.c, line 6. (gdb) b 15 Breakpoint 4 at 0x1201: file t2.c, line 15. (gdb) b 10 if idx = 200 Breakpoint 5 at 0x11db: file t2.c, line 10. (gdb) info b Num Type Disp Enb Address What 3 breakpoint keep y 0x00000000000011b5 in main at t2.c:6 4 breakpoint keep y 0x0000000000001201 in main at t2.c:15 5 breakpoint keep y 0x00000000000011db in main at t2.c:10 stop only if idx = 200
(gdb) r Starting program: /home/minimonk/work/src/malloc/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 3, main () at t2.c:6 6 int *arr = NULL; (gdb) c Continuing.
Breakpoint 5, main () at t2.c:10 10 arr[idx] = idx; (gdb) c Continuing.
Breakpoint 5, main () at t2.c:10 10 arr[idx] = idx; (gdb) print idx $1 = 200
특이한게 배열 loop 돌다 터지는게 아니라 다 돌고 나서 free 가려다가 터진다. 신기하네
$ gcc t2.c -g -fsanitize=address $ ./a.out ================================================================= ==2713847==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x504000000038 at pc 0x609d568b42e0 bp 0x7ffdaa34e820 sp 0x7ffdaa34e810 WRITE of size 4 at 0x504000000038 thread T0 #0 0x609d568b42df in main /home/minimonk/work/src/malloc/t2.c:9 #1 0x7cc2e8429d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #2 0x7cc2e8429e3f in __libc_start_main_impl ../csu/libc-start.c:392 #3 0x609d568b41a4 in _start (/home/minimonk/work/src/malloc/a.out+0x11a4)
0x504000000038 is located 0 bytes to the right of 40-byte region [0x504000000010,0x504000000038) allocated by thread T0 here: #0 0x7cc2e88b4887 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145 #1 0x609d568b4286 in main /home/minimonk/work/src/malloc/t2.c:7 #2 0x7cc2e8429d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/minimonk/work/src/malloc/t2.c:9 in main Shadow bytes around the buggy address: 0x0a087fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0a087fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0a087fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0a087fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0a087fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0a087fff8000: fa fa 00 00 00 00 00[fa]fa fa fa fa fa fa fa fa 0x0a087fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0a087fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0a087fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0a087fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0a087fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb Shadow gap: cc ==2713847==ABORTING
idx 값을 보면 10000번 돌았는데
printf 하려고 하면 바로 malloc(): corrupted top size 하면서 터진다.
$ gdb ./a.out GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1 Copyright (C) 2022 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <https://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>.
For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ./a.out... (gdb) l 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 void main() 5 { 6 int *arr = NULL; 7 arr = (int*)malloc(10 * sizeof(int)); 8 int idx = 0; 9 for(idx = 0; idx < 10000; idx++) 10 arr[idx] = idx; (gdb) l 11 6 int *arr = NULL; 7 arr = (int*)malloc(10 * sizeof(int)); 8 int idx = 0; 9 for(idx = 0; idx < 10000; idx++) 10 arr[idx] = idx; 11 12printf("before\n"); 13 fflush(stdout); 14 15 free(arr); (gdb) b 12 Breakpoint 1 at 0x1201: file t2.c, line 12. (gdb) r Starting program: /home/minimonk/work/src/malloc/a.out [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, main () at t2.c:12 12 printf("before\n"); (gdb) print idx $1 = 10000 (gdb) n malloc(): corrupted top size
Program received signal SIGABRT, Aborted. __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737353705280) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: 그런 파일이나 디렉터리가 없습니다.
그래서 printf / fflush 주석처리하고 free를 바로 브레이크 포인트 잡아서 해도 동일하게
루프 종료되면서 바로 에러가 나는 것 같기도...
15 free(arr); (gdb) c Continuing. malloc(): corrupted top size
Program received signal SIGABRT, Aborted. __pthread_kill_implementation (no_tid=0, signo=6, threadid=140737353705280) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: 그런 파일이나 디렉터리가 없습니다. (gdb)