[MPlayer-users] [patch] mplayer crash

Adam adam at cfar.umd.edu
Wed Apr 10 06:41:02 CEST 2002


hello,
	this patch (attached as well) fixes crash with
	mplayer as reported earlier.

		http://www.eax.com/patches/mplayer-libvo-diff

	all details are inside of the patch,
	but basically memcpy() must returns string len.

	does it look cool?

adam,
not on list, please cc

-- 
Adam
http://www.eax.com	The Supreme Headquarters of the 32 bit registers
-------------- next part --------------
This patch fixes an crash in mplayer while trying to use v4l.

It is for mplayer based on cvs tree from Tue Apr  9 2002.

The actual bug is in libvo which optimizes memcopy().

                =================================
sort answer:

        we optimized memcpy() call. However as per system
        defintion it should return destinatination pointer
        but our optimized version does not do that.

        from man page

        SYNOPSIS
                void *memcpy(void *dest, const void *src, size_t n);
        RETURN VALUE
                The memcpy() function returns a pointer to dest.

                =================================
loooooooooong answer:
                ---------------------------------

                   **** the crash itself: *****

Script started on Mon Apr  8 17:18:34 2002

[root at pepsi main]#  gdb ./mplayer

GNU gdb Red Hat Linux (5.1.90CVS-1)
This GDB was configured as "i386-redhat-linux"...

(gdb) run  -tv on:driver=v4l:width=640:height=480:outfmt=i420 -vc rawi420 -vo x
v

Starting program: /usr/src/Video4linux/Players/mplayer/cvs/main/mplayer
        -tv on:driver=v4l:width=640:height=480:outfmt=i420 -vc rawi420 -vo xv
[New Thread 1024 (LWP 9121)]


MPlayer CVS-020408-17:03-3.0.2 (C) 2000-2002 Arpad Gereoffy (see DOCS!)

CPU vendor name: GenuineIntel  max cpuid level: 2
CPU: Intel Celeron 2/Pentium III Coppermine,Geyserville (Type: 6, Stepping: 6)
Testing OS support for SSE... yes.
Testing OS support for SSE unmasked exceptions... yes.
Tests of OS support for SSE passed.
CPUflags: Type: 6 MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 0
Compiled with RUNTIME CPU Detection - warning, it's not optimal! To get best pe
rformance, recompile mplayer from sources with --disable-runtime-cpudetection
Reading /root/.mplayer/codecs.conf: can't open '/root/.mplayer/codecs.conf': No
 such file or directory
Reading /usr/local/share/mplayer/codecs.conf: 30 audio & 81 video codecs
font: can't open file: /root/.mplayer/font/font.desc
font: can't open file: /usr/local/share/mplayer/font/font.desc
Using Linux's hardware RTC timing (1024Hz)
Can't open input config file /root/.mplayer/input.conf : No such file or direct
ory
Falling back on default (hardcoded) config
Setting up lirc support...
mplayer: could not connect to socket
mplayer: Connection refused
Failed opening lirc support!
You won't be able to use your remote control
Playing TV
Selected driver: v4l
 name: Video 4 Linux input
 author: Alex Beregszaszi <alex at naxine.org>
 comment: under development

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1024 (LWP 9121)]
0x404c3d3b in strlen () from /lib/i686/libc.so.6

(gdb) where

#0  0x404c3d3b in strlen () from /lib/i686/libc.so.6
#1  0x404947bd in vfprintf () from /lib/i686/libc.so.6
#2  0x404b57b4 in vsnprintf () from /lib/i686/libc.so.6
#3  0x080830b6 in mp_msg_c (x=6145,
    format=0x83644de "unable to open '%s': %s\n") at mp_msg.c:47
#4  0x0815b63a in init (priv=0x84a4610) at tvi_v4l.c:192
#5  0x0815a3fc in tv_init (tvh=0x84a13c8) at tv.c:413
#6  0x081584b8 in open_stream (filename=0x8364251 "TV", vcd_track=0,
    file_format=0xbfffe680) at open.c:397
