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