GNOME Bugzilla – Bug 587052
[filesink.c] Support for files >4GB on windows makes filesink element to crash at gst_file_sink_do_seek()
Last modified: 2009-07-13 10:03:23 UTC
Support for files >4GB on Windows makes the filesink element to crash at gst_file_sink_do_seek() using this pipeline: gst-launch videotestsrc ! filesink location=test The execution throws an unhandled exception at line 451: #elif defined (G_OS_UNIX) || defined (G_OS_WIN32) if (lseek (fileno (filesink->file), (off_t) new_offset, SEEK_SET) == (off_t) - 1) The same pipeline works reverting 'filesink.c' to the previous version (0.10.22). I'm using Visual Studio 8 together with the Windows Driver Kit. You can fetch the whole build system here: http://code.google.com/p/ossbuild/ I attach the binaries to reproduce the error
Created attachment 137420 [details] Windows binaries to reproduce the filesink bug
I've tried to debug it in MSVS2008 Express using the .pdb files attached, but Visual Studio says that "The symbol file libgstcoreelements.pdb does not match the module" (the module is C:\gstreamer\lib\gstreamer-0.10\libgstcoreelements.dll) Also, running the same pipeline with --gst-debug-level=5 shows that filesink tries to seek to offset 0, which should not fail. Because i can't debug it, i can only suggest a few things you can do to find the source of the problem: Change #elif defined (G_OS_UNIX) || defined (G_OS_WIN32) if (lseek (fileno (filesink->file), (off_t) new_offset, SEEK_SET) == (off_t) - 1) goto seek_failed; #else to #elif defined (G_OS_UNIX) || defined (G_OS_WIN32) { int filedesc = 0; __int64 lseekresult = 0; filedesc = fileno (filesink->file); GST_DEBUG_OBJECT (filesink, "File descriptor is %d", filedesc); lseekresult = lseek (filedesc, (off_t) new_offset, SEEK_SET); GST_DEBUG_OBJECT (filesink, "Seek result is %" G_GINT64_FORMAT, lseekresult); if (lseekresult == (off_t) - 1) goto seek_failed; } #else And rebuild it. Then launch gst-launch-0.10 --gst-debug-level=5 videotestsrc ! filesink location=test and see what happens.
I tryed with the changes you proposed, but now it dies at this point: GST_DEBUG_OBJECT (filesink, "File descriptor is %d", filedesc); No useful info runing the pipeline: DEBUG filesink gstfilesink.c:443:gst_file_sink_do_seek:<filesink0> Seeking to offset 0 using lseek I fixed the problem with the pdb files here: http://www.gstreamer-winbuild.ylatuya.es/gstreamer.7z Hope you could debug it now.
libgstcoreelements.pdb does not match (libgstbase.pdb does, but that isn't very helpful, since filesink resides ink coreelements). And you should drop me gstfilesink.c (the version used to build the executable), since it is different (now) from the one i have. But frankly, i don't know what i am going to achieve here. If you've managed to build GStreamer with MSVS, you know MSVS better than i do. On the other hand, the stack is: 00905a4d() > libgstcoreelements.dll!0095490c() [Frames below may be incorrect and/or missing, no symbols loaded for libgstcoreelements.dll] libgstcoreelements.dll!00954539() libgstcoreelements.dll!00954fbb() libgstbase.dll!gst_base_sink_change_state(_GstElement * element=, GstStateChange transition=) Line 4010 + 0x3 bytes C which makes me think that the issue is indeed somewhere in gstfilesink.c, not in msvcrt (or whatever contains the _lseeki64())
It could be because you are using two different CRTs - one is used internally by GLib (unless you're building GLib yourself too) to open a FILE* stream, and another is used by GStreamer to convert that stream with fileno().
(In reply to comment #4) > libgstcoreelements.pdb does not match (libgstbase.pdb does, but that isn't very I'll try to update de zip package with the good pbd files (I must be doing a stupid mistake copying and pasting) > helpful, since filesink resides ink coreelements). And you should drop me > gstfilesink.c (the version used to build the executable), since it is different > (now) from the one i have. gstfilesink.c is the same one that is in the 0.10.23 release package. (In reply to comment #5) > It could be because you are using two different CRTs - one is used internally > by GLib (unless you're building GLib yourself too) to open a FILE* stream, and > another is used by GStreamer to convert that stream with fileno(). > I build GLib using Mingw and the GStreamer binaries are built using MSVS2008 but using the Windows Driver Kit, which allows to target msvcrt.dll (the same one used by Mingw) instead of msvcr90.dll. Thus both GLib and GStreamer are using the same CRT. I'll try to make one last test: to build gstreamer with mingw/msys. This way we will be able to discard the CRT problem.
(In reply to comment #6) > I'll try to make one last test: to build gstreamer with mingw/msys. This way we > will be able to discard the CRT problem. > Of course you will. Thing is, i've made the ">4GB files support" patch, and i've been using (and still using) MinGW/MSys to develop GStreamer and related things. The code in MinGW/MSys-generated binaries worked correctly then and it works correctly now (just re-checked).
The problem is in fileno(). As you said the Mingw CRT and the MSVC CRT have different FILE structures that may be incompatibles. I fixed the bug in the following way: -filedesc = fileno(filesink->file); +filedesc = filesink->file->_file; -ret = lseek (fileno(filesink->file), 0, SEEK_CUR); +ret = lseek (filesink->file->_file, 0, SEEK_CUR); Can these changes be applied to UNIX systems? If not we could add something like this: #ifdef _MSC_VER filedesc = filesink->file->_file; #else filedesc = fileno(filesink->file); #endif What I still do not understand is why this incompatibility exists if both GLib and GStreamer are linked against msvcrt.dll ...
From MinGW's stdio.h: /* * The structure underlying the FILE type. * * Some believe that nobody in their right mind should make use of the * internals of this structure. Provided by Pedro A. Aranda Gutiirrez * <paag@tid.es>. */ #ifndef _FILE_DEFINED #define _FILE_DEFINED typedef struct _iobuf { char* _ptr; int _cnt; char* _base; int _flag; int _file; int _charbuf; int _bufsiz; char* _tmpfname; } FILE; #endif /* Not _FILE_DEFINED */
You are right! I think I found the right solution!!! fileno() is deprecated in MSVC, and replaced with _fileno(). This works for me: #ifdef G_OS_WIN32 #include <io.h> /* lseek, open, close, read */ #undef lseek #define lseek _lseeki64 #undef off_t #define off_t guint64 #ifdef _MSC_VER /* Check if we are using MSVC */ #define fileno _fileno #endif #endif
commit 741ef2bc8097f4132d0364c1c13588fc013b1107 Author: Andoni Morales <ylatuya at gmail.com> Date: Mon Jul 13 12:00:47 2009 +0200 filesink: Fix segfault with MSVC Don't use deprecated fileno on MSVC but replace with _fileno Fixes #587052