windows-nt/Source/XPSP1/NT/net/atm/lane/sys/debug.c
2020-09-26 16:20:57 +08:00

450 lines
8.7 KiB
C

/*++
Copyright (c) 1997 FORE Systems, Inc.
Copyright (c) 1997 Microsoft Corporation
Module Name:
debug.c
Abstract:
This file contains debugging support.
Author:
Larry Cleeton, FORE Systems (v-lcleet@microsoft.com, lrc@fore.com)
Environment:
Kernel mode
Revision History:
--*/
#include "precomp.h"
#include <stdarg.h>
#include <stdio.h>
#pragma hdrstop
#if DBG
ULONG DbgVerbosity = 0;
#if DBG_TRACE
ULONG DbgLogSize = 128*1024;
TRACELOG TraceLog;
PUCHAR pTraceLogSpace;
#endif
#include "oidstrng.h"
#include "irpstrng.h"
#define MAX_HD_LENGTH 128
VOID
DbgOut(ULONG Level, PUCHAR Message, ...)
{
char buf[DBG_OUTBUF_SIZE];
va_list ap;
LONG numchars;
if (Level > DbgVerbosity)
return;
va_start(ap, Message);
numchars = _vsnprintf(buf, DBG_OUTBUF_SIZE, Message, ap);
buf[DBG_OUTBUF_SIZE-1] = '\0';
DbgPrint("ATMLANE: %s", buf);
}
//
// Careful! Uses static storage for string
//
PUCHAR
UnicodeToString(PUNICODE_STRING unicodeString)
{
static CHAR ansiStringBuffer[129];
ANSI_STRING ansiString;
ansiString.Length = 0;
ansiString.MaximumLength = 128;
ansiString.Buffer = ansiStringBuffer;
if (unicodeString->Length > 0)
{
NdisUnicodeStringToAnsiString(
&ansiString,
unicodeString);
}
ansiStringBuffer[ansiString.Length] = '\0';
return ansiStringBuffer;
}
//
// Careful! Uses static storage for string.
//
PUCHAR
MacAddrToString(PVOID In)
{
static UCHAR String[20];
static PUCHAR HexChars = "0123456789abcdef";
PUCHAR EthAddr = (PUCHAR) In;
UINT i;
PUCHAR s;
for (i = 0, s = String; i < 6; i++, EthAddr++)
{
*s++ = HexChars[(*EthAddr)>>4];
*s++ = HexChars[(*EthAddr)&0xf];
}
*s = '\0';
return String;
}
//
// Careful! Uses static storage for string.
//
PUCHAR
AtmAddrToString(PVOID In)
{
static UCHAR String[80];
static PUCHAR HexChars = "0123456789abcdef";
PUCHAR AtmAddr = (PUCHAR) In;
UINT i;
PUCHAR s = String;
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 1
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 2
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 3
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 4
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 5
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 6
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 7
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 8
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 9
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 10
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 11
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 12
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 13
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 14
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 15
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 16
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 17
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 18
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 19
*s++ = '.';
*s++ = HexChars[(*AtmAddr)>>4];
*s++ = HexChars[(*AtmAddr++)&0xf]; // 20
*s = '\0';
return String;
}
PUCHAR
OidToString(ULONG Oid)
{
struct _string_table *oidtab;
for (oidtab = &oid_string_table[0]; oidtab->value != 0; oidtab++)
if (oidtab->value == Oid)
return oidtab->string;
return oid_string_table[(sizeof(oid_string_table) /
sizeof(struct _string_table)) - 1].string;
}
PUCHAR
IrpToString(ULONG Irp)
{
struct _string_table *irptab;
for (irptab = &irp_string_table[0]; irptab->value != 0xffffffff; irptab++)
if (irptab->value == Irp)
return irptab->string;
return irp_string_table[(sizeof(irp_string_table) /
sizeof(struct _string_table)) - 1].string;
}
VOID
DbgPrintHexDump(
IN ULONG Level,
IN PUCHAR pBuffer,
IN ULONG Length
)
/*++
Routine Description:
Print a hex dump of the given contiguous buffer. If the length
is too long, we truncate it.
Arguments:
pBuffer - Points to start of data to be dumped
Length - Length of above.
Return Value:
None
--*/
{
ULONG i;
if (Level > DbgVerbosity)
return;
if (Length > MAX_HD_LENGTH)
{
Length = MAX_HD_LENGTH;
}
for (i = 0; i < Length; i++)
{
//
// Check if we are at the end of a line
//
if ((i > 0) && ((i & 0xf) == 0))
{
DbgPrint("\n");
}
//
// Print addr if we are at start of a new line
//
if ((i & 0xf) == 0)
{
DbgPrint("%08x ", pBuffer);
}
DbgPrint(" %02x", *pBuffer++);
}
//
// Terminate the last line.
//
if (Length > 0)
{
DbgPrint("\n");
}
}
VOID
TraceLogWritePkt(
IN PTRACELOG pTraceLog,
IN PNDIS_PACKET pNdisPacket
)
{
PNDIS_BUFFER pBuffer[5] = {(PNDIS_BUFFER)NULL};
do
{
pBuffer[0] = pNdisPacket->Private.Head;
if (pBuffer[0] == (PNDIS_BUFFER)NULL)
break;
pBuffer[1] = pBuffer[0]->Next;
if (pBuffer[1] == (PNDIS_BUFFER)NULL)
break;
pBuffer[2] = pBuffer[1]->Next;
if (pBuffer[2] == (PNDIS_BUFFER)NULL)
break;
pBuffer[3] = pBuffer[2]->Next;
if (pBuffer[3] == (PNDIS_BUFFER)NULL)
break;
pBuffer[4] = pBuffer[3]->Next;
}
while (FALSE);
TraceLogWrite(
pTraceLog,
TL_NDISPACKET,
pNdisPacket,
pNdisPacket->Private.PhysicalCount,
pNdisPacket->Private.TotalLength,
pBuffer[0],
pBuffer[1],
pBuffer[2],
pBuffer[3],
pBuffer[4]
);
}
#endif
#if DEBUG_SPIN_LOCK
ULONG SpinLockInitDone = 0;
NDIS_SPIN_LOCK LockLock;
VOID
AtmLaneAllocateSpinLock(
IN PATMLANE_LOCK pLock,
IN PUCHAR String,
IN PUCHAR FileName,
IN ULONG LineNumber
)
{
DBGP((2, "ALLOCATE LOCK %x %s\n", pLock, String));
if (SpinLockInitDone == 0)
{
SpinLockInitDone = 1;
NdisAllocateSpinLock(&(LockLock));
}
NdisAcquireSpinLock(&(LockLock));
pLock->Signature = ATMLANE_LOCK_SIG;
NdisMoveMemory(pLock->TouchedByFileName, FileName, 32);
pLock->TouchedByFileName[31] = 0x0;
pLock->TouchedInLineNumber = LineNumber;
pLock->IsAcquired = 0;
pLock->OwnerThread = 0;
NdisAllocateSpinLock(&(pLock->NdisLock));
NdisReleaseSpinLock(&(LockLock));
}
VOID
AtmLaneFreeSpinLock(
IN PATMLANE_LOCK pLock,
IN PUCHAR String,
IN PUCHAR FileName,
IN ULONG LineNumber
)
{
DBGP((2, "FREE LOCK %x %s\n", pLock, String));
NdisFreeSpinLock(pLock);
}
VOID
AtmLaneAcquireSpinLock(
IN PATMLANE_LOCK pLock,
IN PUCHAR String,
IN PUCHAR FileName,
IN ULONG LineNumber
)
{
PKTHREAD pThread;
DBGP((4, "ACQUIRE LOCK %x %s\n", pLock, String));
pThread = KeGetCurrentThread();
NdisAcquireSpinLock(&(LockLock));
if (pLock->Signature != ATMLANE_LOCK_SIG)
{
DbgPrint("Trying to acquire uninited lock %x, File %s, Line %d\n",
pLock, FileName, LineNumber);
DbgBreakPoint();
}
if (pLock->IsAcquired != 0)
{
if (pLock->OwnerThread == pThread)
{
DbgPrint("Detected multiple locking!: pLock %x, File %s, Line %d\n",
pLock, FileName, LineNumber);
DbgPrint("pLock %x already acquired in File %s, Line %d\n",
pLock,
pLock->TouchedByFileName,
pLock->TouchedInLineNumber);
DbgBreakPoint();
}
}
//
// Mark this lock.
//
pLock->IsAcquired++;
NdisReleaseSpinLock(&(LockLock));
NdisAcquireSpinLock(&(pLock->NdisLock));
pLock->OwnerThread = pThread;
NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
pLock->TouchedInLineNumber = LineNumber;
}
VOID
AtmLaneReleaseSpinLock(
IN PATMLANE_LOCK pLock,
IN PUCHAR String,
IN PUCHAR FileName,
IN ULONG LineNumber
)
{
DBGP((4, "RELEASE LOCK %x %s\n", pLock, String));
NdisAcquireSpinLock(&(LockLock));
if (pLock->Signature != ATMLANE_LOCK_SIG)
{
DbgPrint("Trying to release uninited lock %x, File %s, Line %d\n",
pLock,
FileName,
LineNumber);
DbgBreakPoint();
}
if (pLock->IsAcquired == 0)
{
DbgPrint("Detected release of unacquired lock %x, File %s, Line %d\n",
pLock,
FileName,
LineNumber);
DbgBreakPoint();
}
NdisMoveMemory(pLock->TouchedByFileName, FileName, LOCK_FILE_NAME_LEN);
pLock->TouchedByFileName[LOCK_FILE_NAME_LEN - 1] = 0x0;
pLock->TouchedInLineNumber = LineNumber;
pLock->IsAcquired--;
pLock->OwnerThread = 0;
NdisReleaseSpinLock(&(LockLock));
NdisReleaseSpinLock(&(pLock->NdisLock));
}
#endif // DEBUG_SPIN_LOCK