Motion - Bug Report 2006x 12x 19x 062432
You are here: Foswiki>Motion Web>BugReports>BugReport2006x12x19x062432 (08 Jan 2007, AngelCarpintero)Edit Attach

BUG: motion in free(): error: modified (chunk-) pointer. Occurs when I use features ffmpeg on FreeBSD.

When I use options ffmpeg then the system breaks. After studying a problem I have come to conclusion, that the mistake is caused with a code in a file ffmpeg.c. In particular, clearing by the used program of memory. After when I have changed a code, the program began to work excellently.


messenger# ./motion -d2
[0] Processing thread 0 - config file /usr/local/etc/motion.conf
[0] Processing config file /usr/local/etc/thread1.conf
[0] Processing config file /usr/local/etc/thread2.conf
[0] Thread 1 is from /usr/local/etc/thread1.conf
[0] Thread 2 is from /usr/local/etc/thread2.conf
[1] Thread started
[2] Thread started
[0] motion-httpd/3.2.7 running, accepting connections
[0] motion-httpd: waiting for data on port TCP 8080
[1] VIDEO_PALETTE_YUV420P palette setting bufsize
[1] HUE [0]
[1] SATURATION [90]
[1] BRIGHTNESS [0]
[1] CONTRAST [108]
[1] VIDEO_PALETTE_YUV420P imgs.type
[1] set brightness to [120]
[2] vid_start cnt->imgs.type [15]
[2]  VIDEO_PALETTE_YUV420P setting imgs.size and imgs.motionsize
[1] Started stream webcam server in port 8083
[2] Started stream webcam server in port 8082
[1] File of type 32 saved to: /video/cam1/20061218-timelapse.mpg
motion in free(): error: modified (chunk-) pointer
(core dumped) 


After these changes all began to work well.
ffmpeg.c.diff
--- ffmpeg.c.orig       Fri Oct 20 05:21:53 2006
+++ ffmpeg.c    Fri Dec  1 12:44:27 2006
@@ -476,7 +476,7 @@
        /* free the stream */
        av_free(ffmpeg->oc);
 #if LIBAVFORMAT_BUILD >= 4629
-       free(ffmpeg->c);
+//     free(ffmpeg->c);
 #endif
        free(ffmpeg);
 }
@@ -497,7 +497,7 @@

        if (picture) {
                ffmpeg_put_frame(ffmpeg, picture);
-               free(picture);
+               av_free(picture);
        }
 }



Environment

Motion version: 3.2.6, 3.2.7
ffmpeg version: 0.4.9
Shared libraries: ffmpeg, mysql, postgresql
Server OS: FreeBSD 6.1, FreeBSD 6.2-RC1

-- RafisKhayrullin - 19 Dec 2006

Follow up

I've tested motion-3.2.7 from official ports , motion-3.2.7 compiled from tarball and current svn version ( that includes a fix for high resolutions ) but i can't reproduce your problem at all ... motion did never segfault. All version i've tested are compiled with FreeBSD native threads ...

Are you running motion compiled with linuxthreads ?

Could you try to reproduce that problem with current svn version with FreeBSD native threads ? ( default compilation option ).

-- AngelCarpintero - 19 Dec 2006

Follow up

I have made the small investigation. Here function which causes crash of the program motion.


/* Puts an arbitrary picture defined by y, u and v. */
void ffmpeg_put_other_image(struct ffmpeg *ffmpeg, unsigned char *y,
                            unsigned char *u, unsigned char *v)
{
        AVFrame *picture;
        /* allocate the encoded raw picture */
        picture = ffmpeg_prepare_frame(ffmpeg, y, u, v);

        if (picture) {
                ffmpeg_put_frame(ffmpeg, picture);
                free(picture);
        }
}

Crash is caused by releasinging of memory by free(picture). Memory has been allocated in this function:

libavcodec/utils.c
AVFrame *ffmpeg_prepare_frame(struct ffmpeg *ffmpeg, unsigned char *y,
                              unsigned char *u, unsigned char *v)
{
        AVFrame *picture;

        picture = avcodec_alloc_frame();
        if (!picture) {
                motion_log(LOG_ERR, 1, "Could not alloc frame");
                return NULL;
        }

        /* take care of variable bitrate setting */
        if (ffmpeg->vbr) {
                picture->quality = ffmpeg->vbr;
        }

        /* setup pointers and line widths */
        picture->data[0] = y;
        picture->data[1] = u;
        picture->data[2] = v;
        picture->linesize[0] = ffmpeg->c->width;
        picture->linesize[1] = ffmpeg->c->width / 2;
        picture->linesize[2] = ffmpeg->c->width / 2;

        return picture;
}

There was a call of function avcodec_alloc_frame () which belongs to a package ffmpeg. That in turn causes function av_malloc (), belonging a package ffmpeg

libavcodec/utils.c
/**
 * allocates a AVPFrame and set it to defaults.
 * this can be deallocated by simply calling free()
 */
AVFrame *avcodec_alloc_frame(void){
    AVFrame *pic= av_malloc(sizeof(AVFrame));

    if(pic==NULL) return NULL;

    avcodec_get_frame_defaults(pic);

    return pic;
}



Here realization of function av_malloc (). Thus it not simple allocation of memory. Allocation of memory directly depends on instruction MEMALIGN_HACK.

libavcodec/mem.c
/**
 * Memory allocation of size byte with alignment suitable for all
 * memory accesses (including vectors if available on the
 * CPU). av_malloc(0) must return a non NULL pointer.
 */
