문제

최신 Xcode 및 GCC를 가정하면 메모리 할당 함수를 무시하는 올바른 방법은 무엇입니까 (Operator New/Delete도 추측). 디버깅 메모리 할당자는 게임에 비해 너무 느립니다. 최소한의 영향으로 직접 할 수있는 몇 가지 기본 통계가 필요합니다.

나는 고리로 인해 Linux에서 쉽게 알고 있으며, 이것은 Heapmanager를 썼을 때 10 년 전 Codewarrior에서 사소한 일이었습니다.

슬프게도 Smartheap에는 더 이상 Mac 버전이 없습니다.

올바른 솔루션이 없습니다

다른 팁

실행 프로그램의 수정이 필요하지 않기 때문에이 작업을 위해 라이브러리 사전 로딩을 사용합니다. 이 작업을 수행하는 일반적인 UNIX 방법에 익숙하다면 LD_PRELOAD를 DYLD_INSERT_LIBRARIES로 대체하는 문제입니다.

첫 번째 단계는 이와 같은 코드로 라이브러리를 작성한 다음 일반 공유 라이브러리 링크 옵션을 사용하여 구축하는 것입니다.gcc -dynamiclib):

void *malloc(size_t size)
{
    void * (*real_malloc)(size_t);
    real_malloc = dlsym(RTLD_NEXT, "malloc");

    fprintf(stderr, "allocating %lu bytes\n", (unsigned long)size);
    /* Do your stuff here */

    return real_malloc(size);
}

당신이 또한 분할하는 경우에 유의하십시오 calloc() 그리고 구현 호출 malloc(), 귀하가 호출되는지 확인하려면 추가 코드가 필요할 수 있습니다. C ++ 프로그램은 매우 안전해야합니다 new 운영자 호출 malloc() 어쨌든, 그러나 표준이 그것을 시행하지 않는다는 점에 유의하십시오. 사용하지 않은 구현을 한 적이 없습니다 malloc(), 그렇지만.

마지막으로 프로그램의 실행중인 환경을 설정하고 시작합니다 (쉘이 환경 변수를 처리하는 방법에 따라 조정이 필요할 수 있습니다).

export DYLD_INSERT_LIBRARIES=./yourlibrary.dylib
export DYLD_FORCE_FLAT_NAMESPACE=1
yourprogram --yourargs

보다 딜드 매뉴얼 페이지 동적 링커 환경 변수에 대한 자세한 내용.

이 방법은 매우 일반적입니다. 그러나 한계가 있습니다.

  • 직접 시스템 호출을 전환 할 수 없습니다
  • 응용 프로그램 자체가 사용하여 속임수를 찍는 경우 dlsym() 로드하려면 malloc주소의 주소는 호출이 전환되지 않습니다. 그러나, 당신은 또한 도발하여 그것을 다시 속이지 않는 한 dlsym!

그만큼 malloc_default_zone 언급 된 기술 http://lists.apple.com/archives/darwin-dev/2005/apr/msg000.html 여전히 작동하는 것으로 보입니다. 예를 들어보십시오 http://code.google.com/p/fileview/source/browse/trunk/fileview/fv_zone.cpp?spec=svn354&r=354 예를 들어, 당신이 의도 한 것과 비슷한 것으로 보입니다.

많은 검색 (여기 포함)과 10.7의 문제 후이 주제에 대한 블로그 게시물을 작성하기로 결정했습니다. OSX Lion에서 Malloc 후크를 설정하는 방법

이 주제에 대한 자세한 정보가 포함 된 게시물 끝에 몇 가지 좋은 링크가 있습니다.

기본 해결책 :

malloc_zone_t *dz=malloc_default_zone();
if(dz->version>=8)
{
    vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ | VM_PROT_WRITE);//remove the write protection
}
original_free=dz->free;
dz->free=&my_free; //this line is throwing a bad ptr exception without calling vm_protect first
if(dz->version==8)
{
    vm_protect(mach_task_self(), (uintptr_t)malloc_zones, protect_size, 0, VM_PROT_READ);//put the write protection back
}

이것은 오래된 질문이지만, 나는 이것을 직접하려고 노력하는 동안 그것을 발견했습니다. 나는 내가 작업하고있는 개인 프로젝트에 대해이 주제에 대해 궁금했습니다. 나는 할당 된 힙의 양을 추적하고 내가 선택한 경우보고 할 수 있도록 C ++ 구현을 작성하게되었습니다.

https://gist.github.com/monitorjbl/3dc6d62cf5514892d5b22a59ff34861

이름에서 지적한 것처럼 이것은 OSX- 특이 적입니다. 그러나 나는 Linux 환경에서 malloc_usable_size

예시

#define MALLOC_DEBUG_OUTPUT
#include "malloc_override_osx.hpp"

int main(){
   int* ip = (int*)malloc(sizeof(int));
   double* dp = (double*)malloc(sizeof(double));

   free(ip);
   free(dp);
}

건물

$ clang++ -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk \
          -pipe -stdlib=libc++ -std=gnu++11 -g -o test test.cpp
$ ./test
0x7fa28a403230 -> malloc(16) -> 16
0x7fa28a403240 -> malloc(16) -> 32
0x7fa28a403230 -> free(16) -> 16
0x7fa28a403240 -> free(16) -> 0

이것이 미래에 다른 사람을 도울 수 있기를 바랍니다!

필요한 기본 통계를 간단한 래퍼로 수집 할 수 있다면 빠른 (그리고 더러운) 트릭은 일부를 사용하는 것입니다. #define 매크로 교체.

void* _mymalloc(size_t size)
{
    void* ptr = malloc(size);

    /* do your stat work? */

    return ptr;
}

그리고

#define malloc(sz_) _mymalloc(sz_)

메모: 매크로가 정의 된 경우 ~ 전에 _mymalloc 정의는 해당 기능 내부의 malloc 호출을 대체하여 무한 재귀로 당신을 남겨 둡니다 ... 그렇지 않은지 확인하십시오. 명시 적으로 원할 수도 있습니다 #undef 그 기능 정의 전에이 상황을 피하기 위해 희망적으로 피하기 위해 그것을 포함하여 어디에 있는지에 따라 나중에 정의합니다.

프로젝트에 포함 된 자신의 .C 파일에서 malloc () 및 free ()를 정의하면 링커가 해당 버전을 해결할 것이라고 생각합니다.

그렇다면 Malloc을 어떻게 구현하려고합니까?

Hoard Memory Allocator 's의 저자 인 Emery Berger's를 확인하십시오. https://github.com/emeryberger/heap-layers/blob/master/wrappers/macwrapper.cpp (그리고 포함 내용에 따라 자신을 추적 할 수있는 다른 파일 몇 개).

이것은 Alex의 답변에 보완 적이지만,이 예는 제공된 시스템을 대체 할 수있는 시스템을 교체하는 것의 자세한 내용이라고 생각했습니다.

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