2015-11-21 20 views
-2

你好傢伙這是我的第一篇文章。移動二進制目錄外的分段錯誤

我的問題是愚蠢的,我想但我找不到任何解決方案,希望你能幫助我!因此,我和一個朋友正在編寫一個小型系統監視器(學習更好/有趣),代碼有2個部分:守護進程和命令行界面(現在),當我編譯CLI部分時, ,守護進程是特別的,因爲當我編譯時,我在編譯目錄中執行它,它的工作原理沒有錯誤!神奇的是,當我移出編譯目錄時,它給了我一個分段錯誤!

編譯器:GCC

這裏是倉庫:https://github.com/StefanoBelli/JASM

的Makefile:

#!/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); 
} 

本質這些是主要的srcs ...

GDB回溯什麼都不說的程序運行立即

+3

顯示代碼,通過gdb運行以獲取更多信息。 –

+0

gdb的「backtrace」命令告訴你什麼? – alk

+0

不要只提供鏈接,但發佈[mcve]。 – Olaf

回答

0

由於這個問題被標記停止,讓我們來看看GDB如何幫助。就我而言,我已經爲libc安裝了debuginfo文件,以便我可以檢查C庫函數的參數,但在這種情況下您並不需要這樣做,因爲我們可以通過查看用戶的源代碼來發現錯誤。

(gdb) run 
Starting program: ./jasm 

Program received signal SIGSEGV, Segmentation fault. 
_IO_vfprintf_internal (s=0x0, format=0x4019b1 "[%s] %s\n", 
    [email protected]=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", 
    [email protected]=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故障的原因。

讓我們來看看我們的源代碼:frame 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。)

+0

我認爲你對fopen()函數是正確的,因爲如果我將二進制文件移動/複製到其他路徑,找不到路徑。 –

+0

當我回家...我會嘗試,但我認爲你絕對righfopen()可能會返回NULL ...謝謝你現在! –

相關問題