Big bugfixes from trying a Clone/fork bomb
authorJohn Hodge <[email protected]>
Sat, 12 Feb 2011 01:28:35 +0000 (09:28 +0800)
committerJohn Hodge <[email protected]>
Sat, 12 Feb 2011 01:28:35 +0000 (09:28 +0800)
- User heap bugfixes (why was I using sbrk?)
- Threads_Kill (handling non-active threads)
- Proc_Clone (Error handling from MM)
- MM_NewKStack (OOM handling)

14 files changed:
Kernel/Makefile.BuildNum.x86_64
Kernel/arch/x86/mm_virt.c
Kernel/arch/x86/proc.c
Kernel/binary.c
Kernel/include/threads.h
Kernel/threads.c
Modules/Display/VESA/main.c
Usermode/Applications/bomb_src/main.c
Usermode/Libraries/crt0.o_src/crt0.asm
Usermode/Libraries/ld-acess.so_src/core.asm
Usermode/Libraries/ld-acess.so_src/export.c
Usermode/Libraries/libc.so_src/heap.c
Usermode/Libraries/libspiderscript.so_src/lex.c
Usermode/Libraries/libspiderscript.so_src/parse.c

index 8882f38..a07f876 100644 (file)
@@ -660,14 +660,28 @@ tVAddr MM_NewKStack(void)
        Uint    i;
        for(base = KERNEL_STACKS; base < KERNEL_STACKS_END; base += KERNEL_STACK_SIZE)
        {
+               // Check if space is free
                if(MM_GetPhysAddr(base) != 0)   continue;
-               for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000) {
-                       MM_Allocate(base+i);
+               // Allocate
+               //for(i = KERNEL_STACK_SIZE; i -= 0x1000 ; )
+               for(i = 0; i < KERNEL_STACK_SIZE; i += 0x1000 )
+               {
+                       if( MM_Allocate(base+i) == 0 )
+                       {
+                               // On error, print a warning and return error
+                               Warning("MM_NewKStack - Out of memory");
+                               // - Clean up
+                               //for( i += 0x1000 ; i < KERNEL_STACK_SIZE; i += 0x1000 )
+                               //      MM_Deallocate(base+i);
+                               return 0;
+                       }
                }
+               // Success
                Log("MM_NewKStack - Allocated %p", base + KERNEL_STACK_SIZE);
                return base+KERNEL_STACK_SIZE;
        }
-       Warning("MM_NewKStack - No address space left\n");
+       // No stacks left
+       Warning("MM_NewKStack - No address space left");
        return 0;
 }
 
index d3c4ab4..4812609 100644 (file)
@@ -566,6 +566,11 @@ int Proc_Clone(Uint *Err, Uint Flags)
        // Initialise Memory Space (New Addr space or kernel stack)
        if(Flags & CLONE_VM) {
                newThread->MemState.CR3 = MM_Clone();
+               // Check for errors
+               if(newThread->MemState.CR3 == 0) {
+                       Threads_Kill(newThread, -2);
+                       return -1;
+               }
                newThread->KernelStack = cur->KernelStack;
        } else {
                Uint    tmpEbp, oldEsp = esp;
@@ -581,7 +586,7 @@ int Proc_Clone(Uint *Err, Uint Flags)
                newThread->KernelStack = MM_NewKStack();
                // Check for errors
                if(newThread->KernelStack == 0) {
-                       free(newThread);
+                       Threads_Kill(newThread, -2);
                        return -1;
                }
 
index aa5d954..fa49e85 100644 (file)
@@ -160,7 +160,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP)
        {
                Log_Warning("BIN", "Proc_Execve - Unable to load '%s'", Threads_GetName(-1));
                LEAVE('-');
-               Threads_Exit(0, 0);
+               Threads_Exit(0, -10);
                for(;;);
        }
        
index 6fbc11f..fc2303c 100644 (file)
@@ -113,6 +113,7 @@ extern tThread      *Proc_GetCurThread(void);
 extern tThread *Threads_GetThread(Uint TID);
 extern void    Threads_SetPriority(tThread *Thread, int Pri);
 extern int     Threads_Wake(tThread *Thread);
+extern void    Threads_Kill(tThread *Thread, int Status);
 extern void    Threads_AddActive(tThread *Thread);
 extern tThread *Threads_GetNextToRun(int CPU, tThread *Last);
 
