PSET4恢复分段故障 [英] PSET4 recover segmentation fault

查看:72
本文介绍了PSET4恢复分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这段代码中,我想从一个文件中写出50个JPG。



(实际说明: [ ^ ]



In this code, I want to write out 50 JPGs from a file.

(actual instructions: )[^]

This is the terminal output:
~/workspace/pset4/jpg/ $ make recover clang -fsanitize=integer -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover ~/workspace/pset4/jpg/ $ ./recover

---Segmentation fault---

With valgrind, I see that there are no leaks, but a line says that no memory allocations were made:

Invalid read of size 4 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85)

==17227== Address 0x0 is not stack'd, malloc'd or (recently) free'd

==17227== 
==17227== 
==17227== Process terminating with default action of signal 11 (SIGSEGV) 
==17227== Access not within mapped region at address 0x0 
==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) 
==17227== by 0x42DB5F: main (recover.c:85) ==17227== If you believe this happened as a result of a stack 
==17227== overflow in your program's main thread (unlikely but 
==17227== possible), you can try to increase the size of the 
==17227== main thread stack using the --main-stacksize= flag. 
==17227== The main thread stack size used in this run was 8388608. 
==17227== 
==17227== HEAP SUMMARY: 
==17227== in use at exit: 0 bytes in 0 blocks 
==17227== total heap usage: 1 allocs, 1 frees, 568 bytes allocated =
=17227== 
==17227== All heap blocks were freed -- no leaks are possible 
==17227== 
==17227== For counts of detected and suppressed errors, rerun with: -v 
==17227== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
 Segmentation fault

Thanks a lot,





我尝试过:





What I have tried:

/**
 * recover.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * Recovers JPEGs from a forensic image.
 */
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdint.h>



int main()
{
    typedef uint8_t BYTEINBITS;

    int pictcount = 0;
    
    
    FILE* input = fopen("card.raw", "r");
 
     if ( input == NULL )
    {
        printf(" Could not open card.raw \n");
        return 2;
    }
    
    FILE* output = NULL;
    
    bool  atend = false;
    
    while ( atend == false)
    {
        BYTEINBITS buffer[512];

         
        fread( &buffer, 512 * sizeof(char), 1, input); 
 
         
        bool jpg = true;
        
        if ( !( ( buffer[0] == 255 ) && ( buffer[1] == 216 ) && ( buffer[2] == 255) && ( buffer[3] > 224 ) ) )         
        {
            jpg = false;
        }
 
         
        if (jpg == true)
        {
             
             if (pictcount >= 1)
             {
              
                  fclose(output);   
             }         
                 
            pictcount++;
            char title[8];
            sprintf(title,"%03d.jpg", pictcount);
            
            output  = fopen("title", "w");
        
        }
        
        if (pictcount > 0)
        {
         
            fwrite( &buffer, 512 * sizeof(char), 1, output );

        }
        
        if ( fread( &buffer, 512*sizeof(char), 1, input) != 1)
        {
            atend = true;   
        }
    }
     
    fclose(input);
    fclose(output);


    
    
}

推荐答案

make recover clang -fsanitize =整数-fsanitize = undefined -ggdb3 -O0 -std = c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover~ / workspace / pset4 / jpg /
make recover clang -fsanitize=integer -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wshadow recover.c -lcrypt -lcs50 -lm -o recover ~/workspace/pset4/jpg/


./ recover

---分段错误---

使用valgrind,我看到没有泄漏,但是一行表示没有进行内存分配:

无效读取大小4 == 17227 ==在0x5E268D4:fclose @@ GLIBC_2.2.5(iofclose.c:54)== 17227 == by 0x42DB5F: main(recover.c:85)

== 17227 ==地址0x0没有堆叠,malloc'd或(最近)free'd

