From 599466207eaeee9cb2bf397a7a62d0455599d05c Mon Sep 17 00:00:00 2001
From: John Hodge <tpg@mutabah.net>
Date: Tue, 19 Oct 2010 15:21:05 +0800
Subject: [PATCH] Buglocating: Some random corruption in VFS, FDD lockups

- FDD driver likes to lock
- Also working on a kernel-level debugger
---
 Kernel/drv/kb.c                        | 20 ++++++++++++++----
 Kernel/include/threads.h               |  5 +++--
 Kernel/threads.c                       | 28 ++++++++++++++++++++++++--
 Kernel/vfs/open.c                      | 17 +++++++---------
 Modules/Filesystems/FAT/fat.c          |  2 +-
 Usermode/Applications/login_src/main.c |  2 +-
 6 files changed, 54 insertions(+), 20 deletions(-)

diff --git a/Kernel/drv/kb.c b/Kernel/drv/kb.c
index 923a58fc..07e07f5d 100644
--- a/Kernel/drv/kb.c
+++ b/Kernel/drv/kb.c
@@ -45,6 +45,8 @@ Uint8	gbaKB_States[3][256];
  int	giKB_KeyLayer = 0;
 #if USE_KERNEL_MAGIC
  int	gbKB_MagicState = 0;
+ int	giKB_MagicAddress = 0;
+ int	giKB_MagicAddressPos = 0;
 #endif
 //Uint64	giKB_ReadBase = 0;
 //Uint32	gaKB_Buffer[KB_BUFFER_SIZE];	//!< Keyboard Ring Buffer
@@ -184,14 +186,24 @@ void KB_IRQHandler(int IRQNum)
 	{
 		switch(ch)
 		{
-		// Kernel Panic (Page Fault)
-		case 'q':	*((int*)1) = 0;	return;
-		// Bochs Magic Breakpoint
-		case 'd':	__asm__ __volatile__ ("xchg %bx, %bx");	return;
+		case '0':	case '1':	case '2':	case '3':
+		case '4':	case '5':	case '6':	case '7':
+		case '8':	case '9':	case 'a':	case 'b':
+		case 'c':	case 'd':	case 'e':	case 'f':
+			{
+			char	str[2] = {ch,0};
+			if(giKB_MagicAddressPos == BITS/4)	break;
+			giKB_MagicAddress |= atoi(str) << giKB_MagicAddressPos;
+			giKB_MagicAddressPos ++;
+			}
+			break;
+		
 		// Thread List Dump
 		case 'p':	Threads_Dump();	return;
 		// Heap Statistics
 		case 'h':	Heap_Stats();	return;
+		// Dump Structure
+		case 's':	return;
 		}
 	}
 	#endif
diff --git a/Kernel/include/threads.h b/Kernel/include/threads.h
index 0af38a51..833a3c77 100644
--- a/Kernel/include/threads.h
+++ b/Kernel/include/threads.h
@@ -34,6 +34,7 @@ typedef struct sThread
 	struct sThread	*GlobalPrev;	//!< Previous thread in global list
 	tShortSpinlock	IsLocked;	//!< Thread's spinlock
 	volatile int	Status;		//!< Thread Status
+	void	*WaitPointer;	//!< What (Mutex/Thread/other) is the thread waiting on
 	 int	RetStatus;	//!< Return Status
 	
 	Uint	TID;	//!< Thread ID
@@ -72,8 +73,8 @@ enum {
 	THREAD_STAT_NULL,	// Invalid process
 	THREAD_STAT_ACTIVE,	// Running and schedulable process
 	THREAD_STAT_SLEEPING,	// Message Sleep
-	THREAD_STAT_OFFSLEEP,	// Mutex Sleep (or waiting on a thread)
-	THREAD_STAT_WAITING,	// ???
+	THREAD_STAT_MUTEXSLEEP,	// Mutex Sleep
+	THREAD_STAT_WAITING,	// ??? (Waiting for a thread)
 	THREAD_STAT_PREINIT,	// Being created
 	THREAD_STAT_ZOMBIE,	// Died, just not removed
 	THREAD_STAT_DEAD	// Why do we care about these???
diff --git a/Kernel/threads.c b/Kernel/threads.c
index 325fa74e..b1a2a613 100644
--- a/Kernel/threads.c
+++ b/Kernel/threads.c
@@ -710,6 +710,7 @@ tThread *Threads_RemActive(void)
 		return NULL;
 	}
 	
+	ret->Next = NULL;
 	ret->Remaining = 0;
 	ret->CurCPU = -1;
 	
@@ -865,6 +866,16 @@ void Threads_Dump(void)
 		Log(" %i (%i) - %s (CPU %i)",
 			thread->TID, thread->TGID, thread->ThreadName, thread->CurCPU);
 		Log("  State %i", thread->Status);
