Attempting to fix heap corruption
authorJohn Hodge <[email protected]>
Fri, 29 Oct 2010 07:14:19 +0000 (15:14 +0800)
committerJohn Hodge <[email protected]>
Fri, 29 Oct 2010 07:14:19 +0000 (15:14 +0800)
- Added lock field to tVFS_Node
- Fixed module makefile

Kernel/heap.c
Kernel/include/acess.h
Kernel/include/vfs.h
Kernel/lib.c
Modules/Filesystems/FAT/fat.c
Modules/Makefile.tpl

index 4c0232e..aa08100 100644 (file)
@@ -7,7 +7,8 @@
 #include <heap_int.h>
 
 #define WARNINGS       1
-#define        DEBUG_TRACE     0
+#define        DEBUG_TRACE     1
+#define        VERBOSE_DUMP    0
 
 // === CONSTANTS ===
 #define        HEAP_INIT_SIZE  0x8000  // 32 KiB
@@ -135,19 +136,20 @@ void *Heap_Merge(tHeapHead *Head)
  * \param Line Source line
  * \param Bytes        Size of region to allocate
  */
-void *Heap_Allocate(const char *File, int Line, size_t Bytes)
+void *Heap_Allocate(const char *File, int Line, size_t __Bytes)
 {
        tHeapHead       *head, *newhead;
        tHeapFoot       *foot, *newfoot;
        tHeapHead       *best = NULL;
        Uint    bestSize = 0;   // Speed hack
+       size_t  Bytes;
        
        // Get required size
        #if POW2_SIZES
-       Bytes = Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot);
-       Bytes = 1UUL << LOG2(Bytes);
+       Bytes = __Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot);
+       Bytes = 1UUL << LOG2(__Bytes);
        #else
-       Bytes = (Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + MIN_SIZE-1) & ~(MIN_SIZE-1);
+       Bytes = (__Bytes + sizeof(tHeapHead) + sizeof(tHeapFoot) + MIN_SIZE-1) & ~(MIN_SIZE-1);
        #endif
        
        // Lock Heap
@@ -247,6 +249,7 @@ void *Heap_Allocate(const char *File, int Line, size_t Bytes)
        newhead->Magic = MAGIC_FREE;
        foot->Head = newhead;   // Update backlink in old footer
        best->Size = Bytes;             // Update size in old header
+       best->ValidSize = __Bytes;
        best->Magic = MAGIC_USED;       // Mark block as used
        best->File = File;
        best->Line = Line;
@@ -318,8 +321,8 @@ void Heap_Deallocate(void *Ptr)
        
        // Mark as free
        head->Magic = MAGIC_FREE;
-       head->File = NULL;
-       head->Line = 0;
+       //head->File = NULL;
+       //head->Line = 0;
        head->ValidSize = 0;
        // Merge blocks
        Heap_Merge( head );
