2009년 12월 22일 화요일

이클립스에서 C/C++ 개발

보통 이클립스는 자바 개발에 사용하지만 gcc, gdb와 연동해서 훌륭한 C/C++ 개발툴이 될수 있다.

이클립스는 C/C++을 플러그인 형태로 지원하는데 이를 CDT라고 한다.

1. 이클립스 다운로드

http://www.eclipse.org/downloads/ 에서 Eclipse IDE for C/C++ Developers (79 MB)을 다운로드 받는다. 별도의 설치과정 없이 적당한 경로에 압축을 풀면된다.

2. JRE(Java Runtime Environment) 설치

이클립스는 자바로 만들어 졌기 때문에 http://java.sun.com/javase/downloads/index.jsp 에서 JRE를 설치한다.

3. 툴체인 설치

이클립스는 순수 IDE이므로 컴파일러와 디버거를 포함하지 않는다.

1) 아래 링크에서 컴파일러를 다운로드 한다.
실행하면 자동으로 설치된다.


2) 아래 링크에서는 디버거(gdb)를 다운로드 한다.
에서 GDB를 다운로드 받고 적당한 위치에 압축을 푼다.

4. 환경 설정(PATH)

제어판 -> 시스템 -> 고급 탭 -> 환경변수에서 PATH 값을 수정해 준다.

예) C:\Program Files\Microsoft Visual Studio\Common\Tools;C:\Program Files\Microsoft Visual Studio\VC98\bin;;C:\Program Files\SSH Communications Security\SSH Secure Shell;C:\Program Files\SoftForum\XecureHSM\;C:\MinGW\bin

환경변수 뒤에 설치한 gcc, gdb가 설치된 경로를 추가해줘야 한다. 난 gdb, gcc를 동일한 경로에 설치해서 PATH에 하나만 추가해 주었다.

5. 이클립스 설정

이클립스를 실행한다.
Window->Preferences를 선택하면 다이얼로그 박스가 나온다. C/C++ 아래의 New CDT project wizard->Makefile Project 를 선택하고
Build command를 mingw32-make 로 바꿔준다.


2009년 12월 14일 월요일

책으로 표현하는 나 <유저스토리북>


유저 스토리북이란 서비스가 베타 오픈을 했습니다.

가까히 사는 분에게 책을 빌려주고 빌려 볼수 있는 그런 사이트입니다.

저두 가입해서 가진 책도 등록하고 했습니다.

그런데 누가 컴쟁이 아니랄까봐 집에 있는 책의 대부분이 IT 관련 서적 ㅠㅠ;;

그 이외에는 전부 재테크, 주식 서적 ㅠㅠ;;

열심히 활동하면서 마음의 양식을 쌓아보렵니다. 아래는 사이트 주소입니다.


사이트가 AJAX로 만들어 졌는지 깔끔하고 별도의 리프레쉬 하면서 발생하는 깜빡거림이 없네요. 이놈의 컴쟁이 본능 관심은 서비스가 아니라 웹페이지 기술 ㅠㅠ;;

Dtrace를 이용한 솔라리스 메모리 누수(memory leak) 잡기

참조 문헌

Dtrace를 이용한 메모리 누수 잡는 법을 소개하고자 한다.

아래 사용한 스크립트는 5번 항목 또는 위의 링크를 참조하도록 한다.


1. 메모리 leak을 유발하는 코드 작성

#include

int main(void)
{
char *test1;

while(1)
{
test1 = malloc(sizeof(char) * 256);

printf("memory leak\n");

sleep(1);
}
return 1;
}

2. 해당 프로그램 실행
# a.out

3. dtrace로 memory malloc과 free한 부분을 찾음
사용법
# ./memleak.d PID > output

사용 예
# su -
# pgrep a.out
5659
# ./memleak.d 5659 > leak.data
Ctrl+c

4. 스크립트로 malloc과 free를 매칭해서 제대로 free가 되지 않은 부분을 추출해 냄
사용법
./findleaks.pl output

사용예
./findleaks.pl leak.data
Ptr=0x22018 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c

---------
Ptr=0x21af0 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c

---------
Ptr=0x21e08 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c

---------
Ptr=0x21d00 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c

---------
Ptr=0x21bf8 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c