void *av_malloc(unsigned int size)
{
    void *ptr;
#ifdef MEMALIGN_HACK
    long diff;
#endif

    /* lets disallow possible ambiguous cases */
    if(size > INT_MAX)
        return NULL;

#ifdef MEMALIGN_HACK
    ptr = malloc(size+16+1);
    diff= ((-(long)ptr - 1)&15) + 1;
    ptr += diff;
    ((char*)ptr)[-1]= diff;
#elif defined (HAVE_MEMALIGN)
    ptr = memalign(16,size);
    /* Why 64?
       Indeed, we should align it:
         on 4 for 386
         on 16 for 486
         on 32 for 586, PPro - k6-III
         on 64 for K7 (maybe for P3 too).
       Because L1 and L2 caches are aligned on those values.
       But I don't want to code such logic here!
     */
     /* Why 16?
        because some cpus need alignment, for example SSE2 on P4, & most RISC cpus
        it will just trigger an exception and the unaligned load will be done in the
        exception handler or it will just segfault (SSE2 on P4)
        Why not larger? because i didnt see a difference in benchmarks ...
     */
     /* benchmarks with p3
        memalign(64)+1          3071,3051,3032
        memalign(64)+2          3051,3032,3041
        memalign(64)+4          2911,2896,2915
        memalign(64)+8          2545,2554,2550
        memalign(64)+16         2543,2572,2563
        memalign(64)+32         2546,2545,2571
        memalign(64)+64         2570,2533,2558

        btw, malloc seems to do 8 byte alignment by default here
     */
#else
    ptr = malloc(size);
#endif
    return ptr;
}

Accordingly, and clearing of memory directly depends on instruction MEMALIGN_HACK.

libavcodec/mem.c
/**
 * Free memory which has been allocated with av_malloc(z)() or av_realloc().
 * NOTE: ptr = NULL is explicetly allowed
 * Note2: it is recommanded that you use av_freep() instead
 */

void av_free(void *ptr)
{
    /* XXX: this test should not be needed on most libcs */
    if (ptr)
#ifdef MEMALIGN_HACK
        free(ptr - ((char*)ptr)[-1]);
#else
        free(ptr);
#endif
}


ffmpeg, by default, it is compiled with #define MEMALIGN_HACK 1.
Therefore I do a conclusion what to use function free(), it is not absolutely correct to areas of memory allocated by functions of a package ffmpeg. And function av_free() or av_freep() should be used.

Thus, my patch is quite logical.

-- RafisKhayrullin - 20 Dec 2006

I'm totally agree that memory allocated by ffmpeg functions have to be freed using av_free() or av_freep() , so the second fix in your patch is fine.

The first fix i'm not sure i have to take some time to look into.

-- AngelCarpintero - 20 Dec 2006

I've included the patch in svn r146

-- AngelCarpintero - 29 Dec 2006
The previous patch has partially solved a problem with clearing memory, however after I have put motion on a permanent job of a problem have proceeded. At night when darkly and practically there is no movement a motion began to break. gdb on backtrace has shown:
#15 0x28581a24 in _nsyyin () from /lib/libc.so.6
#16 0xbf8fcbd8 in ?? ()
#17 0x284f7d49 in _UTF8_init () from /lib/libc.so.6
#18 0x00000000 in ?? ()
#19 0x000001a0 in ?? ()
#20 0x00000000 in ?? ()
#21 0x00000000 in ?? ()
#22 0xffffffff in ?? ()
#23 0x087f90fc in ?? ()
#24 0xbf8fcb68 in ?? ()
#25 0x2818ce35 in av_freep () from /usr/local/lib/libavcodec.so.1
Previous frame inner to this frame (corrupt stack?)
Having put control points everywhere where there is a function av_freep, after studying a situation has found out the reason in the following. Memory under ffmpeg-> video_outbuf is allocated with function mymalloc, certain in motion.c And here clearing of memory in functions ffmpeg_cleanups () and ffmpeg_close () occurs through function av_freep (). Here also there is a crash. As we have found out in BugReport2006x12x19x062432 allocation and clearing of memory by functions of a package ffmpeg occurs is not trivial. So I had one more patch, in addition to svn r147.

--- ffmpeg.c.orig       Mon Jan  8 12:07:05 2007
+++ ffmpeg.c    Mon Jan  8 12:25:16 2007
@@ -428,7 +428,7 @@
                avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));
                pthread_mutex_unlock(&global_lock);
                av_freep(&ffmpeg->picture);
-               av_freep(&ffmpeg->video_outbuf);
+               free(ffmpeg->video_outbuf);
        }

        /* free the streams */
@@ -460,7 +460,7 @@
                avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));
                pthread_mutex_unlock(&global_lock);
                av_freep(&ffmpeg->picture);
-               av_freep(&ffmpeg->video_outbuf);
+               free(ffmpeg->video_outbuf);
        }

        /* write the trailer, if any */

PS. To me it would be very pleasant, if my name in connection with the given question has appeared in CHANGELOG. smile

-- RafisKhayrullin - 08 Jan 2007


Thanks Rafis smile

Commited to svn r148 , with your name added to CHANGELOG and CREDITS files as everyone that contributes to motion project.

-- AngelCarpintero - 08 Jan 2007

Fix record

BugReportForm edit

TopicTitle motion in free(): error: modified (chunk-) pointer. Occurs when I use features ffmpeg on FreeBSD.
BugStatus Monitored
AssignedBugTo -- AngelCarpintero - 19 Dec 2006
SubmittedBy RafisKhayrullin
I Attachment Action Size Date Who Comment
ffmpeg.diffdiff ffmpeg.diff manage 603 bytes 20 Dec 2006 - 17:13 AngelCarpintero proposed patch against svn 145
Topic revision: r8 - 08 Jan 2007, AngelCarpintero
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Please do not email Kenneth for support questions (read why). Use the Support Requests page or join the Mailing List.
This website only use harmless session cookies. See Cookie Policy for details. By using this website you accept the use of these cookies.