Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ktrace.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Module Name: 00004 00005 ktrace.c 00006 00007 Abstract: 00008 00009 This module implements a tracing facility for use by all kernel mode 00010 modules in Windows NT. 00011 00012 Author: 00013 00014 Roy D'Souza (rdsouza@gomez) 22-May-1996 00015 00016 Environment: 00017 00018 User or Kernel mode. 00019 00020 Revision History: 00021 00022 --*/ 00023 00024 #include "ki.h" 00025 #if DBG && IA64_KTRACE 00026 00027 #include "ktrace.h" 00028 #include "ktracep.h" 00029 00030 00031 /*********************************************************************** 00032 Format of KTrace record (144 bytes) 00033 ***********************************************************************/ 00034 typedef struct _KTRACE_RECORD_ { 00035 ULONG ModuleID; 00036 USHORT MessageType; 00037 USHORT MessageIndex; 00038 LARGE_INTEGER SystemTime; 00039 ULONGLONG Arg1; 00040 ULONGLONG Arg2; 00041 ULONGLONG Arg3; 00042 ULONGLONG Arg4; 00043 ULONGLONG Arg5; 00044 LARGE_INTEGER HiResTimeStamp; 00045 } KTRACE_RECORD, *PKTRACE_RECORD; 00046 00047 /* IF YOU MAKE ANY CHANGE TO THE ABOVE TYPEDEF YOU 00048 ALSO NEED TO UPDATE THE CONSTANT RECORD_SIZE_IN_BYTES 00049 IN FILE KTRACEP.H, SO THAT THE SIMDB MACROS WILL CONTINUE 00050 TO WORK CORRECTLY 00051 */ 00052 00053 /*********************************************************************** 00054 KTrace Private Data 00055 ***********************************************************************/ 00056 00057 00058 KTRACE_RECORD KTrace[MAXIMUM_PROCESSORS][KTRACE_LOG_SIZE]; 00059 00060 // 00061 // Current queue head 00062 // 00063 static ULONG KTraceQueueHead = 0; 00064 00065 // 00066 // By default the mask is on for all: 00067 // 00068 static ULONG ModuleIDMask = 0xFFFFFFFF; 00069 00070 /*********************************************************************** 00071 KeEnableKTrace - selectively enable/disable client's rights to trace 00072 ***********************************************************************/ 00073 VOID 00074 NTAPI 00075 KeEnableKTrace ( 00076 ULONG IDMask 00077 ) 00078 /*++ 00079 00080 Routine Description: 00081 00082 Selectively enable or disable individual module's abilities to 00083 write to the KTrace. 00084 00085 By default all modules are permitted to write traces. 00086 00087 Any kernel mode modules can call this routine to toggle write 00088 write permissions. 00089 00090 Arguments: 00091 00092 IDMask 00093 00094 A bit pattern which specifies the modules that are to be enabled. 00095 00096 Return Value: 00097 00098 None. 00099 00100 --*/ 00101 00102 { 00103 ModuleIDMask = IDMask; 00104 00105 return; 00106 00107 } // KeEnableKTrace 00108 00109 /*********************************************************************** 00110 CurrentKTraceEntry -- return address of current entry and update trace index 00111 ***********************************************************************/ 00112 PKTRACE_RECORD CurrentEntry = 0; 00113 00114 PKTRACE_RECORD 00115 NTAPI 00116 KiCurrentKTraceEntry ( 00117 ) 00118 /*++ 00119 00120 Routine Description: 00121 00122 Provide pointer to next trace entry for use by assembly code that updates trace 00123 table. 00124 00125 Arguments: 00126 00127 None. 00128 00129 Return Value: 00130 00131 Pointer to next entry. 00132 00133 --*/ 00134 { 00135 ULONG CurrentProcessor; 00136 00137 CurrentProcessor = KeGetCurrentProcessorNumber(); 00138 if (CurrentProcessor > MAXIMUM_PROCESSORS) { 00139 DbgPrint("KTrace:CurrentKTraceEntry:KeGetCurrentProcessorNumber invalid\n"); 00140 return NULL; 00141 } 00142 00143 CurrentEntry = &KTrace[CurrentProcessor][KTraceQueueHead]; 00144 KTraceQueueHead = (KTraceQueueHead + 1) % KTRACE_LOG_SIZE; 00145 00146 return CurrentEntry; 00147 00148 } // CurrentKTraceEntry 00149 00150 /*********************************************************************** 00151 AddTrace - add an entry into the trace. 00152 ***********************************************************************/ 00153 00154 NTSTATUS 00155 NTAPI 00156 KeAddKTrace ( 00157 ULONG ModuleID, 00158 USHORT MessageType, 00159 USHORT MessageIndex, 00160 ULONGLONG Arg1, 00161 ULONGLONG Arg2, 00162 ULONGLONG Arg3, 00163 ULONGLONG Arg4 00164 ) 00165 /*++ 00166 00167 Routine Description: 00168 00169 Add a record to the KTrace log. Can be called by anybody in the 00170 kernel. (Need to figure out a way to export this through ntoskrnl.lib 00171 so that drivers can access it.) 00172 00173 Arguments: 00174 00175 ModuleID identifies the client making this call. See ktrace.h 00176 for definitions. 00177 00178 MessageType specifies the type/severity of the message (i.e. warning, 00179 error, checkpoint...) See ktrace.h 00180 00181 Arg1-4 for unrestricted use by the client. 00182 00183 Return Value: 00184 00185 Status 00186 00187 STATUS_SUCCESS if successful. 00188 STATUS_UNSUCCESSFUL if failure. 00189 --*/ 00190 { 00191 ULONG CurrentProcessor; 00192 LARGE_INTEGER PerfCtr; 00193 NTSTATUS Status = STATUS_SUCCESS; 00194 LARGE_INTEGER SystemTime; 00195 00196 if (!(ModuleID & ModuleIDMask)) 00197 return STATUS_UNSUCCESSFUL; 00198 00199 CurrentProcessor = KeGetCurrentProcessorNumber(); 00200 if (CurrentProcessor > MAXIMUM_PROCESSORS) { 00201 DbgPrint("KTrace:AddTrace:KeGetCurrentProcessorNumber invalid\n"); 00202 return STATUS_UNSUCCESSFUL; 00203 } 00204 00205 KTrace[CurrentProcessor][KTraceQueueHead].ModuleID = ModuleID; 00206 KTrace[CurrentProcessor][KTraceQueueHead].MessageType = MessageType; 00207 KTrace[CurrentProcessor][KTraceQueueHead].MessageIndex = MessageIndex; 00208 KTrace[CurrentProcessor][KTraceQueueHead].Arg1 = Arg1; 00209 KTrace[CurrentProcessor][KTraceQueueHead].Arg2 = Arg2; 00210 KTrace[CurrentProcessor][KTraceQueueHead].Arg3 = Arg3; 00211 KTrace[CurrentProcessor][KTraceQueueHead].Arg4 = Arg4; 00212 00213 KeQuerySystemTime(&SystemTime); 00214 KTrace[CurrentProcessor][KTraceQueueHead].SystemTime = SystemTime; 00215 #if 0 00216 Status = NtQueryPerformanceCounter(&PerfCtr, NULL); 00217 if (!NT_SUCCESS(Status)) { 00218 DbgPrint("NtQueryPerformanceCounter failed with %x\n", Status); 00219 return Status; 00220 } 00221 00222 KTrace[CurrentProcessor][KTraceQueueHead].HiResTimeStamp = PerfCtr; 00223 #endif 00224 KTraceQueueHead = (KTraceQueueHead + 1) % KTRACE_LOG_SIZE; 00225 00226 return Status; 00227 00228 } // AddTrace 00229 00230 /*********************************************************************** 00231 QueryDumpKTraceBuffer - API query: selectively dump trace 00232 ***********************************************************************/ 00233 LONG 00234 NTAPI 00235 KeQueryDumpKTrace ( 00236 ULONG Processor, 00237 ULONG StartEntry, 00238 ULONG NumberOfEntries, 00239 ULONG ModuleFilter, 00240 ULONG MessageFilter, 00241 BOOLEAN Sort) 00242 00243 /*++ 00244 00245 Routine Description: 00246 00247 Arguments: 00248 00249 ProcessorMask 00250 00251 Specify the particular processor of interest. 00252 00253 StartEntry 00254 00255 The offset from the start of the queue to start dumping records. 00256 If this entry is 0 then the dumping starts from the head of the 00257 queue. 00258 If this argument is specified to be larger than the size of the 00259 KTrace buffer, then the dump wraps around appropriately. 00260 00261 NumberOfEntries 00262 00263 The number of log entries to dump starting from StartEntry. 00264 00265 ModuleFilter 00266 00267 A bit pattern specifying the modules of interest. See ktrace.h 00268 for a definition of modules. Only the logs of these modules are 00269 included in the dump. Bits representing undefined modules are 00270 ignored. 00271 00272 MessageFilter 00273 00274 A bit pattern specifying the subset of message types to dump. See 00275 ktrace.h for definitions of all message types. 00276 00277 Sort 00278 00279 Sort the output before dumping. Base the sort on the global NT 00280 timestamp. Most recent entries are dumped first. (NOT IMPLEMENTED 00281 YET). 00282 00283 Return Value: 00284 00285 The number of records that were dumped. 00286 Returns -1 if error. 00287 00288 --*/ 00289 00290 { 00291 ULONG Index = StartEntry; 00292 ULONG RecordCount = 0; 00293 00294 // 00295 // Verify that we have a valid processor number: 00296 // 00297 #if !defined(NT_UP) 00298 if (Processor > KeRegisteredProcessors) { 00299 DbgPrint("KTrace error: attempt to access invalid processor" 00300 "%d on a system with %d processors\n", 00301 Processor, 00302 KeRegisteredProcessors); 00303 return 0L; 00304 } 00305 #else 00306 if (Processor > 0) { 00307 DbgPrint("KTrace error: attempted to access invalid processor" 00308 "%d on a uni-processor system\n", 00309 Processor); 00310 } 00311 #endif 00312 00313 // 00314 // Loop through the entire KTrace 00315 // 00316 while (NumberOfEntries > 0) { 00317 00318 // 00319 // See if the current record matches the query criteria 00320 // 00321 if ((ModuleFilter & KTrace[Processor][Index].ModuleID) && 00322 (MessageFilter & KTrace[Processor][Index].MessageType)) { 00323 00324 DumpRecord(Processor, Index); 00325 RecordCount++; 00326 } 00327 00328 NumberOfEntries = NumberOfEntries - 1; 00329 Index = Index > 0 ? Index - 1 : KTRACE_LOG_SIZE - 1; 00330 } 00331 return RecordCount; 00332 00333 } // QueryDumpKTraceBuffer 00334 00335 /*********************************************************************** 00336 KePurgeKTrace - delete all records from the trace. 00337 ***********************************************************************/ 00338 00339 VOID 00340 NTAPI 00341 KePurgeKTrace ( 00342 ) 00343 { 00344 00345 ULONG Index1, Index2; 00346 00347 for (Index1 = 0; Index1 < KTRACE_LOG_SIZE; Index1++) { 00348 for (Index2 = 0; Index2 < MAXIMUM_PROCESSORS; Index2++) { 00349 KTrace[Index2][Index1].ModuleID = 0; 00350 KTrace[Index2][Index1].MessageType = 0; 00351 KTrace[Index2][Index1].MessageIndex = 0; 00352 KTrace[Index2][Index1].SystemTime.HighPart = 0; 00353 KTrace[Index2][Index1].SystemTime.LowPart = 0; 00354 KTrace[Index2][Index1].Arg1 = 0; 00355 KTrace[Index2][Index1].Arg2 = 0; 00356 KTrace[Index2][Index1].Arg3 = 0; 00357 KTrace[Index2][Index1].Arg4 = 0; 00358 KTrace[Index2][Index1].HiResTimeStamp.HighPart = 0; 00359 KTrace[Index2][Index1].HiResTimeStamp.LowPart = 0; 00360 } 00361 } 00362 } 00363 00364 /*********************************************************************** 00365 DumpRecord - dump a single record specified by processor number & index. 00366 ***********************************************************************/ 00367 VOID 00368 NTAPI 00369 DumpRecord (IN ULONG ProcessorNumber, 00370 IN ULONG Index) 00371 /*++ 00372 00373 Routine Description: 00374 00375 Dumps out the specified record in the trace associated with the 00376 specified processor out to the remote debugger console. 00377 00378 Arguments: 00379 00380 ProcessorNumber 00381 00382 The processor whose associated trace log is to be accessed. 00383 00384 Index 00385 00386 The offset of the record in the trace to be dumped. 00387 00388 Return Value: 00389 00390 None. 00391 00392 --*/ 00393 { 00394 00395 #if !defined(NT_UP) 00396 if (ProcessorNumber > KeRegisteredProcessors) { 00397 DbgPrint("KTrace:DumpRecord:" 00398 "illegal processor number %x in a %x-processor system\n", 00399 ProcessorNumber, KeRegisteredProcessors); 00400 return; 00401 } 00402 #else 00403 if (ProcessorNumber > 0) { 00404 DbgPrint("KTrace:DumpRecord:" 00405 "illegal processor %x in a uni-processor system\n", 00406 ProcessorNumber); 00407 } 00408 #endif 00409 00410 DbgPrint("Dumping Record Index [%ld], Processor = [%ld]\n", 00411 Index); 00412 DbgPrint("\tModuleID = [%lx]\n", 00413 KTrace[ProcessorNumber][Index].ModuleID); 00414 DbgPrint("\tMessageType = [%lx]\n", 00415 KTrace[ProcessorNumber][Index].MessageType); 00416 DbgPrint("\tMessageIndex = [%lx]\n", 00417 KTrace[ProcessorNumber][Index].MessageIndex); 00418 DbgPrint("\tArg1= [%lx%LX]\n", 00419 KTrace[ProcessorNumber][Index].Arg1, 00420 KTrace[ProcessorNumber][Index].Arg1); 00421 DbgPrint("\tArg2= [%lx%LX]\n", 00422 KTrace[ProcessorNumber][Index].Arg2, 00423 KTrace[ProcessorNumber][Index].Arg2); 00424 DbgPrint("\tArg3= [%lx%LX]\n", 00425 KTrace[ProcessorNumber][Index].Arg3, 00426 KTrace[ProcessorNumber][Index].Arg3); 00427 DbgPrint("\tArg4= [%lx%LX]\n", 00428 KTrace[ProcessorNumber][Index].Arg4, 00429 KTrace[ProcessorNumber][Index].Arg4); 00430 } // DumpRecord 00431 00432 00433 #endif // DBG 00434 00435 // end ktrace.c 00436

Generated on Sat May 15 19:40:35 2004 for test by doxygen 1.3.7