[질문] Out of memory
글쓴이: hultul / 작성시간: 월, 2003/10/06 - 10:20오후
임베디드 환경 application 에서 ping을 구현하였습니다.(busybox참조 ^^)
그런데, 동작은 잘하는데 일정시간이 흐르면 Out of memory 가 납니다. ㅜ.ㅜ
고수님들 한수 지도를 부탁드립니다.
참고로 아래 코드에서 ping 이라는 함수를 1초에 한번씩 실행합니다.
#include <sys/param.h> #include <sys/socket.h> #include <sys/file.h> #include <sys/time.h> #include <sys/times.h> #include <sys/signal.h> #include <netinet/in.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> #include <arpa/inet.h> #include <netdb.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <unistd.h> #include <string.h> #include <stdlib.h> static int create_icmp_socket(void) { struct protoent *proto; int sock; proto = getprotobyname("icmp"); /* if getprotobyname failed, just silently force * proto->p_proto to have the correct value for "icmp" */ if ((sock = socket(AF_INET, SOCK_RAW, (proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */ return -1; } return sock; } static const int DEFDATALEN = 56; static const int MAXIPLEN = 60; static const int MAXICMPLEN = 76; static const int MAXPACKET = 65468; #define MAX_DUP_CHK (8 * 128) static const int MAXWAIT = 10; static const int PINGINTERVAL = 1; /* second */ #define O_QUIET (1 << 0) #define A(bit) rcvd_tbl[(bit)>>3] /* identify byte in array */ #define B(bit) (1 << ((bit) & 0x07)) /* identify bit in byte */ #define SET(bit) (A(bit) |= B(bit)) #define CLR(bit) (A(bit) &= (~B(bit))) #define TST(bit) (A(bit) & B(bit)) int gRet=0; static int in_cksum(unsigned short *buf, int sz) { int nleft = sz; int sum = 0; unsigned short *w = buf; unsigned short ans = 0; while (nleft > 1) { sum += *w++; nleft -= 2; } if (nleft == 1) { *(unsigned char *) (&ans) = *(unsigned char *) w; sum += ans; } sum = (sum >> 16) + (sum & 0xFFFF); sum += (sum >> 16); ans = ~sum; return (ans); } static char *hostname = NULL; void noresp(void) { gRet = -1; DEBUG("No response from %s\n", hostname); } int ping(char *host) { struct hostent *h; struct sockaddr_in pingaddr; struct icmp *pkt; int pingsock, c; char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN]; struct sockaddr_in from; struct iphdr *siphdr; pingsock = create_icmp_socket(); memset(&pingaddr, 0, sizeof(struct sockaddr_in)); pingaddr.sin_family = AF_INET; h = gethostbyname(host); memcpy(&pingaddr.sin_addr, h->h_addr, sizeof(pingaddr.sin_addr)); hostname = h->h_name; pkt = (struct icmp *) packet; memset(pkt, 0, sizeof(packet)); pkt->icmp_type = ICMP_ECHO; pkt->icmp_cksum = in_cksum((unsigned short *) pkt, sizeof(packet)); c = sendto(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in)); if (c < 0 || c != sizeof(packet)) { perror("sendto"); return -1; } alarm(5); while (1) { socklen_t fromlen = sizeof(from); if ((c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &from, &fromlen)) < 0) { if (errno == EINTR) { DEBUG("module_KtSock ERROR: Interrupted\n"); gRet = -1; break; } perror("recvfrom"); continue; } if (c >= 76) { siphdr = (struct iphdr *) packet; pkt = (struct icmp *) (packet + (siphdr->ihl << 2)); if (pkt->icmp_type == ICMP_ECHOREPLY) { gRet = 1; break; } } } alarm(0); return gRet; }
File attachments:
첨부 | 파일 크기 |
---|---|
![]() | 25.69 KB |
Forums:
google에서 찾아봤더니 glibc의 getprotobyname()이나
google에서 찾아봤더니 glibc의 getprotobyname()이나 getservbyname() 에서 memory leak이 있다는 얘기가 있습니다.
흑흑...getprotobyname과 gethostbyname 을 다
흑흑...
getprotobyname과 gethostbyname 을 다른 방법으로 구현했습니다.
그냥 값을 대입하는 방식으로...
그래두 안됩니다. 10분을 못넘기고 out of memory가 나오네요 ㅠ.ㅠ
참고로 PPC, kernel-2.4.18, libc 6 입니다.
별짓 다해봤는데 안되는군요...
고수님들, 함줌의 도움을 부타드립니다.
코더에서 프로그래머까지
ping 함수를 계속 해서 호출하시는거 같은데... 맞는지..????
ping 함수를 계속 해서 호출하시는거 같은데... 맞는지..????
그렇게 하지 마시고 sendto 함수를 반복 호출 하는 로직으로 바꾸시는게 나을 듯 합니다.
이왕이믄 적절한 time 도 사용하시는것이 나을듯 하네용.
^^ 도움이 될라는지...
그럼 수고하세용.
아참 이거 제가어디서 퍼와서 좀 수정 해서 쓰던건데요.. 참조가 되셧으면 하네용
수정 부분은 디바이스 바인딩해서 icmp 날리는 부분입니다.
hi 용
첨부해주신 파일 욜심히 보고 있음다 ^^그리고ping() 함수
첨부해주신 파일 욜심히 보고 있음다 ^^
그리고
ping() 함수를 반복적으로 호출하는거 맞습니다.
ping() 함수 안에 sendto(), recvfrom 함수가 있고요.
그런데 sendto() 함수를 반복적으로 호출해보라는 게 무슨 말씀이신가여?
코더에서 프로그래머까지
ping 함수 내에서 sock 에 대한 여러 설정들을 하고 계시는데.
ping 함수 내에서 sock 에 대한 여러 설정들을 하고 계시는데.
같은 도메인에대하여 한번만 설정 해주면 되는것을 ping 함수 가 호출 될때 마다 설정하게 되어있습니다. 이렇게 하면 제생각인데 메모리 마니 잡아 묵지 않을까 하네용 제가 함 컴파일해서 돌려봤더니 1분두 안되서 메모리 에러 나데용.
물론 time 을 사용하지 않아 엄청남 icmp 를 발생시켰지만. ^^;
만약 다 다른 도메인이면 상관이 업겟지만요.
첨부 한 소스를 보시면 pinger 라는 함수안에 sendto 함수가 있습니다.
그리고 첨부된 소스에 보시면 ip 나 도메인 입력에 대해서 소켓타입 소켓옵션 머 이런것들은 한번 만 호출 되는것을 알수 있습니다.
mian 에서 pinger 함수를 반복문을 통하여 호출 하게 하였고요.
저의 답변은 여기 까지 입니다.
첨부한 소스를 마니 참조하시고요..
수고 하세요.
hi 용
헉...님의 조언대로 socket 생성을 한번만 하니 괜찮아졌음다정말
헉...님의 조언대로 socket 생성을 한번만 하니 괜찮아졌음다
정말정말 감사함다. 귀중한 정보를 얻게 되었습니다
네트웍 프로그래밍은 아무나 하는게 아닌거 같아여 ㅡ.ㅡㅋ
코더에서 프로그래머까지
댓글 달기