vxworks 5.5.1의 posix socket api에 이상한 문제가 있습니다. 코드는 보통 이며 흥미로운 것은 아닙니다 (아래에 추가됨)이지만 그 요지는 다음과 같습니다. 을 호출하는 함수와 다른 함수로 socket()
과 bind()
을 호출하면 recvfrom()
호출에서 페이지 오류가 발생합니다. 모든 것이 동일한 기능으로 수행되면 정상적으로 작동합니다. 패킷이 도착하지 않을 때 recvfrom()
을 호출하면 오류가 바로 발생합니다.VxWorks에서 recvfrom()을 사용할 때 Pagefault
VxWorks는이 API에 대해 예상치 못한 방식으로 스택을 사용합니까?
편집 : 일부 코드가 추가되었습니다. te_serve1()
함수는 정상적으로 작동하지만 te_serve_one()
(도우미 함수 사용)은 작동하지 않습니다.
#include <taskLib.h>
#include <sysLib.h>
#include <string.h>
#include <taskLib.h>
#include <stdlib.h>
#include <stdio.h>
#include <types.h>
#include <sys/socket.h>
#include <sockLib.h>
#include <netinet/in.h>
#ifdef DEBUG
#define DP(...) printf(__VA_ARGS__)
#else
#define DP(...) do { } while(0)
#endif
#define LLB(l, b) ((l & (0x000000FF << (b*8))) >> b*8)
struct msg_log {
unsigned long src;
int size;
};
static int setup(short port)
{
int err = 0;
struct sockaddr_in addr;
int sock;
DP("socket()\n");
err = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (err < 0)
return err;
sock = err;
addr.sin_family = AF_INET;
addr.sin_port = htons(7357);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
DP("bind()\n");
err = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (err) {
close(sock);
return err;
}
return sock;
}
static int serve(int sock, struct msg_log *log)
{
char buf[32];
struct sockaddr_in caddr;
int caddr_len = sizeof(caddr);
int ret;
int len;
bzero((char *)&caddr, sizeof(caddr));
DP("recvfrom()\n");
ret = recvfrom(sock, buf, sizeof(buf), 0,
(struct sockaddr *) &caddr, &caddr_len);
if (ret < 0) return ret;
len = ret;
if (log) {
DP("log()");
log->src = caddr.sin_addr.s_addr;
log->size = len;
}
DP("sendto()");
ret = sendto(sock, (caddr_t) &buf, len, 0, (struct sockaddr *) &caddr, caddr_len);
return ret;
}
static void serve_multiple(int sock)
{
for (;;)
if (serve(sock, NULL) < 0) break;
}
int te_serve_one(void)
{
DP("%s\n", __FUNCTION__);
int sock;
struct msg_log log; /* = {0}; */
int ret = 0;
short port = 1234;
DP("setup()\n");
sock = setup(port);
if (sock < 0)
goto out;
sock = ret;
ret = serve(sock, &log);
if(ret < 0)
goto tidy;
DP("report:\n");
printf("Echo'd %d byte to %lu.%lu.%lu.%lu\n",
log.size,
LLB(log.src, 0),
LLB(log.src, 1),
LLB(log.src, 2),
LLB(log.src, 3));
tidy:
DP("close()");
close(sock);
out:
return ret;
}
int te_serve1(short port)
{
int ret = 0;
int sock;
struct sockaddr_in addr;
char buf[32];
struct sockaddr_in caddr;
int caddr_len = sizeof(caddr);
int len;
DP("socket()\n");
ret = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (ret < 0)
goto out;
sock = ret;
/* host addr */
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
DP("bind()\n");
ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (ret)
goto tidy;
/* serve */
for (;;) {
DP("recvfrom()\n");
ret = recvfrom(sock, buf, sizeof(buf), 0,
(struct sockaddr *) &caddr, &caddr_len);
if (ret < 0)
break;
len = ret;
if (len >= 4 && !strncmp(buf, "kill", 4)) {
ret = 0;
break;
}
DP("sendto()\n");
ret = sendto(sock, (caddr_t) &buf, len, 0,
(struct sockaddr *) &caddr, caddr_len);
printf("Echo'd %d byte to %lu.%lu.%lu.%lu\n",
len,
LLB(caddr.sin_addr.s_addr, 0), LLB(caddr.sin_addr.s_addr, 1),
LLB(caddr.sin_addr.s_addr, 2), LLB(caddr.sin_addr.s_addr, 3));
}
tidy:
DP("close()");
close(sock);
out:
return ret;
}
그렇지 않습니다. 아마도 당신은 recvfrom()에 잘못된 버퍼를 넘겨주고 있거나 스택 크기를 초과했을 수도 있습니다. 아마도 우리에게 몇 가지 코드를 보여줄 것입니다. – nos
@nos : 질문에 코드가 추가되었습니다. – tommyo