Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

495 lines
12 KiB

  1. /*++
  2. Copyright (c) 1995-2000 Microsoft Corporation
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. Debug functions
  7. Revision History:
  8. AmritanR
  9. --*/
  10. #include "precomp.h"
  11. #define __FILE_SIG__ DEBUG_SIG
  12. #include "ipmcast.h"
  13. #define PRINT_BYTES(x) (UCHAR)x,(UCHAR)(x>>8),(UCHAR)(x>>16),(UCHAR)(x>>24)
  14. #if RT_LOCK_DEBUG
  15. KSPIN_LOCK g_kslLockLock;
  16. #endif
  17. #if RT_MEM_DEBUG
  18. RT_LOCK g_rlMemoryLock;
  19. LIST_ENTRY g_leAllocMemListHead;
  20. LIST_ENTRY g_leFreeMemListHead;
  21. #endif
  22. VOID
  23. RtInitializeDebug()
  24. {
  25. #if RT_TRACE_DEBUG
  26. g_byDebugLevel = RT_DBG_LEVEL_WARN;
  27. //g_byDebugLevel = 0x00;
  28. g_fDebugComp = 0xFFFFFFFF;
  29. #endif
  30. #if RT_LOCK_DEBUG
  31. KeInitializeSpinLock(&(g_kslLockLock));
  32. #endif
  33. #if RT_MEM_DEBUG
  34. RtInitializeSpinLock(&g_rlMemoryLock);
  35. InitializeListHead(&g_leAllocMemListHead);
  36. InitializeListHead(&g_leFreeMemListHead);
  37. #endif
  38. }
  39. #if RT_LOCK_DEBUG
  40. VOID
  41. RtpInitializeSpinLock(
  42. IN PRT_LOCK pLock,
  43. IN ULONG ulFileSig,
  44. IN ULONG ulLineNumber
  45. )
  46. {
  47. UNREFERENCED_PARAMETER(ulFileSig);
  48. UNREFERENCED_PARAMETER(ulLineNumber);
  49. pLock->ulLockSig = RT_LOCK_SIG;
  50. pLock->ulFileSig = 0;
  51. pLock->ulLineNumber = 0;
  52. pLock->bAcquired = 0;
  53. pLock->pktLastThread = (PKTHREAD) NULL;
  54. KeInitializeSpinLock(&(pLock->kslLock));
  55. }
  56. VOID
  57. RtpAcquireSpinLock(
  58. IN PRT_LOCK pLock,
  59. OUT PKIRQL pkiIrql,
  60. IN ULONG ulFileSig,
  61. IN ULONG ulLineNumber,
  62. IN BOOLEAN bAtDpc
  63. )
  64. {
  65. PKTHREAD pThread;
  66. KIRQL kiInternalIrql;
  67. pThread = KeGetCurrentThread();
  68. if (bAtDpc) {
  69. kiInternalIrql = KeGetCurrentIrql();
  70. if (kiInternalIrql isnot DISPATCH_LEVEL) {
  71. DbgPrint("RTDBG: Called AcquireSpinLockAtDpc for lock at 0x%x when not at DISPATCH. File %c%c%c%c, Line %d\n",
  72. pLock,
  73. PRINT_BYTES(ulFileSig),
  74. ulLineNumber);
  75. DbgBreakPoint();
  76. }
  77. }
  78. KeAcquireSpinLock(&(g_kslLockLock),
  79. &kiInternalIrql);
  80. if (pLock->ulLockSig isnot RT_LOCK_SIG) {
  81. DbgPrint("RTDBG: Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  82. pLock,
  83. (CHAR) (ulFileSig & 0xff),
  84. (CHAR) ((ulFileSig >> 8) & 0xff),
  85. (CHAR) ((ulFileSig >> 16) & 0xff),
  86. (CHAR) ((ulFileSig >> 24) & 0xff),
  87. ulLineNumber);
  88. DbgBreakPoint();
  89. }
  90. if (pLock->bAcquired isnot 0) {
  91. if (pLock->pktLastThread is pThread) {
  92. DbgPrint("RTDBG: Detected recursive locking!: pLock 0x%x, File %c%c%c%c, Line %d\n",
  93. pLock,
  94. PRINT_BYTES(ulFileSig),
  95. ulLineNumber);
  96. DbgPrint("RTDBG: pLock 0x%x already acquired in File %c%c%c%c, Line %d\n",
  97. pLock,
  98. PRINT_BYTES(pLock->ulFileSig),
  99. pLock->ulLineNumber);
  100. DbgBreakPoint();
  101. }
  102. }
  103. KeReleaseSpinLock(&(g_kslLockLock),
  104. kiInternalIrql);
  105. if (bAtDpc) {
  106. KeAcquireSpinLockAtDpcLevel(&(pLock->kslLock));
  107. } else {
  108. KeAcquireSpinLock(&(pLock->kslLock),
  109. pkiIrql);
  110. }
  111. //
  112. // Mark this lock.
  113. //
  114. pLock->pktLastThread = pThread;
  115. pLock->ulFileSig = ulFileSig;
  116. pLock->ulLineNumber = ulLineNumber;
  117. pLock->bAcquired = TRUE;
  118. }
  119. VOID
  120. RtpReleaseSpinLock(
  121. IN PRT_LOCK pLock,
  122. IN KIRQL kiIrql,
  123. IN ULONG ulFileSig,
  124. IN ULONG ulLineNumber,
  125. IN BOOLEAN bFromDpc
  126. )
  127. {
  128. if (pLock->ulLockSig isnot RT_LOCK_SIG) {
  129. DbgPrint("RTDBG: Trying to release uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  130. pLock,
  131. PRINT_BYTES(ulFileSig),
  132. ulLineNumber);
  133. DbgBreakPoint();
  134. }
  135. if (pLock->bAcquired is 0) {
  136. DbgPrint("RTDBG: Detected release of unacquired lock 0x%x, File %c%c%c%c, Line %d\n",
  137. pLock,
  138. PRINT_BYTES(ulFileSig),
  139. ulLineNumber);
  140. DbgBreakPoint();
  141. }
  142. pLock->ulFileSig = ulFileSig;
  143. pLock->ulLineNumber = ulLineNumber;
  144. pLock->bAcquired = FALSE;
  145. pLock->pktLastThread = (PKTHREAD) NULL;
  146. if (bFromDpc) {
  147. KeReleaseSpinLockFromDpcLevel(&(pLock->kslLock));
  148. } else {
  149. KeReleaseSpinLock(&(pLock->kslLock),
  150. kiIrql);
  151. }
  152. }
  153. #endif // RT_LOCK_DEBUG
  154. #if RT_MEM_DEBUG
  155. PVOID
  156. RtpAllocate(
  157. IN POOL_TYPE ptPool,
  158. IN ULONG ulSize,
  159. IN ULONG ulTag,
  160. IN ULONG ulFileSig,
  161. IN ULONG ulLineNumber
  162. )
  163. {
  164. PVOID pBuffer;
  165. PRT_ALLOCATION pwaAlloc;
  166. KIRQL kiIrql;
  167. pwaAlloc = ExAllocatePoolWithTag(ptPool,
  168. ulSize + sizeof(RT_ALLOCATION),
  169. ulTag);
  170. if (pwaAlloc is NULL) {
  171. Trace(MEMORY, ERROR,
  172. ("Failed to allocate %d bytes in file %c%c%c%c, line %d\n",
  173. ulSize, PRINT_BYTES(ulFileSig), ulLineNumber));
  174. pBuffer = NULL;
  175. } else {
  176. pBuffer = (PVOID) & (pwaAlloc->pucData);
  177. pwaAlloc->ulMemSig = RT_MEMORY_SIG;
  178. pwaAlloc->ulFileSig = ulFileSig;
  179. pwaAlloc->ulLineNumber = ulLineNumber;
  180. pwaAlloc->ulSize = ulSize;
  181. RtAcquireSpinLock(&(g_rlMemoryLock), &kiIrql);
  182. InsertHeadList(&g_leAllocMemListHead,
  183. &(pwaAlloc->leLink));
  184. RtReleaseSpinLock(&g_rlMemoryLock, kiIrql);
  185. }
  186. return pBuffer;
  187. }
  188. VOID
  189. RtpFree(
  190. PVOID pvPointer,
  191. IN ULONG ulFileSig,
  192. IN ULONG ulLineNumber
  193. )
  194. {
  195. PRT_ALLOCATION pwaAlloc;
  196. KIRQL kiIrql;
  197. PRT_FREE pFree;
  198. pwaAlloc = CONTAINING_RECORD(pvPointer, RT_ALLOCATION, pucData);
  199. if (pwaAlloc->ulMemSig is RT_FREE_SIG) {
  200. DbgPrint("RTDBG: Trying to free memory that is already freed. Pointer0x%x, File %c%c%c%c, Line %d. Was freed at File %c%c%c%c, Line %d. \n",
  201. pvPointer,
  202. PRINT_BYTES(ulFileSig),
  203. ulLineNumber,
  204. PRINT_BYTES(pwaAlloc->ulFileSig),
  205. pwaAlloc->ulLineNumber);
  206. return;
  207. }
  208. if (pwaAlloc->ulMemSig isnot RT_MEMORY_SIG) {
  209. DbgPrint("RTDBG: Trying to free memory whose signature is wrong. Pointer 0x%x\n",
  210. pvPointer);
  211. DbgBreakPoint();
  212. return;
  213. }
  214. //
  215. // create a warp free block for it
  216. //
  217. pFree = ExAllocatePoolWithTag(NonPagedPool,
  218. sizeof(RT_FREE),
  219. FREE_TAG);
  220. RtAssert(pFree);
  221. //
  222. // Take the lock so that no one else touches the list
  223. //
  224. RtAcquireSpinLock(&(g_rlMemoryLock), &kiIrql);
  225. RemoveEntryList(&(pwaAlloc->leLink));
  226. pFree->ulMemSig = RT_FREE_SIG;
  227. pFree->ulAllocFileSig = pwaAlloc->ulFileSig;
  228. pFree->ulAllocLineNumber = pwaAlloc->ulLineNumber;
  229. pFree->ulFreeFileSig = ulFileSig;
  230. pFree->ulFreeLineNumber = ulLineNumber;
  231. pFree->ulStartAddr = (ULONG_PTR) (pwaAlloc->pucData);
  232. pFree->ulSize = pwaAlloc->ulSize;
  233. pwaAlloc->ulMemSig = RT_FREE_SIG;
  234. pwaAlloc->ulFileSig = ulFileSig;
  235. pwaAlloc->ulLineNumber = ulLineNumber;
  236. ExFreePool(pwaAlloc);
  237. InsertTailList(&g_leFreeMemListHead,
  238. &(pFree->leLink));
  239. RtReleaseSpinLock(&(g_rlMemoryLock), kiIrql);
  240. }
  241. VOID
  242. RtAuditMemory()
  243. {
  244. PRT_ALLOCATION pwaAlloc;
  245. PLIST_ENTRY pleNode;
  246. PRT_FREE pFree;
  247. while (!IsListEmpty(&g_leAllocMemListHead)) {
  248. pleNode = RemoveHeadList(&g_leAllocMemListHead);
  249. pwaAlloc = CONTAINING_RECORD(pleNode, RT_ALLOCATION, leLink);
  250. if (pwaAlloc->ulMemSig is RT_MEMORY_SIG) {
  251. DbgPrint("RTDBG: Unfreed memory. %d bytes. Pointer 0x%x, File %c%c%c%c, Line %d\n",
  252. pwaAlloc->ulSize,
  253. pwaAlloc->pucData,
  254. PRINT_BYTES(pwaAlloc->ulFileSig),
  255. pwaAlloc->ulLineNumber);
  256. DbgBreakPoint();
  257. ExFreePool(pwaAlloc);
  258. continue;
  259. }
  260. DbgPrint("RTDBG: Allocation with bad signature. Pointer 0x%x\n",
  261. pwaAlloc->pucData);
  262. DbgBreakPoint();
  263. continue;
  264. }
  265. while (!IsListEmpty(&g_leFreeMemListHead)) {
  266. pleNode = RemoveHeadList(&g_leFreeMemListHead);
  267. pFree = CONTAINING_RECORD(pleNode, RT_FREE, leLink);
  268. if (pFree->ulMemSig is RT_FREE_SIG) {
  269. ExFreePool(pFree);
  270. continue;
  271. }
  272. DbgPrint("RTDBG: Freed memory with bad signature.\n");
  273. DbgBreakPoint();
  274. }
  275. }
  276. #endif
  277. #if IF_REFERENCE_DEBUG
  278. uint
  279. DbgLockedReferenceIF(
  280. IN Interface *RefIF,
  281. IN uchar *File,
  282. IN uint Line
  283. )
  284. /*++
  285. Routine Description:
  286. Increases the reference count of a IF and records a history of who
  287. made the call to reference.
  288. Arguments:
  289. RefIF - The IF to reference.
  290. File - The filename containing the calling fcn (output of the __FILE__ macro).
  291. Line - The line number of the call to this fcn (output of the __LINE__ macro).
  292. Return Value:
  293. Reference count
  294. --*/
  295. {
  296. void *CallersCaller;
  297. IF_REFERENCE_HISTORY *RefHistory;
  298. RefHistory = &RefIF->if_refhistory[RefIF->if_refhistory_index];
  299. RefHistory->File = File;
  300. RefHistory->Line = Line;
  301. RtlGetCallersAddress(&RefHistory->Caller, &CallersCaller);
  302. RefHistory->Count = ++RefIF->if_refcount;
  303. RefIF->if_refhistory_index = ++RefIF->if_refhistory_index % MAX_IFREFERENCE_HISTORY;
  304. return RefIF->if_refcount;
  305. }
  306. uint
  307. DbgDereferenceIF(
  308. IN Interface *DerefIF,
  309. IN uchar *File,
  310. IN uint Line
  311. )
  312. /*++
  313. Routine Description:
  314. Lock, Dereference the interface and records a history of who made the call to dereference.
  315. Arguments:
  316. DerefIF - The IF to dereference.
  317. File - The filename containing the calling fcn (output of the __FILE__ macro).
  318. Line - The line number of the call to this fcn (output of the __LINE__ macro).
  319. Return Value:
  320. Original reference count
  321. --*/
  322. {
  323. void *Caller;
  324. IF_REFERENCE_HISTORY *RefHistory;
  325. CTELockHandle RouteTableHandle;
  326. uint RefCount;
  327. CTEGetLock(&RouteTableLock.Lock, &RouteTableHandle);
  328. RefHistory = &DerefIF->if_refhistory[DerefIF->if_refhistory_index];
  329. RefHistory->File = File;
  330. RefHistory->Line = Line;
  331. RtlGetCallersAddress(&Caller, &RefHistory->Caller);
  332. RefCount = DerefIF->if_refcount;
  333. RefHistory->Count = --DerefIF->if_refcount;
  334. DerefIF->if_refhistory_index = ++DerefIF->if_refhistory_index % MAX_IFREFERENCE_HISTORY;
  335. CTEFreeLock(&RouteTableLock.Lock, RouteTableHandle);
  336. return RefCount;
  337. }
  338. uint
  339. DbgLockedDereferenceIF(
  340. IN Interface *DerefIF,
  341. IN uchar *File,
  342. IN uint Line
  343. )
  344. /*++
  345. Routine Description:
  346. Dereference the interface and records a history of who made the call to dereference.
  347. Arguments:
  348. DerefIF - The IF to dereference.
  349. File - The filename containing the calling fcn (output of the __FILE__ macro).
  350. Line - The line number of the call to this fcn (output of the __LINE__ macro).
  351. Return Value:
  352. Reference count
  353. --*/
  354. {
  355. void *Caller;
  356. IF_REFERENCE_HISTORY *RefHistory;
  357. uint RefCount;
  358. RefHistory = &DerefIF->if_refhistory[DerefIF->if_refhistory_index];
  359. RefHistory->File = File;
  360. RefHistory->Line = Line;
  361. RtlGetCallersAddress(&Caller, &RefHistory->Caller);
  362. RefCount = DerefIF->if_refcount;
  363. RefHistory->Count = --DerefIF->if_refcount;
  364. DerefIF->if_refhistory_index = ++DerefIF->if_refhistory_index % MAX_IFREFERENCE_HISTORY;
  365. return RefCount;
  366. }
  367. #endif