Introduzione.

mtdbg è un debugger per il sistema operativo KolibriOS. Questo documento
descrive come utilizzare tale programma. Per eventuali domande conviene
scrivere sul forum (in russo, ma esiste anche una sezione inglese)
-- board.kolibrios.org.

Descrizione generica.

mtdbg è in grado di fare il debug di un solo programma alla volta, se non
viene caricato nessun programma, il debug viene disabilitato.

Il programma è a linea di comando, e accetta in input comandi da tastiera
La linea di comando è posizionata in basso, e accetta in input tasti
Backspace,Delete,Home,End,frecce sinistra/destra.
I comandi non sono case-sensitive e il delimitatore è un numero arbitrario
non nullo di spazi.

Per chiudere il debugger è sufficiente usare il comando "quit" senza
nessun argomento, altrimenti da interfaccia cliccando sul pulsante di
chiusura come per le altre applicazioni.

Quando il debugger viene avviato senza argomenti, non viene caricato
nessun programma. Se invece viene avviato con degli argomenti, mtdbg
cercherà di caricare il programma indicato come primo argomento e con
eventuali parametri per il programma passati come argomenti successivi.

È possibile caricare un qualsiasi programma in un secondo
momento con il comando
load <percorso all'eseguibile> []
ad esempio:
load /rd/1/example
LOAD /rd/1/aclock w200 h200
LoaD /hd0/1/menuetos/dosbox/dosbox
negli esempi, mtdbg caricherà il programma passato come primo argomenti,
un eventuale secondo argomento è il parametro da passare al programma
che si vuole caricare.
Il comando "load" restituisce in output nel "messages window", poco più
in alto della linea di comando, se il programma è stato caricato con
successo o meno. In caso di errore, verra mostrata la causa.
L'errore più comune è del tipo, "file not found", probabilmente perché
si è digitato in modo errato il percorso o il nome del programma da
caricare.

Il debugger è in grado di caricare file con simboli relativi al
programma di cui si vuole effetuare il debug.
Si tratta di file di testo, dei quali ogni riga inizia con
0x<hex_value_of_addr>
(righe che non iniziano in questo modo vengono ignorate). Tali file si
possono creare a mano o tramite fasm. È possibile caricare questi file
esplicitamente con il comando
load-symbols
Inoltre, quando viene eseguito il comando "load", mtdbg controllerà
la presenza di un file contenente simboli relativi al programma e di
estensione .dbg (nel primo esempio controlla la presenza del file
/rd/1/example.dbg). Se tale file esiste, questo viene caricato
automaticamente and if such file exists, e verrà notificato tramite il
messaggio "Symbols loaded", se il caricamento viene eseguito con
successo.

Può succedere che un programma che si vuole caricare è stato
compresso. La compressione funziona, in linea generale, nel
seguente modo: il file di input viene compresso (da qualche
programma apposito), successivamente viene aggiunto un pezzo di codice
che all'avvio del programma effettua una decompressione in memoria.
Se un programma è stato compresso, il suo codice non è visibile al
debugger, e deve venir prima decompresso.
mtdbg è in grado di determinare la maggior parte di compressori
(mxp,mxp_lzo,mxp_nrv,mtappack) e in questi casi suggerisce in automatico
di effettuare la decompressione per vedere il codice del programma.
È sufficiente pigiare 'y' e enter per accettare l'opzione, altrimenti
rifiutarla. Se non viene riconosciuto il metodo di compressione, è
sempre possibile usare il comando unpack (senza argomenti).
Tale comando è da usare solamente se si è sicuro che il programma sia
compresso e che non sia già stato decompresso dal debugger.
[A partire da Kolibri 0.6.5.0, questo paragrafo non è più attuale poiché
è possibile comprimere le applicazioni con kpack e il decompressore è
implementato a livello kernel, in modo da rendere il debug trasparente]

Un programma caricato può essere terminato tramite il comando
"terminate" senza argomenti. Il comando "detach", senza parametri
aggiuntivi "stacca" il programma dal debugger, nel senso che questo
continuerà la sua normale esecuzione senza il debugger, come se questo
non vi fosse mai stato.
Dato uno di questi due comandi, l'attività di debug viene terminata.

È possibile ricaricare il programma precedente con il comando "reload",
senza parametri. Se nel frattempo è stato caricato un altro programma,
questo viene terminato e viene ricaricato il programma precedente con
gli argomenti passati precedentemente, come se fossero stati dati i
comandi
terminate
load
Il vantaggio di reload sta nel fatto di essere più immediato e che viene
mantenuto l'indirizzo di memoria, mentre con il comando load questo
viene spostato all'indirizzo 0. (vedi sotto)

