C语言 文件句柄段错误

57hvy0tb  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(99)

实现一个数据链接协议。我设法通过虚拟串行端口发送整个文件-这应该是困难的部分。奇怪的是,当我试图保存它时,我在fclose()上得到了一个segfault。文件正在创建,这意味着打开成功,但没有任何东西存储在其中。甚至改变了实现,在保存之前将所有文件缓冲到内存中。

int app_rx(const char* outputFile){
    file_data_t fileData;
    if(!receive_ctrl_pckt(&fileData)){
        printf("Could not receive control packet\n");
        return FAILURE;
    }
    printf("Receiving file [%s]\nFile size: %d\n", fileData.fileName, fileData.fileSize);
    unsigned char fileBuffer[fileData.fileSize];
    int fileIndex = 0;
    int totalBytes = 0;
    int stop = 0;
    size_t sqNo = 0;
    int bytes;
    FILE* out = fopen(outputFile, "w");
    do{
        activeBuffer = (activeBuffer + 1) % 2;
        printf("Receiving packet %lu\n", sqNo);
        bytes = llread(BUFFERS[TMP_BUFFER]);
        if(bytes == DUP_ERR){
            printf("Duplicate data. Discarding packet\n");
        }
        else if (bytes == WH_ERR){
            printf("Invalid header. Discarding packet\n");
        }
        else if (bytes == WD_ERR){
            printf("Corrupted data. Awaiting retransmission\n");
        }
        else{
            printf("Packet %lu successfully received\n", sqNo);
            int retrieveRes = retrieve_payload(sqNo);
            switch(retrieveRes){
                case CTRL_END: {
                    stop = 1;
                    break;
                }
                case FAILURE: {
                    printf("Unknown error\nExiting...");
                    exit(1);
                }
                case SQ_ERR:{
                    printf("Unsynchronized packets\nExiting");
                    exit(1);
                }
                default:{
                    for(int i = 0; i < retrieveRes; i++){
                        fileBuffer[fileIndex] = BUFFERS[activeBuffer][i];
                        fileIndex++;
                    }
                    sqNo = (sqNo + 1) % 255;
                    totalBytes += bytes;
                    break;
                }
            }
        }
    }while(!stop);
    printf("file index: %d\n", fileIndex);
    fwrite(fileBuffer, sizeof(unsigned char), fileIndex, out);
    printf("here\n");
    fclose(out);
    if(totalBytes == fileData.fileSize){
        return SUCCESS;
    }
    else{
        return FAILURE;
    }
}

标准输出:

Packet 9 successfully received
Receiving packet 10
Asserting data integrity
Packet 10 successfully received
Receiving packet 11
Asserting data integrity
Packet 11 successfully received
file index: 10968
here
make: *** [Makefile:35: run_rx] Segmentation fault (core dumped)

我知道,这是一个很大的方法。只是想在正确重构之前把它弄清楚。不能为了什么而弄清楚发生了什么。我知道这是可行的,因为我已经用这个方法复制了完全相同的文件,用一个简单的copyfile.c测试驱动程序来模仿cp命令。
有什么想法吗?我发现它创建了输出文件,但没有在上面写任何东西,这特别奇怪。
编辑:在写之前打开文件,设法让它运行起来。仍然不太明白发生了什么

qnakjoqk

qnakjoqk1#

数组fileBuffer存在潜在的缓冲区溢出风险,除非retrieveRes保证未来或等于fileData.fileSize,否则如果存在缓冲区溢出,则在调用fclose时,指针out可能会被覆盖并导致段错误。可以通过在do/while循环和调用fclose之前打印out的值来验证缓冲区溢出。

相关问题