大家好,这是我在这里的第一篇文章。
我认为我的问题很愚蠢,但我找不到任何解决办法,希望你能帮助我!
所以,我和一个朋友正在编写一个小型系统监视器(学习更好/好玩),代码有两个部分:守护进程和命令行界面(现在),当我编译CLI部分时一切都很好,守护进程是特别的,因为当我编译并在编译目录中执行它时,它可以正常工作!奇怪的是,当我离开编译目录时,它给我一个分段错误!
编译器:GCC
以下是存储库:https://github.com/StefanoBelli/JASM
生成文件:
#!/usr/bin/make -f
SHELL=/bin/sh
#### CONFIGURATION ####
CC=gcc
DEBUG=-g
CFLAGS=-O2 -pipe -Wall -std=c11 $(DEBUG)
LIBS=
BINOUT=jasm
#### SOURCES & RULES ####
OBJS:=$(patsubst %.c,%.o,$(wildcard *.c))
install:$(OBJS)
$(CC) $(CFLAGS) $(LIBS) -o $(BINOUT) $(OBJS)
clean:
rm -fv *.o
.PHONY: install,clean
GDB输出:
(gdb) run
Starting program: /home/stefanozzz123/Devel/C.Cpp/JASM/bin/jasm
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a7db04 in vfprintf () from /usr/lib/libc.so.6
(gdb)
谢谢大家们! :)
编辑:正如您在此处所要求的那样是代码:
jasm.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
#include "miscellaneous.h"
#include "ipc.h"
int main(int argc, char *argv[])
{
start_daemon();
start_server();
}
ipc.c
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include "ipc.h"
#include "miscellaneous.h"
#include "getter.h"
static void excecute_command(int fd, char *command)
{
/*
* if get* -> modulo get
* if start* -> modulo dei moduli
*/
// ************************** getter ***************************************
if(strncmp("get", command, 3)==0) { //ricevuto comando getter
int i;
//char buf[BUFSIZ];
strcpy(command, &command[3]);
for(i=0; i<NGETTER; i++) {
if(strcmp(getterName[i], command)==0) { //se esiste getter
log_string("getter found :)");
getterFunction[i](fd);
return;
}
}
log_error("getter NOT found :(");
write(fd, "null\0", 4);
return;
}
// ************************** starter **************************************
if(strncmp("start", command, 5)==0) { //ricevuto start modulo
log_error("starter NOT found :(");
write(fd, "null\0", 4);
return;
}
// ************************** miscellaneous ********************************
if(strcmp("halt", command)==0) { //spegne jasm
log_string("# halt and catch fire, done");
write(fd, "halt\0", 4);
exit(0);
}
/*if(strcmp("getVersion", command)==0) {
write(fd, (void *)VERSION, sizeof(VERSION));
log_string("server reply <version> with success");
return;
}*/
log_error("request not found");
write(fd, "null\0", 4);
}
void start_server()
{
int server_sockfd, client_sockfd;
int server_len;
socklen_t client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result;
fd_set readfds, testfds;
server_sockfd=socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family=AF_INET;
server_address.sin_addr.s_addr=htonl(INADDR_ANY);
server_address.sin_port=htons(SERVER_PORT);
server_len=sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
listen(server_sockfd, 5);
FD_ZERO(&readfds);
FD_SET(server_sockfd, &readfds);
log_string("server started");
while(1) {
char buf[BUFSIZ];
char received[BUFSIZ];
int fd;
int nread;
testfds=readfds;
result=select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
if(result<1) {
log_error("server fail");
exit(1);
}
for(fd=0; fd<FD_SETSIZE; fd++) {
if(FD_ISSET(fd, &testfds)) {
if(fd==server_sockfd) {
client_len=sizeof(client_address);
client_sockfd=accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
FD_SET(client_sockfd, &readfds);
sprintf(buf, "adding client on fd %d", client_sockfd);
log_string(buf);
} else {
ioctl(fd, FIONREAD, &nread);
if(nread==0) {
close(fd);
FD_CLR(fd, &readfds);
sprintf(buf, "removing client on fd %d", fd);
log_string(buf);
} else {
read(fd, &received, BUFSIZ);
sprintf(buf, "received from fd %d command <%s>", fd, received);
log_string(buf);
excecute_command(fd, received);
}
}
}
}
}
}
miscellanous.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "miscellaneous.h"
char * getTime()
{
time_t curtime;
struct tm *loctime;
static char *ret;
curtime=time(NULL);
loctime=localtime(&curtime);
ret=asctime(loctime);
ret[24]='\0';
return ret;
}
void log_string(const char *message)
{
FILE *fp;
fp=fopen(LOGPATH, "a+");
fprintf(fp, "[%s] %s\n", getTime(), message);
fclose(fp);
}
void log_error(const char *message)
{
FILE *fp;
fp=fopen(LOGPATH, "a+");
fprintf(fp, "[%s] ERROR: %s!\n", getTime(), message);
fclose(fp);
}
void start_daemon()
{
pid_t pid;
char buf[BUFSIZ];
log_string("boot");
pid=fork();
switch(pid) {
case -1:
log_error("fork fail");
exit(1);
break;
case 0:
log_string("fork success");
break;
default:
exit(0);
break;
}
if(setsid()<0) {
log_error("setsid fail");
exit(1);
} else {
log_string("setsid success");
}
//chiude i file descriptor di stdin, stdout, stderr
close(0);
close(1);
close(2);
sprintf(buf, "jasm started with pid %d and ppid %d", getpid(), getppid());
log_string(buf);
}
基本上这些都是主要的......
GDB Backtrace没有说什么,因为程序运行立即停止
答案 0 :(得分:0)
由于问题被标记为gdb,让我们看看gdb如何提供帮助。在我的例子中,我已经为libc安装了debuginfo文件,因此我可以检查C库函数的参数,但在这种情况下你并不需要它,因为我们可以通过查看用户的源代码来找到bug。
(gdb) run
Starting program: ./jasm
Program received signal SIGSEGV, Segmentation fault.
_IO_vfprintf_internal (s=0x0, format=0x4019b1 "[%s] %s\n",
ap=ap@entry=0x7fffffffbd38) at vfprintf.c:1295
1295 vfprintf.c: No such file or directory.
(gdb) bt
#0 _IO_vfprintf_internal (s=0x0, format=0x4019b1 "[%s] %s\n",
ap=ap@entry=0x7fffffffbd38) at vfprintf.c:1295
#1 0x00007ffff7a693f7 in __fprintf (stream=<optimized out>,
format=<optimized out>) at fprintf.c:32
#2 0x000000000040149d in log_string (message=0x4019cb "boot")
at miscellaneous.c:46
#3 0x000000000040151f in start_daemon () at miscellaneous.c:64
#4 0x0000000000401400 in main (argc=1, argv=0x7fffffffdf78) at jasm.c:31
vfprintf的声明是:
int vfprintf(FILE *restrict stream, const char *restrict format, va_list ap);
即使我们没有安装vfprintf的源代码,我们也可以看到传递给它的第一个参数s
是一个NULL流指针,这很可能是seg错误的原因
让我们看一下我们的源代码:第2帧,log_string
。
(gdb) frame 2
#2 0x000000000040149d in log_string (message=0x4019cb "boot")
at miscellaneous.c:46
46 fprintf(fp, "[%s] %s\n", getTime(), message);
(gdb) print fp
$2 = (FILE *) 0x0
它就是。
#define LOGPATH "../../../../data/log/jasm.log"
void log_string(const char *message)
{
FILE *fp;
fp=fopen(LOGPATH, "a+");
fprintf(fp, "[%s] %s\n", getTime(), message);
fclose(fp);
}
void log_error(const char *message)
{
FILE *fp;
fp=fopen(LOGPATH, "a+");
fprintf(fp, "[%s] ERROR: %s!\n", getTime(), message);
fclose(fp);
}
检查fopen
的返回值。它可能为NULL,具体取决于运行程序的目录。最好使用绝对路径名,可以在Makefile中设置可移植性。
write(fd, "halt\0", 4);
所有这些都应该有5个,包括尾随的NUL。 (并且绝对不必在字符串文字中明确包含\0
,因为C字符串文字最后隐含地有\0
。)