简体   繁体   English

c语言中的socket和线程分段错误

[英]socket and thread segmentation fault in c language

i'm working to a client/server application in c language for a university project.我正在为大学项目使用 c 语言编写客户端/服务器应用程序。 basically the client process will send server process some command with the given parameter in a thread:基本上,客户端进程将在线程中向服务器进程发送一些带有给定参数的命令:

-store xy (the server save in node of a list x and y) -search x (search if a node with x value matching the given x exists in the list) -corrupt xz (change the y-value of the node with the x value matching given x) -list (simply make the server print the whole list). -store xy(服务器保存在列表 x 和 y 的节点中) -search x(搜索具有与给定 x 匹配的 x 值的节点是否存在于列表中) -corrupt xz(用x 值匹配给定 x) -list(只需让服务器打印整个列表)。

the problem is that every command works except for list, every time i send list from the client it gave me segmentation fault ( or stack smashing sometimes ) i think it's a thread fault because if i make the main thread execute the commands everything works as well.问题是,除了列表之外的每个命令都可以工作,每次我从客户端发送列表时,它都会给我分段错误(或有时堆栈粉碎)我认为这是一个线程错误,因为如果我让主线程执行命令,一切都会正常工作. strace show that the fault maybe is in the accept function. strace 显示错误可能出在接受函数中。 this is the server:这是服务器:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>


#define CMD_BUF 20
#define BYTE_CMD_BUF 20*sizeof(char)



typedef struct nodo
{
    char x[8];
    char y[8];
    struct nodo* next;
}nodo;

typedef nodo* lista;



lista listalocale=NULL;


//////////////////////////////////////////////operazioni su lista

lista save(char* x,char* y,lista head)
{
    if(!head)
    {
        head=malloc(sizeof(nodo));
        strcpy(head->x,x);
        strcpy(head->y,y);
        head->next=NULL;
    }
    else head->next=save(x,y,head->next);
    return head;
}


void printList(lista head)
{
    char buffer[22];
    sprintf(buffer,"(%s,%s)->",head->x,head->y);
    write(1,buffer,strlen(buffer));
    if(head->next) printList(head->next);
    else write(1,"NULL",4);
}



int isPresent(char* x,lista head)
{
    if(!head) return 0;
    else if(!strcmp(head->x,x)) return 1;
    return isPresent(x,head->next);
}



void changeValue(char* x,char* z,lista head)
{
    if(!head) return;
    else if(!strcmp(head->x,x)) strcpy(head->y,z);
    else changeValue(x,z,head->next);
    return;
}

////////////////////////////////////////////////////////////////////////elaborazione e gestione comandi
void formatMessage(char* buff,char* comm, char* val1, char* val2)
{
    comm[0]=buff[0];
    comm[1]=buff[1];
    comm[2]='\0';

    int i=3, j=0;
    while (buff[i]!=' ' & buff[i]!='_') val1[j++]=buff[i++];
    val1[j]='\0';

    j=0;
    while (buff[i]!='_') val2[j++]=buff[i++];
    val2[j]='\0';   
}


void *processCommandServer(void *arg)
{
    char buff[20],com[3],p1[8],p2[8];
    int sd=*(int*)arg;


    if( read(sd,buff,BYTE_CMD_BUF)<1 ) perror("COMANDO SCONOSCIUTO");

    formatMessage(buff,com,p1,p2);


    if(!strcmp(com,"li")) printList(listalocale);
    else if(!strcmp(com,"se")) isPresent(p1,listalocale);
    else if(!strcmp(com,"st")) listalocale=save(p1,p2,listalocale);
    else if(!strcmp(com,"co")) changeValue(p1,p2,listalocale);
    return NULL;
} 

/////////////////////////////////////////////////////////////// gestione connessione

void assegnaIndirizzo(int sd,char* indirizzo,int porta)
{
    struct sockaddr_in  server;

     server.sin_family=AF_INET;
     server.sin_port=htons(porta);
     server.sin_addr.s_addr=inet_addr(indirizzo);

    if(bind(sd,(struct sockaddr*)&server , sizeof( server))<0) 
        perror("ERRORE CONNESSIONE");
}


int creaSocketServer(char* indirizzo,int porta)
{
    int sd=socket(PF_INET,SOCK_STREAM,0);

    if(sd<=0) perror("ERRORE CREAZIONE");
    else assegnaIndirizzo(sd,indirizzo,porta);

    return sd;
}


