2009-09-11 4 views
2

(내 환경, 내 응용 프로그램은 C++ ++ 컴파일 g와 연결. 64 비트 우분투입니다)어떻게하면/var/log/messages의 segfault 명령어 포인터 주소를 .map 파일의 주소/함수에 매핑 할 수 있습니까?

때 응용 프로그램은 0으로 나누기와 같은 무언가를하거나 asm("int $3") 다음 중 하나가 기록됩니다 코드에 남아 실행할 /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"을 사용).

내가 NULL로 설정 소스와 memcpy() 호출에 의해이 경우에는 독방 감금 오류를 일으킬 경우에, 명령 포인터가 범위를 벗어 그래서, 나는 매핑하도록되어 아무 생각이 어떻게 :

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가 내 .map 파일에 따라 memcpy()의 위치 인 0x445e70-0x445e7f 범위에 있어야합니다.

내 질문 :이 경우 ip를 해석하는 트릭이란 무엇입니까?

답변

3

0x7f7e79185000에서 시작하는 프로세스에 매핑 된 libc-2.9.so에서 memcpy() 안에 오류가있는 것으로 보입니다. 이것은 memcpy이 포인터 역 참조를 시도하는 함수이므로 예상됩니다. 명령 포인터는 libc 범위 내에 있으므로 유효하게 보입니다. memcpy를 오버라이드하고 자신의 버전을 호출하려는 경우 -fno-builtin-memcpy으로 컴파일해야 할 수도 있습니다.

편집 : libc를 정적으로 연결할 수도 있지만 메시지에 따라 프로세스 메모리에 매핑 된 libc 공유 라이브러리가 있습니다. 프로그램이 실행되는 동안 /proc/pid/maps에 나열된 것을 볼 수 있습니다. libstdC++와 같은 다른 공유 라이브러리와 연결하고 있으며 libc 공유 라이브러리에 종속되어있을 수 있습니다. 결과적으로 두 가지 버전의 memcpy가 있으며이 경우 상위 주소에 매핑 된 libc 공유 라이브러리 버전이 호출됩니다. libc 공유 라이브러리를 원하지 않으면 모두 라이브러리를 정적으로 연결해야합니다. 링크 선의 시작 부분에 -static 옵션을 사용하십시오.

+0

그러나 링커에 의해 생성 된 .MAP 파일에 따라, 함수 방어 적이기는() 0x445e70에 위치 - 여기 참조 : 0x0000000000445e70 방어 적이기 @@ GLIBC_2.2.5 그래서 왜 IP가 될 것 0x7f7e79209092? –

+0

memcpy는 libc 공유 라이브러리의 일부이므로 코드의 일부로 없어야합니다. 아마도 libc를 정적으로 연결하고 있습니까? – mark4o

+0

예, 애플리케이션이 정적으로 링크되어 있습니다. –

관련 문제