index 8700154..5d15c92 100644 (file)
@@ -279,6 +279,7 @@ tThread *Threads_CloneTCB(Uint *Err, Uint Flags)
        SHORTLOCK( &glThreadListLock );
        new->GlobalPrev = NULL; // Protect against bugs
        new->GlobalNext = gAllThreads;
+       gAllThreads->GlobalPrev = new;
        gAllThreads = new;
        SHORTREL( &glThreadListLock );
        
@@ -466,15 +467,15 @@ void Threads_Kill(tThread *Thread, int Status)
        tMsg    *msg;
        
        // TODO: Kill all children
-       #if 0
+       #if 1
        {
                tThread *child;
                // TODO: I should keep a .Parent pointer, and a .Children list
-               for(child = gActiveThreads;
+               for(child = gAllThreads;
                        child;
-                       child = child->Next)
+                       child = child->GlobalNext)
                {
-                       if(child->PTID == Thread->TID)
+                       if(child->Parent == Thread)
                                Threads_Kill(child, -1);
                }
        }
@@ -496,29 +497,52 @@ void Threads_Kill(tThread *Thread, int Status)
        // Lock thread list
        SHORTLOCK( &glThreadListLock );
        
-       // Delete from active list
-       #if SCHEDULER_TYPE == SCHED_RR_PRI
-       if( !Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
-       #else
-       if( !Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
-       #endif
+       switch(Thread->Status)
        {
-               Warning("Proc_Exit - Current thread is not on the active queue");
-               SHORTREL( &glThreadListLock );
-               SHORTREL( &Thread->IsLocked );
-               return;
-       }
+       case THREAD_STAT_PREINIT:       // Only on main list
+               break;
        
-       // Ensure that we are not rescheduled
-       Thread->Remaining = 0;  // Clear Remaining Quantum
-       Thread->Quantum = 0;    // Clear Quantum to indicate dead thread
-       
-       // Update bookkeeping
-       giNumActiveThreads --;
-       #if SCHEDULER_TYPE == SCHED_LOTTERY
-       if( Thread != Proc_GetCurThread() )
-               giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
-       #endif
+       // Currently active thread
+       case THREAD_STAT_ACTIVE:
+               #if SCHEDULER_TYPE == SCHED_RR_PRI
+               if( Threads_int_DelFromQueue( &gaActiveThreads[Thread->Priority], Thread ) )
+               #else
+               if( Threads_int_DelFromQueue( &gActiveThreads, Thread ) )
+               #endif
+               {
+                       // Ensure that we are not rescheduled
+                       Thread->Remaining = 0;  // Clear Remaining Quantum
+                       Thread->Quantum = 0;    // Clear Quantum to indicate dead thread
+                       
+                       // Update bookkeeping
+                       giNumActiveThreads --;
+                       #if SCHEDULER_TYPE == SCHED_LOTTERY
+                       if( Thread != Proc_GetCurThread() )
+                               giFreeTickets -= caiTICKET_COUNTS[ Thread->Priority ];
+                       #endif
+               }
+               else
+               {
+                       Log_Warning("Threads",
+                               "Threads_Kill - Thread %p(%i,%s) marked as active, but not on list",
+                               Thread, Thread->TID, Thread->ThreadName
+                               );
+               }
+               break;
+       case THREAD_STAT_SLEEPING:
+               if( !Threads_int_DelFromQueue( &gSleepingThreads, Thread ) )
+               {
+                       Log_Warning("Threads",
+                               "Threads_Kill - Thread %p(%i,%s) marked as sleeping, but not on list",
+                               Thread, Thread->TID, Thread->ThreadName
+                               );
+               }
+               break;
+       default:
+               Log_Warning("Threads", "Threads_Kill - BUG Un-checked status (%i)",
+                       Thread->Status);
+               break;
+       }
        
        // Save exit status
        Thread->RetStatus = Status;
@@ -534,7 +558,7 @@ void Threads_Kill(tThread *Thread, int Status)
                Threads_Wake( Thread->Parent );
        }
        
-       Log("Thread %i went *hurk* (%i)", Thread->TID, Thread->Status);
+       Log("Thread %i went *hurk* (%i)", Thread->TID, Status);
        
        // Release spinlocks
        SHORTREL( &glThreadListLock );
