[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The GNU Mach kernel debugger ddb
is a powerful built-in debugger
with a gdb like syntax. It is enabled at compile time using the
`--enable-kdb' option. Whenever you want to enter the debugger
while running the kernel, you can press the key combination
Ctrl-Alt-D.
11.1 Operation | Basic architecture of the kernel debugger. | |
11.2 Commands | Available commands in the kernel debugger. | |
11.3 Variables | Access of variables from the kernel debugger. | |
11.4 Expressions | Usage of expressions in the kernel debugger. |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The current location is called dot. The dot is displayed with a hexadecimal format at a prompt. Examine and write commands update dot to the address of the last line examined or the last location modified, and set next to the address of the next location to be examined or changed. Other commands don't change dot, and set next to be the same as dot.
The general command syntax is:
command[/modifier] address [,count] |
!! repeats the previous command, and a blank line repeats from the address next with count 1 and no modifiers. Specifying address sets dot to the address. Omitting address uses dot. A missing count is taken to be 1 for printing commands or infinity for stack traces.
Current ddb
is enhanced to support multi-thread debugging. A
break point can be set only for a specific thread, and the address space
or registers of non current thread can be examined or modified if
supported by machine dependent routines. For example,
break/t mach_msg_trap $task11.0 |
sets a break point at mach_msg_trap
for the first thread of task
11 listed by a show all threads
command.
In the above example, $task11.0
is translated to the
corresponding thread structure's address by variable translation
mechanism described later. If a default target thread is set in a
variable $thread
, the $task11.0
can be omitted. In
general, if t
is specified in a modifier of a command line, a
specified thread or a default target thread is used as a target thread
instead of the current one. The t
modifier in a command line is
not valid in evaluating expressions in a command line. If you want to
get a value indirectly from a specific thread's address space or access
to its registers within an expression, you have to specify a default
target thread in advance, and to use :t
modifier immediately
after the indirect access or the register reference like as follows:
set $thread $task11.0 print $eax:t *(0x100):tuh |
No sign extension and indirection size(long, half word, byte)
can
be specified with u
, l
, h
and b
respectively
for the indirect access.
Note: Support of non current space/register access and user space break point depend on the machines. If not supported, attempts of such operation may provide incorrect information or may cause strange behavior. Even if supported, the user space access is limited to the pages resident in the main memory at that time. If a target page is not in the main memory, an error will be reported.
ddb
has a feature like a command more
for the output. If
an output line exceeds the number set in the $lines
variable, it
displays `--db_more--' and waits for a response. The valid
responses for it are:
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
examine(x) [/modifier] addr[,count] [ thread ]
t
option in the modifier and thread
parameter. The format characters are
b
h
l
a
,
A
x
z
o
d
u
r
c
s
m
i
I
vax
i386
mips
xf
xb
print[/axzodurc] addr1 [ addr2 ... ]
a
x
z
o
d
u
r
c
. If no modifier is specified, the last one specified to it is
used. addr can be a string, and it is printed as it is. For
example,
print/x "eax = " $eax "\necx = " $ecx "\n" |
will print like
eax = xxxxxx ecx = yyyyyy |
write[/bhlt] addr [ thread ] expr1 [ expr2 ... ]
t
option in the modifier
and thread parameter. Warning: since there is no delimiter
between expressions, strange things may happen. It's best to enclose
each expression in parentheses.
set $variable [=] expr
break[/tuTU] addr[,count] [ thread1 ... ]
t
u
t
or T
option to specify the non-current target user
space. Without u
option, the address is considered in the kernel
space, and wrong space address is rejected with an error message. This
option can be used only if it is supported by machine dependent
routines.
T
t
option except that the break point is valid for all threads
which belong to the same task as the specified target thread.
U
u
option, except that the break point is valid for all threads which share
the same address space even if t
option is specified. t
option is used only to specify the target shared space. Without
t
option, u
and U
have the same meanings. U
is useful for setting a user space break point in non-current address
space with t
option such as in an emulation library space. This
option can be used only if it is supported by machine dependent
routines.
Warning: if a user text is shadowed by a normal user space debugger, user space break points may not work correctly. Setting a break point at the low-level code paths may also cause strange behavior.
delete[/tuTU] addr|#number [ thread1 ... ]
#
, or by addr like specified in
break
command.
cond #number [ condition commands ]
continue
command is executed,
the command execution stops there, and the stopped thread resumes
execution. If the command execution reaches the end of the list, and it
enters into a command input mode. For example,
set $work0 0 break/Tu xxx_start $task7.0 cond #1 (1) set $work0 1; set $work1 0; cont break/T vm_fault $task7.0 cond #2 ($work0) set $work1 ($work1+1); cont break/Tu xxx_end $task7.0 cond #3 ($work0) print $work1 " faults\n"; set $work0 0 cont |
will print page fault counts from xxx_start
to xxx_end
in
task7
.
step[/p] [,count]
p
option is specified, print
each instruction at each step. Otherwise, only print the last
instruction.
Warning: depending on machine type, it may not be possible to single-step through some low-level code paths or user space code. On machines with software-emulated single-stepping (e.g., pmax), stepping through code executed by interrupt handlers will probably do the wrong thing.
continue[/c]
/c
,
count instructions while executing. Some machines (e.g., pmax) also
count loads and stores.
Warning: when counting, the debugger is really silently single-stepping. This means that single-stepping on low-level code may cause strange behavior.
until
next[/p]
p
option is
specified, print the call nesting depth and the cumulative instruction
count at each call or return. Otherwise, only print when the matching
return is hit.
match[/p]
next
.
trace[/tu] [ frame_addr|thread ][,count]
u
option traces user space; if omitted, only traces
kernel space. If t
option is specified, it shows the stack trace
of the specified thread or a default target thread. Otherwise, it shows
the stack trace of the current thread from the frame address specified
by a parameter or from the current frame. count is the number of
frames to be traced. If the count is omitted, all frames are
printed.
Warning: If the target thread's stack is not in the main memory at that time, the stack trace will fail. User space stack trace is valid only if the machine dependent code supports it.
search[/bhl] addr value [mask] [,count]
ddb
doesn't always recover from touching bad memory. The optional count
argument limits the search.
macro name commands
$argxx
can be used to get a parameter
passed to the macro. When a macro is called, each argument is evaluated
as an expression, and the value is assigned to each parameter,
$arg1
, $arg2
, ... respectively. 10 $arg
variables are reserved to each level of macros, and they can be used as
local variables. The nesting of macro can be allowed up to 5 levels.
For example,
macro xinit set $work0 $arg1 macro xlist examine/m $work0,4; set $work0 *($work0) xinit *(xxx_list) xlist .... |
will print the contents of a list starting from xxx_list
by each
xlist
command.
dmacro name
show all threads[/ul]
ddb
prints more information than previous one. It shows UNIX process
information like ps
for each task. The UNIX process
information may not be shown if it is not supported in the machine, or
the bottom of the stack of the target task is not in the main memory at
that time. It also shows task and thread identification numbers. These
numbers can be used to specify a task or a thread symbolically in
various commands. The numbers are valid only in the same debugger
session. If the execution is resumed again, the numbers may change.
The current thread can be distinguished from others by a #
after
the thread id instead of :
. Without l
option, it only
shows thread id, thread structure address and the status for each
thread. The status consists of 5 letters, R(run), W(wait), S(sus
pended), O(swapped out) and N(interruptible), and if corresponding
status bit is off, .
is printed instead. If l
option is
specified, more detail information is printed for each thread.
show task [ addr ]
show thread [ addr ]
show registers[/tu [ thread ]]
t
option and thread parameter. If u
option is specified, it
displays user registers instead of kernel or currently saved one.
Warning: The support of t
and u
option depends on the
machine. If not supported, incorrect information will be displayed.
show map addr
vm_map
at addr.
show object addr
vm_object
at addr.
show page addr
vm_page
structure at addr.
show port addr
ipc_port
structure at addr.
show ipc_port[/t [ thread ]]
ipc_port
structure's addresses the target thread has.
The target thread is a current thread or that specified by a parameter.
show macro [ name ]
show watches
watch[/T] addr,size [ task ]
T
option, addr is assumed to be a kernel address.
If you want to set a watch point in user space, specify T
and
task parameter where the address belongs to. If the task
parameter is omitted, a task of the default target thread or a current
task is assumed. If you specify a wrong space address, the request is
rejected with an error message.
Warning: Attempts to watch wired kernel memory may cause unrecoverable error in some systems such as i386. Watchpoints on user addresses work best.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The debugger accesses registers and variables as $name. Register
names are as in the show registers
command. Some variables are
suffixed with numbers, and may have some modifier following a colon
immediately after the variable name. For example, register variables
can have u
and t
modifier to indicate user register and
that of a default target thread instead of that of the current thread
(e.g. $eax:tu
).
Built-in variables currently supported are:
taskxx[.yy]
show all threads
command respectively. This variable is read only.
thread
t
option is
specified without explicit thread structure address parameter in command
lines or expression evaluation.
radix
maxoff
maxwidth
lines
more
feature.
tabstops
argxx
workxx
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Almost all expression operators in C are supported except ~
,
^
, and unary &
. Special rules in ddb
are:
identifier
.
and :
can be used in the identifier. If supported by
an object format dependent routine,
[file_name:]func[:line_number]
[file_name:]variable, and
file_name[:line_number] can be accepted as a symbol. The
symbol may be prefixed with symbol_table_name::
like
emulator::mach_msg_trap
to specify other than kernel symbols.
number
0x
0o
0t
otherwise, follow current radix.
.
+
..
examine
or write
command.
´
$variable
:
and modifiers as described above.
a
*expr
:
and modifiers as
described above.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |