0

我目前正在开发一个用 C 编写的 FTP 客户端,它运行良好。我成功编写了一个连接到 FTP 服务器并使用用户名和密码登录的函数,但是我在返回错误时遇到了问题。我已经设置了struct FTPError {};3 个字段:

  1. int错误代码
  2. int一个 FTP 错误域(特定于我的功能)
  3. char[256]用户可读的描述

函数的调用者通过引用函数传递一个结构,然后我用数据填充它。但我正在努力填充用户可读的字符串(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

4 回答 4

2

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

于 2010-09-01T16:00:27.867 回答
0

尝试保存 strcpy 变体:

strncpy(errn->message, "any string with unknown length", FTP_ERROR_MAX-1 );
errn->message[ FTP_ERROR_MAX-1 ] = 0;
于 2010-09-01T16:20:52.830 回答
0

你确定你传递的是一个内存分配的结构而不是一个未分配的指针吗?调用应该是这样的:

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

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

FTPError* myError = (FTPError*) malloc(sizeof(FTPError));
FTPConnect(host, user, password, myError);
于 2010-09-01T16:02:48.377 回答
0

从它所说的来看,我猜你用其他一些代码破坏了你的堆栈,它只是出现在那个地方。

无论如何,为了确保你应该总是errn用类似的东西初始化你的结构

 struct FTPError reply = { .status = 0 };
于 2010-09-01T16:13:41.220 回答