#7  0x0807c83d in main (argc=7, argv=0xbffff834, envp=0xbffff854)
    at mplayer.c:918
#8  0x40459df9 in __libc_start_main () from /lib/i686/libc.so.6
(gdb) quit
The program is running.  Exit anyway? (y or n) y

[root at pepsi main]# exit

exit

Script done on Mon Apr  8 17:19:00 2002

                ---------------------------------

                 ***** what is going wrong. *****

things go wrong actually little bit earlier. the problematic fragment is
in

        mplayer/cvs/main/libmpdemux/tvi_v4l.c:167

        tvi_handle_t *tvi_init_v4l(char *device) {
        [...]
            /* set video device name */
            if (!device)
                priv->video_device = strdup("/dev/video0");
            else
                priv->video_device = strdup(device);

here, we expect, as normally strdup() works to get back pointer to the
duplicated string, but instead we are getting getting some random
number (string length?).

now, checking glibc sources we see strdup code as follows:

        /glibc-2.2.4/string/strdup.c

        /* Duplicate S, returning an identical malloc'd string.  */
        char * __strdup (const char *s)
        {

          size_t len = strlen (s) + 1;
          void *new  = malloc (len);
        
          if (new == NULL) return NULL;

          return (char *) memcpy (new, s, len);
        }


what's imporant is the last line where return of strdup() is
return of memcpy(). Now as from strdup() man page

        DESCRIPTION
               The  strdup()  function  returns a pointer to a new string
               which is a duplicate of the string s.

we expect the return value to be destination string. On
the same token looking up memcpy() man page we see

        SYNOPSIS
                void *memcpy(void *dest, const void *src, size_t n);
        RETURN VALUE
                The memcpy() function returns a pointer to dest.

now it is where the issue comes. in libvo we have our optimized
version of memcopy as from

        mplayer/cvs/main/libvo/fastmemcpy.h

        extern void * fast_memcpy(void * to, const void * from, size_t len);
        #define memcpy(a,b,c) fast_memcpy(a,b,c)

and from mplayer/cvs/main/libvo/aclib.c
(this version is run thru cpp to make it more readable)

inline void * fast_memcpy(void * to, const void * from, size_t len)
{
        if(gCpuCaps.hasSSE2)
                fast_memcpy_SSE(to, from, len);
        else if(gCpuCaps.hasMMX2)
                fast_memcpy_MMX2(to, from, len);
        else if(gCpuCaps.has3DNow)
                fast_memcpy_3DNow(to, from, len);
        else if(gCpuCaps.hasMMX)
                fast_memcpy_MMX(to, from, len);
        else
                memcpy(to, from, len);
}

solution is simple

        add "return to;" just before end of function.
        this is what the patch attached below does.

                ---------------------------------

        Adam Sulmicki <adam at cfar.umd.edu>
        Tue Apr  9 23:41:36 EDT 2002
        http://www.eax.com/patches/

-------------------------------------------------------------------------------
Index: libvo/aclib.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/aclib.c,v
retrieving revision 1.6
diff -6 -u -r1.6 aclib.c
--- libvo/aclib.c       19 Mar 2002 22:32:45 -0000      1.6
+++ libvo/aclib.c       10 Apr 2002 04:08:01 -0000
@@ -141,12 +141,14 @@
                fast_memcpy_MMX(to, from, len);
 #else
                memcpy(to, from, len); // prior to mmx we use the standart memc
py
 #endif

 #endif //!RUNTIME_CPUDETECT
+
+       return to;
 }

 inline void * mem2agpcpy(void * to, const void * from, size_t len)
 {
 #ifdef RUNTIME_CPUDETECT
 #ifdef CAN_COMPILE_X86_ASM



More information about the MPlayer-users mailing list