00001 // debug.h 00002 // Data structures for debugging routines. 00003 // 00004 // The debugging routines allow the user to turn on selected 00005 // debugging messages, controllable from the command line arguments 00006 // passed to Nachos (-d). You are encouraged to add your own 00007 // debugging flags. Please.... 00008 // 00009 // Copyright (c) 1992-1996 The Regents of the University of California. 00010 // All rights reserved. See copyright.h for copyright notice and limitation 00011 // of liability and disclaimer of warranty provisions. 00012 00013 #ifndef DEBUG_H 00014 #define DEBUG_H 00015 00016 #include "copyright.h" 00017 #include "utility.h" 00018 #include "sysdep.h" 00019 00020 // The pre-defined debugging flags are: 00021 00022 const char dbgAll = '+'; // turn on all debug messages 00023 const char dbgThread = 't'; // threads 00024 const char dbgSynch = 's'; // locks, semaphores, condition vars 00025 const char dbgInt = 'i'; // interrupt emulation 00026 const char dbgMach = 'm'; // machine emulation 00027 const char dbgDisk = 'd'; // disk emulation 00028 const char dbgFile = 'f'; // file system 00029 const char dbgAddr = 'a'; // address spaces 00030 const char dbgNet = 'n'; // network emulation 00031 const char dbgSys = 'u'; // systemcall 00032 00033 class Debug { 00034 public: 00035 Debug(char *flagList); 00036 00037 bool IsEnabled(char flag); 00038 00039 private: 00040 char *enableFlags; // controls which DEBUG messages are printed 00041 }; 00042 00043 extern Debug *debug; 00044 00045 00046 //---------------------------------------------------------------------- 00047 // DEBUG 00048 // If flag is enabled, print a message. 00049 //---------------------------------------------------------------------- 00050 #define DEBUG(flag,expr) \ 00051 if (!debug->IsEnabled(flag)) {} else { \ 00052 cerr << expr << "\n"; \ 00053 } 00054 00055 00056 //---------------------------------------------------------------------- 00057 // ASSERT 00058 // If condition is false, print a message and dump core. 00059 // Useful for documenting assumptions in the code. 00060 // 00061 // NOTE: needs to be a #define, to be able to print the location 00062 // where the error occurred. 00063 //---------------------------------------------------------------------- 00064 #define ASSERT(condition) \ 00065 if (condition) {} else { \ 00066 cerr << "Assertion failed: line " << __LINE__ << " file " << __FILE__ << "\n"; \ 00067 Abort(); \ 00068 } 00069 00070 //---------------------------------------------------------------------- 00071 // ASSERTNOTREACHED 00072 // Print a message and dump core (equivalent to ASSERT(FALSE) without 00073 // making the compiler whine). Useful for documenting when 00074 // code should not be reached. 00075 // 00076 // NOTE: needs to be a #define, to be able to print the location 00077 // where the error occurred. 00078 //---------------------------------------------------------------------- 00079 00080 #define ASSERTNOTREACHED() \ 00081 { \ 00082 cerr << "Assertion failed: line " << __LINE__ << " file " << __FILE__ << "\n"; \ 00083 Abort(); \ 00084 } 00085 00086 //---------------------------------------------------------------------- 00087 // ASSERTUNIMPLEMENTED 00088 // Print a message that unimplemented code is executed and dump core 00089 //---------------------------------------------------------------------- 00090 #define UNIMPLEMENTED() \ 00091 { \ 00092 cerr << "Reached UNIMPLEMENTED function " << __FUNCTION__ << " in file: " \ 00093 << __FILE__ << " line: " << __LINE__ << ".\n"; \ 00094 } 00095 00096 #endif // DEBUG_H