태그 : module

memory를 가장 많이 사용하는 module 알아내기


(C관련 재미없는 내용입니다)

memory가 부족하다는 메시지가 나옵니다.
RAM을 말하는 거죠. Dynamic Memory allocation입니다.
Program상에서 memory를 많이 사용하는 것인데, 가장 많이 사용하는 부분을 찾아내서 
개선하는 것이 가장 효율적일 것 같다는 생각이 듭니다. 근데, 그 부분을 어떻게 알아내나요?

일단 Application에서 사용하는 '전체 memory의 크기'를 알아내기는 쉽습니다.
ps, top, 작업관리자를 사용하면 알 수 있죠.
근데, main내에서 어떤 코드가 memory를 얼마만큼 사용하고 있는지를 아는 것은
그리 간단한 일이 아니더군요.

관련 Tool을 찾아보았는데, 아직 찾지를 못했습니다.
누군가 알고 계시면, 부탁 드리고요.


제가 사용하는 방법이 도움이 될까 하고 적어봅니다.
저희 팀은 module 단위로 개발을 합니다.
하나의 소프트웨어는 수십, 수백 개의 module을 합쳐서 만들죠. Library라고 불러도 됩니다.
대부분 내부 Source이지만, 외부 Library도 사용합니다.
알고 싶은 것은 memory를 많이 사용하는 module을 순서대로 찾아내는 겁니다.

원리는 간단합니다.
Runtime상에 malloc과 free가 호출될 때마다 address와 size를 모두 기억해놓고,
특정 시점에서 해당 module에서 사용하는 malloc의 size를 합치면 됩니다.
그리고 Sorting해서 보여주기만 하면 되는 거죠.



[ malloc과 free를 intercept 하기 ]
malloc은 standard library 내부에 구현되어 있습니다.
Library는 malloc을 reference 하도록 되어 있죠.
이 중간에 code를 집어넣으려고 하는 겁니다.
Standard library를 수정하던가, Library의 reference를 수정하던가.
후자가 더 쉽습니다. Library를 하나 복사해서 malloc의 reference를 Malloc으로 바꾸어 줍니다.
ELF format을 공부하시면 됩니다. 그리 복잡하지 않습니다.
혹은 단순하게 malloc string을 찾아서 변경해도 정밀하지는 않지만 대부분 동작할 겁니다.

그리고 Malloc 코드를 작성하여 link시에 합쳐줍니다.
그러면 해당 module에서 malloc을 호출할 때마다 우리가 작성한 Malloc()이 불리게 됩니다.

같은 방법으로 free, realloc, strdup등등 필요한 것을 추가해줍니다.



[ malloc을 누가 호출했는지 ]
우리가 관심 있는 건 malloc을 사용하는 module의 이름이죠.
이것을 알아내는 것도 간단합니다.
Compiler의 도움을 받으면 되는데, 아래를 사용하면 됩니다. (gcc 경우)
__builtin_return_address(0)
__builtin_return_address(1)
__builtin_return_address(2)

이런 식으로 부르면 call stack을 쉽게 얻을 수 있습니다.



[ source code 알아내기 ]
근데, call stack에서 얻은 것은 address이죠.
Module을 알려면 file 정보가 있어야 합니다.

debug option을 켜놓으면 실행 file 내부에 debug 정보가 포함됩니다.
gcc라면 DWARF라는 format을 사용하는데, 이건 ELF보다 조금 더 복잡합니다.
공부하시는 것 추천하지 않고요.
대신에, 아래의 명령어를 사용하면 디버깅정보를 이용하여 filename과 lineno를 알 수 있습니다.

addr2line -e main <addr>

여기서 <addr> 이란 위의 __builtin_return_address()에서 받은 값입니다.
이제 필요한 정보를 모두 얻었습니다.
이 정보들을 합치면 어떤 module 혹은 source에서 사용하는 memory의 크기를 알 수 있습니다.



좀 더 자세히 설명할 수도 있지만,
서로의 개발 환경이 달라서 원리만 설명하는 것이 좋을 것 같아 간단하게 적습니다.
게다가 비워져 있는 부분을 스스로 채우는 것이 더 창의적이적인 것 같기도 하고요.

도움이 필요하시면 리플이나 메일로 알려주시고요~
조언도 환영입니다.

고맙습니다.

by 제임스 | 2012/01/18 20:22 | 메인스토리 | 트랙백 | 덧글(18)

◀ 이전 페이지          다음 페이지 ▶