如何调试一个daemon进程?
我的程序本来能正常运行,一把他变成daemon进程就出问题。
也就是程序开始调用了这个:
int
daemon_init(void)
{
pid_t pid;
if((pid=fork())<0)
return(-1);
else if(pid!=0)
exit(0);
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
return(0);
}
可能问题出在哪?我应当怎样进行调试呢?
问题点数:100、回复次数:14Top
1 楼quil(晕)回复于 2005-01-01 10:23:54 得分 0
出什么问题啊。说说啊Top
2 楼hustxxb(萧小斌)回复于 2005-01-01 10:36:58 得分 0
程序实现一个web服务,接受客户请求并返回一个文件给客户。
不用daemon_init()程序能工作,用了之后已开始这个程序能运行,客户一请求他就结束了。
又不能调试,郁闷阿。Top
3 楼quil(晕)回复于 2005-01-01 10:42:04 得分 0
把其他的代码也贴出来,不是daemon_init的问题。这个我也用过的。Top
4 楼longenic(江寒)回复于 2005-01-01 11:41:09 得分 20
你可以把一些信息输出到一个文件中啊,Top
5 楼hustxxb(萧小斌)回复于 2005-01-01 12:24:03 得分 0
麻烦帮看下:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <time.h>
#include <syslog.h>
#include <errno.h>
#include <stdarg.h>
#define BUFFSIZE 4096
#define TCP_SIZE 1460
int listenfd,clifd,maxfd;
char recvbuf[BUFFSIZE],key[BUFFSIZE],sendbuf[BUFFSIZE];
int daemon_init(void);
int sig_do(int);
void sendinfo(int, char *);
void log_open(const char *, int, int);
void log_sys(const char *, ...);
void log_msg(const char *, ...);
static void log_doit(int, int, const char *, va_list ap);
int
main(void)
{
struct sockaddr_in servaddr;
log_open("open.server",LOG_PID,LOG_USER);
daemon_init();
if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
log_sys("socket error");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(80);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
log_sys("bind error");
if(listen(listenfd,5)<0)
log_sys("listen error");
signal(SIGIO,sig_do);
fcntl(listenfd,F_SETOWN,getpid());
fcntl(listenfd,F_SETFL,O_ASYNC);
for(;;);
exit(0);
}
int
sig_do(int signo)
{
struct sockaddr_in cliaddr;
socklen_t addrlen;
char *p;
int recvlen;
while(1){
addrlen=sizeof(cliaddr);
if((clifd=accept(listenfd,(struct sockaddr *)&cliaddr,&addrlen))<0)
log_sys("accept error");
while(1){
if((recvlen=recv(clifd,recvbuf,sizeof(recvbuf),0))<0)
log_sys("recv error");
else if(recvlen==0)
break;
recvbuf[recvlen]=0;
log_msg(recvbuf);
if(strncmp(recvbuf,"GET",3)==0){ /* 判断请求类型是否为GET */
p=strchr(recvbuf+3,'/'); /* 在请求中"/"的匹配之处 */
if(p==0) break;
p++;
//if(*p==' ')
{
sendinfo(clifd,"./index.htm");
break;
}
}else
log_sys("bad request");
}
close(clifd);
}
return;
}
void sendinfo(int sock,char *filename)
{
char *sendDate,sendbuf[16384]="HTTP/1.0 200 OK\nServer: FreeBSD 4.7\n";
int len,pos,fd;
time_t tp;
tp=time(NULL);
sendDate=ctime(&tp);
strcat(sendbuf,sendDate);
strcat(sendbuf,"Content-Type: text/html\nConnection: close\n\n\n\n");
pos=0;
len=strlen(sendbuf);
if((fd=open(filename,O_RDONLY))<0)
log_sys("open error");
len+=read(fd,sendbuf+len,sizeof(sendbuf)-len-1);
while(len>0) /* 每次1460数据发给客户,直到sendbuf空 */
{
send(sock,sendbuf+pos*TCP_SIZE,TCP_SIZE,0);
len-=TCP_SIZE;
pos++;
}
close(fd);
}
int
daemon_init(void)
{
pid_t pid;
if((pid=fork())<0)
return(-1);
else if(pid!=0)
exit(0);
setsid(); /* become session leader */
chdir("/"); /* change working directory */
umask(0); /* clear file mode creation mask */
return(0);
}
void
log_open(const char *ident, int option, int facility)
{
openlog(ident,option,facility);
}
void
log_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
log_doit(0, LOG_ERR, fmt, ap);
va_end(ap);
return;
}
void
log_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap,fmt);
log_doit(1,LOG_ERR,fmt,ap);
va_end(ap);
exit(2);
}
static void
log_doit(int errnoflag, int priority, const char *fmt, va_list ap)
{
int errno_save;
char buf[BUFFSIZE];
errno_save=errno;
vsprintf(buf,fmt,ap);
if(errnoflag)
sprintf(buf+strlen(buf),":%s",strerror(errno_save));
strcat(buf,"\n");
syslog(priority,buf);
return;
}
Top
6 楼quil(晕)回复于 2005-01-01 14:59:18 得分 10
不加daemon真的能正常运行吗?你的SIGIO信号是如何产生的??
你的程序很怪Top
7 楼hustxxb(萧小斌)回复于 2005-01-01 19:22:14 得分 0
一旦在监听套接口上有一个请求连接已完成就会产生一个SIGIO信号。Top
8 楼CoolQ()回复于 2005-01-01 21:25:34 得分 10
use GDBTop
9 楼hustxxb(萧小斌)回复于 2005-01-02 01:07:27 得分 0
daemon进程怎么用gdb?Top
10 楼CoolQ()回复于 2005-01-03 14:13:14 得分 10
#gdb ./test $test_PIDTop
11 楼9653013(csL阴转晴)回复于 2005-01-04 12:52:37 得分 20
SIGCHLD信号没处理吧。系统默认受到此信号程序退出。
这个socket程序基本上说来,比较的不好。Top
12 楼xfzhao_cn(kentoo)回复于 2005-01-04 17:09:26 得分 30
用gdb , attch <pid>Top
13 楼hustxxb(萧小斌)回复于 2005-01-04 18:06:20 得分 0
怎么会产生SIGCHLD信号呢?
“#gdb ./test $test_PID”,“用gdb , attch <pid>”中的$test_PID和attch <pid>是什么,是daemon中fork后子进程的pid吗?那这个pid又是怎么得到的?Top
14 楼hustxxb(萧小斌)回复于 2005-01-04 18:46:50 得分 0
程序是一个daemon程序,主要是用单进程+信号驱动I/O来完成的。
我觉得daemon到是没什么问题,应该是信号驱动I/O这部分写得有问题。Top




