# Depurando com o GDB

O GDB é um depurador de linha de comando que faz parte do projeto GNU. O [Mingw-w64](https://mingw-w64.org/doku.php) já instala o GDB junto com o GCC, e no Linux ele pode ser instalado pelo pacote `gdb`:

```shell-session
$ sudo apt install gdb
```

O GDB pode ser usado para depurar código tanto visualizando o Assembly como também o código-fonte. Para isso é necessário compilar o binário adicionando informações de depuração, com o GCC basta adicionar a opção `-g3` ao compilar. Exemplo:

```shell-session
$ gcc -g3 test.c -o test
```

E pode rodar o GDB passando o caminho do binário assim:

```shell-session
$ gdb ./test
```

{% hint style="info" %}
O caminho do binário é opcional. Caso especificado o GDB já inicia com esse binário como alvo para depuração, mas existem comandos do GDB que podem ser usados para escolher um alvo conforme será explicado mais abaixo.
{% endhint %}

O GDB funciona com comandos, quando você o inicia ele te apresenta um prompt onde você pode ir inserindo comandos para executar determinadas ações. Mais abaixo irei apresentar os principais comandos e como utilizá-los.

Esse depurador suporta depurar código de diversas linguagens de programação (incluindo C++, Go e Rust), mas aqui será demonstrado seu uso somente em um código escrito em C. O seguinte código será usado para demonstração:

{% code title="test.c" %}

```c
#include <stdio.h>

#define DEFINED_VALUE 12345

int add(int a, int b)
{
  return a + b;
}

int main(int argc, char **argv)
{
  char str[] = "a =";
  int x = 8;

  printf("%s %d\n", str, add(x, 3));
  return 0;
}
```

{% endcode %}

E será compilado da seguinte forma:

```shell-session
$ gcc -g3 test.c -o test
```

{% hint style="info" %}
A opção `-g` é usada para adicionar informações de depuração ao executável. Esse `3` seria o nível de informações que serão adicionadas, onde 3 é o maior nível.

Para mais informações consulte a [documentação do GCC](https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html).
{% endhint %}

## Expressões

Determinadas instruções do GDB recebem uma expressão como argumento onde é possível usar qualquer tipo de constante, variável ou operador da linguagem que está sendo depurada (neste caso C). Isso inclui *casts*, *strings* literais, macros e até mesmo chamadas de funções. Logo a expressão interpretada é quase idêntica a uma expressão que você escreveria na linguagem que está sendo depurada (no nosso caso C).

Também é possível referenciar o valor de algum registrador na expressão usando o prefixo `$`, como `$rax` por exemplo. Na imagem abaixo é uma demonstração usando o comando `print`:

![Saída do GDB ao usar o comando \`print\`](https://2466397120-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lif0YmrEB3G3dh1VxSC%2F-Mi6hhWHFMI4FqO4dAUI%2F-Mi6pf2QwQV5EjjJmzWM%2Fimage.png?alt=media\&token=d3b660e9-b686-4c71-afc0-ac8016f8653a)

## Comandos

O GDB aceita abreviações dos comandos, onde ele identifica o comando a ser executado de acordo com suas primeiras letras ou abreviações definidas pelo depurador. Por exemplo o comando `breakpoint` pode ser executado também como `break`, `br` ou apenas `b`.

Ao apertar *enter* sem digitar nenhum comando o GDB irá reexecutar o último comando que você executou.

### quit

```
quit [EXPR]
```

Finaliza o GDB. A expressão opcional é avaliada e o resultado dela é usado como código de saída. Se a expressão não for passada o GDB sai com código `0`.

### file

```
file FILE
```

Usa o arquivo binário especificado como alvo para depuração. O programa é procurado no diretório atual ou em qualquer caminho registrado na variável de ambiente PATH.

### attach e detach

```
attach <process-id>
detach
```

O comando `attach` faz o [*attach*](https://mentebinaria.gitbook.io/assembly/depuracao-de-codigo/entendendo-os-depuradores) no processo de ID especificado. Já o comando `detach` desfaz o *attach* no processo que está atualmente conectado.

Você também pode iniciar a execução do GDB com a opção `-p` para ele já inicializar fazendo *attach* em um processo, como em:

```
$ gdb -p 12345
```

### breakpoint

```
break [PROBE_MODIFIER] [LOCATION] [thread THREADNUM] [if CONDITION]
```

Se o comando for executado sem qualquer argumento o *breakpoint* será adicionado na instrução atual.

LOCATION é a posição onde o *breakpoint* deve ser inserido e pode ser o número de uma linha, endereço ou posição explícita.

Ao especificar o número da linha, o nome do arquivo e o número da linha são separados por `:`. Se não especificar o nome do arquivo o *breakpoint* será adicionado a linha do arquivo atual. Exemplos:

```
(gdb) b 15
(gdb) b test.c:17
```

Onde o primeiro adicionaria o *breakpoint* na linha 15 do arquivo atual, e o segundo adicionaria na linha 17 do arquivo `test.c`.

O endereço pode ser simplesmente o nome de uma função ou então uma expressão, onde nesse caso é necessário usar `*` como prefixo ao símbolo ou endereço de memória. Como em:

```
(gdb) b main
(gdb) b *main + 8
(gdb) b *0x12345
```

No primeiro caso um *breakpoint* seria adicionado a função **main**. No segundo caso o endereço da primeira instrução da função **main** seria somado com 8, e o endereço resultante seria onde o *breakpoint* seria inserido. Já no terceiro caso o *breakpoint* seria inserido no endereço `0x12345`.

Também é possível especificar para qual *thread* o *breakpoint* deve ser inserido, onde por padrão o *breakpoint* é válido para todas as *threads*. Exemplo:

```
(gdb) b add thread 2
```

Isso adicionaria o *breakpoint* somente para a *thread* de ID 2.

{% hint style="info" %}
É possível usar o comando `info threads` para obter a lista de *threads* e seus números de identificação.
{% endhint %}

E por fim dá para adicionar uma condição de parada ao *breakpoint*. Onde CONDITION é [uma expressão](#expressoes) booleana. Exemplo:

```
(gdb) b 7 if a == 8
```

Onde no contexto do nosso código de exemplo, `a` seria o primeiro parâmetro da função **add**.

### clear

```
clear [LOCATION]
```

Remove um *breakpoint* no local especificado. LOCATION funciona da mesma forma que no comando `breakpoint`.

Caso LOCATION não seja especificado remove o *breakpoint* na posição atual.

### run

```
run [arg1, arg2, arg3...]
```

O comando `run` inicia (ou reinicia) a execução do programa alvo. Opcionalmente pode-se passar argumentos de linha de comando para o programa. Caso os argumentos não sejam especificados, os mesmos argumentos utilizados na última execução de `run` serão utilizados.

Nos argumentos é possível usar o caractere curinga `*`, ele será expandido pela shell do sistema. Também é possível usar os redirecionadores `<`, `>` ou `>>`.

### kill

Finaliza a execução do programa que está sendo depurado.

### start, starti

```
start [arg1, arg2, arg3...]
starti [arg1, arg2, arg3...]
```

O uso desses dois comandos é idêntico ao uso de `run`. Porém o comando `start` inicia a execução do programa parando no começo da função **main**. Já o `starti` inicia parando na primeira instrução do programa.

### next, nexti

```
next [N]
nexti [N]
```

O comando `next` (ou apenas `n`) executa uma linha de código. Se N for especificado ele executa N linhas de código. Já o comando `nexti` (ou apenas `ni`) executa uma ou N instruções Assembly.

Os dois comandos atuam como um [*step over*](https://mentebinaria.gitbook.io/assembly/entendendo-os-depuradores#execucao-passo-a-passo), ou seja, não entram em chamadas de procedimentos.

### step, stepi

```
step [N]
stepi [N]
```

O `step` (ou `s`) executa uma ou N linhas de código. Já o `stepi` (ou `si`) executa uma ou N instruções Assembly. Os dois comandos entram em chamadas de procedimentos.

### jump

```
jump LOCATION
```

Salta (modifica RIP) para o ponto do código especificado. Onde LOCATION é idêntico ao caso do comando *breakpoint* onde é possível especificar um número de linha ou endereço.

### advance

```
advance LOCATION
```

Esse comando continua a execução do programa até o ponto do código especificado, daí para a execução lá. Assim como na instrução `jump`, o comando `advance` (ou `adv`) recebe um LOCATION como argumento.

O comando `advance` também para quando a função atual retorna.

### finish

Executa até o retorno da função atual. Quando a função retorna é criada uma variável (como no caso do comando [print](#print)) com o valor de retorno da função.

### continue

Continua a execução normal do programa.

### record e reverse-\*

Imagine que mágico seria se o depurador pudesse voltar no tempo e desfazer as instruções executadas no programa, fazendo ele executar de maneira reversa parecido com rebobinar uma fita. Bom, o GDB pode fazer isso. :sunglasses:

Quando o programa já está em execução você pode executar o comando `record full` para iniciar a gravação das instruções executadas e `record stop` para parar de gravar.

Quando há a gravação é possível executar o programa em ordem reversa usando os comandos: `reverse-step` (`rs`), `reverse-stepi` (`rsi`), `reverse-next` (`rn`), `reverse-nexti` (`rni`) e `reverse-continue` (`rc`).

Esses comandos fazem a mesma coisa que os comandos normais, porém executando o programa ao reverso. Cada instrução revertida tem suas modificações na memória ou registradores desfeitas. Conforme demonstra a imagem abaixo.

![GDB usando execução reversa.](https://2466397120-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lif0YmrEB3G3dh1VxSC%2F-Mi9qBjz0FOrtktmE9JQ%2F-MiBq3wsJht9xSt7faTr%2Fimage.png?alt=media\&token=22dc7395-b803-46b3-9c60-8a7eb219be93)

Outros subcomandos de `record` são:

#### record goto

Salta para uma determinada instrução que foi gravada. Pode-se usar `record goto begin` para voltar ao início da gravação (desfazendo todas as instruções), `record goto end` para ir para o final da gravação ou `record goto N` onde N seria o número da instrução na gravação para saltar para ela.

#### record save \<filename>

Salva os logs de execução no arquivo.

#### record restore \<filename>

Restaura os logs de execução a partir do arquivo.

### thread

```
thread <thread-id>
thread apply <thread-id> <command>
thread find <regex>
thread name <thread-name>
```

O comando `thread` pode ser usado para trocar entre *threads* do processo. Você pode usar o comando `info threads` para listar as *threads* do processo e obter seus ID. Exemplo:

```
(gdb) thread 2
```

Isso trocaria para a *thread* de ID 2. Esse comando também tem os seguintes subcomandos:

#### thread apply

Executa um comando na *thread* especificada.

#### thread name

Define um nome para a *thread* atual, facilitando a identificação dela.

#### thread find

Recebe uma expressão regular como argumento que é usada para listar as *threads* cujo o nome coincida com a expressão regular. O comando exibe o ID das *threads* listadas.

### print

```
print[/FMT] [EXPR]
```

O comando `print` (ou `p`) exibe no terminal o resultado da expressão passada como argumento. Opcionalmente pode-se especificar o formato de saída, onde os formatos são os mesmos utilizados no [comando x](#x). Exemplo:

```
(gdb) p/x 15
$1 = 0xf
```

Repare que a cada execução do comando `print` ele define uma variável (`$1`, `$2` etc.) que armazena o resultado da expressão do comando. Você também pode usar o valor dessas variáveis em uma expressão e assim reaproveitar o resultado de uma execução anterior do comando. Os símbolos `$` e `$$` se referem aos valores da última e penúltima execução do comando, respectivamente. Exemplo:

```
(gdb) p x + $3
```

Existe também o operador binário `@` que pode ser usado para tratar o valor no endereço especificado como uma *array*. O formato do uso desse operador é `array@size`, passando à esquerda o primeiro elemento da *array*.

Onde o tipo de cada elemento da *array* é definido de acordo com o tipo do objeto que está sendo referenciado. Na imagem abaixo é demonstrado o uso desse operador para visualizar todo o conteúdo da *array* **argv**.

![Saída do GDB ao usar Artificial Array](https://2466397120-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lif0YmrEB3G3dh1VxSC%2F-MiByJ1nQKTiRtkvcF9J%2F-MiC4IKnX5NeH8PUZuhr%2Fimage.png?alt=media\&token=dafc8d1e-7870-4836-8306-abfe27c0a2fa)

### printf

```
printf "format string", ARG1, ARG2, ARG3, ..., ARG
```

Esse comando pode ser usado de maneira semelhante a função **printf** da libc. Cada argumento é separado por vírgula e o primeiro argumento é a *format string* que suporta quase todos os formatos suportados pela função **printf**. Os demais argumentos são [expressões](#expressoes).

Exemplo de uso:

```
(gdb) printf "%p\n", $rsp
0x7fffffffdf20
```

### dprintf

```
dprintf LOCATION, "format string", ARG1, ARG2, ARG3, ..., ARG
```

Esse comando insere um *breakpoint* no código onde, toda vez que ele é alcançado, o comando `printf` é executado e depois a execução continua. O uso desse comando é semelhante ao do comando `printf`. Exemplo:

```
(gdb) dprintf 7, "%d + %d\n", a, b
```

No nosso código de exemplo, isso inseria o *dynamic printf* na linha 7 que está dentro da função **add**. Conforme a imagem abaixo demonstra:

![Demonstração de uso do dprintf no GDB](https://2466397120-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lif0YmrEB3G3dh1VxSC%2F-MiCbL7r7S5ApFRjfcsq%2F-MiCmOV0JaTVhTH2oY1j%2Fimage.png?alt=media\&token=7944d72d-5475-4820-98c7-b1af4bef115e)

### x

```
x[/FMT] ADDRESS
```

O comando `x` serve para ver valores na memória. O argumento FMT (opcional) é o número de valores a serem exibidos, seguido de uma letra indicando o formato do valor seguido de uma letra que indica o tamanho do valor. Por padrão exibe apenas um valor caso o número não seja especificado. O formato e tamanho padrão é o mesmo utilizado na última execução do comando `x`.

As letras de formato são: `o` (octal), `x` (hexadecimal), `d` (decimal), `u` (decimal não-sinalizado), `t` (binário), `f` (*float*), `a` (endereço), `i` (instrução), `c` (caractere de 1 byte), `s` (*string*) e `z` (hexadecimal com zeros à esquerda).

Ao usar o formato `i` será feito o *disassembly* do código no endereço. O número de valores é usado para especificar o número de instruções para fazer o *disassembly*.

Exemplo:

```
(gdb) x/x 0x7fffffffdf64
0x7fffffffdf64:	0x003d2061
```

As letras de tamanho são: `b` (byte), `h` (metade de uma palavra), `w` (palavra) e `g` (*giant*, 8 bytes). Na arquitetura x86-64 uma palavra é 32-bit (4 bytes).

Exemplos:

```
(gdb) x/xb 0x7fffffffdf64
0x7fffffffdf64:	0x61
(gdb) x/4xb 0x7fffffffdf64
0x7fffffffdf64:	0x61	0x20	0x3d	0x00
```

### disassembly

```
disassembly[/MODIFIER] [ADDRESS]
disassembly[/MODIFIER] start,end
disassembly[/MODIFIER] start,+length
```

O comando `disassembly` (ou `disas`) pode ser usado para exibir o *disassembly* de uma função ou *range* de endereço. O argumento ADDRESS (opcional) é uma expressão, sem esse argumento ele faz o *disassembly* na posição ou função atual.

Também é possível especificar um *range* de endereços para exibir o *dissasembly* das instruções, separando o endereço inicial e final por vírgula. Se usar o `+` no segundo argumento separado por vírgula, ele é considerado como o tamanho em bytes do *range* iniciado em **start**.

Exemplos:

```
(gdb) disas 0x00005555555551b4,0x00005555555551b9
Dump of assembler code from 0x5555555551b4 to 0x5555555551b9:
   0x00005555555551b4 <main+51>:	mov    $0x3,%esi
End of assembler dump.
(gdb) disas 0x00005555555551b4,+5
Dump of assembler code from 0x5555555551b4 to 0x5555555551b9:
   0x00005555555551b4 <main+51>:	mov    $0x3,%esi
End of assembler dump.
```

O argumento MODIFIER é uma (ou mais) das seguintes letras:

* `s` - Exibe também as linhas de código correspondentes as instruções em Assembly.
* `r` - Também exibe o código de máquina em hexadecimal.

Exemplo:

```
(gdb) disas/rs 0x00005555555551b4,+5
Dump of assembler code from 0x5555555551b4 to 0x5555555551b9:
test.c:
15	  printf("%s %d\n", str, add(x, 3));
   0x00005555555551b4 <main+51>:	be 03 00 00 00	mov    $0x3,%esi
End of assembler dump.
```

{% hint style="info" %}
Por padrão o *disassembly* é feito em sintaxe AT\&T, mas você pode modificar para sintaxe Intel com o comando: `set disassembly-flavor intel`
{% endhint %}

### list

```
list
list LINENUM
list FILE:LINENUM
list FUNCTION
list FILE:FUNCTION
list *ADDRESS
```

Exibe a listagem de código na linha ou início da função especificada. Um endereço também pode ser especificado usando um `*` como prefixo, as linhas de código correspondentes ao endereço serão exibidas.

Caso `list` seja executado sem argumentos mais linhas são exibidas a partir da última linha exibida pela última execução de `list`.

O número de linhas exibido é por padrão 10, mas esse valor pode ser alterado com o comando `set listsize <number-of-lines>`.

### backtrace

```
backtrace [COUNT]
```

O comando `backtrace` (ou `bt`) exibe o *stack backtrace* atual. O argumento COUNT é o número máximo de *stack frames* que serão exibidos. Se for um número negativo exibe os primeiros *stack frames*.

Exemplo:

```
(gdb) bt
#0  add (a=8, b=3) at test.c:7
#1  0x00005555555551c0 in main (argc=1, argv=0x7fffffffe068) at test.c:15
```

### frame

```
frame [FRAME_NUMBER]
```

Sem argumentos exibe o *stack frame* selecionado. Caso seja especificado um número como argumento, seleciona e exibe o *stack frame* indicado pelo número. Esse número pode ser consultado com o comando `backtrace`.

Esse comando tem os seguintes subcomandos:

#### frame address

```
frame address STACK_ADDRESS
```

Exibe o *stack frame* no endereço especificado.

#### frame apply

```
frame apply COUNT COMMAND
frame apply all COMMAND
frame apply level FRAME_NUMBER COMMAND
```

O comando `frame apply` executa o mesmo comando em um ou mais *stack frames*. Esse subcomando é útil, por exemplo, para ver o valor das variáveis locais que estão em uma função de outro *stack frame* além do atual.

COUNT é o número de *frames* onde o comando será executado. Por exemplo `frame apply 2 p x` executaria o comando `print` nos últimos 2 *frames* (o atual e o anterior).

&#x20;O `frame apply all` executa o comando em todos os *frames*. Já o `frame apply level` executa o comando em um *frame* específico. exemplo:

```
(gdb) frame apply level 1 info locals
#1  0x00005555555551c0 in main (argc=1, argv=0x7fffffffe068) at test.c:15
str = "a ="
x = 8
```

#### frame function

```
frame function FUNCTION_NAME
```

Exibe o *stack frame* da função especificada.

#### frame level

```
frame level FRAME_NUMBER
```

Exibe o *stack frame* do número especificado.

### info

O comando `info` contém diversos subcomandos para exibir informações sobre o programa que está sendo depurado. Abaixo será listado apenas os subcomandos principais.

#### info registers

Exibe os valores dos registradores. Pode-se passar como argumento uma lista (separada por espaço) dos registradores para exibir. Sem argumentos exibe o valor de todos os [registradores de propósito geral](https://mentebinaria.gitbook.io/assembly/a-base/registradores-de-proposito-geral), [registradores de segmento](https://mentebinaria.gitbook.io/assembly/aprofundando-em-assembly/registradores-de-segmento) e [EFLAGS](https://mentebinaria.gitbook.io/assembly/aprofundando-em-assembly/flags-do-processador). Exemplo:

```
(gdb) info reg rax rbx
```

#### info frame

O uso desse subcomando é semelhante ao uso do comando [frame](#frame) e contém os mesmos subcomandos. A diferença é que ele exibe todas as informações relacionadas ao *stack frame*. Enquanto o comando `frame` apenas exibe informações de um ponto de vista de alto-nível.

#### info args

```
info args [NAMEREGEXP]
```

Exibe os argumentos passados para a função do *stack frame* atual. Se NAMEREGEXP for especificado exibe apenas os argumentos cujo o nome coincida com a expressão regular.

#### info locals

```
info locals [NAMEREGEXP]
```

Uso idêntico ao de `info args` só que exibe o valor das variáveis locais.

#### info functions

```
info functions [NAMEREGEXP]
```

Exibe todas as funções cujo o nome coincida com a expressão regular. Se o argumento não for especificado lista todas as funções.

#### info breakpoints

Exibe os *breakpoints* definidos no programa.

#### info source

Exibe informações sobre o código-fonte atual.

#### info threads

Lista as *threads* do processo.

### display e undisplay

```
display[/FMT] EXPRESSION
undisplay [NUM]
```

Esse comando pode ser usado da mesma maneira que o comando [print](#print). Ele registra uma expressão para ser exibida a cada vez que a execução do processo faz uma parada. Exemplo:

```
(gdb) display/7i $rip
```

Isso exibiria o *disassembly* de 7 instruções a partir de RIP a cada passo executado.

Se `display` for executado sem argumentos ele exibe todas as expressões registradas para auto-display.

Enquanto o comando `undisplay` remove a expressão com o número especificado. Sem argumentos remove todas as expressões registradas por `display`.

### source

```
source FILE
```

Carrega o arquivo especificado e executa os comandos no arquivo como um script.

{% hint style="info" %}
Quando o GDB inicia ele faz o *source* automático do script de nome `.gdbinit` presente na sua pasta *home*. Exceto se o GDB for iniciado com a *flag* `--nh`.
{% endhint %}

### help

O comando `help`, sem argumentos, lista as classes de comandos. É possível rodar `help CLASS` para obter a lista de comandos daquela classe.

Também é possível rodar `help COMMAND` para obter ajuda para um comando específico, pode-se inclusive usar abreviações. E também é possível obter ajuda para subcomandos, conforme exemplos:

```
(gdb) help ni
(gdb) help info reg
(gdb) help frame apply level
```

## Text User Interface (TUI)

É possível usar o GDB com uma interface textual permitindo que seja mais agradável acompanhar a execução enquanto observa o código-fonte. Para isso basta iniciar o GDB com a *flag* `-tui`, como em:

```shell-session
$ gdb -tui ./test
```

![GDB Text User Interface](https://2466397120-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lif0YmrEB3G3dh1VxSC%2F-MiCxAu88EhID1bcbDWV%2F-MiD0Mys6LNQzvAibEnc%2Fimage.png?alt=media\&token=2687ca77-8116-4476-afd1-42981472e763)

### Atalhos de teclado

| Atalho de teclado | Descrição                                                                                                                                                                                                                                 |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ctrl+x a          | O atalho `Ctrl+x a` (Ctrl+x seguido da tecla `a`) alterna para o modo TUI caso tenha iniciado o GDB normalmente.                                                                                                                          |
| Ctrl+x 1          | Alterna para o *layout* de janela única.                                                                                                                                                                                                  |
| Ctrl+x 2          | Alterna para o *layout* de janela dupla. Quando já está no *layout* de janela dupla o próximo *layout* com duas janelas é selecionado. Onde é possível exibir código-fonte+Assembly, registradores+Assembly e registradores+código-fonte. |
| Ctrl+x o          | Muda a janela ativa.                                                                                                                                                                                                                      |
| Ctrl+x s          | Muda para o modo [Single Key Mode](#single-key-mode).                                                                                                                                                                                     |
| PgUp              | Rola a janela ativa uma página para cima.                                                                                                                                                                                                 |
| PgDn              | Rola a janela ativa uma página para baixo.                                                                                                                                                                                                |
| ↑ (Up)            | Rola a janela ativa uma linha para cima.                                                                                                                                                                                                  |
| ↓ (Down)          | Rola a janela ativa uma linha para baixo.                                                                                                                                                                                                 |
| ← (Left)          | Rola a janela ativa uma coluna para a esquerda.                                                                                                                                                                                           |
| → (Right)         | Rola a janela ativa uma coluna para a direita.                                                                                                                                                                                            |
| Ctrl+L            | Redesenha a tela.                                                                                                                                                                                                                         |

### Single Key Mode

Quando se está no modo ***Single Key*** é possível executar alguns comandos pressionando uma única tecla,  conforme tabela abaixo:

<table data-header-hidden><thead><tr><th width="150">Tecla</th><th>Comando</th><th>Nota</th></tr></thead><tbody><tr><td>Tecla</td><td>Comando</td><td>Nota</td></tr><tr><td>c</td><td>continue</td><td></td></tr><tr><td>d</td><td>down</td><td></td></tr><tr><td>f</td><td>finish</td><td></td></tr><tr><td>n</td><td>next</td><td></td></tr><tr><td>o</td><td>nexti</td><td>"o" de <em>step <strong>o</strong>ver</em>.</td></tr><tr><td>q</td><td>-</td><td>Sai do modo <em>Single Key</em>.</td></tr><tr><td>r</td><td>run</td><td></td></tr><tr><td>s</td><td>step</td><td></td></tr><tr><td>i</td><td>stepi</td><td></td></tr><tr><td>u</td><td>up</td><td></td></tr><tr><td>v</td><td>info locals</td><td>"v" de <em><strong>v</strong>ariables</em>.</td></tr><tr><td>w</td><td>where</td><td>Alias para o comando <code>backtrace</code>.</td></tr></tbody></table>

Qualquer outra tecla alterna temporariamente para o modo de comandos. Após um comando ser executado ele retorna para o modo *Single Key*.
