213 lines
10 KiB
Plaintext
213 lines
10 KiB
Plaintext
|
Introduction.
|
|||
|
|
|||
|
mtdbg is a debugger for Kolibri operating system. This documentation describes
|
|||
|
debugger features and work with it. Feel free to ask on our board (mostly
|
|||
|
in Russian, but has an English forum) -- board.kolibrios.org.
|
|||
|
|
|||
|
General description.
|
|||
|
|
|||
|
In each moment of time mtdbg can debug only one program. I will call it
|
|||
|
loaded program. If no program is loaded, overwhelming majority of debugging
|
|||
|
actions is disabled.
|
|||
|
|
|||
|
mtdbg is controlled by command line, entering from keyboard. Command line
|
|||
|
is drawn in the bottom part of debugger window. Debugger handles standard
|
|||
|
input keys Backspace,Delete,Home,End,left/right arrows.
|
|||
|
Commands are case-insensitive. Delimiter is arbitrary nonzero number of spaces.
|
|||
|
|
|||
|
At any moment mtdbg can be terminated by command "quit" (without arguments).
|
|||
|
You can also simply press to close button in the right upper corner of window.
|
|||
|
|
|||
|
When debugger is started without command string parameters, no program is
|
|||
|
loaded. Also mtdbg can be started with command string, in this case it tries
|
|||
|
to load program with the name pointed to in first parameter in command string
|
|||
|
and parameters pointed to following (if present).
|
|||
|
|
|||
|
If no program is loaded, you can load a program with the command
|
|||
|
load <full name of executable file> [<parameters>]
|
|||
|
Examples:
|
|||
|
load /rd/1/example
|
|||
|
LOAD /rd/1/aclock w200 h200
|
|||
|
LoaD /hd0/1/menuetos/dosbox/dosbox
|
|||
|
All that stays after first space after executable file name, is exactly passed
|
|||
|
to program as command string.
|
|||
|
The command "load" reports result in the messages window (a little higher
|
|||
|
than command line window). If program was loaded successfully, there will
|
|||
|
be the appropriate message; otherwise the message will contain error reason.
|
|||
|
Most probable error is "file not found" if wrong file name is given.
|
|||
|
|
|||
|
The debugger can load files with information on symbols in the program
|
|||
|
(labels, global variables) - text files, each line of which has format
|
|||
|
0x<hex_value_of_addr> <name>
|
|||
|
(lines, which do not have such format, are ignored). Such file can be created
|
|||
|
by hand or generated automatically by fasm. Evident load can be done by command
|
|||
|
load-symbols <full name of symbols file>
|
|||
|
Furthermore, when the debugger executes the command "load", it checks for
|
|||
|
presence of file with name as of loading binary and extension '.dbg'
|
|||
|
(/rd/1/example.dbg in the first of examples above), and if such file exists,
|
|||
|
the debugger loads it automatically (with the message "Symbols loaded", if
|
|||
|
all is OK).
|
|||
|
|
|||
|
It can happen so that loaded program is packed. General principle of
|
|||
|
program packing is following: at first input file is packed (by some
|
|||
|
pack algorithm), then is appended small code which gets control at program
|
|||
|
start, unpacks input code in the memory and then passes control to it.
|
|||
|
If program is packed, it "real" code is not visible and for debugging it is
|
|||
|
needed previously to pass through unpacker code.
|
|||
|
mtdbg determines most of existing packers (mxp,mxp_lzo,mxp_nrv,mtappack)
|
|||
|
and in this case suggests to automatically go to "real" code. It is recommended
|
|||
|
to accept (press 'y' or <Enter>), but you can refuse too. At refusal and if
|
|||
|
program is packed by something unknown the command "unpack" (without arguments)
|
|||
|
can be used. Call it only in the case when you are sure that program is packed
|
|||
|
and control has not already went to main code! [Starting from Kolibri 0.6.5.0,
|
|||
|
this paragraph is no more actual, because one can pack applications as all
|
|||
|
binary files with kpack and the unpacker code in this case is located in the
|
|||
|
kernel and is transparent for debug.]
|
|||
|
|
|||
|
Loaded program can be terminated by the command "terminate" (without
|
|||
|
arguments). The command "detach" (without arguments) detaches from program,
|
|||
|
after that program continues execution normally, as if there was no debugger.
|
|||
|
After both this commands program stops to be debugged.
|
|||
|
|
|||
|
It is possible to anew load program for debugging by the command "reload"
|
|||
|
(without arguments). If there is already loaded program, it is terminated
|
|||
|
and new instance is started (from the beginning) (with the same command
|
|||
|
string), in this case the command is similar to the commands
|
|||
|
terminate
|
|||
|
load <last program name> <last program arguments>
|
|||
|
Otherwise is loaded anew latest program, which was debugged (in the current
|
|||
|
seance of work with mtdbg) (with the same command string), i.e. is similar to
|
|||
|
load <last program name> <last program arguments>,
|
|||
|
but the command "reload" in both cases is shorter and more convenient;
|
|||
|
moreover, "load" thinks that new program is loaded and moves data window
|
|||
|
(see below) to zero address, and "reload" keeps current address.
|
|||
|
|
|||
|
The command "help", which can be shorten to "h", is always available.
|
|||
|
All commands are divided on groups.
|
|||
|
"help" without arguments displays the list of command groups.
|
|||
|
"help" with group name displays the list of commands in this group with short
|
|||
|
comments.
|
|||
|
"help" with command name displays information about given command.
|
|||
|
Examples:
|
|||
|
help
|
|||
|
help control
|
|||
|
h LoaD
|
|||
|
|
|||
|
The debugger window consists from the following items enumerated from up
|
|||
|
to down:
|
|||
|
- status string. If there is loaded program, shows its name and state
|
|||
|
("Running/Paused"), otherwise reports "No program loaded".
|
|||
|
- registers window - shows values of general-purpose registers, register eip
|
|||
|
and states of single flags: CF,PF,AF,ZF,SF,DF,OF: if flag is cleared, then
|
|||
|
is displayed lower-case letter, if flag is set, then upper-case one.
|
|||
|
Registers which are changed from previous moment are highlighted in green.
|
|||
|
- data window (dump window) - shows memory contains of loaded program
|
|||
|
- code window (disassembler window) - shows program code as disassembled
|
|||
|
instructions
|
|||
|
- messages window
|
|||
|
- command line window
|
|||
|
|
|||
|
Dump window can display data starting from any address, to this serves
|
|||
|
the command
|
|||
|
d <expression>
|
|||
|
The command "d" without arguments flicks dump window down.
|
|||
|
The same is for code window and the command
|
|||
|
u <expression>
|
|||
|
or simply "u".
|
|||
|
Examples:
|
|||
|
d esi - displays data at address esi (e.g. is useful before execution of
|
|||
|
instruction rep movsb)
|
|||
|
d esp - displays stack
|
|||
|
u eip - disassembles instruction starting from the current
|
|||
|
|
|||
|
Expressions in mtdbg can include
|
|||
|
- hexadecimal constants
|
|||
|
- names of all general-purpose registers (8 32-bits, 8 16-bits and
|
|||
|
8 8-bits) and register eip; values of 16- and 8-bits registers are padded
|
|||
|
with zeroes to 32 bits
|
|||
|
- four arithmetic operations +,-,*,/ (with standard priorities) and
|
|||
|
brackets
|
|||
|
- [if symbols information was loaded] names, loaded from dbg-file
|
|||
|
All calculations are realized modulo 2^32.
|
|||
|
Examples of expressions:
|
|||
|
eax
|
|||
|
eip+2
|
|||
|
ecx-esi-1F
|
|||
|
al+AH*bl
|
|||
|
ax + 2* bH*(eip+a73)
|
|||
|
3*esi*di/EAX
|
|||
|
The command
|
|||
|
? <expression>
|
|||
|
calculates value of specified expression.
|
|||
|
|
|||
|
Values of registers in loaded program can be changed by the command "r", which
|
|||
|
has two absolutely equivalent forms:
|
|||
|
r <register> <expression>
|
|||
|
r <register>=<expression>
|
|||
|
(in both cases you can place spaces as you want). Register can be any of
|
|||
|
above-mentioned - 24 general-purpose registers and eip.
|
|||
|
|
|||
|
|
|||
|
Let us assume that the command "load" was successfully load program for
|
|||
|
debugging.
|
|||
|
Immediately after loading program is suspended and does not execute.
|
|||
|
Press Ctrl+F7 (command-line analog is the command "s") to make one step
|
|||
|
in loaded program, after that control returns to debugger which displays
|
|||
|
new contains of registers and memory. The system call "int 40h" is considered
|
|||
|
as one step.
|
|||
|
Pressing Ctrl+F8 (command-line analog is the command "p") also makes step in
|
|||
|
loaded program, but procedure calls, string operations with prefix
|
|||
|
rep/repz/repnz and 'loop' cycles are executed as one step.
|
|||
|
The one-step commands are used usually on single program sections,
|
|||
|
when it is needed, for example, to regularly trace registers value and/or
|
|||
|
some variables in memory.
|
|||
|
The command
|
|||
|
g <expression>
|
|||
|
resumes program execution and waits until control goes to eip=given address,
|
|||
|
and in this moment suspends program. The command "g" without arguments
|
|||
|
simply resumes execution.
|
|||
|
|
|||
|
To suspend program use the command "stop" (without arguments).
|
|||
|
|
|||
|
In the typical situation it is required that program is executed normally,
|
|||
|
but when some conditions are satisfied, program suspends and debugger receives
|
|||
|
control. The corresponding conditions are called breakpoints or simply breaks.
|
|||
|
Primary type of breakpoints is to concrete address, i.e. stop execution at
|
|||
|
eip=<given value>. Such breakpoints are set by the command
|
|||
|
bp <expression>
|
|||
|
Note that if there is only one such breakpoint, there is more convenient to use
|
|||
|
the command "g" with argument instead.
|
|||
|
|
|||
|
Other type of breakpoints is on access to given memory area. Maximum
|
|||
|
numbers of such breakpoints is 4 (because hardware features of x86 processors
|
|||
|
are used and they allows only 4).
|
|||
|
bpm <expression> - breaks at any access to byte at given address
|
|||
|
bpm w <expression> - breaks at write to byte at given address
|
|||
|
bpmb,bpmw,bpmd <expression> - breaks to access correspondingly to byte, word
|
|||
|
or dword at given address. bpm <20> bpmb are synonyms. When bpmw,bpmd are used,
|
|||
|
address must be aligned according to correspondingly word bound (i.e. be even)
|
|||
|
or dword bound (i.e. be divisible by 4).
|
|||
|
bpmb,bpmw,bpmd w <expression> - similar to break on write.
|
|||
|
|
|||
|
To see the list of set breakpoints use the command "bl", to obtain information
|
|||
|
on concrete breakpoint use "bl <number>". Unnecessary breakpoints can be
|
|||
|
deleted with the command "bc <number>", temporarily unnecessary can be
|
|||
|
disabled by the command "bd <number>", when they will be needed again,
|
|||
|
use the command "be <number>".
|
|||
|
|
|||
|
Remarks.
|
|||
|
|
|||
|
1. When debugging your own programs you can put in code instructions
|
|||
|
int3 (pay attention to absence of space!). Such instruction causes
|
|||
|
exception at normal run, which leads to process termination, but
|
|||
|
at work under debugger it is simply activated (with the message
|
|||
|
"int3 command at xxx"). This feature allows to not think about addresses
|
|||
|
to use in the commands g and/or bp.
|
|||
|
2. All output and all input is oriented on hexadecimal scale of notation.
|
|||
|
3. When program is executed, registers and data window shows information
|
|||
|
regarding to moment before resume; you can not set registers value in this
|
|||
|
mode. Nevertheless the command "d" in this mode shows information that
|
|||
|
was true in the moment of command delivery.
|
|||
|
|
|||
|
diamond
|