---------
Ptr=0x21f10 Size=256
libc.so.1`malloc+0x6c
a.out`main+0x8
a.out`_start+0x5c


5. 스크립트

1)
# cat ./memleak.d

-------------------------------------- cut --------------------------------------------
#!/usr/sbin/dtrace -s

pid$1:libc.so.1:malloc:entry
{
self->trace = 1;
self->size = arg0;
}
pid$1:libc.so.1:malloc:return
/self->trace == 1/
{
printf("Ptr=0x%p Size=%d", arg1, self->size);
ustack();
self->trace = 0;
self->size = 0;
}

pid$1:libc.so.1:realloc:entry
{
self->trace = 1;
self->size = arg1;
self->oldptr = arg0;
}

pid$1:libc.so.1:realloc:return
/self->trace == 1/
{
printf("Ptr=0x%p Oldptr=0x%p Size=%d", arg1, self->oldptr, self->size);
ustack();
self->trace = 0;
self->size = 0;
}

pid$1:libc.so.1:calloc:entry
/self->trace == 1/
{
self->trace = 1;
self->size = arg1;
}

pid$1:libc.so.1:calloc:return
/self->trace == 1/
{
printf("Ptr=0x%p Size=%d", arg1, self->size);
ustack();
self->trace = 0;
self->size = 0;
}

pid$1:libc.so.1:free:entry
{
printf("Ptr=0x%p ", arg0);
}
-------------------------------------- cut --------------------------------------------

2)
# cat findleaks.pl

-------------------------------------- cut --------------------------------------------
#!/usr/bin/perl

use Data::Dumper;

my %hash = ();

while (<>) {
if ((/malloc:return Ptr=([^ ]*) Size=(.*)/) ||
(/calloc:return Ptr=([^ ]*) Size=(.*)/)) {
$hash{$1} = { size => $2 };
while (<>) {
last if /^$/;
$hash{$1}->{stack} .= $_;
}
}
elsif (/free:entry Ptr=([^ ]*)/) {
if (exists $hash{$1} and $hash{$1}) {
$hash{$1} = '';
}
}
elsif (/realloc:entry Ptr=([^ ]*) Oldptr=([^ ]*) Size=(.*)/) {
if ($1 eq $2) {
if (exists $hash{$1} and $hash{$1}) {
$hash{$1} = { size => $3 };
$hash{$1}->{stack} = '';
while (<>) {
last if /^$/;
$hash{$1}->{stack} .= $_;
}
}
} else {
$hash{$1} = '';
$hash{$2}= { size => $3 };
$hash{$2}->{stack} = '';
while (<>) {
last if /^$/;
$hash{$2}->{stack} .= $_;
}
}
}

}

foreach my $key (keys %hash) {
next if not $hash{$key}->{size};
print "Ptr=$key Size=", $hash{$key}->{size}, "\n";
print $hash{$key}->{stack}, "\n---------\n";
}
-------------------------------------- cut --------------------------------------------

2009년 12월 8일 화요일

솔라리스 메모리 누수 확인(Memory Leak)

* 솔라리스에서 메모리 누수를 확인하는 방법

1. 누수를 확인할 블럭 실행
- sh, ksh, bash 일 경우
# UMEM_DEBUG=default UMEM_LOGGING=transaction LD_PRELOAD=libumem.so.1 ./block&
- csh 일 경우
setenv UMEM_DEBUG default; setenv UMEM_LOGGING transaction; setenv LD_PRELOAD libumem.so.1; ./block&
[1] 1234

2. 코어 덤프
# gcore 1234 gcore: core.1234 dumped

3. 덤프 분석
root@wl # mdb core.1234
Loading modules: [ libumem.so.1 libc.so.1 ld.so.1 ]
> ::umem_status
> ::umem_log
> ::umalog ...
> ::findleaks
CACHE LEAKED BUFCTL CALLER
080798d0 1 0808ae30 main+0xf
08079c50 1 0808eaf8 main+0x1e
----------------------------------------------------------------------
Total 2 buffers, 64 bytes

Ctrl+D

- 출처(자세한 사항은 링크 를 참조하세요)

2009년 12월 1일 화요일

MFC에서 CString과 char* 형변환

개인적으로 MFC의 CString을 극도로 혐오하지만, MFC 개발을 한다면 반드시 써야한다.

1. CString에서 char*으로 형변환

CString my_cstr;
my_str = "Hello World!";

char* my_pchar = LPSTR(LPCTSTR(my_str ));


2. char*에서 CString으로 형변환

char my_pchar[] = "Hello World!";

CString my_cstr;
my_cstr.Format("%s", my_pchar);

※ Windows에서 MFC가 없어지는 그날까지...