Como faço para mapear um endereço de ponteiro de instrução segfault de/var/log/mensagens para um endereço/função no meu arquivo .map?

StackOverflow https://stackoverflow.com/questions/1408788

  •  05-07-2019
  •  | 
  •  

Pergunta

(Meu ambiente é Ubuntu de 64 bits, meu aplicativo é compilado C ++ e vinculado ao G ++.)

Quando um aplicativo faz algo como dividir por zero ou executar um asm("int $3") Deixado no código, um dos seguintes é registrado via syslog para /var/log/kern.log e /var/log/messages:

Sep 10 18:06:47 VM kernel: [117194.123452] a.out[20288] trap divide error ip:45c59d sp:7fff65a91810 error:0 in a.out[400000+144000]
Sep 10 18:07:10 VM kernel: [117217.020833] a.out[20294] trap int3 ip:45c493 sp:7fff5cc559f0 error:0

Em ambos os casos, o endereço do ponteiro de instrução aponta para algo que eu posso olhar facilmente no .map arquivo produzido no horário do link (usando o "-Wl,-Map,output.map").

Mas se eu causar uma falha de SEG, neste caso por uma chamada para memcpy() Com a fonte definida como NULL, o ponteiro de instrução está tão fora de alcance, não tenho idéia de como ele deve ser mapeado:

Sep 10 18:06:13 VM kernel: [117160.228587] a.out[20282]: segfault at 0 ip 00007f7e79209092 sp 00007fff831faf08 error 4 in libc-2.9.so[7f7e79185000+168000]

Neste exemplo, eu esperaria que o IP estivesse na faixa de 0x445e70-0x445e7f, que é o local de memcpy () de acordo com o meu arquivo .map.

Minha pergunta: qual é o truque para interpretar o IP neste caso?

Foi útil?

Solução

De acordo com a mensagem, parece que travou dentro memcpy(), a partir de libc-2.9.so, que é mapeado para o seu processo a partir de 0x7F7E79185000. Isso é esperado desde memcpy é a função que está tentando desreferenciar o ponteiro. O ponteiro de instrução parece válido, pois está dentro do intervalo da LIBC. Se você pretendia substituir o memcpy e ligar para sua própria versão, pode ser necessário compilar com -fno-builtin-memcpy.

Editar: Você pode estar vinculando a libc estaticamente, mas de acordo com a mensagem, você também tem a biblioteca compartilhada da LIBC mapeada para a memória do processo. Você deve vê -lo listado em /proc/pid/maps Enquanto seu programa está em execução. Pode ser que você esteja vinculando outra biblioteca compartilhada, como LibSTDC ++, e depende da biblioteca compartilhada da LIBC. Como resultado, você tem duas versões de memcpy e, nesse caso, está chamando a versão da biblioteca compartilhada da LIBC, que é mapeada no endereço alto. Se você não deseja a biblioteca compartilhada da LibC, verifique se está vinculando tudo bibliotecas estaticamente; use o -static opção no início da sua linha de link.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top