== 17227 ==
== 17227 ==
== 17227 ==使用信号11的默认操作终止进程(SIGSEGV)
== 17227 ==不在地址0x0 $ b的映射区域内访问$ b == 17227 ==在0x5E268D4:fclose @@ GLIBC_2.2.5(iofclose.c:54)
== 17227 == by 0x42DB5F:main(recover.c:85)== 17227 ==如果你认为这是因为你的程序的主线程中出现了堆栈
== 17227 ==溢出(不太可能但是
== 17227 ==可能),你可以尝试增加
== 17227 ==使用--main-stacksize =标志的主线程堆栈。
== 17227 ==此次运行中使用的主要线程堆栈大小为8388608.
== 17227 ==
== 17227 == HEAP SUMMARY:
== 17227 = =在退出时使用:0个块中的0个字节
== 17227 ==总堆使用量:1个分配,1个释放,568个字节分配=
= 17227 ==
== 17227 = =释放所有堆块 - 不可能发生泄漏
== 17227 ==
== 17227 ==对于检测到的和抑制的错误计数,请重新运行:-v
== 17227 ==错误摘要:来自1个上下文的1个错误(被抑制:0从0开始)
分段错误

非常感谢,
./recover ---Segmentation fault--- With valgrind, I see that there are no leaks, but a line says that no memory allocations were made: Invalid read of size 4 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85) ==17227== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==17227== ==17227== ==17227== Process terminating with default action of signal 11 (SIGSEGV) ==17227== Access not within mapped region at address 0x0 ==17227== at 0x5E268D4: fclose@@GLIBC_2.2.5 (iofclose.c:54) ==17227== by 0x42DB5F: main (recover.c:85) ==17227== If you believe this happened as a result of a stack ==17227== overflow in your program's main thread (unlikely but ==17227== possible), you can try to increase the size of the ==17227== main thread stack using the --main-stacksize= flag. ==17227== The main thread stack size used in this run was 8388608. ==17227== ==17227== HEAP SUMMARY: ==17227== in use at exit: 0 bytes in 0 blocks ==17227== total heap usage: 1 allocs, 1 frees, 568 bytes allocated = =17227== ==17227== All heap blocks were freed -- no leaks are possible ==17227== ==17227== For counts of detected and suppressed errors, rerun with: -v ==17227== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0) Segmentation fault Thanks a lot,





我尝试过:





What I have tried:

/**
 * recover.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * Recovers JPEGs from a forensic image.
 */
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <stdint.h>



int main()
{
    typedef uint8_t BYTEINBITS;

    int pictcount = 0;
    
    
    FILE* input = fopen("card.raw", "r");
 
     if ( input == NULL )
    {
        printf(" Could not open card.raw \n");
        return 2;
    }
    
    FILE* output = NULL;
    
    bool  atend = false;
    
    while ( atend == false)
    {
        BYTEINBITS buffer[512];

         
        fread( &buffer, 512 * sizeof(char), 1, input); 
 
         
        bool jpg = true;
        
        if ( !( ( buffer[0] == 255 ) && ( buffer[1] == 216 ) && ( buffer[2] == 255) && ( buffer[3] > 224 ) ) )         
        {
            jpg = false;
        }
 
         
        if (jpg == true)
        {
             
             if (pictcount >= 1)
             {
              
                  fclose(output);   
             }         
                 
            pictcount++;
            char title[8];
            sprintf(title,"%03d.jpg", pictcount);
            
            output  = fopen("title", "w");
        
        }
        
        if (pictcount > 0)
        {
         
            fwrite( &buffer, 512 * sizeof(char), 1, output );

        }
        
        if ( fread( &buffer, 512*sizeof(char), 1, input) != 1)
        {
            atend = true;   
        }
    }
     
    fclose(input);
    fclose(output);


    
    
}


错误在于:

The error is here:
BYTEINBITS buffer[512];
fread( &buffer, 512 * sizeof(char), 1, input); 



buffer 是一个数组,因此已经是一个指针,但是你将该指针的地址传递给 fread (你传递指针指针而不是指针)。



工作版应该如下: br />


buffer is an array and therefore already a pointer but you are passing the address of that pointer to fread (you are passing a pointer to a pointer instead of a pointer).

A working version should look like:

uint8_t buffer[512];
fread(buffer, sizeof(buffer), 1, input); 



请注意,我还为 uint8_t typedef c>(它使代码的可读性降低),固定缓冲区大小为512, sizeof(char)(可能与不一样)的sizeof(uint8_t))。只需使用 sizeof(缓冲区),它将扩展为以字节为单位的数组大小。


Note that I have also removed the useless typedef for uint8_t (it makes the code less readable), the fixed buffer size of 512 and the sizeof(char) (which might not always the same as sizeof(uint8_t)). Just use sizeof(buffer) which expands to the array size in bytes.


这篇关于PSET4恢复分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