1

sbrk를 사용하여 비교적 기본적인 메모리 할당자를 작성했습니다. 나는 메모리 덩어리를 요구하고, 65k라고 말하고 동적 메모리를 요구하는 변수에 대해 필요에 따라 그것을 조각 낸다. 65k 블록에 메모리를 다시 추가하여 메모리를 확보합니다. 65k 블록은 sizeof (16 바이트) 유니온에서 파생됩니다. 그런 다음 블록을 16 바이트 경계까지 정렬합니다. 그러나 나는 비정상적인 행동을하고있다.메모리 (sbrk) 포인터 접근시 16 바이트 정렬 쉬프트

메모리에 액세스하면 데이터 구조를 할당하고 채우기 시작합니다. 내 함수 호출 중 하나에서 전역 구조의 멤버 변수에 포인터를 전달하지만 포인터 인수의 주소는 그렇지 않습니다. 해당 회원의 주소로 직접 매핑하십시오.

예를 들어,이 특정 구성원의 실제 주소는 다음과 같습니다. 0x100313d50 그러나 특정 기능 (특별한 것은 없음)을 실행할 때 구성원의 주소는 0x100313d70으로 표시됩니다. 디버거 내부에서 실제 주소를 쿼리 할 수 ​​있으며이 주소가있는 곳에서 함수가 올바르게 표시됩니다. 이것은 첫 번째 멤버도 액세스되는 것이 아니며 두 번째 이전 메모리 액세스도 괜찮습니다.하지만 세 번째 액세스 중에이 비정상적인 전환이 발생합니다.

정렬되지 않은 블록을 통해이 메모리에 액세스 할 수 있습니까? 그것은 가능하지만 나는 SIGBUS 예외 (SPARC 칩)를 던지기를 기대합니다. -memalign = 16s를 사용하여 컴파일 중이므로 오정렬을 트래핑하고 수정하는 대신 SIGBUS를 사용해야합니다.

내 모든 구조는 16 바이트의 배수로 채워집니다. sizeof (구조체) % 16 = 0.이 유형의 동작에 경험이있는 사람이 있습니까? 일반적으로 말하자면, 어떤 종류의 물건/물건/등. 포인터가 메모리 주소를 왜곡 할 수 있습니까?

건배, 트레이시.

현대적인 SPARC 프로세서의 Solaris 10, SunStudio-12, C 언어 (도움이 될 경우).

+0

방금 ​​sbrk 대신 malloc을 사용하여 시도했지만 동작은 동일합니다. –

+0

글쎄, 내 메모리 할당 자와 관련이없는 것처럼 보입니다. 나는 모든 동적 메모리 요청을 평범한 구형 malloc으로 바꾸고 동일한 구조 (다른 메모리 위치)로 동일하지만 동일한 구조체 멤버에서 동일한 홀수 포인터 오프셋을 사용했다. –

답변

3

다른 누군가가 비슷한 문제가있는 경우 내 자신의 질문에 대답해야합니다.

메모리 주소가 이동하는 이유는 유틸리티 함수에 대한 이전 호출이 실수로 전역 구조의 메타 주소를 덮어 썼기 때문에 해당 블록의 메타 주소가 다시 쓰여졌 기 때문에 해당 블록의 조회가 실제 데이터는 여전히 원래 블록에있었습니다.

간단히 말해서, 나는 내 버퍼를 썼다. 내가 꼬리에서 추억을 나눠주기 때문에 덮어 쓰기는 내 세계적인 구조 (또는 무엇이든)를 위해 많이 필요로하는 메타 주소를 날려 버릴 것이다. 이제 정의되지 않은 동작이 어떤 모양인지 알 수 있습니다.

+0

정확히 말하면 정의되지 않은 동작의 예가 무엇인지 알 것입니다. 여전히 백만 명이 될 수 있습니다.) 마지막 문장은 – Mikeage

+1

+1입니다. @ Mikeage : 나는 OP가 "정의되지 않은 행동이 어떻게 생겼는지"를 의미한다고 생각합니다. 예기치 않게 어려운 프로그램 동작을 추적하려고했던 전체 경험이었습니다. –