GitHub Copilot ChatGPT Claude Codex CLI Cursor opencode Skill Text

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

Ciza · 0 points · 31 views 1 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download microsoft-skills-.github_skills_debugview-e58528d.zip · 14 KB
Part of microsoft/skills — 195 skills

Install

skills CLI npx skills add https://github.com/microsoft/skills/tree/main/.github/skills/debugview
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install microsoft-skills@llmmart
Git 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

  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
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.

No comments yet.

Reviews (0)

No reviews yet.

Related