Estou depurando uma falha de segmentação em um programa em C++, mas primeiro estou tentando entender melhor como usar o comando gdb
para inspecionar o layout da memória no arquivo principal, produzido quando o processo sofre uma falha de segmentação. Estou usando o seguinte programa de brinquedo, que sofre uma falha de segmentação intencional, para entender gdb
melhor a saída do .
int main() {
int a = 4;
int b = 12;
*(int *)0 =11;
return a + b;
}
Quando abro o arquivo principal (usando gdb my_executable path/to/core.pid
), posso ver os endereços de memória que contêm os valores de a
e b
, o que faz sentido, já que sizeof(int) == 4
:
(gdb) p &a
$5 = (int *) 0x7ffff940e078
(gdb) p &b
$6 = (int *) 0x7ffff940e07c
E quando pergunto pelo conteúdo da memória começando por &a
isso, até que faz sentido, exceto que estou em uma máquina Intel, que deveria ser little endian, e parece que esses inteiros são big endian:
(gdb) x/4x &a
0x7ffff940e078: 0x00000004 0x0000000c 0xf940e120 0x00007fff
# (added by me) ---a==4--- --b==12--- other stuff ->
Então, se eu perguntar o conteúdo da memória começando no próximo endereço, eu esperaria o seguinte (todos os bytes se deslocam um para a esquerda):
(gdb) x/4x 0x7ffff940e079
0x7ffff940e079: 0x00000400 0x00000cf9 0x40e12000 0x007fff..
Mas o que gdb
realmente imprime é isto:
(gdb) x/4x 0x7ffff940e079
0x7ffff940e079: 0x0c000000 0x20000000 0xfff940e1 0xca00007f
# --b==12?-- other stuff ->
Parece que avançamos 7 bytes, ou 4 bytes, e agora b
é little endian. Mas a memória depois desse primeiro 0x0c
byte é diferente do que era no último comando (antes era, 0xf940e...
agora é 0x2000...
). Será que estou lendo a memória acidentalmente com alinhamento diferente? E alguém sabe por que os valores parecem ser big endian?
Estou compilando o código com g++
a versão 13.3.0 no Ubuntu 24.04, caso isso ajude.