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.

640 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. D:\nt\private\ntos\tdi\rawwan\core\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. #include "ntddk.h"
  15. #include "ndis.h"
  16. #include "atm.h"
  17. #define STRUCT_OF(type, address, field) CONTAINING_RECORD(address, type, field)
  18. #include "debug.h"
  19. ULONG gHackSendSize = 0;
  20. #if DBG
  21. INT RWanDebugLevel=DL_WARN;
  22. ULONG RWanDebugComp=DC_WILDCARD;
  23. INT RWanDataDebugLevel=0;
  24. INT RWandBigDataLength=8000;
  25. INT RWanSkipAll = 0;
  26. #if DBG_LOG_PACKETS
  27. NDIS_SPIN_LOCK RWanDPacketLogLock;
  28. #endif
  29. NDIS_SPIN_LOCK RWanDbgLogLock;
  30. PRWAND_ALLOCATION RWandMemoryHead = (PRWAND_ALLOCATION)NULL;
  31. PRWAND_ALLOCATION RWandMemoryTail = (PRWAND_ALLOCATION)NULL;
  32. ULONG RWandAllocCount = 0; // how many allocated so far (unfreed)
  33. NDIS_SPIN_LOCK RWandMemoryLock;
  34. BOOLEAN RWandInitDone = FALSE;
  35. PVOID
  36. RWanAuditAllocMem(
  37. PVOID pPointer,
  38. ULONG Size,
  39. ULONG FileNumber,
  40. ULONG LineNumber
  41. )
  42. {
  43. PVOID pBuffer;
  44. PRWAND_ALLOCATION pAllocInfo;
  45. if (!RWandInitDone)
  46. {
  47. NdisAllocateSpinLock(&(RWandMemoryLock));
  48. RWandInitDone = TRUE;
  49. }
  50. NdisAllocateMemoryWithTag(
  51. (PVOID *)&pAllocInfo,
  52. Size+sizeof(RWAND_ALLOCATION),
  53. (ULONG)'naWR'
  54. );
  55. if (pAllocInfo == (PRWAND_ALLOCATION)NULL)
  56. {
  57. RWANDEBUGP(DL_VERY_LOUD+50, DC_WILDCARD,
  58. ("RWanAuditAllocMem: file %d, line %d, Size %d failed!\n",
  59. FileNumber, LineNumber, Size));
  60. pBuffer = NULL;
  61. }
  62. else
  63. {
  64. pBuffer = (PVOID)&(pAllocInfo->UserData);
  65. RWAN_SET_MEM(pBuffer, 0xaf, Size);
  66. pAllocInfo->Signature = RWAND_MEMORY_SIGNATURE;
  67. pAllocInfo->FileNumber = FileNumber;
  68. pAllocInfo->LineNumber = LineNumber;
  69. pAllocInfo->Size = Size;
  70. pAllocInfo->Location = (ULONG_PTR)pPointer;
  71. pAllocInfo->Next = (PRWAND_ALLOCATION)NULL;
  72. NdisAcquireSpinLock(&(RWandMemoryLock));
  73. pAllocInfo->Prev = RWandMemoryTail;
  74. if (RWandMemoryTail == (PRWAND_ALLOCATION)NULL)
  75. {
  76. // empty list
  77. RWandMemoryHead = RWandMemoryTail = pAllocInfo;
  78. }
  79. else
  80. {
  81. RWandMemoryTail->Next = pAllocInfo;
  82. }
  83. RWandMemoryTail = pAllocInfo;
  84. RWandAllocCount++;
  85. NdisReleaseSpinLock(&(RWandMemoryLock));
  86. }
  87. RWANDEBUGP(DL_VERY_LOUD+100, DC_WILDCARD,
  88. ("RWanAuditAllocMem: file %c%c%c%c, line %d, %d bytes, [0x%x] <- 0x%x\n",
  89. (CHAR)(FileNumber & 0xff),
  90. (CHAR)((FileNumber >> 8) & 0xff),
  91. (CHAR)((FileNumber >> 16) & 0xff),
  92. (CHAR)((FileNumber >> 24) & 0xff),
  93. LineNumber, Size, pPointer, pBuffer));
  94. return (pBuffer);
  95. }
  96. VOID
  97. RWanAuditFreeMem(
  98. PVOID Pointer
  99. )
  100. {
  101. PRWAND_ALLOCATION pAllocInfo;
  102. NdisAcquireSpinLock(&(RWandMemoryLock));
  103. pAllocInfo = STRUCT_OF(RWAND_ALLOCATION, Pointer, UserData);
  104. if (pAllocInfo->Signature != RWAND_MEMORY_SIGNATURE)
  105. {
  106. RWANDEBUGP(DL_ERROR, DC_WILDCARD,
  107. ("RWanAuditFreeMem: unknown buffer 0x%x!\n", Pointer));
  108. NdisReleaseSpinLock(&(RWandMemoryLock));
  109. #ifdef DBG
  110. DbgBreakPoint();
  111. #endif
  112. return;
  113. }
  114. pAllocInfo->Signature = (ULONG)'DEAD';
  115. if (pAllocInfo->Prev != (PRWAND_ALLOCATION)NULL)
  116. {
  117. pAllocInfo->Prev->Next = pAllocInfo->Next;
  118. }
  119. else
  120. {
  121. RWandMemoryHead = pAllocInfo->Next;
  122. }
  123. if (pAllocInfo->Next != (PRWAND_ALLOCATION)NULL)
  124. {
  125. pAllocInfo->Next->Prev = pAllocInfo->Prev;
  126. }
  127. else
  128. {
  129. RWandMemoryTail = pAllocInfo->Prev;
  130. }
  131. RWandAllocCount--;
  132. NdisReleaseSpinLock(&(RWandMemoryLock));
  133. NdisFreeMemory(pAllocInfo, 0, 0);
  134. }
  135. VOID
  136. RWanAuditShutdown(
  137. VOID
  138. )
  139. {
  140. if (RWandInitDone)
  141. {
  142. if (RWandAllocCount != 0)
  143. {
  144. RWANDEBUGP(DL_ERROR, DC_WILDCARD, ("AuditShutdown: unfreed memory, %d blocks!\n",
  145. RWandAllocCount));
  146. RWANDEBUGP(DL_ERROR, DC_WILDCARD, ("MemoryHead: 0x%x, MemoryTail: 0x%x\n",
  147. RWandMemoryHead, RWandMemoryTail));
  148. DbgBreakPoint();
  149. {
  150. PRWAND_ALLOCATION pAllocInfo;
  151. while (RWandMemoryHead != (PRWAND_ALLOCATION)NULL)
  152. {
  153. pAllocInfo = RWandMemoryHead;
  154. RWANDEBUGP(DL_INFO, DC_WILDCARD, ("AuditShutdown: will free 0x%x\n", pAllocInfo));
  155. RWanAuditFreeMem(&(pAllocInfo->UserData));
  156. }
  157. }
  158. }
  159. RWandInitDone = FALSE;
  160. }
  161. }
  162. #define MAX_HD_LENGTH 128
  163. VOID
  164. DbgPrintHexDump(
  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 (Length > MAX_HD_LENGTH)
  181. {
  182. Length = MAX_HD_LENGTH;
  183. }
  184. for (i = 0; i < Length; i++)
  185. {
  186. //
  187. // Check if we are at the end of a line
  188. //
  189. if ((i > 0) && ((i & 0xf) == 0))
  190. {
  191. DbgPrint("\n");
  192. }
  193. //
  194. // Print addr if we are at start of a new line
  195. //
  196. if ((i & 0xf) == 0)
  197. {
  198. DbgPrint("%08x ", pBuffer);
  199. }
  200. DbgPrint(" %02x", *pBuffer++);
  201. }
  202. //
  203. // Terminate the last line.
  204. //
  205. if (Length > 0)
  206. {
  207. DbgPrint("\n");
  208. }
  209. }
  210. VOID
  211. DbgPrintAtmAddr(
  212. IN PCHAR pString,
  213. IN ATM_ADDRESS UNALIGNED * pAddr
  214. )
  215. {
  216. ULONG i;
  217. ULONG NumOfDigits;
  218. PUCHAR pSrc, pDst;
  219. UCHAR AddrString[(ATM_ADDRESS_LENGTH*2) + 1];
  220. //
  221. // Prepare the Address string in ASCII
  222. //
  223. if ((NumOfDigits = pAddr->NumberOfDigits) > ATM_ADDRESS_LENGTH)
  224. {
  225. NumOfDigits = ATM_ADDRESS_LENGTH;
  226. }
  227. pSrc = pAddr->Address;
  228. pDst = AddrString;
  229. for (i = 0; i < NumOfDigits; i++, pSrc++)
  230. {
  231. *pDst = ((*pSrc) >> 4);
  232. *pDst += (((*pDst) > 9) ? ('A' - 10) : '0');
  233. pDst++;
  234. *pDst = ((*pSrc) & 0x0F);
  235. *pDst += (((*pDst) > 9) ? ('A' - 10) : '0');
  236. pDst++;
  237. }
  238. *pDst = '\0';
  239. DbgPrint("%s%s\n", pString, AddrString);
  240. }
  241. VOID
  242. RWanCoSendPackets(
  243. IN NDIS_HANDLE NdisVcHandle,
  244. IN PNDIS_PACKET * PacketArray,
  245. IN UINT PacketCount
  246. )
  247. {
  248. PNDIS_PACKET pNdisPacket;
  249. UINT c;
  250. NDIS_STATUS Status;
  251. PNDIS_BUFFER pNdisBuffer;
  252. PULONG pContext;
  253. for (c = 0; c < PacketCount; c++)
  254. {
  255. pNdisPacket = PacketArray[c];
  256. RWAN_ASSERT(pNdisPacket->Private.Head != NULL);
  257. Status = NDIS_GET_PACKET_STATUS(pNdisPacket);
  258. RWAN_ASSERT(Status != NDIS_STATUS_FAILURE);
  259. for (pNdisBuffer = pNdisPacket->Private.Head;
  260. pNdisBuffer != NULL;
  261. pNdisBuffer = pNdisBuffer->Next)
  262. {
  263. if (pNdisBuffer->Next == NULL)
  264. {
  265. RWAN_ASSERT(pNdisBuffer == pNdisPacket->Private.Tail);
  266. }
  267. }
  268. pContext = (PULONG)&(pNdisPacket->WrapperReserved[0]);
  269. *pContext = 'RWan';
  270. }
  271. NdisCoSendPackets(NdisVcHandle, PacketArray, PacketCount);
  272. }
  273. #endif // DBG
  274. #if DBG_SPIN_LOCK
  275. ULONG RWandSpinLockInitDone = 0;
  276. NDIS_SPIN_LOCK RWandLockLock;
  277. VOID
  278. RWanAllocateSpinLock(
  279. IN PRWAN_LOCK pLock,
  280. IN ULONG FileNumber,
  281. IN ULONG LineNumber
  282. )
  283. {
  284. if (RWandSpinLockInitDone == 0)
  285. {
  286. RWandSpinLockInitDone = 1;
  287. NdisAllocateSpinLock(&(RWandLockLock));
  288. }
  289. NdisAcquireSpinLock(&(RWandLockLock));
  290. pLock->Signature = RWANL_SIG;
  291. pLock->TouchedByFileNumber = FileNumber;
  292. pLock->TouchedInLineNumber = LineNumber;
  293. pLock->IsAcquired = 0;
  294. pLock->OwnerThread = 0;
  295. NdisAllocateSpinLock(&(pLock->NdisLock));
  296. NdisReleaseSpinLock(&(RWandLockLock));
  297. }
  298. VOID
  299. RWanAcquireSpinLock(
  300. IN PRWAN_LOCK pLock,
  301. IN ULONG FileNumber,
  302. IN ULONG LineNumber
  303. )
  304. {
  305. PKTHREAD pThread;
  306. pThread = KeGetCurrentThread();
  307. NdisAcquireSpinLock(&(RWandLockLock));
  308. if (pLock->Signature != RWANL_SIG)
  309. {
  310. DbgPrint("Trying to acquire uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  311. pLock,
  312. (CHAR)(FileNumber & 0xff),
  313. (CHAR)((FileNumber >> 8) & 0xff),
  314. (CHAR)((FileNumber >> 16) & 0xff),
  315. (CHAR)((FileNumber >> 24) & 0xff),
  316. LineNumber);
  317. DbgBreakPoint();
  318. }
  319. if (pLock->IsAcquired != 0)
  320. {
  321. if (pLock->OwnerThread == pThread)
  322. {
  323. DbgPrint("Detected multiple locking!: pLock 0x%x, File %c%c%c%c, Line %d\n",
  324. pLock,
  325. (CHAR)(FileNumber & 0xff),
  326. (CHAR)((FileNumber >> 8) & 0xff),
  327. (CHAR)((FileNumber >> 16) & 0xff),
  328. (CHAR)((FileNumber >> 24) & 0xff),
  329. LineNumber);
  330. DbgPrint("pLock 0x%x already acquired in File %c%c%c%c, Line %d\n",
  331. pLock,
  332. (CHAR)(pLock->TouchedByFileNumber & 0xff),
  333. (CHAR)((pLock->TouchedByFileNumber >> 8) & 0xff),
  334. (CHAR)((pLock->TouchedByFileNumber >> 16) & 0xff),
  335. (CHAR)((pLock->TouchedByFileNumber >> 24) & 0xff),
  336. pLock->TouchedInLineNumber);
  337. DbgBreakPoint();
  338. }
  339. }
  340. pLock->IsAcquired++;
  341. NdisReleaseSpinLock(&(RWandLockLock));
  342. NdisAcquireSpinLock(&(pLock->NdisLock));
  343. //
  344. // Mark this lock.
  345. //
  346. pLock->OwnerThread = pThread;
  347. pLock->TouchedByFileNumber = FileNumber;
  348. pLock->TouchedInLineNumber = LineNumber;
  349. }
  350. VOID
  351. RWanReleaseSpinLock(
  352. IN PRWAN_LOCK pLock,
  353. IN ULONG FileNumber,
  354. IN ULONG LineNumber
  355. )
  356. {
  357. NdisDprAcquireSpinLock(&(RWandLockLock));
  358. if (pLock->Signature != RWANL_SIG)
  359. {
  360. DbgPrint("Trying to release uninited lock 0x%x, File %c%c%c%c, Line %d\n",
  361. pLock,
  362. (CHAR)(FileNumber & 0xff),
  363. (CHAR)((FileNumber >> 8) & 0xff),
  364. (CHAR)((FileNumber >> 16) & 0xff),
  365. (CHAR)((FileNumber >> 24) & 0xff),
  366. LineNumber);
  367. DbgBreakPoint();
  368. }
  369. if (pLock->IsAcquired == 0)
  370. {
  371. DbgPrint("Detected release of unacquired lock 0x%x, File %c%c%c%c, Line %d\n",
  372. pLock,
  373. (CHAR)(FileNumber & 0xff),
  374. (CHAR)((FileNumber >> 8) & 0xff),
  375. (CHAR)((FileNumber >> 16) & 0xff),
  376. (CHAR)((FileNumber >> 24) & 0xff),
  377. LineNumber);
  378. DbgBreakPoint();
  379. }
  380. pLock->TouchedByFileNumber = FileNumber;
  381. pLock->TouchedInLineNumber = LineNumber;
  382. pLock->IsAcquired--;
  383. pLock->OwnerThread = 0;
  384. NdisDprReleaseSpinLock(&(RWandLockLock));
  385. NdisReleaseSpinLock(&(pLock->NdisLock));
  386. }
  387. #endif // DBG_SPIN_LOCK
  388. #ifdef PERF
  389. #define MAX_SEND_LOG_ENTRIES 100
  390. LARGE_INTEGER TimeFrequency;
  391. BOOLEAN SendLogInitDone = FALSE;
  392. BOOLEAN SendLogUpdate = TRUE;
  393. NDIS_SPIN_LOCK SendLogLock;
  394. DL_SEND_LOG_ENTRY SendLog[MAX_SEND_LOG_ENTRIES];
  395. ULONG SendLogIndex = 0;
  396. PDL_SEND_LOG_ENTRY pSendLog = SendLog;
  397. ULONG MaxSendTime;
  398. #define TIME_TO_ULONG(_pTime) *((PULONG)_pTime)
  399. VOID
  400. RWandLogSendStart(
  401. IN PNDIS_PACKET pNdisPacket,
  402. IN ULONG Destination,
  403. IN PVOID pRCE
  404. )
  405. {
  406. ULONG Length;
  407. if (SendLogInitDone == FALSE)
  408. {
  409. SendLogInitDone = TRUE;
  410. (VOID)KeQueryPerformanceCounter(&TimeFrequency);
  411. MaxSendTime = (TIME_TO_ULONG(&TimeFrequency) * 2)/3;
  412. NdisAllocateSpinLock(&SendLogLock);
  413. }
  414. NdisQueryPacket(
  415. pNdisPacket,
  416. NULL,
  417. NULL,
  418. NULL,
  419. &Length
  420. );
  421. NdisAcquireSpinLock(&SendLogLock);
  422. pSendLog->Flags = DL_SEND_FLAG_WAITING_COMPLETION;
  423. if (pRCE != NULL)
  424. {
  425. pSendLog->Flags |= DL_SEND_FLAG_RCE_GIVEN;
  426. }
  427. pSendLog->pNdisPacket = pNdisPacket;
  428. pSendLog->Destination = Destination;
  429. pSendLog->Length = Length;
  430. pSendLog->SendTime = KeQueryPerformanceCounter(&TimeFrequency);
  431. pSendLog++;
  432. SendLogIndex++;
  433. if (SendLogIndex == MAX_SEND_LOG_ENTRIES)
  434. {
  435. SendLogIndex = 0;
  436. pSendLog = SendLog;
  437. }
  438. NdisReleaseSpinLock(&SendLogLock);
  439. }
  440. VOID
  441. RWandLogSendUpdate(
  442. IN PNDIS_PACKET pNdisPacket
  443. )
  444. {
  445. PDL_SEND_LOG_ENTRY pEntry;
  446. ULONG Index;
  447. ULONG SendTime;
  448. if (!SendLogUpdate)
  449. {
  450. return;
  451. }
  452. NdisAcquireSpinLock(&SendLogLock);
  453. pEntry = SendLog;
  454. for (Index = 0; Index < MAX_SEND_LOG_ENTRIES; Index++)
  455. {
  456. if (((pEntry->Flags & DL_SEND_FLAG_WAITING_COMPLETION) != 0) &&
  457. (pEntry->pNdisPacket == pNdisPacket))
  458. {
  459. pEntry->SendTime = KeQueryPerformanceCounter(&TimeFrequency);
  460. break;
  461. }
  462. pEntry++;
  463. }
  464. NdisReleaseSpinLock(&SendLogLock);
  465. }
  466. VOID
  467. RWandLogSendComplete(
  468. IN PNDIS_PACKET pNdisPacket
  469. )
  470. {
  471. PDL_SEND_LOG_ENTRY pEntry;
  472. ULONG Index;
  473. ULONG SendTime;
  474. NdisAcquireSpinLock(&SendLogLock);
  475. pEntry = SendLog;
  476. for (Index = 0; Index < MAX_SEND_LOG_ENTRIES; Index++)
  477. {
  478. if (((pEntry->Flags & DL_SEND_FLAG_WAITING_COMPLETION) != 0) &&
  479. (pEntry->pNdisPacket == pNdisPacket))
  480. {
  481. pEntry->Flags &= ~DL_SEND_FLAG_WAITING_COMPLETION;
  482. pEntry->Flags |= DL_SEND_FLAG_COMPLETED;
  483. pEntry->SendCompleteTime = KeQueryPerformanceCounter(&TimeFrequency);
  484. if (((pEntry->Flags & DL_SEND_FLAG_RCE_GIVEN) != 0) &&
  485. ((SendTime = TIME_TO_ULONG(&pEntry->SendCompleteTime) -
  486. TIME_TO_ULONG(&pEntry->SendTime)) > MaxSendTime))
  487. {
  488. DbgPrint("Dest %d.%d.%d.%d, Pkt 0x%x, Len %d, Flags 0x%x, Took Long %d (0x%x)\n",
  489. ((PUCHAR)&pEntry->Destination)[0],
  490. ((PUCHAR)&pEntry->Destination)[1],
  491. ((PUCHAR)&pEntry->Destination)[2],
  492. ((PUCHAR)&pEntry->Destination)[3],
  493. pNdisPacket, pEntry->Length, pEntry->Flags, SendTime, SendTime);
  494. }
  495. break;
  496. }
  497. pEntry++;
  498. }
  499. NdisReleaseSpinLock(&SendLogLock);
  500. }
  501. VOID
  502. RWandLogSendAbort(
  503. IN PNDIS_PACKET pNdisPacket
  504. )
  505. {
  506. PDL_SEND_LOG_ENTRY pEntry;
  507. ULONG Index;
  508. ULONG SendTime;
  509. NdisAcquireSpinLock(&SendLogLock);
  510. pEntry = SendLog;
  511. for (Index = 0; Index < MAX_SEND_LOG_ENTRIES; Index++)
  512. {
  513. if (((pEntry->Flags & DL_SEND_FLAG_WAITING_COMPLETION) != 0) &&
  514. (pEntry->pNdisPacket == pNdisPacket))
  515. {
  516. pEntry->Flags = 0;
  517. break;
  518. }
  519. pEntry++;
  520. }
  521. NdisReleaseSpinLock(&SendLogLock);
  522. }
  523. #endif // PERF