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.

380 lines
9.7 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. debug.c
  5. Abstract:
  6. This module contains all debug-related code.
  7. Revision History:
  8. Who When What
  9. -------- -------- ----------------------------------------------
  10. arvindm 05-29-97 Created, based on ATM ARP.
  11. Notes:
  12. --*/
  13. #include <precomp.h>
  14. #define __FILENUMBER 'GBED'
  15. #if DBG
  16. INT ndisprotDebugLevel=DL_WARN;
  17. NDIS_SPIN_LOCK ndisprotDbgLogLock;
  18. PNUIOD_ALLOCATION ndisprotdMemoryHead = (PNUIOD_ALLOCATION)NULL;
  19. PNUIOD_ALLOCATION ndisprotdMemoryTail = (PNUIOD_ALLOCATION)NULL;
  20. ULONG ndisprotdAllocCount = 0; // how many allocated so far (unfreed)
  21. NDIS_SPIN_LOCK ndisprotdMemoryLock;
  22. BOOLEAN ndisprotdInitDone = FALSE;
  23. PVOID
  24. ndisprotAuditAllocMem(
  25. PVOID pPointer,
  26. ULONG Size,
  27. ULONG FileNumber,
  28. ULONG LineNumber
  29. )
  30. {
  31. PVOID pBuffer;
  32. PNUIOD_ALLOCATION pAllocInfo;
  33. if (!ndisprotdInitDone)
  34. {
  35. NdisAllocateSpinLock(&(ndisprotdMemoryLock));
  36. ndisprotdInitDone = TRUE;
  37. }
  38. NdisAllocateMemoryWithTag(
  39. (PVOID *)&pAllocInfo,
  40. Size+sizeof(NUIOD_ALLOCATION),
  41. (ULONG)'oiuN'
  42. );
  43. if (pAllocInfo == (PNUIOD_ALLOCATION)NULL)
  44. {
  45. DEBUGP(DL_VERY_LOUD+50,
  46. ("ndisprotAuditAllocMem: file %d, line %d, Size %d failed!\n",
  47. FileNumber, LineNumber, Size));
  48. pBuffer = NULL;
  49. }
  50. else
  51. {
  52. pBuffer = (PVOID)&(pAllocInfo->UserData);
  53. NPROT_SET_MEM(pBuffer, 0xaf, Size);
  54. pAllocInfo->Signature = NUIOD_MEMORY_SIGNATURE;
  55. pAllocInfo->FileNumber = FileNumber;
  56. pAllocInfo->LineNumber = LineNumber;
  57. pAllocInfo->Size = Size;
  58. pAllocInfo->Location = (ULONG_PTR)pPointer;
  59. pAllocInfo->Next = (PNUIOD_ALLOCATION)NULL;
  60. NdisAcquireSpinLock(&(ndisprotdMemoryLock));
  61. pAllocInfo->Prev = ndisprotdMemoryTail;
  62. if (ndisprotdMemoryTail == (PNUIOD_ALLOCATION)NULL)
  63. {
  64. // empty list
  65. ndisprotdMemoryHead = ndisprotdMemoryTail = pAllocInfo;
  66. }
  67. else
  68. {
  69. ndisprotdMemoryTail->Next = pAllocInfo;
  70. }
  71. ndisprotdMemoryTail = pAllocInfo;
  72. ndisprotdAllocCount++;
  73. NdisReleaseSpinLock(&(ndisprotdMemoryLock));
  74. }
  75. DEBUGP(DL_VERY_LOUD+100,
  76. ("ndisprotAuditAllocMem: file %c%c%c%c, line %d, %d bytes, [0x%x] <- 0x%x\n",
  77. (CHAR)(FileNumber & 0xff),
  78. (CHAR)((FileNumber >> 8) & 0xff),
  79. (CHAR)((FileNumber >> 16) & 0xff),
  80. (CHAR)((FileNumber >> 24) & 0xff),
  81. LineNumber, Size, pPointer, pBuffer));
  82. return (pBuffer);
  83. }
  84. VOID
  85. ndisprotAuditFreeMem(
  86. PVOID Pointer
  87. )
  88. {
  89. PNUIOD_ALLOCATION pAllocInfo;
  90. NdisAcquireSpinLock(&(ndisprotdMemoryLock));
  91. pAllocInfo = CONTAINING_RECORD(Pointer, NUIOD_ALLOCATION, UserData);
  92. if (pAllocInfo->Signature != NUIOD_MEMORY_SIGNATURE)
  93. {
  94. DEBUGP(DL_ERROR,
  95. ("ndisprotAuditFreeMem: unknown buffer 0x%x!\n", Pointer));
  96. NdisReleaseSpinLock(&(ndisprotdMemoryLock));
  97. #if DBG
  98. DbgBreakPoint();
  99. #endif
  100. return;
  101. }
  102. pAllocInfo->Signature = (ULONG)'DEAD';
  103. if (pAllocInfo->Prev != (PNUIOD_ALLOCATION)NULL)
  104. {
  105. pAllocInfo->Prev->Next = pAllocInfo->Next;
  106. }
  107. else
  108. {
  109. ndisprotdMemoryHead = pAllocInfo->Next;
  110. }
  111. if (pAllocInfo->Next != (PNUIOD_ALLOCATION)NULL)
  112. {
  113. pAllocInfo->Next->Prev = pAllocInfo->Prev;
  114. }
  115. else
  116. {
  117. ndisprotdMemoryTail = pAllocInfo->Prev;
  118. }
  119. ndisprotdAllocCount--;
  120. NdisReleaseSpinLock(&(ndisprotdMemoryLock));
  121. NdisFreeMemory(pAllocInfo, 0, 0);
  122. }
  123. VOID
  124. ndisprotAuditShutdown(
  125. VOID
  126. )
  127. {
  128. if (ndisprotdInitDone)
  129. {
  130. if (ndisprotdAllocCount != 0)
  131. {
  132. DEBUGP(DL_ERROR, ("AuditShutdown: unfreed memory, %d blocks!\n",
  133. ndisprotdAllocCount));
  134. DEBUGP(DL_ERROR, ("MemoryHead: 0x%x, MemoryTail: 0x%x\n",
  135. ndisprotdMemoryHead, ndisprotdMemoryTail));
  136. DbgBreakPoint();
  137. {
  138. PNUIOD_ALLOCATION pAllocInfo;
  139. while (ndisprotdMemoryHead != (PNUIOD_ALLOCATION)NULL)
  140. {
  141. pAllocInfo = ndisprotdMemoryHead;
  142. DEBUGP(DL_INFO, ("AuditShutdown: will free 0x%x\n", pAllocInfo));
  143. ndisprotAuditFreeMem(&(pAllocInfo->UserData));
  144. }
  145. }
  146. }
  147. ndisprotdInitDone = FALSE;
  148. }
  149. }
  150. #define MAX_HD_LENGTH 128
  151. VOID
  152. DbgPrintHexDump(
  153. IN PUCHAR pBuffer,
  154. IN ULONG Length
  155. )
  156. /*++
  157. Routine Description:
  158. Print a hex dump of the given contiguous buffer. If the length
  159. is too long, we truncate it.
  160. Arguments:
  161. pBuffer - Points to start of data to be dumped
  162. Length - Length of above.
  163. Return Value:
  164. None
  165. --*/
  166. {
  167. ULONG i;
  168. if (Length > MAX_HD_LENGTH)
  169. {
  170. Length = MAX_HD_LENGTH;
  171. }
  172. for (i = 0; i < Length; i++)
  173. {
  174. //
  175. // Check if we are at the end of a line
  176. //
  177. if ((i > 0) && ((i & 0xf) == 0))
  178. {
  179. DbgPrint("\n");
  180. }
  181. //
  182. // Print addr if we are at start of a new line
  183. //
  184. if ((i & 0xf) == 0)
  185. {
  186. DbgPrint("%08x ", pBuffer);
  187. }
  188. DbgPrint(" %02x", *pBuffer++);
  189. }
  190. //
  191. // Terminate the last line.
  192. //
  193. if (Length > 0)
  194. {
  195. DbgPrint("\n");
  196. }
  197. }
  198. #endif // DBG
  199. #if DBG_SPIN_LOCK
  200. ULONG ndisprotdSpinLockInitDone = 0;
  201. NDIS_SPIN_LOCK ndisprotdLockLock;
  202. VOID
  203. ndisprotAllocateSpinLock(
  204. IN PNPROT_LOCK pLock,
  205. IN ULONG FileNumber,
  206. IN ULONG LineNumber
  207. )
  208. {
  209. if (ndisprotdSpinLockInitDone == 0)
  210. {
  211. ndisprotdSpinLockInitDone = 1;
  212. NdisAllocateSpinLock(&(ndisprotdLockLock));
  213. }
  214. NdisAcquireSpinLock(&(ndisprotdLockLock));
  215. pLock->Signature = NUIOL_SIG;
  216. pLock->TouchedByFileNumber = FileNumber;
  217. pLock->TouchedInLineNumber = LineNumber;
  218. pLock->IsAcquired = 0;
  219. pLock->OwnerThread = 0;
  220. NdisAllocateSpinLock(&(pLock->NdisLock));
  221. NdisReleaseSpinLock(&(ndisprotdLockLock));
  222. }
  223. VOID
  224. ndisprotAcquireSpinLock(
  225. IN PNPROT_LOCK pLock,
  226. IN ULONG FileNumber,
  227. IN ULONG LineNumber
  228. )
  229. {
  230. PKTHREAD pThread;
  231. pThread = KeGetCurrentThread();
  232. NdisAcquireSpinLock(&(ndisprotdLockLock));
  233. if (pLock->Signature != NUIOL_SIG)
  234. {
  235. DbgPrint("Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  236. pLock,
  237. (CHAR)(FileNumber & 0xff),
  238. (CHAR)((FileNumber >> 8) & 0xff),
  239. (CHAR)((FileNumber >> 16) & 0xff),
  240. (CHAR)((FileNumber >> 24) & 0xff),
  241. LineNumber);
  242. DbgBreakPoint();
  243. }
  244. if (pLock->IsAcquired != 0)
  245. {
  246. if (pLock->OwnerThread == pThread)
  247. {
  248. DbgPrint("Detected multiple locking!: pLock 0x%x, File %c%c%c%c, Line %d\n",
  249. pLock,
  250. (CHAR)(FileNumber & 0xff),
  251. (CHAR)((FileNumber >> 8) & 0xff),
  252. (CHAR)((FileNumber >> 16) & 0xff),
  253. (CHAR)((FileNumber >> 24) & 0xff),
  254. LineNumber);
  255. DbgPrint("pLock 0x%x already acquired in File %c%c%c%c, Line %d\n",
  256. pLock,
  257. (CHAR)(pLock->TouchedByFileNumber & 0xff),
  258. (CHAR)((pLock->TouchedByFileNumber >> 8) & 0xff),
  259. (CHAR)((pLock->TouchedByFileNumber >> 16) & 0xff),
  260. (CHAR)((pLock->TouchedByFileNumber >> 24) & 0xff),
  261. pLock->TouchedInLineNumber);
  262. DbgBreakPoint();
  263. }
  264. }
  265. pLock->IsAcquired++;
  266. NdisReleaseSpinLock(&(ndisprotdLockLock));
  267. NdisAcquireSpinLock(&(pLock->NdisLock));
  268. //
  269. // Mark this lock.
  270. //
  271. pLock->OwnerThread = pThread;
  272. pLock->TouchedByFileNumber = FileNumber;
  273. pLock->TouchedInLineNumber = LineNumber;
  274. }
  275. VOID
  276. ndisprotReleaseSpinLock(
  277. IN PNPROT_LOCK pLock,
  278. IN ULONG FileNumber,
  279. IN ULONG LineNumber
  280. )
  281. {
  282. NdisDprAcquireSpinLock(&(ndisprotdLockLock));
  283. if (pLock->Signature != NUIOL_SIG)
  284. {
  285. DbgPrint("Trying to release uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  286. pLock,
  287. (CHAR)(FileNumber & 0xff),
  288. (CHAR)((FileNumber >> 8) & 0xff),
  289. (CHAR)((FileNumber >> 16) & 0xff),
  290. (CHAR)((FileNumber >> 24) & 0xff),
  291. LineNumber);
  292. DbgBreakPoint();
  293. }
  294. if (pLock->IsAcquired == 0)
  295. {
  296. DbgPrint("Detected release of unacquired lock 0x%x, File %c%c%c%c, Line %d\n",
  297. pLock,
  298. (CHAR)(FileNumber & 0xff),
  299. (CHAR)((FileNumber >> 8) & 0xff),
  300. (CHAR)((FileNumber >> 16) & 0xff),
  301. (CHAR)((FileNumber >> 24) & 0xff),
  302. LineNumber);
  303. DbgBreakPoint();
  304. }
  305. pLock->TouchedByFileNumber = FileNumber;
  306. pLock->TouchedInLineNumber = LineNumber;
  307. pLock->IsAcquired--;
  308. pLock->OwnerThread = 0;
  309. NdisDprReleaseSpinLock(&(ndisprotdLockLock));
  310. NdisReleaseSpinLock(&(pLock->NdisLock));
  311. }
  312. #endif // DBG_SPIN_LOCK