Source code of Windows XP (NT5)
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.

449 lines
8.7 KiB

  1. /*++
  2. Copyright (c) 1997 FORE Systems, Inc.
  3. Copyright (c) 1997 Microsoft Corporation
  4. Module Name:
  5. debug.c
  6. Abstract:
  7. This file contains debugging support.
  8. Author:
  9. Larry Cleeton, FORE Systems (v-lcleet@microsoft.com, lrc@fore.com)
  10. Environment:
  11. Kernel mode
  12. Revision History:
  13. --*/
  14. #include "precomp.h"
  15. #include <stdarg.h>
  16. #include <stdio.h>
  17. #pragma hdrstop
  18. #if DBG
  19. ULONG DbgVerbosity = 0;
  20. #if DBG_TRACE
  21. ULONG DbgLogSize = 128*1024;
  22. TRACELOG TraceLog;
  23. PUCHAR pTraceLogSpace;
  24. #endif
  25. #include "oidstrng.h"
  26. #include "irpstrng.h"
  27. #define MAX_HD_LENGTH 128
  28. VOID
  29. DbgOut(ULONG Level, PUCHAR Message, ...)
  30. {
  31. char buf[DBG_OUTBUF_SIZE];
  32. va_list ap;
  33. LONG numchars;
  34. if (Level > DbgVerbosity)
  35. return;
  36. va_start(ap, Message);
  37. numchars = _vsnprintf(buf, DBG_OUTBUF_SIZE, Message, ap);
  38. buf[DBG_OUTBUF_SIZE-1] = '\0';
  39. DbgPrint("ATMLANE: %s", buf);
  40. }
  41. //
  42. // Careful! Uses static storage for string
  43. //
  44. PUCHAR
  45. UnicodeToString(PUNICODE_STRING unicodeString)
  46. {
  47. static CHAR ansiStringBuffer[129];
  48. ANSI_STRING ansiString;
  49. ansiString.Length = 0;
  50. ansiString.MaximumLength = 128;
  51. ansiString.Buffer = ansiStringBuffer;
  52. if (unicodeString->Length > 0)
  53. {
  54. NdisUnicodeStringToAnsiString(
  55. &ansiString,
  56. unicodeString);
  57. }
  58. ansiStringBuffer[ansiString.Length] = '\0';
  59. return ansiStringBuffer;
  60. }
  61. //
  62. // Careful! Uses static storage for string.
  63. //
  64. PUCHAR
  65. MacAddrToString(PVOID In)
  66. {
  67. static UCHAR String[20];
  68. static PUCHAR HexChars = "0123456789abcdef";
  69. PUCHAR EthAddr = (PUCHAR) In;
  70. UINT i;
  71. PUCHAR s;
  72. for (i = 0, s = String; i < 6; i++, EthAddr++)
  73. {
  74. *s++ = HexChars[(*EthAddr)>>4];
  75. *s++ = HexChars[(*EthAddr)&0xf];
  76. }
  77. *s = '\0';
  78. return String;
  79. }
  80. //
  81. // Careful! Uses static storage for string.
  82. //
  83. PUCHAR
  84. AtmAddrToString(PVOID In)
  85. {
  86. static UCHAR String[80];
  87. static PUCHAR HexChars = "0123456789abcdef";
  88. PUCHAR AtmAddr = (PUCHAR) In;
  89. UINT i;
  90. PUCHAR s = String;
  91. *s++ = HexChars[(*AtmAddr)>>4];
  92. *s++ = HexChars[(*AtmAddr++)&0xf]; // 1
  93. *s++ = '.';
  94. *s++ = HexChars[(*AtmAddr)>>4];
  95. *s++ = HexChars[(*AtmAddr++)&0xf]; // 2
  96. *s++ = HexChars[(*AtmAddr)>>4];
  97. *s++ = HexChars[(*AtmAddr++)&0xf]; // 3
  98. *s++ = '.';
  99. *s++ = HexChars[(*AtmAddr)>>4];
  100. *s++ = HexChars[(*AtmAddr++)&0xf]; // 4
  101. *s++ = '.';
  102. *s++ = HexChars[(*AtmAddr)>>4];
  103. *s++ = HexChars[(*AtmAddr++)&0xf]; // 5
  104. *s++ = HexChars[(*AtmAddr)>>4];
  105. *s++ = HexChars[(*AtmAddr++)&0xf]; // 6
  106. *s++ = HexChars[(*AtmAddr)>>4];
  107. *s++ = HexChars[(*AtmAddr++)&0xf]; // 7
  108. *s++ = '.';
  109. *s++ = HexChars[(*AtmAddr)>>4];
  110. *s++ = HexChars[(*AtmAddr++)&0xf]; // 8
  111. *s++ = HexChars[(*AtmAddr)>>4];
  112. *s++ = HexChars[(*AtmAddr++)&0xf]; // 9
  113. *s++ = '.';
  114. *s++ = HexChars[(*AtmAddr)>>4];
  115. *s++ = HexChars[(*AtmAddr++)&0xf]; // 10
  116. *s++ = HexChars[(*AtmAddr)>>4];
  117. *s++ = HexChars[(*AtmAddr++)&0xf]; // 11
  118. *s++ = '.';
  119. *s++ = HexChars[(*AtmAddr)>>4];
  120. *s++ = HexChars[(*AtmAddr++)&0xf]; // 12
  121. *s++ = HexChars[(*AtmAddr)>>4];
  122. *s++ = HexChars[(*AtmAddr++)&0xf]; // 13
  123. *s++ = '.';
  124. *s++ = HexChars[(*AtmAddr)>>4];
  125. *s++ = HexChars[(*AtmAddr++)&0xf]; // 14
  126. *s++ = HexChars[(*AtmAddr)>>4];
  127. *s++ = HexChars[(*AtmAddr++)&0xf]; // 15
  128. *s++ = HexChars[(*AtmAddr)>>4];
  129. *s++ = HexChars[(*AtmAddr++)&0xf]; // 16
  130. *s++ = HexChars[(*AtmAddr)>>4];
  131. *s++ = HexChars[(*AtmAddr++)&0xf]; // 17
  132. *s++ = HexChars[(*AtmAddr)>>4];
  133. *s++ = HexChars[(*AtmAddr++)&0xf]; // 18
  134. *s++ = HexChars[(*AtmAddr)>>4];
  135. *s++ = HexChars[(*AtmAddr++)&0xf]; // 19
  136. *s++ = '.';
  137. *s++ = HexChars[(*AtmAddr)>>4];
  138. *s++ = HexChars[(*AtmAddr++)&0xf]; // 20
  139. *s = '\0';
  140. return String;
  141. }
  142. PUCHAR
  143. OidToString(ULONG Oid)
  144. {
  145. struct _string_table *oidtab;
  146. for (oidtab = &oid_string_table[0]; oidtab->value != 0; oidtab++)
  147. if (oidtab->value == Oid)
  148. return oidtab->string;
  149. return oid_string_table[(sizeof(oid_string_table) /
  150. sizeof(struct _string_table)) - 1].string;
  151. }
  152. PUCHAR
  153. IrpToString(ULONG Irp)
  154. {
  155. struct _string_table *irptab;
  156. for (irptab = &irp_string_table[0]; irptab->value != 0xffffffff; irptab++)
  157. if (irptab->value == Irp)
  158. return irptab->string;
  159. return irp_string_table[(sizeof(irp_string_table) /
  160. sizeof(struct _string_table)) - 1].string;
  161. }
  162. VOID
  163. DbgPrintHexDump(
  164. IN ULONG Level,
  165. IN PUCHAR pBuffer,
  166. IN ULONG Length
  167. )
  168. /*++
  169. Routine Description:
  170. Print a hex dump of the given contiguous buffer. If the length
  171. is too long, we truncate it.
  172. Arguments:
  173. pBuffer - Points to start of data to be dumped
  174. Length - Length of above.
  175. Return Value:
  176. None
  177. --*/
  178. {
  179. ULONG i;
  180. if (Level > DbgVerbosity)
  181. return;
  182. if (Length > MAX_HD_LENGTH)
  183. {
  184. Length = MAX_HD_LENGTH;
  185. }
  186. for (i = 0; i < Length; i++)
  187. {
  188. //
  189. // Check if we are at the end of a line
  190. //
  191. if ((i > 0) && ((i & 0xf) == 0))
  192. {
  193. DbgPrint("\n");
  194. }
  195. //
  196. // Print addr if we are at start of a new line
  197. //
  198. if ((i & 0xf) == 0)
  199. {
  200. DbgPrint("%08x ", pBuffer);
  201. }
  202. DbgPrint(" %02x", *pBuffer++);
  203. }
  204. //
  205. // Terminate the last line.
  206. //
  207. if (Length > 0)
  208. {
  209. DbgPrint("\n");
  210. }
  211. }
  212. VOID
  213. TraceLogWritePkt(
  214. IN PTRACELOG pTraceLog,
  215. IN PNDIS_PACKET pNdisPacket
  216. )
  217. {
  218. PNDIS_BUFFER pBuffer[5] = {(PNDIS_BUFFER)NULL};
  219. do
  220. {
  221. pBuffer[0] = pNdisPacket->Private.Head;
  222. if (pBuffer[0] == (PNDIS_BUFFER)NULL)
  223. break;
  224. pBuffer[1] = pBuffer[0]->Next;
  225. if (pBuffer[1] == (PNDIS_BUFFER)NULL)
  226. break;
  227. pBuffer[2] = pBuffer[1]->Next;
  228. if (pBuffer[2] == (PNDIS_BUFFER)NULL)
  229. break;
  230. pBuffer[3] = pBuffer[2]->Next;
  231. if (pBuffer[3] == (PNDIS_BUFFER)NULL)
  232. break;
  233. pBuffer[4] = pBuffer[3]->Next;
  234. }
  235. while (FALSE);
  236. TraceLogWrite(
  237. pTraceLog,
  238. TL_NDISPACKET,
  239. pNdisPacket,
  240. pNdisPacket->Private.PhysicalCount,
  241. pNdisPacket->Private.TotalLength,
  242. pBuffer[0],
  243. pBuffer[1],
  244. pBuffer[2],
  245. pBuffer[3],
  246. pBuffer[4]
  247. );
  248. }
  249. #endif
  250. #if DEBUG_SPIN_LOCK
  251. ULONG SpinLockInitDone = 0;
  252. NDIS_SPIN_LOCK LockLock;
  253. VOID
  254. AtmLaneAllocateSpinLock(
  255. IN PATMLANE_LOCK pLock,
  256. IN PUCHAR String,
  257. IN PUCHAR FileName,
  258. IN ULONG LineNumber
  259. )
  260. {
  261. DBGP((2, "ALLOCATE LOCK %x %s\n", pLock, String));
  262. if (SpinLockInitDone == 0)
  263. {
  264. SpinLockInitDone = 1;
  265. NdisAllocateSpinLock(&(LockLock));
  266. }
  267. NdisAcquireSpinLock(&(LockLock));
  268. pLock->Signature = ATMLANE_LOCK_SIG;
  269. NdisMoveMemory(pLock->TouchedByFileName, FileName, 32);
  270. pLock->TouchedByFileName[31] = 0x0;
  271. pLock->TouchedInLineNumber = LineNumber;
  272. pLock->IsAcquired = 0;
  273. pLock->OwnerThread = 0;
  274. NdisAllocateSpinLock(&(pLock->NdisLock));
  275. NdisReleaseSpinLock(&(LockLock));
  276. }
  277. VOID
  278. AtmLaneFreeSpinLock(
  279. IN PATMLANE_LOCK pLock,
  280. IN PUCHAR String,
  281. IN PUCHAR FileName,
  282. IN ULONG LineNumber
  283. )
  284. {
  285. DBGP((2, "FREE LOCK %x %s\n", pLock, String));
  286. NdisFreeSpinLock(pLock);
  287. }
  288. VOID
  289. AtmLaneAcquireSpinLock(
  290. IN PATMLANE_LOCK pLock,
  291. IN PUCHAR String,
  292. IN PUCHAR FileName,
  293. IN ULONG LineNumber
  294. )
  295. {
  296. PKTHREAD pThread;
  297. DBGP((4, "ACQUIRE LOCK %x %s\n", pLock, String));
  298. pThread = KeGetCurrentThread();
  299. NdisAcquireSpinLock(&(LockLock));
  300. if (pLock->Signature != ATMLANE_LOCK_SIG)
  301. {
  302. DbgPrint("Trying to acquire uninited lock %x, File %s, Line %d\n",
  303. pLock, FileName, LineNumber);
  304. DbgBreakPoint();
  305. }
  306. if (pLock->IsAcquired != 0)
  307. {
  308. if (pLock->OwnerThread == pThread)
  309. {
  310. DbgPrint("Detected multiple locking!: pLock %x, File %s, Line %d\n",
  311. pLock, FileName, LineNumber);
  312. DbgPrint("pLock %x already acquired in File %s, Line %d\n",
  313. pLock,
  314. pLock->TouchedByFileName,
  315. pLock->TouchedInLineNumber);
  316. DbgBreakPoint();
  317. }
  318. }
  319. //
  320. // Mark this lock.
  321. //
  322. pLock->IsAcquired++;
  323. NdisReleaseSpinLock(&(LockLock));
  324. NdisAcquireSpinLock(&(pLock->NdisLock));
  325. pLock->OwnerThread = pThread;
  326. NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
  327. pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
  328. pLock->TouchedInLineNumber = LineNumber;
  329. }
  330. VOID
  331. AtmLaneReleaseSpinLock(
  332. IN PATMLANE_LOCK pLock,
  333. IN PUCHAR String,
  334. IN PUCHAR FileName,
  335. IN ULONG LineNumber
  336. )
  337. {
  338. DBGP((4, "RELEASE LOCK %x %s\n", pLock, String));
  339. NdisAcquireSpinLock(&(LockLock));
  340. if (pLock->Signature != ATMLANE_LOCK_SIG)
  341. {
  342. DbgPrint("Trying to release uninited lock %x, File %s, Line %d\n",
  343. pLock,
  344. FileName,
  345. LineNumber);
  346. DbgBreakPoint();
  347. }
  348. if (pLock->IsAcquired == 0)
  349. {
  350. DbgPrint("Detected release of unacquired lock %x, File %s, Line %d\n",
  351. pLock,
  352. FileName,
  353. LineNumber);
  354. DbgBreakPoint();
  355. }
  356. NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
  357. pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
  358. pLock->TouchedInLineNumber = LineNumber;
  359. pLock->IsAcquired--;
  360. pLock->OwnerThread = 0;
  361. NdisReleaseSpinLock(&(LockLock));
  362. NdisReleaseSpinLock(&(pLock->NdisLock));
  363. }
  364. #endif // DEBUG_SPIN_LOCK