1 /* 2 * Copyright (c) 1998-2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29 #include <sys/sysctl.h> 30 31 #include <libkern/c++/OSContainers.h> 32 #include <libkern/c++/OSCPPDebug.h> 33 34 #include <IOKit/IOKitDebug.h> 35 #include <IOKit/IOLib.h> 36 #include <IOKit/assert.h> 37 #include <IOKit/IODeviceTreeSupport.h> 38 #include <IOKit/IOService.h> 39 40 #ifdef IOKITDEBUG 41 #define DEBUG_INIT_VALUE IOKITDEBUG 42 #else 43 #define DEBUG_INIT_VALUE 0 44 #endif 45 46 SInt64 gIOKitDebug = DEBUG_INIT_VALUE; 47 SInt64 gIOKitTrace = 0; 48 49 SYSCTL_QUAD(_debug, OID_AUTO, iokit, CTLFLAG_RW | CTLFLAG_LOCKED, &gIOKitDebug, "boot_arg io"); 50 SYSCTL_QUAD(_debug, OID_AUTO, iotrace, CTLFLAG_RW | CTLFLAG_LOCKED, &gIOKitTrace, "trace io"); 51 52 53 int debug_malloc_size; 54 int debug_iomalloc_size; 55 56 vm_size_t debug_iomallocpageable_size; 57 int debug_container_malloc_size; 58 // int debug_ivars_size; // in OSObject.cpp 59 60 extern "C" { 61 62 #if 0 63 #define DEBG(fmt, args...) { kprintf(fmt, ## args); } 64 #else 65 #define DEBG(fmt, args...) { IOLog(fmt, ## args); } 66 #endif 67 68 void IOPrintPlane( const IORegistryPlane * plane ) 69 { 70 IORegistryEntry * next; 71 IORegistryIterator * iter; 72 OSOrderedSet * all; 73 char format[] = "%xxxs"; 74 IOService * service; 75 76 iter = IORegistryIterator::iterateOver( plane ); 77 assert( iter ); 78 all = iter->iterateAll(); 79 if( all) { 80 DEBG("Count %d\n", all->getCount() ); 81 all->release(); 82 } else 83 DEBG("Empty\n"); 84 85 iter->reset(); 86 while( (next = iter->getNextObjectRecursive())) { 87 snprintf(format + 1, sizeof(format) - 1, "%ds", 2 * next->getDepth( plane )); 88 DEBG( format, ""); 89 DEBG( "\033[33m%s", next->getName( plane )); 90 if( (next->getLocation( plane ))) 91 DEBG("@%s", next->getLocation( plane )); 92 DEBG("\033[0m <class %s", next->getMetaClass()->getClassName()); 93 if( (service = OSDynamicCast(IOService, next))) 94 DEBG(", busy %ld", (long) service->getBusyState()); 95 DEBG( ">\n"); 96 // IOSleep(250); 97 } 98 iter->release(); 99 } 100 101 void dbugprintf(const char *fmt, ...); 102 void db_dumpiojunk( const IORegistryPlane * plane ); 103 104 void db_piokjunk(void) { 105 106 dbugprintf("\nDT plane:\n"); 107 db_dumpiojunk( gIODTPlane ); 108 dbugprintf("\n\nService plane:\n"); 109 db_dumpiojunk( gIOServicePlane ); 110 dbugprintf("\n\n" 111 "ivar kalloc() 0x%08x\n" 112 "malloc() 0x%08x\n" 113 "containers kalloc() 0x%08x\n" 114 "IOMalloc() 0x%08x\n" 115 "----------------------------------------\n", 116 debug_ivars_size, 117 debug_malloc_size, 118 debug_container_malloc_size, 119 debug_iomalloc_size 120 ); 121 122 } 123 124 125 void db_dumpiojunk( const IORegistryPlane * plane ) 126 { 127 IORegistryEntry * next; 128 IORegistryIterator * iter; 129 OSOrderedSet * all; 130 char format[] = "%xxxs"; 131 IOService * service; 132 133 iter = IORegistryIterator::iterateOver( plane ); 134 135 all = iter->iterateAll(); 136 if( all) { 137 dbugprintf("Count %d\n", all->getCount() ); 138 all->release(); 139 } else dbugprintf("Empty\n"); 140 141 iter->reset(); 142 while( (next = iter->getNextObjectRecursive())) { 143 snprintf(format + 1, sizeof(format) - 1, "%ds", 2 * next->getDepth( plane )); 144 dbugprintf( format, ""); 145 dbugprintf( "%s", next->getName( plane )); 146 if( (next->getLocation( plane ))) 147 dbugprintf("@%s", next->getLocation( plane )); 148 dbugprintf(" <class %s", next->getMetaClass()->getClassName()); 149 if( (service = OSDynamicCast(IOService, next))) 150 dbugprintf(", busy %ld", service->getBusyState()); 151 dbugprintf( ">\n"); 152 } 153 iter->release(); 154 } 155 156 void IOPrintMemory( void ) 157 { 158 159 // OSMetaClass::printInstanceCounts(); 160 161 IOLog("\n" 162 "ivar kalloc() 0x%08x\n" 163 "malloc() 0x%08x\n" 164 "containers kalloc() 0x%08x\n" 165 "IOMalloc() 0x%08x\n" 166 "----------------------------------------\n", 167 debug_ivars_size, 168 debug_malloc_size, 169 debug_container_malloc_size, 170 debug_iomalloc_size 171 ); 172 } 173 174 } /* extern "C" */ 175 176 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 177 178 #define super OSObject 179 OSDefineMetaClassAndStructors(IOKitDiagnostics, OSObject) 180 181 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 182 183 OSObject * IOKitDiagnostics::diagnostics( void ) 184 { 185 IOKitDiagnostics * diags; 186 187 diags = new IOKitDiagnostics; 188 if( diags && !diags->init()) { 189 diags->release(); 190 diags = 0; 191 } 192 193 return( diags ); 194 } 195 196 void IOKitDiagnostics::updateOffset( OSDictionary * dict, 197 UInt32 value, const char * name ) 198 { 199 OSNumber * off; 200 201 off = OSNumber::withNumber( value, 32 ); 202 if( !off) 203 return; 204 205 dict->setObject( name, off ); 206 off->release(); 207 } 208 209 bool IOKitDiagnostics::serialize(OSSerialize *s) const 210 { 211 OSDictionary * dict; 212 bool ok; 213 214 dict = OSDictionary::withCapacity( 5 ); 215 if( !dict) 216 return( false ); 217 218 updateOffset( dict, debug_ivars_size, "Instance allocation" ); 219 updateOffset( dict, debug_container_malloc_size, "Container allocation" ); 220 updateOffset( dict, debug_iomalloc_size, "IOMalloc allocation" ); 221 updateOffset( dict, debug_iomallocpageable_size, "Pageable allocation" ); 222 223 OSMetaClass::serializeClassDictionary(dict); 224 225 ok = dict->serialize( s ); 226 227 dict->release(); 228 229 return( ok ); 230 } 231 232 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 233