@@ -485,6 +488,7 @@ void Heap_Dump(void)
        while( (Uint)head < (Uint)gHeapEnd )
        {               
                foot = (void*)( (Uint)head + head->Size - sizeof(tHeapFoot) );
+               #if VERBOSE_DUMP
                Log_Log("Heap", "%p (0x%llx): 0x%08lx (%i) %4C",
                        head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
                Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
@@ -492,7 +496,7 @@ void Heap_Dump(void)
                        Log_Log("Heap", "%sowned by %s:%i",
                                (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
                }
-               Log_Log("Heap", "");
+               #endif
                
                // Sanity Check Header
                if(head->Size == 0) {
@@ -518,6 +522,10 @@ void Heap_Dump(void)
                        break;
                }
                
+               #if VERBOSE_DUMP
+               Log_Log("Heap", "");
+               #endif
+               
                // All OK? Go to next
                head = foot->NextHead;
        }
@@ -525,13 +533,24 @@ void Heap_Dump(void)
        // Check for a bad return
        if( (tVAddr)head >= (tVAddr)gHeapEnd )
                return ;
+
+       #if !VERBOSE_DUMP
+       Log_Log("Heap", "%p (0x%llx): 0x%08lx (%i) %4C",
+               head, MM_GetPhysAddr((Uint)head), head->Size, head->ValidSize, &head->Magic);
+       Log_Log("Heap", "%p %4C", foot->Head, &foot->Magic);
+       if(head->File) {
+               Log_Log("Heap", "%sowned by %s:%i",
+                       (head->Magic==MAGIC_FREE?"was ":""), head->File, head->Line);
+       }
+       Log_Log("Heap", "");
+       #endif
        
-       badHead = head;
        
-       Log_Log("Heap", "==== Going Backwards ==== (from %p)", badHead);
+       badHead = head;
        
        // Work backwards
        foot = (void*)( (tVAddr)gHeapEnd - sizeof(tHeapFoot) );
+       Log_Log("Heap", "==== Going Backwards ==== (from %p)", foot);
        head = foot->Head;
        while( (tVAddr)head >= (tVAddr)badHead )
        {
index e6afcf5..9337567 100644 (file)
@@ -329,7 +329,9 @@ extern char *strncpy(char *__dest, const char *__src, size_t max);
 extern int     strcmp(const char *__str1, const char *__str2);
 extern int     strncmp(const char *Str1, const char *Str2, size_t num);
 extern int     strucmp(const char *Str1, const char *Str2);
-extern char    *strdup(const char *Str);
+//extern char  *strdup(const char *Str);
+#define strdup(Str)    _strdup(_MODULE_NAME_"/"__FILE__, __LINE__, (Str))
+extern char    *_strdup(const char *File, int Line, const char *Str);
 extern char    **str_split(const char *__str, char __ch);
 extern int     strpos(const char *Str, char Ch);
 extern int     strpos8(const char *str, Uint32 search);
index 4f1fc66..c2f2e35 100644 (file)
@@ -104,6 +104,13 @@ typedef struct sVFS_Node
         *       this if needed
         */
        void    *Data;
+       
+       /**
+        * \brief Node mutex
+        * \note Provided for the Filesystem driver's use
+        */
+       tMutex  Lock;
+       
        /**
         * \}
         */
index 4fa226c..8a07ea7 100644 (file)
@@ -27,7 +27,7 @@ char  *strcpy(char *__str1, const char *__str2);
 char   *strncpy(char *__str1, const char *__str2, size_t max);
  int   strcmp(const char *str1, const char *str2);
  int   strncmp(const char *str1, const char *str2, size_t num);
-char   *strdup(const char *Str);
+char   *_strdup(const char *File, int Line, const char *Str);
 char   **str_split(const char *__str, char __ch);
  int   strpos8(const char *str, Uint32 Search);
  int   ReadUTF8(Uint8 *str, Uint32 *Val);
@@ -54,7 +54,8 @@ EXPORT(strcpy);
 EXPORT(strncpy);
 EXPORT(strcmp);
 EXPORT(strncmp);
-EXPORT(strdup);
+//EXPORT(strdup);
+EXPORT(_strdup);       // Takes File/Line too
 EXPORT(str_split);
 EXPORT(strpos8);
 EXPORT(DivUp);
@@ -451,6 +452,7 @@ int strncmp(const char *Str1, const char *Str2, size_t num)
        return *Str1-*Str2;
 }
 
+#if 0
 /**
  * \fn char *strdup(const char *Str)
  * \brief Duplicates a string
@@ -463,6 +465,20 @@ char *strdup(const char *Str)
        strcpy(ret, Str);
        return ret;
 }
+#endif
+
+/**
+ * \fn char *_strdup(const char *File, int Line, const char *Str)
+ * \brief Duplicates a string
+ */
+char *_strdup(const char *File, int Line, const char *Str)
+{
+       char    *ret;
+       ret = Heap_Allocate(File, Line, strlen(Str)+1);
+       if( !ret )      return NULL;
+       strcpy(ret, Str);
+       return ret;
+}
 
 /**
  * \brief Split a string using the passed character
index 7eab093..26b1961 100644 (file)
@@ -40,6 +40,7 @@
 typedef struct sFAT_LFNCacheEnt\r
 {\r
         int    ID;\r
+       // TODO: Handle UTF16 names correctly\r
        char    Data[256];\r
 }      tFAT_LFNCacheEnt;\r
 /**\r
@@ -920,6 +921,10 @@ char *FAT_int_CreateName(fat_filetable *ft, char *LongFileName)
        {\r
        #endif\r
                ret = (char*) malloc(13);\r
+               if( !ret ) {\r
+                       Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed");\r
+                       return NULL;\r
+               }\r
                FAT_int_ProperFilename(ret, ft->name);\r
        #if USE_LFN\r
        }\r
@@ -1099,12 +1104,7 @@ int FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry)
 }\r
 #endif\r
 \r
-#if USE_LFN\r
-// I should probably more tightly associate the LFN cache with the node\r
-// somehow, maybe by adding a field to tVFS_Node before locking it\r
-// Maybe .Cache or something like that (something that is free'd by the\r
-// Inode_UncacheNode function)\r
-       \r
+#if USE_LFN    \r
 /**\r
  * \fn char *FAT_int_GetLFN(tVFS_Node *node)\r
  * \brief Return pointer to LFN cache entry\r
@@ -1241,32 +1241,29 @@ char *FAT_ReadDir(tVFS_Node *Node, int ID)
        if(fileinfo[a].attrib == ATTR_LFN)\r
        {\r
                fat_longfilename        *lfnInfo;\r
-                int    len;\r
                \r
                lfnInfo = (fat_longfilename *) &fileinfo[a];\r
                \r
                // Get cache for corresponding file\r
+               // > ID + Index gets the corresponding short node\r
                lfn = FAT_int_GetLFN( Node, ID + (lfnInfo->id & 0x3F) );\r
                \r
                // Bit 6 indicates the start of an entry\r
                if(lfnInfo->id & 0x40)  memset(lfn, 0, 256);\r
                \r
-               // Get the current length\r
-               len = strlen(lfn);\r
+               a = (lfnInfo->id & 0x3F) * 13;\r
                \r
                // Sanity Check (FAT implementations should not allow >255 character names)\r
-               if(len + 13 > 255)      return VFS_SKIP;\r
-               // Rebase all bytes\r
-               for(a=len+1;a--;)       lfn[a+13] = lfn[a];\r
+               if(a > 255)     return VFS_SKIP;\r
                \r
                // Append new bytes\r
-               lfn[ 0] = lfnInfo->name1[0];    lfn[ 1] = lfnInfo->name1[1];\r
-               lfn[ 2] = lfnInfo->name1[2];    lfn[ 3] = lfnInfo->name1[3];\r
-               lfn[ 4] = lfnInfo->name1[4];    \r
-               lfn[ 5] = lfnInfo->name2[0];    lfn[ 6] = lfnInfo->name2[1];\r
-               lfn[ 7] = lfnInfo->name2[2];    lfn[ 8] = lfnInfo->name2[3];\r
-               lfn[ 9] = lfnInfo->name2[4];    lfn[10] = lfnInfo->name2[5];\r
-               lfn[11] = lfnInfo->name3[0];    lfn[12] = lfnInfo->name3[1];\r
+               lfn[a+ 0] = lfnInfo->name1[0];  lfn[a+ 1] = lfnInfo->name1[1];\r
+               lfn[a+ 2] = lfnInfo->name1[2];  lfn[a+ 3] = lfnInfo->name1[3];\r
+               lfn[a+ 4] = lfnInfo->name1[4];  \r
+               lfn[a+ 5] = lfnInfo->name2[0];  lfn[a+ 6] = lfnInfo->name2[1];\r
+               lfn[a+ 7] = lfnInfo->name2[2];  lfn[a+ 8] = lfnInfo->name2[3];\r
+               lfn[a+ 9] = lfnInfo->name2[4];  lfn[a+10] = lfnInfo->name2[5];\r
+               lfn[a+11] = lfnInfo->name3[0];  lfn[a+12] = lfnInfo->name3[1];\r
                LOG("lfn = '%s'", lfn);\r
                LEAVE('p', VFS_SKIP);\r
                return VFS_SKIP;\r
index 1a10e1c..750f2dc 100644 (file)
@@ -12,7 +12,7 @@ CFGFILES += $(shell test -f Makefile.cfg && echo Makefile.cfg)
 -include $(CFGFILES)
 
 CPPFLAGS := -I$(ACESSDIR)/Kernel/include -I$(ACESSDIR)/Kernel/arch/$(ARCHDIR)/include -DARCH=$(ARCH) $(_CPPFLAGS)
-CFLAGS = -Wall -Werror -fno-stack-protector $(CPPFLAGS) -g -O3 -fno-builtin
+CFLAGS := -Wall -Werror -fno-stack-protector -g -O3 -fno-builtin
 
 ifneq ($(CATEGORY),)
        FULLNAME := $(CATEGORY)_$(NAME)
@@ -64,7 +64,7 @@ endif
 
 %.o.$(_SUFFIX): %.c Makefile ../Makefile.tpl $(CFGFILES)
        @echo --- $(CC) -o $@
-       @$(CC) $(CFLAGS) -o $@ -c $<
+       @$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ -c $<
        @$(CC) -M $(CPPFLAGS) -MT $@ -o $*.d.$(ARCH) $<
 
 -include $(DEPFILES)

UCC git Repository :: git.ucc.asn.au