| -cli | Selects the CLI to use. Available CLIs are "gdb" and "ddbg" (default) |
| -cmd | execute a string of Ddbg commands separated by semicolons, e.g. ddbg -cmd="sp src; onex \"wmd ddbg.dmp; r\"; r" debuggee.exe |
| <exe file> | The name of the debuggee. If no extension is given, ".exe" is assumed. |
| [arguments] | Optional arguments that are passed to the debuggee. |
In order to be able to debug a program it has to be compiled with DMD's "-g" switch.
This section describes the Ddbg CLI that is active by default.
Running
-----------------------------------------------------------------------------
in step into at source level
ov step over at source level
out step out at source level
r run/continue the program
Breakpoints
-----------------------------------------------------------------------------
bp [<file>:<line>[#<thrd>]] [ind] set breakpoint #index at given file:line
optionally only for the given thread id
optionally with the given breakpoint index
dbp [<file>:<line>|#index|*] delete breakpoint by index, line or all
lbp list breakpoints
ltbp list temporary breakpoints
Stack/Memory/Registers
-----------------------------------------------------------------------------
dm <start> <length> dump memory (start in hex, length in dec)
dr [cpu] [fpu] [mmx] [sse] dump registers [toggle register groups]
ds dump stack (last line is top)
lsv list variables in current scope
mi [free] [rsrv] memory information. lists blocks in state
commit and optionally free and reserve
us unwind stack, prints full stacktrace
Expressions
-----------------------------------------------------------------------------
= <expr> evaluate expression
ed <depth> set max depth of implicit evaluation of
recursive structures
el <length> set max number of array elements to print
er toggle between ed 0 and previous ed
f <number> select frame for evaluation.
default: current frame = 0
t <expression> type of expression
Source
-----------------------------------------------------------------------------
jkf toggle whether to switch to stack frame of
last known source location on exception
lsm [substring] list source modules
lsp list source search paths
ps [count] print count lines of source before
and after current location
sp <path> add source search path
Disassembly
-----------------------------------------------------------------------------
da [start] disassemble from start
(default = function start) to next ret
dal [#lines] disassemble to/from +/- source lines
Threads
-----------------------------------------------------------------------------
lt list threads
st <threadId> select thread to be evaluation context
Minidumps
-----------------------------------------------------------------------------
rmd <file> read minidump from file
wmd <file> write minidump to file
Miscellaneous
-----------------------------------------------------------------------------
arg <args> set command line arguments
ii print image information
ldll list loaded DLLs
lm [substring] list debug modules
ld [substring] list data symbols
lf [substring] list function symbols
lg [substring] list global symbols
lp [substring] list global publics
ls [substring] list all symbols
nc toggle new console for process
onex <cmd; cmd; ...> on exception execute list of commands
onterm <cmd; cmd; ...> on termination execute list of commands
q quit debugger
return repeats the last command
For static and dynamic arrays, Ddbg supports the "ptr" and "length" properties, for associative arrays the "length" property.
Evaluate an expression with the "=" command, print the type of an expression with the "t" command.
By default, expressions are evaluated one level deep. That means that if the result of an expression is a non-scalar data structure (struct, class, arrays),
the evaluation is stopped and "..." is printed instead. You can change the evaluation depth with the "ed" and "er" commands.
Usually it's fine to use depth 1, though, since that gives you a short listing of all scope variables ("lsv" command) and you can inspect variables deeper by issuing explicit "=" commands for single variables.
Here are some sample expressions:
->= somevariable ->= myclass.mymember ->= mystruct ->= args[0][3..12] ->= (cast(char[][char[]])assoc_array)["key"] ->= assoc_array.length ->= array.ptr ->= (cast(Vector!(float,3)[])vertices)[2 .. 23] ->= *cast(uint*)#eax ->= (cast(double[2])#xmm0)[0] ->= this.surface.vertices[this.surface.faces[7].a].x ->= *cast(Foo*)0x12ffc4
The exact syntax of Ddbg's expressions is:
Expr = Deref Cast DotChain
Deref = "*" Deref
| epsilon
DotChain = Register
| "(" Expr ")" RefExpr
| Ident RefExpr
RefExpr = "." Ident RefExpr
| "[" Args "]" RefExpr
| epsilon
Args = Arg ".." Arg
| Arg
Arg = Lit
| Expr
Register = "#" NoWhiteSpace RegName
RegName = regexp("e[abcd]x|e[ds]i|e[bs]p|eip|efl")
| regexp("[abcd]x|[ds]i|[bs]p|(cdefgs)s")
| regexp("[abcd][hl]")
| regexp("st[0-7]")
| regexp("mm[0-7]")
| regexp("xmm[0-7]")
Cast = "cast" "(" Type ")"
| epsilon
Type = BaseType QuantList
BaseType = FQNIdent TplParams
QuantList = Quantifier QuantList
| epsilon
Quantifier = "*"
| "[" "]"
| "[" Integer "]"
| "[" Type "]"
TplParams = "!" "(" TplParam TplParams2 ")"
| epsilon
TplParams2 = "," TplParam TplParams2
| epsilon
TplParam = Type
| Lit
Lit = Sign Integer IntegerSuffix
| regexp("\"(([^\"\\\\]*(\\\\(['\"\\?\\\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))?)*)\"")
| regexp("'(([^'\\\\]|(\\\\(['\"\\?\\\\abfnrtv]|(x[0-9a-fA-F]{2})|(u[0-9a-fA-F]{4})|(U[0-9a-fA-F]{8})))))'")
Ident = regexp("[a-zA-Z_][_a-zA-Z0-9]*")
FQNIdent = regexp("[a-zA-Z_][_a-zA-Z0-9.]*")
Integer = regexp("0[xX][0-9a-fA-F_]+")
| regexp("0[bB][01_]+")
| regexp("0[0-7_]+")
| regexp("0|([1-9][0-9_]*)")
IntegerSuffix = regexp("L[uU]|[uU]L")
| "L"
| regexp("[uU]")
| epsilon
Sign = "-"
| epsilon
Ddbg uses the DBGHELP API to support minidumps. It is available on every Windows XP Installation. For other Windows versions, the Platform SDK must be installed.
To run a debuggee such that it automatically creates a minidump file when it crashes, use the following command line:
ddbg -cmd="onex \"wmd ddbg.dmp; q\"; onterm \"q\"; r" debuggee.exeTo browse the minidump, you can start ddbg as usual:
ddbg debuggee.exeand issue an rmd command to load the minidump file
->rmd ddbg.dmpIf the minidump was saved after an exception occured, you will now recieve the exception's message again. Minidumps can be created at anytime, though. Therefore you can also examine problems that do not necessarily throw an exception.
The following call triggers writing of a minidump and continues the debuggee afterwards:
import win32.winbase;
// ...
OutputDebugStringA(toStringz("Ddbg: wmd problem1.dmp; r"));