CR: Error handler for filesystem exception due to usb disk unplug

"Zhao, Halley" <[email protected]>
Newsgroups gmane.comp.multimedia.helix.devel
Message-ID <094BCE01AFBE9646AF220B0B3F367AAB03499F5B@pdsmsx413.ccr.corp.intel.com>
    I'm not familiar with file system plugin, please kindly review the patch and give your suggestion.

    Great thanks.

    

Synopsis: 

    The patch fix bug #8471: Device hang up after play music from USB then plug out and plug in the USB.

    I added error handle for usb disk unplug exception.

 

Overview: 

   Memory map is used in helix plugin for file io, In GetBlock() of common/fileio/mmapmgr.cpp, 

the pBuffer address is calculated from the memory page information. it may be invalid due to the device being removed; 

then when there is a memcpy() in the future, it will crash the engine.

  On Windows system, it tests IsBadReadPtr()to catch the exception as early as possible. 

But there is no such check (error handle) for Linux platform. I added a function to act as IsBadReadPtr() to catch the exception.

 

    After memory map exception (MMAP_EOF_EXCEPTION) occurred, the Read() function in common/fileio/platform/unix/mmapdatf.cpp 

will regress to normal_read. and it will consume some data which has been mapped in memory. 

then in CheckForCorruptFile() of filesystem/local/full/smplfsys.cpp, we should try to consider this situation. 

and in this scenario file size (m_ulSize) isn't initialized. We could determine it is a corrupt file depends on m_ulSize equal to 0.

 

Files Added:

       No file added

Files Modified:

    common/fileio/mmapmgr.cpp

        add function _IsBadReadPtr() to detect whether the file is available, and try to catch the exception due to device removed.

    filesystem/local/full/smplfsys.cpp

        file size (m_ulSize) equal to 0 means a corrupt file.

            

Image Size and Heap Use impact (Client -Only):

    little

Platforms and Profiles Affected:

    platform:   linux-2.2-libc6-gcc32-i586

    profile:    helix-client-all-defines

 

Distribution Libraries Affected:

    <smplfsys.so>

Distribution library impact and planned action:

    <None>

Platforms and Profiles Build Verified:

    Set BIF branch  -> hxclient_3_1_0_atlas_restricted

    Set Target(s)   -> player_mid_all_installers (or splay)

    Set Profile     -> helix-client-all-defines

    System ID       -> linux-2.2-libc6-gcc32-i586

Branch: 

    HEAD

Copyright assignment: <MUST be one of the following statements >

   2.      Intel has signed and delivered a Joint Copyright Assignment

           to RealNetworks, and received acknowledgment that the 

           agreement was received. 

Files Attached:

    common-fileio-mmapmgr.cpp.diff.txt

    filesystem-local-smplsys.cpp.diff.txt

 

ZHAO, Halley (Aihua)

Email: [email protected] <mailto:[email protected]> 

Tel: +86(21)61166476

iNet: 8821-6476

SSG/OTC/UMD

_______________________________________________
Helix-client-dev mailing list
[email protected]
http://lists.helixcommunity.org/mailman/listinfo/helix-client-dev
filesystem-local-smplsys.cpp.diff.txt (text/plain, 675 B)
Index: full/smplfsys.cpp
===================================================================
RCS file: /cvsroot/filesystem/local/full/smplfsys.cpp,v
retrieving revision 1.46.2.1
diff -u -w -r1.46.2.1 smplfsys.cpp
--- full/smplfsys.cpp	4 Feb 2008 05:49:53 -0000	1.46.2.1
+++ full/smplfsys.cpp	17 Jul 2008 05:05:08 -0000
@@ -1941,7 +1941,7 @@
             ulDesiredReadCount = actual < m_ulPendingReadCount ? m_ulPendingReadCount-actual : 0;
         }
 
