2013-06-03 2 views
1

최근에 정기적으로 segfaulting하는 응용 프로그램을 디버깅했습니다. 이는 비교적 평범한 (null 포인터에서 읽음) 문제를 해결했지만 몇 가지 잔여 질문이 있습니다. 혼자 힘으로 해결할 수 없었습니다.GDB 및 Segfault 메시지 이해

gdb를 스택 추적은 대부분의 경우 다음과 같이 시작 : 나는 것을 볼 수있는 공유 라이브러리의 기본 주소를 달성하기 위해/proc 디렉토리/[나의 시저의 ID]에서 /지도 정보를 사용하여

0x00007fdff330059f in __strlen_sse42() from /lib64/libc.so.6 

공유 라이브러리의 동일한 명령어에서 발생한 문제 - 명령어 0x13259f에서 발생했습니다. 즉

pcmpeqb (%rdi),%xmm1 (gdb) 

지금까지는 그렇게 좋았습니다. 그러나 OS (Linux)는/var/logs/messags에 다음과 같은 오류 메시지를 씁니다.

[3540502.783205] node[24638]: segfault at 0 ip 00007f8abbe6459f sp 00007fff7bf2f148 error 4 in libc-2.12.so[7f8abbd32000+189000] 

나를 혼란스럽게합니다. 한편으로는 커널이 오류 (사용자 모드 보호 오류)를 올바르게 식별하고 명령 포인터에서 공유 라이브러리의 기본 주소를 빼서 같은 상대 오프셋 (0x13259f)에 도착합니다. do gdb. 그러나 커널이 식별하는 라이브러리는 다르며 명령어의 주소가 다르며 해당 라이브러리 내의 함수와 명령어가 다릅니다. 그건 내 질문에 gdb를 할 수있는 방법이며, libc-2-12.so 내 명령이 그래서

0x13259f <__memset_sse2+911>: movdqa %xmm0,-0x43(%edx) 

이다,하고 커널 메시지는 오류의 유형에 동의에에 지시 상대의 오프셋 (offset) 공유 라이브러리의 기본 주소이지만 사용중인 명령어 포인터와 공유 라이브러리의 주소가 일치하지 않습니까?

+0

공유 라이브러리의 진입 점에 대한 프로세스 개인 주소가 그대로 있다는 사실을 알 수 있습니다. 프로세스의 로컬. 라이브러리의 텍스트 세그먼트가 실제로있는 커널에서 "변환"되었습니다. 귀하의 프로세스가 요구하는 것과 일치합니다. "변형되지 않은"버전은 커널 상주입니다. 그래서, 그들은 모두 정확합니다. 그것에 대해 생각 해봐. 모든 프로세스는 0x00000 주소를 가질 수 없습니다. 각 프로세스의 기본 주소는 실제 메모리의 다른 위치에 물리적으로 위치합니다. 프로세스가 생각하는 곳이 아닙니다. –

+0

이것은 의미가 있지만 커널이 /lib/libc-2.12에서 오류가 발생했다고 설명하는 이유에 대해서는 설명하지 않습니다.그래서 gdb는 /lib64/libc.so.6에 오류를 넣었습니다. 64 비트 시스템을 실행 중이므로 아마도이 라이브러리가 동일할까요? –

+0

하나는 심볼 링크이고 다른 하나는 코드가 링크 된 실제 라이브러리 파일입니다. 컴파일 된 파일에 대한 ldd 명령의 출력을보십시오. ldd myexecutable –

답변

1

그러나 커널이 식별 라이브러리는 다른,

아니, 그렇지 않습니다. ls -l /lib64/libc.so.6을 입력하면 libc-2.12.so에 대한 심볼릭 링크임을 알 수 있습니다.

명령어의 주소는 커널 메시지는 GDB에서 관찰 한 것과 다른 실행을위한

다르고, address randomizationlibc-2.12.so는 다른 기본 주소에로드되는 원인.

이며 해당 라이브러리 내의 기능 및 명령어가 다릅니다. 즉 libc-2-12.so 내 명령은 0x13259f <__memset_sse2+911>: movdqa %xmm0,-0x43(%edx)

당신이 실제로 사용되는 것과 다른 libc-2.12.so에서 본 것입니다이다.