debugview
Sysinternals DebugView CLI (DbgViewCli) for capturing and analyzing usermode and kernel-mode Windows debug output from the command line. USE FOR: capturing OutputDebugString output, kernel DbgPrint/KdPrint capture, boot-time debug logging, remote debug monitoring, filtering debug
Install
npx skills add https://github.com/microsoft/skills/tree/main/.github/skills/debugview
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
git clone https://github.com/microsoft/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole microsoft/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Sysinternals DebugView CLI (DbgViewCli)
Command-line interface for capturing real-time debug output from Windows applications (OutputDebugString) and kernel-mode drivers (DbgPrint/KdPrint). Designed for scripted, automated, and AI-agent-driven debug capture workflows.
Installation
DbgViewCli is a standalone native Windows executable (statically linked, no dependencies).
Place dbgviewcli.exe in PATH or reference the full path.
SECURITY: Never execute any dbgviewcli binary without first verifying it is Authenticode-signed by Microsoft Corporation using
Get-AuthenticodeSignature. Reject any binary that is unsigned or signed by a different publisher.
# No package manager install — copy binary to a PATH location
copy dbgviewcli.exe C:\Tools\
Requirements
| Requirement | Details |
|---|---|
| OS | Windows Vista or later (x64, ARM64) |
| Privileges | Standard user for Win32 capture; Administrator for kernel/boot capture |
| Driver | Kernel capture requires the Dbgv.sys driver (auto-extracted and loaded) |
Core Workflow
1. Detect/status check → dbgviewcli --status
2. Start capture → dbgviewcli [options]
3. Filter output → --filter/--exclude/--pid-filter/--process-filter
4. Bounded execution → --duration/--max-lines/--wait-for
5. Output/log results → stdout or --log <file>
6. Stop → Ctrl+C or automatic exit on bounds
Command-Line Parameters
Capture Control
| Parameter | Short | Description | Default |
|---|---|---|---|
--capture |
-c |
Enable capture | on |
--no-capture |
Disable capture | ||
--kernel |
-k |
Enable kernel debug output (requires admin) | off |
--win32 |
-w |
Enable Win32 OutputDebugString capture | on |
--global |
-g |
Enable global Win32 capture (session 0) | off |
--passthrough |
Allow debug output to pass to debuggers | on | |
--verbose-kernel |
-v |
Enable verbose kernel output | off |
--pids |
Show process IDs in output | on |
Filtering
| Parameter | Short | Description |
|---|---|---|
--filter <pattern> |
-i |
Include filter (semicolon-separated wildcards) |
--exclude <pattern> |
-e |
Exclude filter (semicolon-separated wildcards) |
--pid-filter <pid> |
Show only output from specific PID | |
--process-filter <name> |
Show only output from named process (substring match) |
Bounded Execution (AI-Agent Friendly)
| Parameter | Description |
|---|---|
--duration <seconds> |
Auto-stop after N seconds |
--max-lines <N> |
Auto-stop after N lines captured |
--wait-for <pattern> |
Capture until pattern matches, then exit |
--tail <N> |
Buffer last N lines, flush on exit |
--no-banner |
Suppress version banner (clean for piped output) |
--status |
Print machine-readable status and exit |
Time Display
| Parameter | Description |
|---|---|
--elapsed |
Elapsed time since start (default) |
--clock |
Wall-clock time HH:MM:SS |
--clock-ms |
Wall-clock with milliseconds HH:MM:SS.mmm |
Output Format
| Parameter | Description |
|---|---|
--format text |
Tab-separated text (default) |
--format csv |
Comma-separated values |
--format xml |
XML elements |
Logging
| Parameter | Description |
|---|---|
--log <file> |
Log output to file |
--log-append |
Append to existing log |
--log-limit <MB> |
Max log file size in MB |
--log-wrap |
Wrap log when full |
--log-daily |
New log file each day |
Boot Logging (Requires Admin)
| Parameter | Description |
|---|---|
--boot-enable |
Enable boot-time kernel debug logging |
--boot-disable |
Disable boot-time logging |
--boot-status |
Show boot logging status and exit |
Remote Monitoring
| Parameter | Description |
|---|---|
--connect <computer> |
Connect to remote DbgView instance |
--disconnect |
Disconnect from remote |
Crash Dump & File Operations
| Parameter | Description |
|---|---|
--crashdump <file> |
Analyze crash dump for debug output |
--load <file> |
Load saved log file |
--save <file> |
Save captured output on exit |
Runtime Control (Inter-Process)
| Parameter | Description |
|---|---|
--pause |
Pause a running DbgViewCli instance via named event |
--resume |
Resume a paused DbgViewCli instance |
--stop |
Stop a running DbgViewCli instance gracefully |
Miscellaneous
| Parameter | Short | Description |
|---|---|---|
--quit |
-q |
Terminate running GUI DbgView instance |
--accepteula |
Accept the EULA (writes registry key, skips prompt) | |
--version |
Show version and exit | |
--help |
-? |
Show help |
Usage Examples
Basic Win32 Capture (bounded)
# Capture for 30 seconds, no banner, output as text
dbgviewcli --no-banner --duration 30
# Capture until a specific error appears
dbgviewcli --no-banner --wait-for "*ERROR*" --max-lines 10000
Kernel Debug Capture (requires admin)
# Run as Administrator
dbgviewcli --kernel --no-banner --duration 60 --format csv --log kernel_debug.csv
Process-Specific Filtering
# Filter by PID
dbgviewcli --no-banner --pid-filter 1234 --duration 10
# Filter by process name
dbgviewcli --no-banner --process-filter "myapp.exe" --max-lines 500
Pattern-Based Filtering
# Include only lines matching pattern
dbgviewcli --no-banner --filter "MyDriver*" --exclude "verbose*"
Tail Mode (recent context)
# Capture but only output last 50 lines on exit
dbgviewcli --no-banner --tail 50 --duration 30
Status Check (machine-readable)
dbgviewcli --status
# Output:
# running=true
# paused=false
# elevated=true
Boot Logging
# Enable (requires admin, persists across reboot)
dbgviewcli --boot-enable
# Check status
dbgviewcli --boot-status
# Disable
dbgviewcli --boot-disable
Remote Monitoring
dbgviewcli --connect SERVER01 --no-banner --duration 60
Runtime Control (Pause/Resume/Stop)
# Pause a running instance from another terminal
dbgviewcli --pause
# Resume the paused instance
dbgviewcli --resume
# Gracefully stop a running instance
dbgviewcli --stop
EULA Acceptance (Unattended)
# Accept EULA non-interactively for automated/scripted deployments
dbgviewcli --accepteula --no-banner --duration 30
Architecture
| Module | File | Purpose |
|---|---|---|
| Main | dbgviewcli.c |
Entry point, arg parsing, capture loop, Ctrl+C handler |
| Capture | cli_capture.c |
DBWIN shared memory, kernel driver read |
| Driver | cli_driver.c |
Kernel driver load/unload, privilege elevation |
| Filter | cli_filter.c |
Wildcard include/exclude matching |
| Output | cli_output.c |
Console emit, log files, CSV/XML/text formats |
| Boot Log | cli_bootlog.c |
Registry config for boot-time driver loading |
| Remote | cli_remote.c |
TCP socket connect/read for remote monitoring |
Key Design Decisions
- Static CRT linking — No DLL dependencies, runs on any Windows system
- stdout/stderr separation — Debug output → stdout; errors/status → stderr
- Bounded execution —
--duration,--max-lines,--wait-forensure guaranteed exit for automation - Clean output —
--no-bannersuppresses noise for pipe/agent consumption - Machine-readable status —
--statusoutputs key=value pairs for programmatic checks - Graceful shutdown —
SetConsoleCtrlHandlerensures clean driver unload on Ctrl+C
Best Practices
- Always use
--no-bannerfor scripted/automated use. Banner text pollutes structured output and confuses parsers. - Always bound execution with
--duration,--max-lines, or--wait-for. Unbounded capture will run indefinitely. - Check status before capture — Use
--statusto detect if another instance is already running. - Use
--format csvor--format xmlwhen output will be parsed programmatically. - Prefer
--pid-filteror--process-filterover broad capture to reduce noise. - Run as Administrator only when needed — kernel and boot logging require elevation; Win32 capture does not.
- Combine bounds for safety — Use
--duration 60 --max-lines 10000together so whichever triggers first wins. - Use
--tailfor "what just happened" queries instead of capturing full history.
Bundled Resources
| Type | File | Purpose |
|---|---|---|
| Script | scripts/detect-dbgview.ps1 |
Locate dbgviewcli.exe on PATH or common directories |
| Script | scripts/capture-wrapper.ps1 |
Safe bounded capture with parameter validation |
| Script | scripts/boot-logging-workflow.ps1 |
End-to-end boot logging lifecycle management |
| Reference | references/driver-ioctls.md |
Kernel driver IOCTL codes and buffer structures |
| Reference | references/output-formats.md |
Text/CSV/XML output format specifications |
| Reference | references/remote-protocol.md |
TCP remote monitoring wire protocol |
Troubleshooting
| Issue | Resolution |
|---|---|
| "Access denied" on kernel capture | Run as Administrator |
| No output from Win32 capture | Verify target app uses OutputDebugString; check no debugger is attached |
| Another instance running | Use --status to check; use --quit to terminate existing GUI instance |
| Boot logging not capturing | Ensure --boot-enable was run as admin; driver must be in System32\Drivers |
| Remote connection fails | Verify target has DbgView running with remote enabled on ports 2020-2030 |
Files (skills)
-
references
-
driver-ioctls.md 5.8 KB
# Driver IOCTLs and Buffer Formats Reference documentation for the Dbgv.sys kernel driver interface used by DbgViewCli. --- ## Device Identity | Property | Value | |----------|-------| | Device Type | `FILE_DEVICE_DBGMON` (`0x00008305`) | | Driver File | `Dbgv.sys` | | Service Name | `DBGV` | | Registry Key | `HKLM\System\CurrentControlSet\Services\Dbgv` | | Version | `0x320` | --- ## IOCTL Commands All IOCTLs use `CTL_CODE(FILE_DEVICE_DBGMON, function, method, access)`. | IOCTL Name | Function | Method | Description | |------------|----------|--------|-------------| | `DBGMON_hook` | `0x00` | `METHOD_BUFFERED` | Hook kernel debug output (start capturing DbgPrint) | | `DBGMON_unhook` | `0x01` | `METHOD_BUFFERED` | Unhook kernel debug output (stop capturing) | | `DBGMON_zerostats` | `0x02` | `METHOD_BUFFERED` | Clear the driver's internal output buffer | | `DBGMON_getstats` | `0x03` | `METHOD_NEITHER` | Read accumulated debug output from driver buffer | | `DBGMON_swallow` | `0x04` | `METHOD_BUFFERED` | Suppress pass-through of debug output to attached debuggers | | `DBGMON_dontswallow` | `0x05` | `METHOD_BUFFERED` | Allow debug output to pass through to debuggers | | `DBGMON_hookW32` | `0x06` | `METHOD_BUFFERED` | Hook Win32 debug output (session 0 global) | | `DBGMON_unhookW32` | `0x07` | `METHOD_BUFFERED` | Unhook Win32 debug output | | `DBGMON_getsequence` | `0x08` | `METHOD_BUFFERED` | Get current sequence number from driver | | `DBGMON_version` | `0x09` | `METHOD_BUFFERED` | Get driver version (handshake) | | `DBGMON_gettime` | `0x0A` | `METHOD_BUFFERED` | Get driver timer resolution | | `DBGMON_remotequit` | `0x0B` | `METHOD_BUFFERED` | Signal remote agent to quit | | `DBGMON_connect` | `0x0C` | `METHOD_BUFFERED` | Remote connection notification | | `DBGMON_forcecr` | `0x0D` | `METHOD_BUFFERED` | Force carriage return on output lines | | `DBGMON_dontforcecr` | `0x0E` | `METHOD_BUFFERED` | Don't force carriage return | | `DBGMON_enabledbgfilter` | `0x0F` | `METHOD_BUFFERED` | Enable debug output filtering in driver | | `DBGMON_restoredbgfilter` | `0x10` | `METHOD_BUFFERED` | Restore default debug output filtering | --- ## Buffer Structures ### STORE_BUF — Driver Output Buffer The driver accumulates debug messages in a linked list of `STORE_BUF` pages. ```c #define NUM_STORE_PAGES 1 #define MAX_STORE (PAGE_SIZE * NUM_STORE_PAGES - 4 * sizeof(ULONG)) #define STORE_SIGNATURE 0xFEADDEAF #pragma pack(1) typedef struct _store { ULONG Signature; // Must be STORE_SIGNATURE ULONG UpdateSequence; // Incremented on each write struct _store * Next; // Pointer to next buffer in chain ULONG Len; // Bytes used in Data[] char Data[MAX_STORE]; // Packed ENTRY records } STORE_BUF, *PSTORE_BUF; #pragma pack() ``` **Size:** `STORESIZE = ((sizeof(STORE_BUF) + 0xFFF) / 0x1000)` pages ### STORE_BUF_DUMP64 — 64-bit Crash Dump Variant For reading driver buffers from 64-bit crash dumps (pointer width differs): ```c #pragma pack(1) typedef struct _store_dump64 { ULONG Signature; // STORE_SIGNATURE ULONG UpdateSequence; ULONGLONG Next64; // 8 bytes (64-bit kernel pointer) ULONG Len; char Data[MAX_STORE]; } STORE_BUF_DUMP64, *PSTORE_BUF_DUMP64; #pragma pack() ``` ### ENTRY — Individual Debug Output Record Each entry in `Data[]` is packed sequentially: ```c #pragma pack(1) typedef struct { ULONG seq; // Sequence number LARGE_INTEGER datetime; // File time (100ns since 1601-01-01) LARGE_INTEGER perftime; // Performance counter value char text[0]; // Null-terminated message string } ENTRY, *PENTRY; #pragma pack() ``` **Walking entries:** Advance by `sizeof(ENTRY) + strlen(entry->text) + 1`, aligned as needed. Validate that the next entry start does not exceed `Data + Len`. ### WIN32OUTPUT — Win32 Shared Memory Record Used for DBWIN shared-memory capture (OutputDebugString): ```c typedef struct _win32rec { struct _win32rec * next; // Linked list pointer ULONG sequence; // Sequence number LARGE_INTEGER time; // Timestamp LARGE_INTEGER perftime; // Performance counter char text[]; // Flexible array — null-terminated message } WIN32OUTPUT, *PWIN32OUTPUT; ``` ### CLIENT_RESOLUTION — Timer Resolution Shared between service and GUI/CLI for timestamp calibration: ```c typedef struct { LARGE_INTEGER TimerResolution; } CLIENT_RESOLUTION, *PCLIENT_RESOLUTION; ``` --- ## Win32 DBWIN Shared Memory Protocol DbgViewCli captures `OutputDebugString` by creating these named objects: | Object Type | Name (Local Session) | Name (Global/Session 0) | |-------------|---------------------|------------------------| | Section (File Mapping) | `DBWIN_BUFFER` | `Global\DBWIN_BUFFER` | | Event (buffer ready) | `DBWIN_BUFFER_READY` | `Global\DBWIN_BUFFER_READY` | | Event (data ready) | `DBWIN_DATA_READY` | `Global\DBWIN_DATA_READY` | **Protocol:** 1. Create the section and events with appropriate security descriptors 2. Signal `DBWIN_BUFFER_READY` to indicate buffer is available 3. Wait on `DBWIN_DATA_READY` — signaled when a process calls `OutputDebugString` 4. Read PID (first 4 bytes) + message text from the shared section 5. Signal `DBWIN_BUFFER_READY` again for the next message --- ## Boot Logging Registry Configuration When boot logging is enabled, the driver loads at boot: | Registry Value | Type | Data | |----------------|------|------| | `Start` | `REG_DWORD` | `0` (SERVICE_BOOT_START) | | `Group` | `REG_SZ` | `System Bus Extender` | | `Tag` | `REG_DWORD` | `1` | | `Type` | `REG_DWORD` | `1` | | `ImagePath` | `REG_EXPAND_SZ` | `System32\Drivers\Dbgv.sys` | The driver binary must be copied to `%SystemRoot%\System32\Drivers\` before enabling. -
output-formats.md 4 KB
# Output Formats DbgViewCli supports three output formats selectable via `--format <text|csv|xml>`. --- ## Text Format (Default) Tab-separated fields written to stdout. This is the default when `--format text` or no format is specified. ### Schema ``` <sequence>\t<timestamp>\t[<pid>]\t<message>\n ``` ### Fields | Field | Description | Example | |-------|-------------|---------| | Sequence | Monotonically increasing line number | `1`, `2`, `3` | | Timestamp | Depends on `--elapsed`, `--clock`, `--clock-ms` | `0.123`, `14:30:05`, `14:30:05.123` | | PID | Process ID in brackets (when `--pids` is on) | `[1234]` | | Message | The debug output string | `MyDriver: Init complete` | ### Timestamp Modes | Mode | Flag | Format | Example | |------|------|--------|---------| | Elapsed | `--elapsed` (default) | Seconds since capture start | `12.456` | | Clock | `--clock` | Wall clock HH:MM:SS | `14:30:05` | | Clock+ms | `--clock-ms` | Wall clock with milliseconds | `14:30:05.123` | ### Example Output ``` 1 0.000 [4567] MyApp: Starting initialization 2 0.001 [4567] MyApp: Loading configuration 3 0.015 [4567] MyApp: Configuration loaded 4 1.203 [4567] MyApp: Ready ``` --- ## CSV Format Comma-separated values with header row. Selected via `--format csv`. ### Schema ``` "Sequence","Timestamp","PID","Message" <seq>,"<timestamp>","<pid>","<message>" ``` ### Rules - All fields are quoted with double quotes - Embedded double quotes in message text are escaped as `""` - Newlines in messages are preserved within quotes - Header row is emitted first ### Example Output ```csv "Sequence","Timestamp","PID","Message" "1","0.000","4567","MyApp: Starting initialization" "2","0.001","4567","MyApp: Loading configuration" "3","0.015","4567","Config value=""debug_level=3""" "4","1.203","4567","MyApp: Ready" ``` --- ## XML Format Simple XML elements. Selected via `--format xml`. ### Schema ```xml <?xml version="1.0" encoding="UTF-8"?> <debugoutput> <entry seq="N" time="TIMESTAMP" pid="PID"><![CDATA[MESSAGE]]></entry> ... </debugoutput> ``` ### Elements | Element/Attribute | Description | |-------------------|-------------| | `<debugoutput>` | Root element wrapping all entries | | `<entry>` | Single debug output line | | `@seq` | Sequence number | | `@time` | Timestamp string (format depends on time mode) | | `@pid` | Process ID (omitted if `--no-pids`) | | CDATA content | The debug message text | ### Special Characters - Message content is wrapped in `<![CDATA[...]]>` to avoid XML escaping issues - If the message contains the literal string `]]>`, it must be split across CDATA sections ### Example Output ```xml <?xml version="1.0" encoding="UTF-8"?> <debugoutput> <entry seq="1" time="0.000" pid="4567"><![CDATA[MyApp: Starting initialization]]></entry> <entry seq="2" time="0.001" pid="4567"><![CDATA[MyApp: Loading configuration]]></entry> <entry seq="3" time="0.015" pid="4567"><![CDATA[MyApp: Config loaded]]></entry> <entry seq="4" time="1.203" pid="4567"><![CDATA[MyApp: Ready]]></entry> </debugoutput> ``` --- ## Log File Options All formats can be written to a log file simultaneously with stdout output. | Option | Description | |--------|-------------| | `--log <file>` | Write output to file | | `--log-append` | Append to existing file instead of overwriting | | `--log-limit <MB>` | Maximum log file size in megabytes | | `--log-wrap` | When limit reached, wrap to beginning (ring buffer) | | `--log-daily` | Create new file each day with date suffix (e.g., `debug_20250518.log`) | ### Daily Log File Naming When `--log-daily` is used with `--log debug.log`: - Day 1: `debug_20250518.log` - Day 2: `debug_20250519.log` --- ## Status Output Format The `--status` command outputs machine-readable key=value pairs: ``` running=true paused=false elevated=true ``` | Key | Type | Description | |-----|------|-------------| | `running` | boolean | Whether a DbgViewCli instance is actively capturing | | `paused` | boolean | Whether the running instance is paused | | `elevated` | boolean | Whether the current process has admin privileges | -
remote-protocol.md 5.6 KB
# Remote Monitoring Protocol DbgViewCli can connect to a remote machine running DbgView (GUI or service) and receive debug output over TCP. This document describes the wire protocol. --- ## Connection ### Port Scanning The client scans TCP ports `DBGVPORTLO` (2020) through `DBGVPORTHI` (2030) on the target machine, attempting a connection on each until one succeeds. | Constant | Value | |----------|-------| | `DBGVPORTLO` | 2020 | | `DBGVPORTHI` | 2030 | | Connection Timeout | 10 seconds (`REMOTE_CONNECT_TIMEOUT`) | | Update Timeout | 30 minutes (`REMOTE_UPDATE_TIMEOUT`) | ### Connection Sequence ``` Client Remote Agent (DbgView) | | |--- TCP connect (port 2020-2030) ----->| | | |--- DBGMON_version (DWORD) ----------->| Request version |<-- version (DWORD) ------------------| Response | | |--- DBGMON_hook (DWORD) -------------->| Start kernel capture |--- DBGMON_swallow/dontswallow ------->| Configure pass-through |--- DBGMON_forcecr/dontforcecr ------->| Configure CR mode | | |--- DBGMON_gettime (DWORD) ----------->| Request timer resolution |<-- CLIENT_RESOLUTION (16 bytes) -----| Timer resolution response | | | ... connected ... | ``` --- ## Version Handshake After TCP connection is established: 1. Client sends `DBGMON_version` command (4 bytes, DWORD) 2. Remote responds with its driver version (4 bytes, DWORD) ### Version Interpretation | Response Value | Meaning | |----------------|---------| | `DEBUGVIEW_VERSION` (0x320) | Compatible version — proceed | | `0xFFFFFFFF & ~WIN9XVERSIONBIT` | Remote has no kernel driver loaded (Win32 only) | | Any other value | Incompatible version — disconnect | The high bit (`WIN9XVERSIONBIT = 0x80000000`) indicates a Windows 9x remote. --- ## Commands (Client → Remote) All commands are sent as a single DWORD (4 bytes, little-endian). | Command | IOCTL Value | Description | |---------|-------------|-------------| | `DBGMON_hook` | `CTL_CODE(0x8305, 0x00, ...)` | Start capturing kernel debug output | | `DBGMON_unhook` | `CTL_CODE(0x8305, 0x01, ...)` | Stop capturing kernel debug output | | `DBGMON_zerostats` | `CTL_CODE(0x8305, 0x02, ...)` | Clear output buffer | | `DBGMON_getstats` | `CTL_CODE(0x8305, 0x03, ...)` | Request buffered output data | | `DBGMON_swallow` | `CTL_CODE(0x8305, 0x04, ...)` | Suppress debug pass-through | | `DBGMON_dontswallow` | `CTL_CODE(0x8305, 0x05, ...)` | Allow debug pass-through | | `DBGMON_version` | `CTL_CODE(0x8305, 0x09, ...)` | Request version | | `DBGMON_gettime` | `CTL_CODE(0x8305, 0x0A, ...)` | Request timer resolution | | `DBGMON_remotequit` | `CTL_CODE(0x8305, 0x0B, ...)` | Tell remote agent to quit | | `DBGMON_forcecr` | `CTL_CODE(0x8305, 0x0D, ...)` | Enable forced CR | | `DBGMON_dontforcecr` | `CTL_CODE(0x8305, 0x0E, ...)` | Disable forced CR | --- ## Data Retrieval (Polling) The client periodically requests accumulated debug output: ``` Client Remote Agent | | |--- DBGMON_getstats (DWORD) --------->| |<-- STORE_BUF data (up to MAX_STORE) -| | | ``` ### Response Format The remote sends raw `STORE_BUF.Data` content — a packed sequence of `ENTRY` records: ```c typedef struct { ULONG seq; // Sequence number LARGE_INTEGER datetime; // File time LARGE_INTEGER perftime; // Performance counter char text[0]; // Null-terminated message } ENTRY, *PENTRY; ``` **Walking the buffer:** ``` offset = 0 while offset < bytesRead: entry = (ENTRY*)(buffer + offset) process entry->text offset += sizeof(ENTRY) + strlen(entry->text) + 1 ``` ### Timeout The read uses a 500ms timeout. If no data arrives within that window, the client continues its main loop (checking duration limits, exit signals, etc.). --- ## Disconnection Graceful disconnect sequence: ``` Client Remote Agent | | |--- DBGMON_unhook (DWORD) ----------->| Stop capturing |--- DBGMON_remotequit (DWORD) ------->| Request agent exit | | |--- closesocket() ------------------->| TCP close ``` If the connection is broken (remote closed or network error), the client detects this via failed `ReadFile`/`WriteFile` and sets `Closing = TRUE` to prevent further operations on that slot. --- ## Multi-Remote Support DbgViewCli supports up to `MAXREMOTE` (10) simultaneous remote connections. Each connection occupies a slot in the `g_ComputerInfo[MAXREMOTE]` array. | Field | Description | |-------|-------------| | `Name` | Hostname or IP of the remote | | `IpAddress` | Resolved IPv4 address (network byte order) | | `Socket` | TCP socket handle | | `Config` | Per-connection capture configuration | | `NoDriver` | TRUE if remote has no kernel driver | | `Closing` | TRUE if connection is being torn down | | `Stats` | Allocated buffer for `DBGMON_getstats` responses | | `ReadEvent` | Overlapped I/O event for async reads | | `Time` | Remote's timer resolution | --- ## Security Considerations - Remote monitoring uses **unencrypted TCP**. Do not use over untrusted networks. - The remote agent must have DbgView running with network listening enabled. - No authentication is performed beyond the version handshake. - Consider using VPN or SSH tunneling for remote debug capture over WAN.
-
-
scripts
-
boot-logging-workflow.ps1 3.6 KB · in bundle
-
capture-wrapper.ps1 2.8 KB · in bundle
-
detect-dbgview.ps1 1.5 KB · in bundle
-
-
SKILL.md 10.4 KB
--- name: debugview description: | Sysinternals DebugView CLI (DbgViewCli) for capturing and analyzing usermode and kernel-mode Windows debug output from the command line. USE FOR: capturing OutputDebugString output, kernel DbgPrint/KdPrint capture, boot-time debug logging, remote debug monitoring, filtering debug output by PID or process name, crash dump analysis, automated debug capture with bounded execution. DO NOT USE FOR: non-Windows platforms, application-level logging frameworks (log4j, serilog), Azure Monitor or cloud telemetry, ETW tracing (use WPR/xperf instead), user-mode crash dumps (use WinDbg). Triggers: "debug output", "DbgView", "DebugView", "kernel debug", "capture debug logs", "boot logging", "OutputDebugString", "DbgPrint", "KdPrint", "remote debug monitor", "debug capture CLI". --- # Sysinternals DebugView CLI (DbgViewCli) Command-line interface for capturing real-time debug output from Windows applications (OutputDebugString) and kernel-mode drivers (DbgPrint/KdPrint). Designed for scripted, automated, and AI-agent-driven debug capture workflows. ## Installation DbgViewCli is a standalone native Windows executable (statically linked, no dependencies). Place `dbgviewcli.exe` in PATH or reference the full path. > **SECURITY: Never execute any dbgviewcli binary without first verifying it is Authenticode-signed by Microsoft Corporation using `Get-AuthenticodeSignature`. Reject any binary that is unsigned or signed by a different publisher.** ```bash # No package manager install — copy binary to a PATH location copy dbgviewcli.exe C:\Tools\ ``` ## Requirements | Requirement | Details | |-------------|---------| | OS | Windows Vista or later (x64, ARM64) | | Privileges | Standard user for Win32 capture; **Administrator** for kernel/boot capture | | Driver | Kernel capture requires the Dbgv.sys driver (auto-extracted and loaded) | ## Core Workflow ``` 1. Detect/status check → dbgviewcli --status 2. Start capture → dbgviewcli [options] 3. Filter output → --filter/--exclude/--pid-filter/--process-filter 4. Bounded execution → --duration/--max-lines/--wait-for 5. Output/log results → stdout or --log <file> 6. Stop → Ctrl+C or automatic exit on bounds ``` ## Command-Line Parameters ### Capture Control | Parameter | Short | Description | Default | |-----------|-------|-------------|---------| | `--capture` | `-c` | Enable capture | on | | `--no-capture` | | Disable capture | | | `--kernel` | `-k` | Enable kernel debug output (requires admin) | off | | `--win32` | `-w` | Enable Win32 OutputDebugString capture | on | | `--global` | `-g` | Enable global Win32 capture (session 0) | off | | `--passthrough` | | Allow debug output to pass to debuggers | on | | `--verbose-kernel` | `-v` | Enable verbose kernel output | off | | `--pids` | | Show process IDs in output | on | ### Filtering | Parameter | Short | Description | |-----------|-------|-------------| | `--filter <pattern>` | `-i` | Include filter (semicolon-separated wildcards) | | `--exclude <pattern>` | `-e` | Exclude filter (semicolon-separated wildcards) | | `--pid-filter <pid>` | | Show only output from specific PID | | `--process-filter <name>` | | Show only output from named process (substring match) | ### Bounded Execution (AI-Agent Friendly) | Parameter | Description | |-----------|-------------| | `--duration <seconds>` | Auto-stop after N seconds | | `--max-lines <N>` | Auto-stop after N lines captured | | `--wait-for <pattern>` | Capture until pattern matches, then exit | | `--tail <N>` | Buffer last N lines, flush on exit | | `--no-banner` | Suppress version banner (clean for piped output) | | `--status` | Print machine-readable status and exit | ### Time Display | Parameter | Description | |-----------|-------------| | `--elapsed` | Elapsed time since start (default) | | `--clock` | Wall-clock time HH:MM:SS | | `--clock-ms` | Wall-clock with milliseconds HH:MM:SS.mmm | ### Output Format | Parameter | Description | |-----------|-------------| | `--format text` | Tab-separated text (default) | | `--format csv` | Comma-separated values | | `--format xml` | XML elements | ### Logging | Parameter | Description | |-----------|-------------| | `--log <file>` | Log output to file | | `--log-append` | Append to existing log | | `--log-limit <MB>` | Max log file size in MB | | `--log-wrap` | Wrap log when full | | `--log-daily` | New log file each day | ### Boot Logging (Requires Admin) | Parameter | Description | |-----------|-------------| | `--boot-enable` | Enable boot-time kernel debug logging | | `--boot-disable` | Disable boot-time logging | | `--boot-status` | Show boot logging status and exit | ### Remote Monitoring | Parameter | Description | |-----------|-------------| | `--connect <computer>` | Connect to remote DbgView instance | | `--disconnect` | Disconnect from remote | ### Crash Dump & File Operations | Parameter | Description | |-----------|-------------| | `--crashdump <file>` | Analyze crash dump for debug output | | `--load <file>` | Load saved log file | | `--save <file>` | Save captured output on exit | ### Runtime Control (Inter-Process) | Parameter | Description | |-----------|-------------| | `--pause` | Pause a running DbgViewCli instance via named event | | `--resume` | Resume a paused DbgViewCli instance | | `--stop` | Stop a running DbgViewCli instance gracefully | ### Miscellaneous | Parameter | Short | Description | |-----------|-------|-------------| | `--quit` | `-q` | Terminate running GUI DbgView instance | | `--accepteula` | | Accept the EULA (writes registry key, skips prompt) | | `--version` | | Show version and exit | | `--help` | `-?` | Show help | ## Usage Examples ### Basic Win32 Capture (bounded) ```bash # Capture for 30 seconds, no banner, output as text dbgviewcli --no-banner --duration 30 # Capture until a specific error appears dbgviewcli --no-banner --wait-for "*ERROR*" --max-lines 10000 ``` ### Kernel Debug Capture (requires admin) ```bash # Run as Administrator dbgviewcli --kernel --no-banner --duration 60 --format csv --log kernel_debug.csv ``` ### Process-Specific Filtering ```bash # Filter by PID dbgviewcli --no-banner --pid-filter 1234 --duration 10 # Filter by process name dbgviewcli --no-banner --process-filter "myapp.exe" --max-lines 500 ``` ### Pattern-Based Filtering ```bash # Include only lines matching pattern dbgviewcli --no-banner --filter "MyDriver*" --exclude "verbose*" ``` ### Tail Mode (recent context) ```bash # Capture but only output last 50 lines on exit dbgviewcli --no-banner --tail 50 --duration 30 ``` ### Status Check (machine-readable) ```bash dbgviewcli --status # Output: # running=true # paused=false # elevated=true ``` ### Boot Logging ```bash # Enable (requires admin, persists across reboot) dbgviewcli --boot-enable # Check status dbgviewcli --boot-status # Disable dbgviewcli --boot-disable ``` ### Remote Monitoring ```bash dbgviewcli --connect SERVER01 --no-banner --duration 60 ``` ### Runtime Control (Pause/Resume/Stop) ```bash # Pause a running instance from another terminal dbgviewcli --pause # Resume the paused instance dbgviewcli --resume # Gracefully stop a running instance dbgviewcli --stop ``` ### EULA Acceptance (Unattended) ```bash # Accept EULA non-interactively for automated/scripted deployments dbgviewcli --accepteula --no-banner --duration 30 ``` ## Architecture | Module | File | Purpose | |--------|------|---------| | Main | `dbgviewcli.c` | Entry point, arg parsing, capture loop, Ctrl+C handler | | Capture | `cli_capture.c` | DBWIN shared memory, kernel driver read | | Driver | `cli_driver.c` | Kernel driver load/unload, privilege elevation | | Filter | `cli_filter.c` | Wildcard include/exclude matching | | Output | `cli_output.c` | Console emit, log files, CSV/XML/text formats | | Boot Log | `cli_bootlog.c` | Registry config for boot-time driver loading | | Remote | `cli_remote.c` | TCP socket connect/read for remote monitoring | ## Key Design Decisions 1. **Static CRT linking** — No DLL dependencies, runs on any Windows system 2. **stdout/stderr separation** — Debug output → stdout; errors/status → stderr 3. **Bounded execution** — `--duration`, `--max-lines`, `--wait-for` ensure guaranteed exit for automation 4. **Clean output** — `--no-banner` suppresses noise for pipe/agent consumption 5. **Machine-readable status** — `--status` outputs key=value pairs for programmatic checks 6. **Graceful shutdown** — `SetConsoleCtrlHandler` ensures clean driver unload on Ctrl+C ## Best Practices 1. **Always use `--no-banner` for scripted/automated use.** Banner text pollutes structured output and confuses parsers. 2. **Always bound execution** with `--duration`, `--max-lines`, or `--wait-for`. Unbounded capture will run indefinitely. 3. **Check status before capture** — Use `--status` to detect if another instance is already running. 4. **Use `--format csv` or `--format xml`** when output will be parsed programmatically. 5. **Prefer `--pid-filter` or `--process-filter`** over broad capture to reduce noise. 6. **Run as Administrator only when needed** — kernel and boot logging require elevation; Win32 capture does not. 7. **Combine bounds for safety** — Use `--duration 60 --max-lines 10000` together so whichever triggers first wins. 8. **Use `--tail`** for "what just happened" queries instead of capturing full history. ## Bundled Resources | Type | File | Purpose | |------|------|---------| | Script | `scripts/detect-dbgview.ps1` | Locate dbgviewcli.exe on PATH or common directories | | Script | `scripts/capture-wrapper.ps1` | Safe bounded capture with parameter validation | | Script | `scripts/boot-logging-workflow.ps1` | End-to-end boot logging lifecycle management | | Reference | `references/driver-ioctls.md` | Kernel driver IOCTL codes and buffer structures | | Reference | `references/output-formats.md` | Text/CSV/XML output format specifications | | Reference | `references/remote-protocol.md` | TCP remote monitoring wire protocol | ## Troubleshooting | Issue | Resolution | |-------|-----------| | "Access denied" on kernel capture | Run as Administrator | | No output from Win32 capture | Verify target app uses `OutputDebugString`; check no debugger is attached | | Another instance running | Use `--status` to check; use `--quit` to terminate existing GUI instance | | Boot logging not capturing | Ensure `--boot-enable` was run as admin; driver must be in System32\Drivers | | Remote connection fails | Verify target has DbgView running with remote enabled on ports 2020-2030 |
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.