Thread: Segmentation Fault

  1. #1
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220

    Segmentation Fault

    Is there any tool that detects where i had a segmentation fault? If there isn't how can i do it with GDB? [Linux Platform]

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There are two things you can do, depending on circumstances:
    If you have a "core" file, then you can do "gdb core", and it will show you where the application was when it crashed with "where" [assuming you haven't completely shot the app to pieces - there are some types of "segmentation fault" causing ways you can completely loose track of what went on - a good one is to load the stack pointer with zero and try to return or something - althoguh "disp registers" will show you that the %esp register is zero in this case, but it's hard to say how it became zero, since you have no stack to inspect].

    If you haven't got a core-file, then you have to run the app again inside GDB, then do the steps to make it crash, and do "where" or some such.

    If the app is relatively simple, you can of course step through a bit at a time until it crashes - but it's usually better to run it once until the crash [recording exactly what steps to take to make it crash helps here - assuming it's easily reproducable], and then set a breakpoint on the place just before [e.g the start of the function it is in when it dies] it crashes, and step from there.

    A few more tips:
    If it dies in a library function, for example strcpy(), set a breakpoint in YOUR function that is just under strcpy() in the stack-trace ("where" in GDB).

    If you can't reproduce the problem consistently, try to find a way to make it reproduce first, before you try to single-step.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    I'm getting really lost, i think that the problem is inside a webcam driver, can i send you the code to analyze it? It's like 6 files... =/

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Not likely that I can fix that - I don't have a Linux setup running at the moment [I do have a Linux box, but it's not connected to network, power, monitor, keyboard or mouse or anything else for that matter].

    Are you saying you get a segfault in the Linux kernel (a Kernel OOPS)? Or is your application that talks to the Webcam getting a segfault - or some other app?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    My application that talks to the webcam is getting the segfault, i have got a backtrace when my app crashed:

    Code:
    *** glibc detected *** ./dist/Debug/GNU-Linux-x86/examples: free(): invalid next size (fast): 0x08667008 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0x452e5df1]
    /lib/libc.so.6(cfree+0x90)[0x452e9430]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x466fa091]
    ./dist/Debug/GNU-Linux-x86/examples(__gxx_personality_v0+0x1b7)[0x8048b1b]
    /lib/libc.so.6(__libc_start_main+0xe0)[0x45293f70]
    ./dist/Debug/GNU-Linux-x86/examples(__gxx_personality_v0+0x5d)[0x80489c1]
    ======= Memory map: ========
    00237000-00258000 r-xp 00000000 fd:00 313907     /usr/lib/libjpeg.so.62.0.0
    00258000-00259000 rwxp 00020000 fd:00 313907     /usr/lib/libjpeg.so.62.0.0
    08048000-0804a000 r-xp 00000000 fd:00 934127     
    /home/scarvenger/Projects/C++/ScarVideo/examples/dist/Debug/GNU-Linux-x86/examples
    0804a000-0804b000 rwxp 00001000 fd:00 934127     
    /home/scarvenger/Projects/C++/ScarVideo/examples/dist/Debug/GNU-Linux-x86/examples
    08667000-08688000 rwxp 08667000 00:00 0 
    4525f000-4527a000 r-xp 00000000 fd:00 213109     /lib/ld-2.6.so
    4527a000-4527b000 r-xp 0001a000 fd:00 213109     /lib/ld-2.6.so
    4527b000-4527c000 rwxp 0001b000 fd:00 213109     /lib/ld-2.6.so
    4527e000-453cc000 r-xp 00000000 fd:00 215337     /lib/libc-2.6.so
    453cc000-453ce000 r-xp 0014e000 fd:00 215337     /lib/libc-2.6.so
    453ce000-453cf000 rwxp 00150000 fd:00 215337     /lib/libc-2.6.so
    453cf000-453d2000 rwxp 453cf000 00:00 0 
    453d4000-453fb000 r-xp 00000000 fd:00 215340     /lib/libm-2.6.so
    453fb000-453fc000 r-xp 00026000 fd:00 215340     /lib/libm-2.6.so
    453fc000-453fd000 rwxp 00027000 fd:00 215340     /lib/libm-2.6.so
    4661e000-46629000 r-xp 00000000 fd:00 215345     /lib/libgcc_s-4.1.2-20070925.so.1
    46629000-4662a000 rwxp 0000a000 fd:00 215345     /lib/libgcc_s-4.1.2-20070925.so.1
    46646000-46726000 r-xp 00000000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    46726000-46729000 r-xp 000e0000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    46729000-4672b000 rwxp 000e3000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    4672b000-46731000 rwxp 4672b000 00:00 0 
    b7e00000-b7e21000 rwxp b7e00000 00:00 0 
    b7e21000-b7f00000 --xp b7e21000 00:00 0 
    b7fd3000-b7fd5000 rwxp b7fd3000 00:00 0 
    b7fe3000-b7fe4000 rwxp b7fe3000 00:00 0 
    b7fe4000-b7fe5000 r-xp b7fe4000 00:00 0          [vdso]
    bfe41000-bfe57000 rw-p bfe41000 00:00 0          [stack]
    I'm not calling any free() in my app, just a mmap and unmap, i will post the relevant code that does this:
    Code:
    #include "VideoDevice.h"
    
    VideoDevice::VideoDevice(char* device) : image(NULL, 1, 1, 24)
    {
        this->device    = device;
        this->width     = -1;
        this->height    = -1;
        this->isValid   = true;
        this->isRunning = false;
    
        file = open(device, O_RDWR);
    
        if (file < 0)
        {
            isValid = false;
        }
        else
        {
            if (loadCapability() < 0)
    	{
                isValid = false;
    	}
    	else if (loadFormat() < 0)
    	{
                isValid = false;
    	}
    	else if (!(capability.type & VID_TYPE_CAPTURE))
    	{
    		isValid = false;
    	}
        }
    }
    
    VideoDevice::~VideoDevice()
    {
        if (isRunning)
        {
             stop();
        }
        close(file);
    }
    
    bool VideoDevice::start()
    {
        if(ioctl(file, VIDIOCGMBUF, &mbuffer) < 0)
            return false;
    
        frameBuffer = (unsigned char*) mmap(0, mbuffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, file, 0);
    
        if (width  < 0)
            setWidth(getMaxWidth());
        if (height < 0)
            setHeight(getMaxHeight());
    
        mmapFrames.frame  = 0;
        mmapFrames.height = height;
        mmapFrames.width  = width;
        mmapFrames.format = VIDEO_PALETTE_RGB24;
    
        currentFrame = 0;
        isRunning    = true;
    
        return true;
    }
    
    bool VideoDevice::isOk()
    {
        return isValid;
    }
    
    void VideoDevice::stop()
    {
        isRunning = false;
        /*int zero = 0;
        
        ioctl(file, VIDIOCSYNC, 0 );
        ioctl(file, VIDIOCCAPTURE, &zero );*/
    
        if (frameBuffer)
        {
            munmap(frameBuffer, mbuffer.size);
            frameBuffer = NULL;
        }
    }
    
    Image* VideoDevice::nextFrame()
    {
        if (ioctl(file, VIDIOCMCAPTURE, &mmapFrames) < 0)
            return false;
    
        if (ioctl(file, VIDIOCSYNC, &currentFrame) < 0)
            return false;
    
        bgrToRgb(frameBuffer, width * height);
    
        currentFrame = (currentFrame + 1) &#37; mbuffer.frames;
        image.data = frameBuffer;
        
        return &image;
    }
    
    void VideoDevice::bgrToRgb(unsigned char* buffer, unsigned int size)
    {
        register char copyBuffer;
    
        while (--size)
        {
            copyBuffer = buffer[0];
            buffer[0]  = buffer[2];
            buffer[2]  = copyBuffer;
            buffer     += 3;
        }
    }
    
    void VideoDevice::setWidth(int width)
    {
        this->width = width;
        image.width = width;
    }
    
    void VideoDevice::setHeight(int height)
    {
        this->height = height;
        image.height = height;
    }
    
    int VideoDevice::getWidth()
    {
        if (width < 0)
        {
            return (width = getMaxWidth());
        }
        return width;
    }
    
    int VideoDevice::getHeight()
    {
        if (height < 0)
        {
            return (height = getMaxHeight());
        }
        return height;
    }
    
    int VideoDevice::loadCapability()
    {
        return ioctl(file, VIDIOCGCAP, &capability);
    }
    
    int VideoDevice::loadFormat()
    {
        return ioctl(file, VIDIOCGPICT, &picture);
    }
    
    char* VideoDevice::getDevice()
    {
        return device;
    }
    
    //video_capability struct
    
    char* VideoDevice::getName()
    {
        return capability.name;
    }
    
    int VideoDevice::getMaxWidth()
    {
        return capability.maxwidth;
    }
    
    int VideoDevice::getMaxHeight()
    {
        return capability.maxheight;
    }
    
    int VideoDevice::getMinWidth()
    {
        return capability.minwidth;
    }
    
    int VideoDevice::getMinHeight()
    {
        return capability.minheight;
    }
    
    //video_picture struct
    
    int VideoDevice::getBrightness()
    {
        return picture.brightness;
    }
    
    int VideoDevice::getHue()
    {
        return picture.hue;
    }
    
    int VideoDevice::getColour()
    {
        return picture.colour;
    }
    
    int VideoDevice::getContrast()
    {
        return picture.contrast;
    }
    
    int VideoDevice::getWhiteness()
    {
        return picture.whiteness;
    }
    
    int VideoDevice::getDepth()
    {
        return picture.depth;
    }
    
    int VideoDevice::getPalette()
    {
        return picture.palette;
    }
    
    bool saveFormat(unsigned long palette)
    {
        return false;
    }
    Any idea?

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    First, to get useful backtrace information you must compile in debug mode: "-g" option to gcc. Then, you have two options.

    1. Run your program normally until it crashes. This produces a file called "core" or possibly "core.XXXXX" where XXXXX is a number. Load this file into gdb like this:

    Code:
    $ gdb my_program core
    Then, at the gdb prompt, type "where". This will print a stack trace with line numbers.

    Or...

    2. Run the program directly in gdb:

    Code:
    $ gdb my_program
    Then at the gdb prompt, type "run." The program will run until it crashes. Again, type "where" to get a stack trace.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Is this size in bytes or blocks of 24 bits?
    Code:
        while (--size)
        {
            copyBuffer = buffer[0];
            buffer[0]  = buffer[2];
            buffer[2]  = copyBuffer;
            buffer     += 3;
        }
    If it is bytes, then you should divide size by 3, or you'll overwrite a bunch of data.


    Are you using new/delete anywhere in your code [particulary for arrays]? Check the indexing of those arrays in that case - that's a very likely scenario of messing up the heap - which is the signs you are seeing in the crash.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    It is blocks of 24 bits, and the only place where i am using new/delete in my code is in the test code:
    Code:
    int main(int argc, char** argv) 
    {
        VideoDevice* device = new VideoDevice("/dev/video0");
        device->start();
        
        Image* image;
        
        for (int i = 0;i < 50;i++)
            image = device->nextFrame();
        
        //image->save("me.jpeg", Image::JPEG, 100);
        delete device;
        
        return 1;
    }
    the bgrToRgb function() i am almost sure that is correct...

    By the way, don't know if this helps but i am getting the segmentation fault only when i delete my VideoDevice* object...

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Scarvenger View Post
    the bgrToRgb function() i am almost sure that is correct...
    Yes, that's fine if it's blocks of 24 bits.
    By the way, don't know if this helps but i am getting the segmentation fault only when i delete my VideoDevice* object...
    That's probbaly becuse either:
    - That's the only delete you do.
    - Any other delete is of uncorrupted memory.

    You may try to put a "bumper" around any arrays in your class - fill the "bumper" with a pattern, check that it's still there at regular intervals.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    What's that bumper thing you are saying? Ahhhh, im doing everything okay, why is this happening? .

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    For example, change:
    Code:
    struct something {
       ...
       int array[100];
       ...
    };
    into
    Code:
    struct something {
       ...
       int bumper1[10];
       int array[100];
       int bumper2[10];
       ...
    };
    Fill bumper1 and bumper2 with some defined value, then check that it's the value you expect later on. If it isn't, then you are overwriting some array boundary.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Code:
    Image* VideoDevice::nextFrame()
    {
        if (ioctl(file, VIDIOCMCAPTURE, &mmapFrames) < 0)
            return false;
    
        if (ioctl(file, VIDIOCSYNC, &currentFrame) < 0)
            return false;
    
        bgrToRgb(frameBuffer, width * height);
    
        currentFrame = (currentFrame + 1) &#37; mbuffer.frames;
        image.data = frameBuffer;
        
        return &image;
    }
    
    // then later on
    
        Image* image;
        
        for (int i = 0;i < 50;i++)
            image = device->nextFrame();
    What exactly are 'image' and 'framebuffer'?

    Why do I get the feeling that you're either returning pointers to local variables, returning pointers to private member variables, or generally ending up with 50 pointers to the same bit of information.

    > I'm not calling any free() in my app, just a mmap and unmap,
    But that doesn't mean none of the services you make use of aren't using malloc on your behalf.

    If it's a malloc/free problem, then
    gcc -g prog.c -lefence
    gdb a.out
    run

    Electric fence will cause a seg-fault at the instruction which steps beyond the bounds of allocated memory. This is much more useful than the "damaged free" diagnostic which you get much later.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    image is a Image object (nothing really important happens in this class, it just stores width, height, etc..) and frameBuffer is a unsigned char* wich is mmaped to access the frame in the device.

    I used eletric fence and got the backtrace in the gdb:
    Code:
    (gdb) run
    Starting program: /home/scarvenger/Projects/C++/ScarVideo/examples/a.out 
    *** glibc detected *** 
    /home/scarvenger/Projects/C++/ScarVideo/examples/a.out: free(): invalid next size (fast): 0x09a8e008 ***
    ======= Backtrace: =========
    /lib/libc.so.6[0x452e5df1]
    /lib/libc.so.6(cfree+0x90)[0x452e9430]
    /usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x466fa091]
    /home/scarvenger/Projects/C++/ScarVideo/examples/a.out(__gxx_personality_v0+0x229)[0x8048b8d]
    /lib/libc.so.6(__libc_start_main+0xe0)[0x45293f70]
    /home/scarvenger/Projects/C++/ScarVideo/examples/a.out(__gxx_personality_v0+0x5d)[0x80489c1]
    ======= Memory map: ========
    00110000-00111000 r-xp 00110000 00:00 0          [vdso]
    00237000-00258000 r-xp 00000000 fd:00 313907     /usr/lib/libjpeg.so.62.0.0
    00258000-00259000 rwxp 00020000 fd:00 313907     /usr/lib/libjpeg.so.62.0.0
    08048000-0804a000 r-xp 00000000 fd:00 935085     /home/scarvenger/Projects/C++/ScarVideo/examples/a.out
    0804a000-0804b000 rwxp 00001000 fd:00 935085     /home/scarvenger/Projects/C++/ScarVideo/examples/a.out
    09a8e000-09aaf000 rwxp 09a8e000 00:00 0 
    4525f000-4527a000 r-xp 00000000 fd:00 213109     /lib/ld-2.6.so
    4527a000-4527b000 r-xp 0001a000 fd:00 213109     /lib/ld-2.6.so
    4527b000-4527c000 rwxp 0001b000 fd:00 213109     /lib/ld-2.6.so
    4527e000-453cc000 r-xp 00000000 fd:00 215337     /lib/libc-2.6.so
    453cc000-453ce000 r-xp 0014e000 fd:00 215337     /lib/libc-2.6.so
    453ce000-453cf000 rwxp 00150000 fd:00 215337     /lib/libc-2.6.so
    453cf000-453d2000 rwxp 453cf000 00:00 0 
    453d4000-453fb000 r-xp 00000000 fd:00 215340     /lib/libm-2.6.so
    453fb000-453fc000 r-xp 00026000 fd:00 215340     /lib/libm-2.6.so
    453fc000-453fd000 rwxp 00027000 fd:00 215340     /lib/libm-2.6.so
    4661e000-46629000 r-xp 00000000 fd:00 215345     /lib/libgcc_s-4.1.2-20070925.so.1
    46629000-4662a000 rwxp 0000a000 fd:00 215345     /lib/libgcc_s-4.1.2-20070925.so.1
    46646000-46726000 r-xp 00000000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    46726000-46729000 r-xp 000e0000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    46729000-4672b000 rwxp 000e3000 fd:00 325021     /usr/lib/libstdc++.so.6.0.8
    4672b000-46731000 rwxp 4672b000 00:00 0 
    b7e00000-b7e21000 rw-p b7e00000 00:00 0 
    b7e21000-b7f00000 ---p b7e21000 00:00 0 
    b7f93000-b7fad000 rw-s 0004f000 00:10 35359      /dev/video0
    b7fad000-b7fb0000 rw-p b7fad000 00:00 0 
    bff4d000-bff62000 rw-p bff4d000 00:00 0          [stack]
    
    Program received signal SIGABRT, Aborted.
    0x00110402 in __kernel_vsyscall ()
    (gdb) bt
    #0  0x00110402 in __kernel_vsyscall ()
    #1  0x452a6fa0 in raise () from /lib/libc.so.6
    #2  0x452a88b1 in abort () from /lib/libc.so.6
    #3  0x452ddd6b in __libc_message () from /lib/libc.so.6
    #4  0x452e5df1 in _int_free () from /lib/libc.so.6
    #5  0x452e9430 in free () from /lib/libc.so.6
    #6  0x466fa091 in operator delete () from /usr/lib/libstdc++.so.6
    #7  0x08048b8d in main () at Capture.cpp.cc:33
    Im still lost, the problem doesn't seems to be at my code o.O.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > at Capture.cpp.cc:33
    What line of code is here?
    A 'delete' from the look of things, which then calls free() to free the actual memory (following calls to destructors), and then it all goes pear shaped.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220
    Code:
    int main(int argc, char** argv) 
    {
        VideoDevice* device = new VideoDevice("/dev/video0");
        device->start();
        
        Image* image;
        
        for (int i = 0;i < 50;i++)
            image = device->nextFrame();
        
        //image->save("me.jpeg", Image::JPEG, 100);
        delete device;
        
        return 1;
    }
    The Capture.cpp.cc:33 is at the red line... Yes, all goes down when i delete the VideoDevice object, and when there&#180;s nothing at the destructor the program still crashes...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM