/var/log/메시지에서 .map 파일의 주소/함수로 Segfault 명령어 포인터 주소를 매핑하려면 어떻게해야합니까?
-
05-07-2019 - |
문제
(내 환경은 64 비트 Ubuntu이고, 내 응용 프로그램은 C ++ 컴파일되어 G ++와 연결되어 있습니다.)
응용 프로그램이 0으로 나누거나 실행하는 것과 같은 것을 수행하는 경우 asm("int $3")
코드에 남겨두면 다음 중 하나가 Syslog를 통해 로그인됩니다. /var/log/kern.log
그리고 /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
이 두 경우 모두 지침 포인터 주소는 내가 쉽게 찾을 수있는 것을 가리 킵니다. .map
링크 시간에 생성 된 파일 (사용 사용-Wl,-Map,output.map
").
그러나 내가 SEG 결함을 일으키면이 경우 전화로 memcpy()
소스가 Null로 설정되면 명령 포인터가 범위를 벗어 났기 때문에 어떻게 매핑되어야하는지 전혀 모른다.
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]
이 예에서는 IP가 0x445e70-0x445e7f 범위에있을 것으로 예상했을 것입니다.
내 질문 :이 경우 IP를 해석하는 요령은 무엇입니까?
해결책
메시지에 따르면 내부에서 추락 한 것 같습니다. memcpy()
, 에서 libc-2.9.so
, 이것은 0x7F7E79185000에서 시작하여 프로세스에 매핑됩니다. 이것은 이후로 예상됩니다 memcpy
포인터를 해석하려는 함수입니다. 명령어 포인터는 LIBC 범위 내에 있으므로 유효합니다. Memcpy를 무시하고 자신의 버전을 호출하려는 경우 컴파일해야 할 수도 있습니다. -fno-builtin-memcpy
.
편집하다: LIBC를 정적으로 연결하고 있지만 메시지에 따라 LIBC 공유 라이브러리가 프로세스 메모리에 매핑되어 있습니다. 당신은 그것을 나열된 것을 볼 수 있어야합니다 /proc/
PID/maps
프로그램이 실행되는 동안. libstdc ++와 같은 다른 공유 라이브러리와 연결하고 있으며 LIBC 공유 라이브러리에 따라 다를 수 있습니다. 결과적으로 두 가지 버전의 Memcpy가 있으며이 경우 높은 주소에 매핑되는 LIBC 공유 라이브러리 버전을 호출합니다. LIBC 공유 라이브러리를 원하지 않으면 연결 중인지 확인하십시오. 모두 정적으로 라이브러리; 사용 -static
링크 라인의 시작 부분에서 옵션.