Il comando "help", oppure "h", è sempre disponibile.
Tutti i comandi sono divisi in gruppi
"help" senza argomenti mostra l'elenco dei comandi disponibili
"help" con il nome di un gruppo mostra i comandi relativi al gruppo
"help" con il nome di un comando mostra informazioni sull'uso di tale
comando
esempi:
help
help control
h LoaD

La finestra del debugger è composta dai seguenti elementi enumerati
dall'alto al basso:

Nella "Dump window" è possibile osservare i dati a partire da ogni
indirizzo, usare il comando
d
Il comando "d", senza parametri mostra la "dump window".
In modo analogo funziona il seguente comando per la "code window"
u
oppure "u".
Esempi:
d esi - mostra i dati all'indirizzo esi (e.g. utile prima di eseguire
una istruzione rep movsb)
d esp - mostra lo stack
u eip - disassembla le istruzioni a partire dall'attuale indirizzo

Le espressioni in mtdbg possono includere

I valori del registro caricato nel programma può essere modificato con
il comando "r" in uno dei seguenti modi (sono equivalenti)
r
r =

Supponendo che sia stato caricato un programma con successo per il
debug, subito dopo il programma verrà sospeso e non più eseguito.
Premendo Ctrl+F7 (oppure dalla linea di comando "s") è possibile far
effettuare una azione al programma, dopodiché questo verrà sospeso
immediatamente, e il debugger mostrerà i nuovi valori nel registro e in
memoria.
la chiamata di sistema "int 40h" è considerata una azione.
Premendo Ctrl+F8 (oppure dalla linea di comando "p") permette di
eseguire il programma, e chiamate a procedure esterne, cicli e altre
strutture di controllo oppure operazioni con prefisso rep/repz/repnz
verranno interpretate come una singola azione.
Solitamente si chiede di eseguire azioni singole su sezioni di
programmi, ad esempio per tenere traccia dei valori in memoria e nel
registro.
Il comando
g
riprende l'esecuzione del programma e attende che il controllo vada a
eip=indirizzo dato, e in quel momento sospende il programma.
Se il comando "g" viene dato senza argomenti, viene semplicemente
ripresa l'esecuzione del programma.

Per sospendere l'esecuzione del programma è sufficiente usare il comando
"stop", senza parametri o argomenti.

In una situazione standard il programma viene eseguito normalmente,
quando sono soddisfatte alcune condizioni, il programma viene sospeso e
invia un segnale al debugger. Tali condizioni sono chiamate
"breakpoints" o "breaks".
L'utilizzo principale dei breakpoints è quello di interrompere
l'esecuzione del programma in determinati punti. I breakpoint si
impostano con il comando
bp
Si noti che se è presente un solo breakpoint, allora è più conveniente
usare il comando "g" con parametri.

Vi sono altri tipi di breakpoint che permettono di accedera ad una data
area di memoria. Il numero massimo di breakpoint di questo tipo sono 4,
causa limitazioni hardware.
bpm - interrompe ad ogni accesso ad ogni byte ad un
indirizzo dato
bpm w - interrompe alla scrittura di ogni byte ad un
indirizzo dato
bpmb,bpmw,bpmd - interrompe all'accesso di ogni byte, o
dword all'indirizzo dato. bpm e bpmb sono
sinonimi. Quando viene usato bpmw o bpmd,
gli indirizzi devono essere del tipo
corrispondenti al tipo di dato, quindi
per i word è dispari, per i dword è
divisibile per 4.
bpmb,bpmw,bpmd w - simile al break in scrittura.

Per vedere la lista dei breakpoints impostati, usare il comando "bl",
per ottenere informazioni su un particolare breakpoint, usare il
comando "bl ".
È possibile rimuovere i breakpoint con il comando "bc ", oppure
disabilitati momentaneamente con il comando "bd " e riabilitati
con "be "

Note.

  1. Quando si effettua il debug di un proprio programma, è possibile
    mettere nel codice istruzione int3. Queste istruzioni creano delle
    eccezioni durante la normale esecuzione, che porta alla terminazione
    del programma, ma durante l'attività di debug permette di non dover
    pensare agli indirizzi di memoria da usare nei comandi g e bp.

  2. La notazione standard per l'output e input è quella esadecimale.

  3. Quando il programma viene eseguito, la finestra del registro e dei
    dati mostrano delle informazioni prima dell'avvio. Non si possono
    impostare i valori di registro in questo mode. Tuttavia il
    comando "d" in questo modo mostra informazioni che erano vere nel
    momento in cui si è immesso il comando.

     				diamond