@@ -915,7 +939,9 @@ tThread *Threads_GetNextToRun(int CPU, tThread *Last)
        while(gDeleteThreads)
        {
                thread = gDeleteThreads->Next;
-               if( IS_LOCKED(&gDeleteThreads->IsLocked) ) {    // Only free if structure is unused
+               // Only free if structure is unused
+               if( !IS_LOCKED(&gDeleteThreads->IsLocked) )
+               {
                        // Set to dead
                        gDeleteThreads->Status = THREAD_STAT_BURIED;
                        // Free name
index 479be30..1cd6a91 100644 (file)
@@ -2,7 +2,7 @@
  * AcessOS 1\r
  * Video BIOS Extensions (Vesa) Driver\r
  */\r
-#define DEBUG  1\r
+#define DEBUG  0\r
 #define VERSION        0x100\r
 \r
 #include <acess.h>\r
@@ -474,10 +474,19 @@ int Vesa_Int_FindMode(tVideo_IOCtl_Mode *data)
                        break;\r
                }\r
                \r
-               tmp = gVesa_Modes[i].width * gVesa_Modes[i].height * gVesa_Modes[i].bpp;\r
-               tmp -= data->width * data->height * data->bpp;\r
+               tmp = gVesa_Modes[i].width * gVesa_Modes[i].height;\r
+               tmp -= data->width * data->height;\r
                tmp = tmp < 0 ? -tmp : tmp;\r
-               factor = tmp * 100 / (data->width * data->height * data->bpp);\r
+               factor = tmp * 100 / (data->width * data->height);\r
+               \r
+               if( (data->bpp == 32 || data->bpp == 24)\r
+                && (gVesa_Modes[i].bpp == 32 || gVesa_Modes[i].bpp == 24) )\r
+               {\r
+                       \r
+               }\r
+               else {\r
+                       factor *= 10;\r
+               }\r
                \r
                LOG("factor = %i", factor);\r
                \r
index d792322..944d6c3 100644 (file)
@@ -46,8 +46,30 @@ int main(int argc, char *argv[])
                for(;;) clone(CLONE_VM, 0);
        }
        else {
-               for(;;) clone(0, malloc(512-16)+512-16);
+               for(;;)
+               {
+                       const int stackSize = 512-16; 
+                       const int stackOffset = 65; 
+                       char *stack = calloc(1, stackSize);
+                        int    tid;
+                       if( !stack ) {
+                               printf("Outta heap space!\n");
+                               return 0;
+                       }
+                       tid = clone(0, stack+stackSize-stackOffset);
+                       if( tid == 0 )
+                       {
+                               // Sleep forever (TODO: Fix up the stack so it can nuke)
+                               for(;;) sleep();
+                       }
+                       if( tid < 0 ) {
+                               printf("Clone failed\n");
+                               return 0;
+                       }
+                       printf("stack = %p, tid = %i\n", stack, tid);
+               }
        }
 
+       printf("RETURN!?\n");
        return 0;
 }
index b923d18..b8f5270 100644 (file)
@@ -15,5 +15,5 @@ _start:
 start:
        call main
        push eax
-       call _exit      
+       call _exit
        jmp $   ; This should never be reached
index c44dc53..0bf80c1 100644 (file)
@@ -10,9 +10,76 @@ _errno:
        dd      0
 
 [section .text]
-; --- Process Controll ---
+; DEST
+; SRC
+_memcpy:
+       push ebp
+       mov ebp, esp
+       push edi
+       push esi        ; DI and SI must be maintained, CX doesn't
+       
+       mov ecx, [ebp+16]
+       mov esi, [ebp+12]
+       mov edi, [ebp+8]
+       rep movsb
+       
+       pop esi
+       pop edi
+       pop ebp
+       ret
+
+; --- Process Control ---
 SYSCALL1       _exit, SYS_EXIT
+
+%if 0
 SYSCALL2       clone, SYS_CLONE
+%else
+[global clone:func]
+clone:
+       push ebp
+       mov ebp, esp
+       push ebx
+       
+       mov ebx, [ebp+12]       ; Get new stack pointer
+       
+       ; Check if the new stack is being used
+       test ebx, ebx
+       jz .doCall
+       ; Modify it to include the calling function (and this)
+       %if 0
+       mov eax, [ebp]  ; Get old stack frame
+       sub eax, ebp    ; Get size
+       sub ebx, eax    ; Alter new stack pointer
+       push eax        ; < Size
+       push DWORD [ebp]        ; < Source
+       push ebx        ; < Dest
+       call _memcpy
+       add esp, 4*3    ; Restore stack
+       ; EBX should still be the new stack pointer
+       mov eax, [ebp]  ; Save old stack frame pointer in new stack
+       mov [ebx-4], eax
+       mov eax, [ebp-4]        ; Save EBX there too
+       mov [ebx-8], eax
+       sub ebx, 8      ; Update stack pointer for system
+       %else
+       ; Quick hack, just this stack frame
+       mov eax, [ebp+4]
+       mov [ebx-4], eax        ; Return
+       mov [ebx-8], ebx        ; EBP
+       mov DWORD [ebx-12], 0   ; EBX
+       sub ebx, 12
+       %endif
+.doCall:
+       mov eax, SYS_CLONE
+       mov ecx, ebx    ; Stack
+       mov ebx, [ebp+8]        ; Flags
+       SYSCALL_OP
+       mov [_errno], ebx
+       pop ebx
+       pop ebp
+       ret
+%endif
+
 SYSCALL2       kill, SYS_KILL
 SYSCALL0       yield, SYS_YIELD
 SYSCALL0       sleep, SYS_SLEEP
