ddn.dev.gdbmi
An idiomatic, asynchronous wrapper around the GDB Machine Interface (MI).
The implementation focuses on:
- A robust MI parser and value model (MiValue, MiRecord)
- A cross-platform process wrapper (GdbMiSession) using threads + an event queue
- An integration-friendly API for GUI and TUI applications (non-blocking event polling)
The wrapper is intentionally fully generic: you can send any MI command string. Higher-level helper functions can be layered on top without changing the core.
Copyright
Types 42
MI stream channel kinds.
MI async record kinds.
A single variable=value entry in MI output.
MI tuple value: { result (, result)* }.
MiResult[] resultsResults inside the tuple.MI list kind.
MI list value: `[ ... ]`.
MiListKind kindWhether the list contains values or results.MiValue[] valuesValue items (valid when `kind == MiListKind.VALUES`).MiResult[] resultsResult items (valid when `kind == MiListKind.RESULTS`).MI value kind.
MI value.
Note
representation finite-sized, MiValue is a reference type.
string getDemangledString() @safeReturns: Demangled string value. Throws: `Exception` if `kind != MiValueKind.STRING`.MiResult[] asDAssociativeArray() @safeTries to fetch and parse a D associative array into key-value pairs.string findInSummary(string summary, string key) @safeTries to find a value in a GDB string summary like "{a = 1, b = 2}".long asInt() @safeReturns: String value parsed as integer. Throws: `Exception` if not a string or not an integer.bool asBool() @safeReturns: String value parsed as boolean. Throws: `Exception` if not a string or not a known boolean representation.A delegate that takes an MI value and returns a user-friendly string representation. If the visualizer does not handle the value, it should return an empty Nullable.
Registry for D-language custom visualizers.
Visualizers are tried in registration order (first-match wins). Once a visualizer returns a non-null Nullable!string, no further visualizers are consulted.
Registration (register) and lookup (visualize) are not synchronized. Register all visualizers before starting any GDB session to avoid data races. The built-in visualizers registered by registerBuiltins() are typically called once at program startup.
call to visualize(). Registering a visualizer while a visualize() call is in progress on another thread constitutes a data race.
MiVisualizer[] _visualizersstring visualize(MiValue value, string typeName = null, GdbMiSession session = null) @safeTries to visualize an MI value using registered visualizers.Nullable!string visualizeSysTime(MiValue value, string typeName, GdbMiSession session) @safeVisualizer for `std.datetime.SysTime`.Nullable!string visualizeVariant(MiValue value, string typeName, GdbMiSession session) @safeVisualizer for `std.variant.Variant`.Nullable!string visualizeRange(MiValue value, string typeName, GdbMiSession session) @safeVisualizer for common D ranges.MI prompt record: (gdb).
MI async record: *stopped,..., =thread-created,..., ...
MiToken tokenOptional token.MiAsyncKind kindKind (`*`, `+`, `=`).string asyncClassAsync class (`stopped`, `running`, `thread-created`, ...).MiResult[] resultsResults.MI stream record: `~"..."`, `@"..."`, `&"..."`.
Manages GDB console history and state.
string[] _historysize_t _maxHistorystring _historyFilevoid delegate(string, Exception) @safe _errorCallbackthis(size_t maxHistory = 1000, string historyFile = null,
void delegate(string, Exception) @safe errorCallback = null)Creates a console manager.An unrecognized/opaque line produced by GDB.
string lineRaw line text (without line ending).Any MI record.
Disassembly modes.
Watchpoint kinds.
Represents a single disassembled instruction.
string addressAddress of the instruction.string funcNameName of the function containing the instruction.long offsetOffset from the start of the function.string instThe instruction text.string opcodesOpcode bytes (if requested).long lineSource line number (in mixed mode).string fileSource file name (in mixed mode).Event produced by GdbMiSession.
MiRecord recordParsed record (if any).string rawLineRaw line as received from GDB (without line ending).Debugger engine kinds.
Priority for MI commands.
Log filtering rules.
string regexOnly log records matching this regex (on raw line).string[] asyncClassesOnly log these async record classes (e.g. ["stopped", "running"]).bool onlyResultsOnly log result records.bool onlyAsyncOnly log async records.bool onlyStreamOnly log stream records.bool delegate(string rawLine, bool isOutgoing) @safe filterCustom filter delegate. Returns true to log.Session configuration.
GdbMiEngine engineDebugger engine.string debuggerPathPath to the debugger executable (e.g. `gdb`, `lldb-mi`).string[] extraArgsExtra arguments passed to the debugger.bool forwardResultRecordsToEventsWhether `^result` records should also be forwarded to the event queue.void delegate(string, bool) @safe loggerLogger delegate for MI traffic. Params are (rawLine, isOutgoing).GdbMiLogFilter logFilterLogging filter.string workingDirectoryWorking directory for the debugger.string[string] envEnvironment variables for the debugger.bool autoDispatchEventsWhether events should be automatically dispatched to listeners from the reader thread.uint commandsPerSecondMaximum commands to send per second. 0 means no limit.Metadata about the debugger engine.
string nameEngine name (GNU gdb, LLDB, etc.).string versionStringFull version string.int majorMajor version number.int minorMinor version number.int patchPatch version number.string[] featuresSupported features.D-language type information including qualifiers.
string baseTypeBase type name without qualifiers.bool isSharedWhether the type is shared.bool isImmutableWhether the type is immutable.bool isConstWhether the type is const.bool isInoutWhether the type is inout (wildcard).Information about a DUB project.
string targetPathPath to the target executable.string[] importPathsList of import paths.Base exception for all GDB-related errors.
this(string msg, string file = __FILE__, size_t line = __LINE__)Exception thrown when a GDB command fails.
string resultClassMI result class (e.g. "error").this(string msg, string resultClass, string file = __FILE__, size_t line = __LINE__)Exception thrown when the GDB process fails.
this(string msg, string file = __FILE__, size_t line = __LINE__)Exception thrown when a GDB command times out.
Includes the command text, token, and timeout duration for diagnostics.
ulong tokenToken of the command that timed out.string commandCommand string that timed out.Duration timeoutDuration that was waited.Thrown when a memory read fails or returns unexpected data.
this(string msg, string file = __FILE__, size_t line = __LINE__)Thrown when an operation is attempted on a stopped session.
this(string msg = "Session is stopped", string file = __FILE__, size_t line = __LINE__)Thrown when MI output parsing fails.
Includes the parser position, a description of what was expected, and a short snippet of the input around the error location to aid diagnostics.
size_t positionParser position where the error was detected.string expectedDescription of what was expected (e.g. `"'"`, `"identifier"`, `"value"`).string snippetShort excerpt of the input around the error position (max 40 chars).this(string msg, size_t position, string expected, string snippet,
string file = __FILE__, size_t line = __LINE__)Constructs a parse exception.A pending MI command.
ulong _tokenMutex _mutexCondition _condbool _readyNullable!MiResultRecord _resultThrowable _errorMonoTime _startTimeDuration _roundTripTimeint _completedCountstring _commandMiResultRecord wait(Duration timeout = DEFAULT_COMMAND_TIMEOUT)Waits for the command to complete.Duration roundTripTime() @trustedReturns: The round-trip time for this command. Throws: `Exception` if not yet ready.void fulfill(MiResultRecord record) @trustedCompletes this pending command with a parsed MI result record.this(ulong token, string command = "")Creates a pending command.Internal structure for enqueued MI commands.
int opCmp(const ref MiQueuedCommand rhs) const @safe pure nothrow @nogcCompares two queued commands for priority.Session lifecycle states.
Used internally to reject operations on a stopping or stopped session.
ACTIVE — normal operation. STOPPING — stop() has been called; cleanup in progress. STOPPED — cleanup complete; session is fully shut down.
A running GDB process in MI mode.
You interact with the session by:
- Sending commands with
sendCommand(non-blocking) and optionally waiting viaMiPendingCommand - Polling
tryPopEventfor async and stream output (and optionally result records)
GdbMiConfig _configFile _stdinFile _stdoutFile _stderrtypeof(pipeProcess(["gdb"], Redirect.stdin | Redirect.stdout | Redirect.stderr)) _proculong _nextTokenMutex _writeMutexMutex _commandQueueMutexCondition _commandQueueCondMiQueuedCommand[] _commandQueueThread _commandSenderThreadMutex _pendingMutexMiPendingCommand[ulong] _pendingMutex _eventMutexCondition _eventCondGdbMiEvent[] _eventssize_t _eventHeadvoid delegate(GdbMiEvent)[] _eventListenersThread _stdoutThreadThread _stderrThreadGdbMiSessionState _statestring _currentThreadIdint _currentFrameLevelMiPendingCommand sendCommand(string command, MiCommandPriority priority = MiCommandPriority.NORMAL) @trustedSends an MI command.MiPendingCommand cliExecute(string command) @trustedExecutes a raw CLI command using the console interpreter.MiPendingCommand cliComplete(string partialCommand) @trustedGets completion suggestions for a partial CLI command.MiPendingCommand macroExpand(string macroName) @trustedExpands a macro at a specific source location.MiPendingCommand macroList(string file = null, int line = - 1) @trustedLists macros defined at a specific source location.MiPendingCommand breakCondition(int number, string condition = null) @trustedSets the condition of a breakpoint.MiPendingCommand breakCommands(int number, string[] commands) @trustedSets the commands to be executed when a breakpoint is hit.MiPendingCommand breakCatch(string event, bool temporary = false, string[] extraArgs = null) @trustedInserts a catchpoint.MiPendingCommand breakExceptionAdd(string exception = null, bool unhandled = false, bool temporary = false) @trustedAdds an Ada exception catchpoint.void autoConfigureFromDub(string projectPath) @trustedAuto-configures the session based on a DUB project. Loads the executable and sets up source search paths.void autoConfigureDubTests(string projectPath) @trustedAuto-configures the session for running DUB unit tests. It builds the test executable and loads it.MiPendingCommand execNext() @trustedExecutes the next line of source code, stepping over function calls.MiPendingCommand execStep() @trustedExecutes the next line of source code, stepping into function calls.MiPendingCommand execNextInstruction() @trustedExecutes the next instruction, stepping over function calls.MiPendingCommand execStepInstruction() @trustedExecutes the next instruction, stepping into function calls.MiPendingCommand execUntil(string location) @trustedContinues execution until a location is reached.MiPendingCommand execSignal(string signal) @trustedResumes execution and sends an OS signal to the inferior.MiPendingCommand execReturn(string value = null) @trustedMakes the current function return immediately.MiPendingCommand execReverseNext() @trustedExecutes the previous line of source code, stepping over function calls.MiPendingCommand execReverseStep() @trustedExecutes the previous line of source code, stepping into function calls.MiPendingCommand execReverseFinish() @trustedExecutes in reverse until the current function was called.MiPendingCommand checkpoint() @trustedCreates a checkpoint of the current state of the debugged program.MiPendingCommand targetRecordFull() @trustedStarts recording for reverse debugging using the 'full' recording method.MiPendingCommand targetRecordBTrace() @trustedStarts recording for reverse debugging using the 'btrace' recording method.MiPendingCommand traceDefineVariable(string name, string value = null) @trustedDefines a trace variable.MiPendingCommand traceSave(string filename, bool remote = false) @trustedSaves trace data to a file.string targetGetMemoryProtection(string address) @trustedTries to get memory protection for an address.MiPendingCommand stackListVariables(int printValues = 0) @trustedLists both locals and arguments for the current stack frame.MiPendingCommand dataReadMemory(string address, char fmt, int wordSize, int rows, int cols) @trustedReads memory from the debugged process.MiPendingCommand dataWriteMemory(string address, int wordSize, string value) @trustedWrites memory to the debugged process.MiPendingCommand dataWriteMemoryBytes(string address, const(ubyte)[] bytes) @trustedWrites raw memory bytes.MiPendingCommand dataWriteMemoryTag(string address, size_t count, int tagType, string[] tags) @trustedWrites a memory tag.MiPendingCommand dataSearchMemory(string address, size_t length, string pattern) @trustedSearches memory for a pattern.void writeMemory(string address, const(ubyte)[] bytes) @trustedWrites raw memory bytes from a buffer.MiPendingCommand dataEvaluateExpression(string expr, string threadId = null, int frameLevel = - 1) @trustedEvaluates an expression.MiValue[] dataEvaluateRange(string rangeExpr, int maxElements = 100) @trustedEvaluates a D range and returns its elements.MiPendingCommand varCreate(string expression, string name = "-", string frame = "*") @trustedCreates a variable object.MiPendingCommand varSetFormat(string name, string fmt) @trustedSets the output format for a variable object.MiPendingCommand varEvaluateExpression(string name) @trustedEvaluates the expression of a variable object.MiPendingCommand varInfoNumChildren(string name) @trustedReturns the number of children of a variable object.MiPendingCommand varInfoExpression(string name) @trustedReturns the expression used to create a variable object.MiPendingCommand varInfoPathExpression(string name) @trustedReturns the path expression of a variable object.MiPendingCommand varAssign(string name, string expression) @trustedAssigns a new value to a variable object.MiPendingCommand varSetVisualizer(string name, string value) @trustedEnables or disables Python visualizers for a variable object.MiPendingCommand fileExecAndSymbols(string file) @trustedLoads the target executable and its symbols.MiPendingCommand fileListExecSourceFiles() @trustedGets a list of source files used to build the executable.MiPendingCommand symbolListLines(string file) @trustedGets the mapping between source lines and addresses for a file.MiPendingCommand symbolInfoModuleFunctions(string moduleRegex = null, string nameRegex = null) @trustedLists functions in a module.MiPendingCommand symbolInfoModuleVariables(string moduleRegex = null, string nameRegex = null) @trustedLists variables in a module.MiPendingCommand symbolInfoFunctions(string name = null, bool details = false) @trustedSearches for information about functions.MiPendingCommand symbolInfoVariables(string name = null, bool details = false) @trustedSearches for information about variables.MiPendingCommand symbolInfoTypes(string name = null, bool details = false) @trustedSearches for information about types.MiPendingCommand dataListRegisterNames(int[] regnos = null) @trustedLists the names of available registers.MiPendingCommand dataListRegisterValues(char fmt, int[] regnos = null) @trustedReads current register values.MiPendingCommand dataWriteRegisterValues(char fmt, Tuple!(int, string)[] regnosValues) @trustedModifies register contents.MiPendingCommand dataDisassemble(string startAddr, string endAddr, GdbMiDisassemblyMode mode) @trustedDisassembles a range of addresses.MiPendingCommand dataDisassemble(string file, int line, int numLines, GdbMiDisassemblyMode mode) @trustedDisassembles a range of lines in a file.MiPendingCommand targetSetMemoryAttributes(string startAddress, string endAddress, string attributes) @trustedTries to set memory attributes for a range in GDB. See GDB 'mem' command documentation for details.MiPendingCommand loadCoreFile(string exe, string core) @trustedLoads a core file for post-mortem debugging.MiPendingCommand listThreadGroups(bool available = false, string group = null) @trustedLists thread groups.MiPendingCommand breakWatch(string expression, GdbMiWatchKind kind = GdbMiWatchKind.WRITE) @trustedInserts a watchpoint.MiPendingCommand breakPasscount(int number, int passcount) @trustedSets the passcount for a breakpoint.string currentThreadId() const @safe pure nothrow @nogcReturns: Current thread ID (may be null if unknown).void onStopped(void delegate(MiAsyncRecord) listener) @safeRegisters a listener for 'stopped' events.void onThreadCreated(void delegate(MiAsyncRecord) listener) @safeRegisters a listener for 'thread-created' events.MiPendingCommand environmentDirectory(string[] directories, bool reset = false) @trustedAdds directories to the source file search path.MiPendingCommand environmentCd(string directory) @trustedChanges the working directory of GDB (and the inferior).MiPendingCommand setSubstitutePath(string from, string to) @trustedSets a source path substitution rule.auto popEvent(Duration timeout = DEFAULT_EVENT_TIMEOUT) @trustedPops one event, blocking until an event arrives or timeout expires.void logShutdownError(string context, Exception e) @trustedLogs a shutdown/cleanup error through the configured logger if available.bool shouldLog(string rawLine, bool isOutgoing) @safeChecks if a line should be logged based on configuration.void handleParsedLine(string raw, MiRecord rec) @trustedRoutes a parsed stdout line to either the pending-command map or the event queue.this(GdbMiConfig config = GdbMiConfig.init)Spawns GDB in MI mode.High-level wrapper for a GDB variable object.
This class manages the lifecycle of a variable object created via -var-create. It provides ergonomic methods for updating and querying the variable state.
this(GdbMiSession session, string name, string expression, string type, int numChildren)Creates a variable object wrapper.const(char)[] _ssize_t _iGdbMiParseException parserError(string expected) @safeBuilds a `GdbMiParseException` at the current parser position.bool looksLikeResult() @safe pure nothrow @nogcReturns: `true` if the remaining input looks like a `name=value` pair.bool isIdentStart(char c) @safe pure nothrow @nogcReturns: `true` if `c` can start an MI identifier.bool isIdentContinue(char c) @safe pure nothrow @nogcReturns: `true` if `c` can continue an MI identifier.this(const(char)[] s)Creates a parser.Functions 18
MiValue findResult(scope MiResult[] results, string variable) @safeFinds the first result with the given variable name.MiValue requireResult(scope MiResult[] results, string variable) @safeReturns the result value for a variable name, throwing if not present.GdbMiInstruction[] parseInstructions(MiValue val) @safeParses a list of instructions from an MI value.DubProjectInfo parseDubProject(string projectPath) @trustedParses DUB project information using 'dub describe'.bool debuggerAvailable(string debuggerPath) @safeReturns: `true` if `debuggerPath` looks runnable.MiStreamKind parseStreamKind(char c) @safe pure nothrow @nogcConverts an MI stream-record prefix character to `MiStreamKind`.MiAsyncKind parseAsyncKind(char c) @safe pure nothrow @nogcConverts an MI async-record prefix character to `MiAsyncKind`.string escapeMiCString(string text) @safeEscapes a string as an MI C-string literal content (without surrounding quotes).string quoteMiArg(string text) @safeQuotes a string as an MI argument (C-string with surrounding quotes).string buildTestExecutable(string[] sourcePaths) @safeCompiles D source files to an executable for use in integration tests.string buildTestExecutable(string sourcePath) @safeCompiles a single D source file to an executable for use in integration tests.Variables 3
DEFAULT_COMMAND_TIMEOUT = dur!"seconds"(10)Default timeout for MI command completion (MiPendingCommand.wait()).
Ten seconds balances responsiveness against slow debuggee startup and symbol loading on large projects.
DEFAULT_EVENT_TIMEOUT = dur!"seconds"(1)Default timeout for event polling (GdbMiSession.popEvent()).
One second is a reasonable upper bound for event polling in an interactive application; callers that need longer waits should pass an explicit timeout.
string[string] _debuggerAvailableCache