/var/log/메시지에서 .map 파일의 주소/함수로 Segfault 명령어 포인터 주소를 매핑하려면 어떻게해야합니까?

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

  •  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 링크 라인의 시작 부분에서 옵션.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top