저는 임베디드 Linux 시스템(kernel-5.10.186)을 개발 중이며 프로그램의 메모리 누수를 디버깅하고 싶습니다.
를 통해 pmap -x PID
프로세스의 힙이 계속 증가한다는 사실을 발견했습니다.
증가가 어디서 오는지 알아내기 위해 커널 mm/mmap.c에 다음 코드를 추가했습니다.
--- a/kernel/kernel-5.10/mm/mmap.c
+++ b/kernel/kernel-5.10/mm/mmap.c
@@ -269,6 +269,12 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
goto out;
mm->brk = brk;
+ if (strstr(current->comm, "testprog")) {
+ printk("XXXXXX mm->start_brk: %lx, mm->brk: %lx\n", mm->start_brk, mm->brk);
+ if (mm->brk - mm->start_brk >= 0xd0000) {
+ send_sig(SIGSEGV, current, 0);
+ }
+ }
따라서 힙 크기가 0xd0000을 초과하면 SIGSEGV를 보내 testprog
코어 덤프를 가져온 다음 gdb
역추적을 분석하여 증가분의 출처를 알아냅니다.
성공적으로 코어를 생성했지만 gdb testprog core
부분적인 트레이스백만 얻었습니다.
(gdb) bt
#0 0x77de1994 in brk () from /lib/libc.so.6
#1 0x77de1a88 in sbrk () from /lib/libc.so.6
Backtrace stopped: frame did not save the PC
어디서/누가 전화하는지 표시되지 않습니다 sbrk()/brk()
.
그런 다음 실시간 역추적을 캡처하기 위해 gdb로 실행을 시도했지만 testprog
여전히 실패했습니다.
이것은 테스트에 사용된 testprog.c의 데모 코드입니다(코어는 전체 추적을 표시하지 않습니다).
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
int main()
{
char *p;
p = malloc(0x2410);
if(p == NULL)
{
printf("malloc error!");
return 0;
}
printf("XXXXXXXXXXXX p = %p\n", p);
printf("Press any key to deploy\n");
getchar();
memset(p, 0, 4100);
printf("Will set more\n");
memset(p, 1, 8192);
while(1) {
p = malloc(1000);
printf("ppppp %p\n", p);
usleep(1000);
}
return 0;
}
이 메모리 누수를 디버깅하는 방법을 모르겠고(core 및 gdb 사용, 둘 다 실패함) valgrind는 실제 누수를 포착하지 못합니다.
저를 도와주실 수 있는 방법이 있나요? 커널 소스 코드가 있으므로 디버깅을 돕기 위해 수정할 수 있습니다.