Skip to content

Commit

Permalink
Move WinDbg Extension to GitHub (#126)
Browse files Browse the repository at this point in the history
  • Loading branch information
nibanks authored Feb 12, 2020
1 parent 882a941 commit 51d021f
Show file tree
Hide file tree
Showing 18 changed files with 2,686 additions and 0 deletions.
116 changes: 116 additions & 0 deletions src/tools/dbg/analyze.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC Debugger Extension Command 'analyze'. This command is for analyzing
possible issues on a QUIC handle.
--*/

#include "quictypes.h"

EXT_COMMAND(
quicanalyze,
"Analyze issues of a handle",
"{;e,r;addr;The address of the handle}"
)
{
QuicHandle Handle(GetUnnamedArgU64(0));
auto Type = Handle.Type();

if (Type == QUIC_HANDLE_TYPE_CLIENT || Type == QUIC_HANDLE_TYPE_CHILD) {
AnalyzeConnection(Handle.Addr);
} else if (Type == QUIC_HANDLE_TYPE_STREAM) {
AnalyzeStream(Handle.Addr);
} else {
Dml("Not supported for handle type: %s", Handle.TypeStr());
}

Dml("\n");
}

void EXT_CLASS::AnalyzeConnection(UINT64 Addr)
{
Connection Conn(Addr);

QUIC_CONNECTION_STATE state = Conn.State();
if (state.Freed) {
Dml("The connection has been freed.\n");
} else if (state.HandleClosed) {
Dml("The connection has been closed by the application and is in the process of being deleted.\n");
} else if (state.HandleShutdown) {
Dml("The connection has completed the shutdown process and is ready to be closed by the application.\n");
} else if (state.ClosedLocally || state.ClosedRemotely) {
Dml("The connection is in the process of shutting down.");
if (state.ClosedLocally) {
Dml(" It has been closed locally.");
}
if (state.ClosedRemotely) {
Dml(" It has been closed remotely.");
}
Dml("\n");
} else if (state.Connected) {
Dml("The connection is connected.\n");
} else if (state.Started) {
Dml("The connection is in the process of performing the handshake.\n");
} else if (state.Initialized) {
Dml("The connection has been allocated and successfully initialized.\n");
} else if (state.Allocated) {
Dml("The connection has been allocated.\n");
} else {
Dml("The connection is invalid.\n");
}

//
// TODO ...
//
}

void EXT_CLASS::AnalyzeStream(UINT64 Addr)
{
Stream Strm(Addr);

QUIC_STREAM_FLAGS flags = Strm.Flags();
if (flags.Freed) {
Dml("The stream has been freed.\n");
} else if (flags.HandleClosed) {
Dml("The stream has been closed by the application.\n");
} else if (flags.HandleShutdown) {
Dml("The stream has completed the shutdown process and is ready to be closed by the application.\n");
} else {
auto LocallyClosed = flags.LocalCloseFin || flags.LocalCloseReset;
auto RemotelyClosed = flags.RemoteCloseFin || flags.RemoteCloseReset;

if (RemotelyClosed) {
if (flags.RemoteCloseAcked) {
Dml("The stream's receive pipe has been closed and acknowledged.\n");
} else {
Dml("The stream's receive pipe has been closed but not yet acknowledged.\n");
}
} else {
Dml("The stream's receive pipe is open.\n");
}

if (LocallyClosed) {
if (flags.LocalCloseAcked) {
Dml("The stream's send pipe has been closed and acknowledged.\n");
} else {
Dml("The stream's send pipe has been closed but not yet acknowledged.\n");
}
} else {
Dml("The stream's send pipe is open.\n");
}
}

UINT32 SendRequestsCount = 0;
ULONG64 SendRequestsPtr = Strm.SendRequests();
while (SendRequestsPtr != 0) {
SendRequest Request(SendRequestsPtr);
SendRequestsPtr = Request.Next();
SendRequestsCount++;
}
Dml("The stream has %u send requests pending.\n", SendRequestsCount);
}
92 changes: 92 additions & 0 deletions src/tools/dbg/binding.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*++
Copyright (c) Microsoft Corporation.
Licensed under the MIT License.
Abstract:
QUIC Debugger Extension Command 'binding'. This command is for querying the
state of a single binding.
--*/

#include "quictypes.h"

EXT_COMMAND(
quicbinding,
"Shows all information about a Binding",
"{;e,r;addr;The address of the Binding}"
)
{
Binding Binding(GetUnnamedArgU64(0));
auto Lookup = Binding.GetLookup();
auto DatapathBinding = Binding.GetDatapathBinding();

Dml("\n<b>BINDING</b> (<link cmd=\"dt msquic!QUIC_BINDING 0x%I64X\">raw</link>)\n"
"\n"
"\tExclusive %s\n"
"\tConnected %s\n"
"\tRefCount %u\n"
"\tCidCount %u\n"
"\tPartitionCount %u\n"
"\tLocalAddress %s\n"
"\tRemoteAddress %s\n"
"\n",
Binding.Addr,
Binding.Exclusive() ? "true" : "false",
Binding.Connected() ? "true" : "false",
Binding.RefCount(),
Lookup.CidCount(),
Lookup.PartitionCount(),
DatapathBinding.GetLocalAddress().IpString,
DatapathBinding.GetRemoteAddress().IpString);

bool HasAtLeastOne = false;
auto Listeners = Binding.GetListeners();
while (!CheckControlC()) {
ULONG64 LinkAddr = Listeners.Next();
if (LinkAddr == 0) {
break;
}

ULONG64 ListenerAddr = LinkEntryToType(LinkAddr, "msquic!QUIC_LISTENER", "Link");
Dml("\t<link cmd=\"!quiclistener 0x%I64X\">Listener 0x%I64X</link>\n",
ListenerAddr,
ListenerAddr);
HasAtLeastOne = true;
}

if (!HasAtLeastOne) {
Dml("\tNo Listeners\n");
}

Dml("\n");

UCHAR PartitionCount = Lookup.PartitionCount();
if (PartitionCount == 0) {
Connection Conn(Lookup.GetLookupPtr());
Dml("\t<link cmd=\"!quicconnection 0x%I64X\">Connection 0x%I64X</link> [%s]\n",
Conn.Addr,
Conn.Addr,
Conn.TypeStr());
} else {
for (UCHAR i = 0; i < PartitionCount; i++) {
HashTable Hash(Lookup.GetLookupTable(i).GetTablePtr());
Dml("\t<link cmd=\"!hashtable 0x%I64X\">Hash Table %d</link> (%u entries)\n",
Hash.Addr,
i,
Hash.NumEntries());
ULONG64 EntryPtr;
while (!CheckControlC() && Hash.GetNextEntry(&EntryPtr)) {
CidHashEntry Entry(EntryPtr);
Connection Conn(Entry.GetConnection());
Dml("\t <link cmd=\"!quicconnection 0x%I64X\">Connection 0x%I64X</link> [%s]\n",
Conn.Addr,
Conn.Addr,
Conn.TypeStr());
}
}
}

Dml("\n");
}
Loading

0 comments on commit 51d021f

Please sign in to comment.