-        if (m_ulPos+ulDesiredReadCount <= m_ulSize)
+        if (m_ulPos+ulDesiredReadCount <= m_ulSize || m_ulSize == 0)
         {
             statusReturned = HXR_CORRUPT_FILE;
             bErrorToBeReported = TRUE;
common-fileio-mmapmgr.cpp.diff.txt (text/plain, 2.9 KB)
Index: mmapmgr.cpp
===================================================================
RCS file: /cvsroot/common/fileio/mmapmgr.cpp,v
retrieving revision 1.16
diff -u -w -r1.16 mmapmgr.cpp
--- mmapmgr.cpp	6 Jul 2007 20:35:11 -0000	1.16
+++ mmapmgr.cpp	17 Jul 2008 05:04:10 -0000
@@ -73,6 +73,8 @@
 #if defined(_UNIX) && !defined(_BEOS)
 #include <sys/mman.h>
 #endif
+#include <setjmp.h>
+#include <signal.h>
 
 #include "hxcom.h"
 #include "hxtypes.h"
@@ -605,6 +607,43 @@
     }
 }
 
+static unsigned char g_ucCalledByTestRoutine = 0;
+static jmp_buf g_pBuf;
+
+void  MemTestHandler ( int nSig) __attribute__ ((cdecl));
+void  MemTestHandler ( int nSig) 
+{
+     if ( g_ucCalledByTestRoutine ) 
+     {
+        longjmp ( g_pBuf, 1);
+     }
+
+
+}
+bool _IsBadReadPtr(const void* pv, unsigned long ulSize)
+{
+        
+    char* pc;
+    void(*pPrev) ( int sig);
+
+    g_ucCalledByTestRoutine = 1;
+    if(setjmp ( g_pBuf))
+    {
+         return true;
+    }
+    pPrev = signal (SIGBUS, MemTestHandler);
+    if(pPrev == SIG_ERR)
+    {
+       printf("cant register my error handle\n");
+    }
+    
+    pc = (char*) malloc ( ulSize);
+    memcpy ( pc, pv, ulSize);
+    g_ucCalledByTestRoutine = 0;
+    free(pc);
+    signal ( SIGBUS, pPrev);
+    return false;
+}
 
 UINT32
 MemoryMapManager::GetBlock(REF(IHXBuffer*) pBuffer, void* pHandle,
@@ -726,6 +765,38 @@
 	pEntry->pPage =
 	    mmap(0, ulChunkSize, PROT_READ, MAP_PRIVATE, 
 	    pInfo->Descriptor, ulNeededPageNumber * m_ulChunkSize);
+	if (pEntry->pPage == 0)
+	{
+	    pEntry->pPage = MAP_FAIL;
+	}
+	else
+	{
+            // When MapViewOfFile is called it returns a handle to a page of memory that
+            // the system no longer knows about so an exception occurs.  It is usally a 
+            // EXCEPTION_IN_PAGE_ERROR. Reading the documentation it appears that all access
+            // to handles returned from memory mapped I/O should be wrapped in try/catch blocks 
+            // since the handles may be invalid.  I added try/catch logic to test this out and
+            // it fixes the bug.  The main problem I'm not sure about is that this code is also 
+            // used by the server and IsBadReadPtr may iterate over the memory block which can 
+            // be slow.  Because this is the layer of code that "knows" it is using memory mapped 
+            // I/O this is probably where the try/catch code belongs so that if an exception
+            // occurs then it can return an error and no buffer since the buffer wouldn't be
+            // accessible anyway.
+            HXBOOL bInvalid = TRUE;
+
+            try
+            {
+               bInvalid = _IsBadReadPtr(pEntry->pPage, ulChunkSize);
+            }
+            catch (...)
+            {
+            }
+
+            if (bInvalid)
+            {
+               pEntry->pPage = MAP_FAIL;
+            }
+	}
 #else
 	pEntry->pPage = MapViewOfFile(pInfo->Descriptor, FILE_MAP_READ, 0,
 	    ulNeededPageNumber * m_ulChunkSize, ulChunkSize);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.