struct中的strcpy给出了SIGABRT

时间:2010-09-01 15:53:14

标签: c struct pass-by-reference strcpy sigabrt

我目前正在开发一个用C语言编写的FTP客户端,它工作得非常好。我成功地编写了一个连接到FTP服务器并使用用户名和密码登录的功能,但是我在返回错误时遇到了问题。我设置了一个struct FTPError {};,其中包含3个字段:

  1. int错误代码
  2. int FTP错误域(特定于我的功能)
  3. char[256]用户可读的描述
  4. 函数的调用者通过引用函数传递结构,然后用数据填充它。但我正在努力填写用户可读的字符串(char[256])。我用strcpy填充字符串,但是当我调用它时,我的程序发出SIGABRT信号。我给你一个简化的代码:

    struct FTPError {
        int status;
        int domain;
        char message[FTP_ERROR_MAX];
    };
    
    typedef int FTPConnection;
    
    FTPConnection FTPConnect(const char *hostname, const char *username, const char *password, struct FTPError *errn) {
    
        int socket = /* socket file descriptor */
    
        // Success
        if(success == 1) {
            if(errn) {
                // when I comment out the line below, no signal is sent
                strcpy(errn->message, "User successfully loged in");
                errn->status = 230;
                errn->domain = kServerReplyDomain;
            }
        }
    
        // return the file descriptor
        return sockfd;
    }
    

    PS: 这就是Xcode在错误控制台中给我的东西:

    Program loaded.
    run
    [Switching to process 2566]
    Running…
    SOCK: 3
    Program received signal:  “SIGABRT”.
    sharedlibrary apply-load-rules all
    kill
    quit
    
    0x00007fff824c03cc  <+0000>  mov    $0x2000025,%eax
    0x00007fff824c03d1  <+0005>  mov    %rcx,%r10
    0x00007fff824c03d4  <+0008>  syscall 
    0x00007fff824c03d6  <+0010>  jae    0x7fff824c03dd <__kill+17> --> (points this line) 
    0x00007fff824c03d8  <+0012>  jmpq   0x7fff82560a8c <cerror>
    0x00007fff824c03dd  <+0017>  retq 
    
    3 __kill
    2 __abort
    1 __stack_chk_fail
    0 main
    

    PPS:我被要求显示调用该函数的代码:

    int main (int argc, const char * argv[]) {
        struct FTPError reply;
        FTPConnection socket;
    
        socket = FTPConnect("ftp.belnet.be", "anonymous", "pwd", &reply);
    
        printf("SOCK: %d\n", socket);
    
        return 0;
    }
    

4 个答案:

答案 0 :(得分:2)

很可能,给函数的errn指针未正确初始化,或者无效。否则FTP_ERROR_MAX也可能是一个太小的数字,因此strcpy()会产生缓冲区溢出。

答案 1 :(得分:0)

您确定要传递内存分配结构而不是未分配指针吗? 电话应该是:

FTPError myError;
FTPConnect(host, user, password, &myError);

否则,如果您更喜欢使用指针:

FTPError* myError = (FTPError*) malloc(sizeof(FTPError));
FTPConnect(host, user, password, myError);

答案 2 :(得分:0)

从它的内容来看,我猜你用其他一些代码破坏了你的堆栈,并且它只是出现在那里。

无论如何,确保您应该始终使用类似

的内容初始化errn结构
 struct FTPError reply = { .status = 0 };

答案 3 :(得分:0)

尝试使用save strcpy变体:

strncpy(errn->message, "any string with unknown length", FTP_ERROR_MAX-1 );
errn->message[ FTP_ERROR_MAX-1 ] = 0;