index 867e17f..9aa47e6 100644 (file)
@@ -60,7 +60,8 @@ const struct {
        EXP(_SysOpenChild),
        
        EXP(_SysGetPhys),
-       EXP(_SysAllocate)
+       EXP(_SysAllocate),
+       EXP(_SysDebug)
 
 };
 
index d049070..14066e9 100644 (file)
@@ -36,6 +36,7 @@ EXPORT void   free(void *mem);
 EXPORT void    *realloc(void *mem, Uint bytes);\r
 EXPORT void    *sbrk(int increment);\r
 LOCAL void     *extendHeap(int bytes);\r
+static void *FindHeapBase();\r
 LOCAL uint     brk(Uint newpos);\r
 \r
 //Code\r
@@ -68,7 +69,7 @@ EXPORT void *malloc(size_t bytes)
        \r
        while((Uint)curBlock < (Uint)_heap_end)\r
        {\r
-               //SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);\r
+               //_SysDebug(" malloc: curBlock = 0x%x, curBlock->magic = 0x%x\n", curBlock, curBlock->magic);\r
                if(curBlock->magic == MAGIC_FREE)\r
                {\r
                        if(curBlock->size == bestSize)\r
@@ -81,14 +82,14 @@ EXPORT void *malloc(size_t bytes)
                else if(curBlock->magic != MAGIC)\r
                {\r
                        //Corrupt Heap\r
-                       //SysDebug("malloc: Corrupt Heap\n");\r
+                       _SysDebug("malloc: Corrupt Heap\n");\r
                        return NULL;\r
                }\r
                curBlock = (heap_head*)((Uint)curBlock + curBlock->size);\r
        }\r
        \r
        if((Uint)curBlock < (Uint)_heap_start) {\r
-               //SysDebug("malloc: Heap underrun for some reason\n");\r
+               _SysDebug("malloc: Heap underrun for some reason\n");\r
                return NULL;\r
        }\r
        \r
@@ -102,7 +103,7 @@ EXPORT void *malloc(size_t bytes)
        if(!closestMatch) {\r
                curBlock = extendHeap(bestSize);        //Allocate more\r
                if(curBlock == NULL) {\r
-                       //SysDebug("malloc: Out of Heap Space\n");\r
+                       _SysDebug("malloc: Out of Heap Space\n");\r
                        return NULL;\r
                }\r
                curBlock->magic = MAGIC;\r
@@ -243,7 +244,6 @@ LOCAL void *extendHeap(int bytes)
        if(foot == (void*)-1)\r
                return NULL;\r
        \r
-       \r
        //Create New Block\r
        // Header\r
        head->magic = MAGIC_FREE;       //Unallocated\r
@@ -275,24 +275,52 @@ LOCAL void *extendHeap(int bytes)
 */\r
 EXPORT void *sbrk(int increment)\r
 {\r
-       size_t newEnd;\r
        static size_t oldEnd = 0;\r
        static size_t curEnd = 0;\r
 \r
-       //_SysDebug("sbrk: (increment=%i)\n", increment);\r
+       //_SysDebug("sbrk: (increment=%i)", increment);\r
 \r
-       if (oldEnd == 0)        curEnd = oldEnd = brk(0);\r
+       if (curEnd == 0) {\r
+               oldEnd = curEnd = (size_t)FindHeapBase();\r
+               //_SysAllocate(curEnd); // Allocate the first page\r
+       }\r
 \r
-       //SysDebug(" sbrk: oldEnd = 0x%x\n", oldEnd);\r
+       //_SysDebug(" sbrk: oldEnd = 0x%x", oldEnd);\r
        if (increment == 0)     return (void *) curEnd;\r
 \r
-       newEnd = curEnd + increment;\r
-\r
-       if (brk(newEnd) == curEnd)      return (void *) -1;\r
        oldEnd = curEnd;\r
-       curEnd = newEnd;\r
-       //SysDebug(" sbrk: newEnd = 0x%x\n", newEnd);\r
 \r
+       // Single Page\r
+       if( (curEnd & 0xFFF) && (curEnd & 0xFFF) + increment < 0x1000 )\r
+       {\r
+               //if( curEnd & 0xFFF == 0 )\r
+               //{\r
+               //      if( !_SysAllocate(curEnd) )\r
+               //      {\r
+               //              _SysDebug("sbrk - Error allocating memory");\r
+               //              return (void*)-1;\r
+               //      }\r
+               //}\r
+               curEnd += increment;\r
+               //_SysDebug("sbrk: RETURN %p (single page, no alloc)", (void *) oldEnd);\r
+               return (void *)oldEnd;\r
+       }\r
+\r
+       increment -= curEnd & 0xFFF;\r
+       curEnd += 0xFFF;        curEnd &= ~0xFFF;\r
+       while( increment > 0 )\r
+       {\r
+               if( !_SysAllocate(curEnd) )\r
+               {\r
+                       // Error?\r
+                       _SysDebug("sbrk - Error allocating memory");\r
+                       return (void*)-1;\r
+               }\r
+               increment -= 0x1000;\r
+               curEnd += 0x1000;\r
+       }\r
+\r
+       //_SysDebug("sbrk: RETURN %p", (void *) oldEnd);\r
        return (void *) oldEnd;\r
 }\r
 \r
@@ -364,7 +392,7 @@ LOCAL uint brk(Uint newpos)
        uint    ret = curpos;\r
         int    delta;\r
        \r
-       //_SysDebug("brk: (newpos=0x%x)", newpos);\r
+       _SysDebug("brk: (newpos=0x%x)", newpos);\r
        \r
        // Find initial position\r
        if(curpos == 0) curpos = (uint)FindHeapBase();\r
@@ -375,7 +403,7 @@ LOCAL uint brk(Uint newpos)
        if(newpos < curpos)     return newpos;\r
        \r
        delta = newpos - curpos;\r
-       //_SysDebug(" brk: delta = 0x%x", delta);\r
+       _SysDebug(" brk: delta = 0x%x", delta);\r
        \r
        // Do we need to add pages\r
        if(curpos & 0xFFF && (curpos & 0xFFF) + delta < 0x1000)\r
index 7121ce1..fd395e0 100644 (file)
@@ -7,6 +7,8 @@
 #include <stdio.h>
 #include <string.h>
 
+// Make the scope character ('.') be a symbol, otherwise it's just
+// a ident character
 #define USE_SCOPE_CHAR 0
 
 #define DEBUG  0
index f32f876..0b48198 100644 (file)
@@ -201,7 +201,6 @@ tAST_Node *Parse_DoBlockLine(tParser *Parser)
        
        // Return from a method
        case TOK_RWD_RETURN:
-               //printf("return\n");
                GetToken(Parser);
                ret = AST_NewUniOp(Parser, NODETYPE_RETURN, Parse_DoExpr0(Parser));
                break;
@@ -662,11 +661,11 @@ tAST_Node *Parse_GetVariable(tParser *Parser)
 }
 
 /**
- * \brief Get an identifier (constand or function call)
+ * \brief Get an identifier (constant or function call)
  */
 tAST_Node *Parse_GetIdent(tParser *Parser)
 {
-       tAST_Node       *ret;
+       tAST_Node       *ret = NULL;
        char    *name;
        SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
        name = strndup( Parser->TokenStr, Parser->TokenLen );
@@ -674,7 +673,9 @@ tAST_Node *Parse_GetIdent(tParser *Parser)
        #if 0
        while( GetToken(Parser) == TOK_SCOPE )
        {
-               ret = AST_New
+               ret = AST_NewScopeDereference( Parser, ret, name );
+               SyntaxAssert(Parser, GetToken(Parser), TOK_IDENT );
+               name = strndup( Parser->TokenStr, Parser->TokenLen );
        }
        PutBack(Parser);
        #endif
@@ -703,7 +704,7 @@ tAST_Node *Parse_GetIdent(tParser *Parser)
                }
        }
        else {
-               // Runtime Constant
+               // Runtime Constant / Variable (When implemented)
                #if DEBUG >= 2
                printf("Parse_GetIdent: Referencing '%s'\n", name);
                #endif

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