+		switch(thread->Status)
+		{
+		case THREAD_STAT_MUTEXSLEEP:
+			Log("  Mutex Pointer: %p", thread->WaitPointer);
+			break;
+		case THREAD_STAT_ZOMBIE:
+			Log("  Return Status: %i", thread->RetStatus);
+			break;
+		default:	break;
+		}
 		Log("  Priority %i, Quantum %i", thread->Priority, thread->Quantum);
 		Log("  KStack 0x%x", thread->KernelStack);
 	}
@@ -1121,8 +1132,10 @@ void Mutex_Acquire(tMutex *Mutex)
 		SHORTLOCK( &glThreadListLock );
 		// - Remove from active list
 		us = Threads_RemActive();
+		us->Next = NULL;
 		// - Mark as sleeping
-		us->Status = THREAD_STAT_OFFSLEEP;
+		us->Status = THREAD_STAT_MUTEXSLEEP;
+		us->WaitPointer = Mutex;
 		
 		// - Add to waiting
 		if(Mutex->LastWaiting) {
@@ -1133,10 +1146,21 @@ void Mutex_Acquire(tMutex *Mutex)
 			Mutex->Waiting = us;
 			Mutex->LastWaiting = us;
 		}
+		#if 1
+		{
+			 int	i = 0;
+			tThread	*t;
+			for( t = Mutex->Waiting; t; t = t->Next, i++ )
+				Log("[%i] (tMutex)%p->Waiting[%i] = %p (%i %s)", us->TID, Mutex, i,
+					t, t->TID, t->ThreadName);
+		}
+		#endif
+		
 		SHORTREL( &glThreadListLock );
 		SHORTREL( &Mutex->Protector );
-		while(us->Status == THREAD_STAT_OFFSLEEP)	Threads_Yield();
+		while(us->Status == THREAD_STAT_MUTEXSLEEP)	Threads_Yield();
 		// We're only woken when we get the lock
+		us->WaitPointer = NULL;
 	}
 	// Ooh, let's take it!
 	else {
diff --git a/Kernel/vfs/open.c b/Kernel/vfs/open.c
index 40c1d39b..32d6e4d9 100644
--- a/Kernel/vfs/open.c
+++ b/Kernel/vfs/open.c
@@ -1,8 +1,8 @@
 /*
- * AcessMicro VFS
+ * Acess2 VFS
  * - Open, Close and ChDir
  */
-#define DEBUG	0
+#define DEBUG	1
 #include <acess.h>
 #include <mm_virt.h>
 #include "vfs.h"
@@ -237,12 +237,6 @@ tVFS_Node *VFS_ParsePath(const char *Path, char **TruePath)
 		longestMount = mnt;
 	}
 	
-	// Sanity Check
-	/*if(!longestMount) {
-		Log("VFS_ParsePath - ERROR: No Root Node\n");
-		return NULL;
-	}*/
-	
 	// Save to shorter variable
 	mnt = longestMount;
 	
@@ -294,11 +288,14 @@ tVFS_Node *VFS_ParsePath(const char *Path, char **TruePath)
 			LEAVE('n');
 			return NULL;
 		}
-		LOG("FindDir(%p, '%s')", curNode, pathEle);
+		LOG("FindDir{=%p}(%p, '%s')", curNode->FindDir, curNode, pathEle);
 		// Get Child Node
 		tmpNode = curNode->FindDir(curNode, pathEle);
 		LOG("tmpNode = %p", tmpNode);
-		if(curNode->Close)	curNode->Close(curNode);
+		if(curNode->Close) {
+			//LOG2("curNode->Close = %p", curNode->Close);
+			curNode->Close(curNode);
+		}
 		curNode = tmpNode;
 		
 		// Error Check
diff --git a/Modules/Filesystems/FAT/fat.c b/Modules/Filesystems/FAT/fat.c
index a88ffb5f..a63bac01 100644
--- a/Modules/Filesystems/FAT/fat.c
+++ b/Modules/Filesystems/FAT/fat.c
@@ -17,7 +17,7 @@
  * \todo Implement changing of the parent directory when a file is written to
  * \todo Implement file creation / deletion
  */
-#define DEBUG	0
+#define DEBUG	1
 #define VERBOSE	1
 
 #define CACHE_FAT	0	//!< Caches the FAT in memory
diff --git a/Usermode/Applications/login_src/main.c b/Usermode/Applications/login_src/main.c
index 2bafe3b2..8774298a 100644
--- a/Usermode/Applications/login_src/main.c
+++ b/Usermode/Applications/login_src/main.c
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
 			sPassword = GetPassword();
 			if( (uid = ValidateUser(sUsername, sPassword)) == -1 )
 			{
-				printf("\nInvalid username or password for '%s'\n", sUsername);
+				printf("\nInvalid username or password\n");
 				free(sUsername);
 				free(sPassword);
 			}
-- 
GitLab