int waitConnection(int sd)
{
    struct sockaddr_in address;
    socklen_t l=sizeof(address);
    int sd2;
    pthread_t tid=0;

    listen(sd,5);

    sd2=accept(sd,(struct sockaddr*)&address,&l);                  //commenta se vuoi eliminare thread
    pthread_create(&tid,NULL,processCommandServer,(void*) &sd2);   //commenta se vuoi eliminare thread

    while(1)
    {
        sd2=accept(sd,(struct sockaddr*)&address,&l);
        //processCommandServer((void*)&sd2);                            //scommenta se vuoi eliminare thread
        pthread_join(tid,NULL);                                         //commenta se vuoi eliminare thread
        pthread_create(&tid,NULL,processCommandServer,(void*) &sd2);    //commenta se vuoi eliminare thread
    }
}
/////////////////////////////////////////////////////////////////

int main(int argc, char const *argv[])
{
    int sd=creaSocketServer("192.168.1.195",atoi(argv[1]));
    waitConnection(sd);
}

and this is the client:这是客户端:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>


#define CMD_BUF 20
#define BYTE_CMD_BUF 20*sizeof(char)


/////////////////////////////////////////////////////////////////gestione connessioni
void sendData(int sd, char* comando)
{
    int res=write(sd,comando,strlen(comando)*sizeof(char));     //invia comando

    if(res > 0) write(STDOUT_FILENO,"Message Delivered\n",sizeof("Message Delivered\n"));   //controlla esito invio comando
    else perror("ERROR");
}

void connettiSocket(int sd,const char* indirizzo,int porta)
{
    struct sockaddr_in client;   

    client.sin_family=AF_INET;                      //imposta connessione tcp
    client.sin_port=htons(porta);                   //imposta porta
    client.sin_addr.s_addr=inet_addr(indirizzo);    //imposta indirizzo

    if( connect(sd,(struct sockaddr*)&client,sizeof(client)) <0 )  //si connette a client e controlla errori 
        perror("ERRORE CONNESSIONE");
}

int creaSocketClient(const char* indirizzo,int porta)
{
    int sd=socket(PF_INET,SOCK_STREAM,0);       //crea socket

    if(sd<=0) perror("ERRORE CREAZIONE");       //controlla errori
    else connettiSocket(sd,indirizzo, porta);

    return sd;
}

///////////////////////////////////////////////////////////////////////////comandi
void store(const char* x, const char* y,const char* ip, int porta)
{
    int sd=creaSocketClient(ip,porta);  //crea connessione

    char cmd[CMD_BUF];                  //buffer comando
    sprintf(cmd,"st %s %s_",x,y);       //formatta comando

    sendData(sd,cmd);                   
}

void corrupt(const char* x, const char* z,const char* ip, int porta) //vedi store
{
    int sd=creaSocketClient(ip,porta);

    char cmd[CMD_BUF];
    sprintf(cmd,"co %s %s_",x,z);

    sendData(sd,cmd);
}

void search(const char* x,const char* ip, int porta)//vedi store
{
    int sd=creaSocketClient(ip,porta);

    char cmd[CMD_BUF];
    sprintf(cmd,"se %s_",x);

    sendData(sd,cmd);
}

void list(const char* ip, int porta)//vedi store
{
    int sd=creaSocketClient(ip,porta);

    char cmd[CMD_BUF];
    sprintf(cmd,"li_");

    sendData(sd,cmd);
}
////////////////////////////////////////////////////////////////////////

int main(int argc, char const *argv[])
{
         if(!strcmp(argv[3],"store")   & argc==6) store(argv[4],argv[5],argv[1],atoi(argv[2]));
    else if(!strcmp(argv[3],"corrupt") & argc==6) corrupt(argv[4],argv[5],argv[1],atoi(argv[2]));
    else if(!strcmp(argv[3],"search")  & argc==5) search(argv[4],argv[1],atoi(argv[2]));
    else if(!strcmp(argv[3],"list")    & argc==4) list(argv[1],atoi(argv[2]));
    else perror("comando non valido");  
}

this is the strace output if i send 2 store command and 1 list command:如果我发送 2 个 store 命令和 1 个 list 命令,这是 strace 输出:

execve("./a.out", ["./a.out", "5900"], 0x7ffff0e72298 /* 25 vars */) = 0
brk(NULL)                               = 0x555c05424000
arch_prctl(0x3001 /* ARCH_??? */, 0x7ffd14dbd370) = -1 EINVAL (Argomento non valido)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (File o directory non esistente)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=228153, ...}) = 0
mmap(NULL, 228153, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f066cef9000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340f\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=155408, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f066cef7000
lseek(3, 808, SEEK_SET)                 = 808
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 131528, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f066ced6000
mmap(0x7f066cedc000, 61440, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x6000) = 0x7f066cedc000
mmap(0x7f066ceeb000, 24576, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x15000) = 0x7f066ceeb000
mmap(0x7f066cef1000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1a000) = 0x7f066cef1000
mmap(0x7f066cef3000, 12744, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f066cef3000
close(3)                                = 0
openat(AT_FDCWD, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0000C\2\0\0\0\0\0"..., 832) = 832
lseek(3, 792, SEEK_SET)                 = 792
read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
fstat(3, {st_mode=S_IFREG|0755, st_size=2136840, ...}) = 0
lseek(3, 792, SEEK_SET)                 = 792
read(3, "\4\0\0\0\24\0\0\0\3\0\0\0GNU\0\201\336\t\36\251c\324\233E\371SoK\5H\334"..., 68) = 68
lseek(3, 864, SEEK_SET)                 = 864
read(3, "\4\0\0\0\20\0\0\0\5\0\0\0GNU\0\2\0\0\300\4\0\0\0\3\0\0\0\0\0\0\0", 32) = 32
mmap(NULL, 1848896, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f066cd12000
mprotect(0x7f066cd34000, 1671168, PROT_NONE) = 0
mmap(0x7f066cd34000, 1355776, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x22000) = 0x7f066cd34000
mmap(0x7f066ce7f000, 311296, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x16d000) = 0x7f066ce7f000
mmap(0x7f066cecc000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b9000) = 0x7f066cecc000
mmap(0x7f066ced2000, 13888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f066ced2000
close(3)                                = 0
mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f066cd0f000
arch_prctl(ARCH_SET_FS, 0x7f066cd0f740) = 0
mprotect(0x7f066cecc000, 16384, PROT_READ) = 0
mprotect(0x7f066cef1000, 4096, PROT_READ) = 0
mprotect(0x555c0363d000, 4096, PROT_READ) = 0
mprotect(0x7f066cf5a000, 4096, PROT_READ) = 0
munmap(0x7f066cef9000, 228153)          = 0
set_tid_address(0x7f066cd0fa10)         = 10560
set_robust_list(0x7f066cd0fa20, 24)     = 0
rt_sigaction(SIGRTMIN, {sa_handler=0x7f066cedc130, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0x7f066cee83c0}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {sa_handler=0x7f066cedc1d0, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0x7f066cee83c0}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(5900), sin_addr=inet_addr("192.168.1.195")}, 16) = 0
listen(3, 5)                            = 0
accept(3, {sa_family=AF_INET, sin_port=htons(60902), sin_addr=inet_addr("192.168.1.195")}, [16]) = 4
mmap(NULL, 8392704, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK, -1, 0) = 0x7f066c50e000
mprotect(0x7f066c50f000, 8388608, PROT_READ|PROT_WRITE) = 0
brk(NULL)                               = 0x555c05424000
brk(0x555c05445000)                     = 0x555c05445000
clone(child_stack=0x7f066cd0dfb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f066cd0e9d0, tls=0x7f066cd0e700, child_tidptr=0x7f066cd0e9d0) = 10562
accept(3, {sa_family=AF_INET, sin_port=htons(60904), sin_addr=inet_addr("192.168.1.195")}, [16]) = 5
clone(child_stack=0x7f066cd0dfb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f066cd0e9d0, tls=0x7f066cd0e700, child_tidptr=0x7f066cd0e9d0) = 10564
accept(3, {sa_family=AF_INET, sin_port=htons(60906), sin_addr=inet_addr("192.168.1.195")}, [16]) = 6
clone(child_stack=0x7f066cd0dfb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f066cd0e9d0, tls=0x7f066cd0e700, child_tidptr=0x7f066cd0e9d0) = 10566
accept(3,  <unfinished ...>)            = ?
+++ killed by SIGSEGV (core dumped) +++
Segmentation Fault

the error was in the formatMessage function, list got no parameter so it have 3 character the function start copying the command(first 2 char) and the jump to the 4th that is out of the list command array bound.错误出在 formatMessage 函数中,list 没有参数,因此它有 3 个字符,该函数开始复制命令(前 2 个字符)并跳转到列表命令数组范围之外的第 4 个字符。 As well your tips where very useful以及您的提示非常有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM