EzDoum

찾기
처음으로 | 찾기 | 아카이브 | 글 올리기 | 링크 | 자료실 | 통계 | 연락처 | 자유게시판
이지도움 특집
전체보기
네트워크
TI OMAP35x
TI DaVinci
Analog Blackfin
RobotWar2005
임베디드!
캐쉬의 모든것
메모리 할당 알고리즘
CPU 파이프라이닝
자료구조(Tree)
금융

Login
이름

암호

기억하기


사용자 등록

현재 접속중인 등록 사용자는 0명, 익명 사용자는 2명 입니다.
전체 등록 사용자: 751명

마지막 답장
·libcurl + fuse 조합으로 되는게 많네. (1)
·Linux Ftrace에 관해 (3)
·Android MTP ( Media Transfer Protocol ) (1)
·Lighttpd에 인증을 digest 사용시 IE 오동작 문제? (1)
·Dtrace에 관해 (1)

최근글
·OpenSSL and multi-threads (0)
·ARM 환경에서 OpenCL 사용 (0)
·IoT용 WIFI 모듈 비교 ( MCU ) 클래스 (0)
·Glances - 리눅스 여러 가지 항목을 한 화면에서 모니터링 (0)
·plugin 방식의 로그 분석기 (0)

뜨거운 감자
·나는 인터렉티브한 환경에서 역어셈블 한다. (12)
·GNU REGEX (정규표현식) 프로그래밍 강좌 (7)
·SoCRobotWar 2005 - 신입생 기초 교육자료 (7)
·ASP.NET의 데이터 그리드와 사용자 컨트롤 (7)
·DHTML Editing Control (7)

가장 많이 읽은 글
·[Cache] 2-way Set-Associative 방식이란 무엇일까? (2)
·멀티쓰레드(Pthread) 프로그래밍
·Sorting Algorithm Animation (2)
·GNU REGEX (정규표현식) 프로그래밍 강좌 (7)
·SoCRobotWar 2005 - 신입생 기초 교육자료 (7)

리눅스 문제 분석과 해결
글쓴이: EzDoum 글쓴날: 2007년 02월 28일 오후 03:39
책소개



동작상태를 수집하는 스크립트 vacuum 가 부록으로 들어 있는데, 이것만 능동적으로 사용해도 (왜 저런정보를 수집해야 하고 값을 해석할 수 있다면) 이 책은 값어치를 다했다.

리눅스 문제 분석과 해결
아무도 가르쳐주지 않았던 리눅스 실전 노하우


태그 : 리눅스, 디버깅, 문제해결, 오픈소스
원서명 : Self-Service Linux: Mastering the Art of Problem Determination
Mark Wilding, Dan Behman 지음
박재호, 이해영 옮김

오픈소스 프로그래밍 시리즈
ISBN : 8989975999
28,000원 | 2006년 9월 28일 펴냄
페이퍼백 | 472쪽 | 190*250mm



모든 리눅스 관리자, 개발자, 지원 부서, 고급 사용자를 괴롭혀왔던 불가결의 문제 해결 길잡이가 드디어 출간되었다. 오류, 비정상 종료, 정지, 성능 저하, 기대하지 않은 행동 양식, 기대하지 않은 결과를 시스템적으로 파헤치며, strace, gdb, kdb, SysRq, /proc 등 핵심적인 리눅스 문제 해결 도구에 통달하는 방법을 알려준다.


Quote:이 책의 특징


드디어 모든 고급 사용자, 관리자, 개발자를 위한 구조적이며 실질적인 리눅스 문제 해결사가 등장했다. IBM의 선도 리눅스 전문가 두 명은 이 책에서 오류, 비정상 종료, 정지, 성능 저하, 기대하지 않은 행동 양식, 기대하지 않은 결과와 같은 모든 유형의 리눅스 관련 시스템이나 응용프로그램 문제를 찾아서 해결하기 위한 네 단계 방법론을 소개한다. 리눅스의 핵심 문제해결 도구를 사용해서 정확하게 문제를 손수 해결하며 리눅스 공동체에 퍼져있는 지식을 효과적으로 활용하는 방법을 배워보자.

리눅스를 업무에서 활용하는 사람이라면, 이 책은 효율성, 생산성, 시장성을 놀랄 만큼 높여줄 수 있다. 회사에서 리눅스를 배포하거나 관리하는 업무를 맡고 있다면, 이 책은 운영 비용을 절감하고, 중단 시간을 줄이고, ROI를 높이는 과정에서 도움을 준다.

▒ 리눅스 환경에서 문제를 파악하는 증명된 우수 기법을 찾는다
▒ 다른 플랫폼에서 습득한 문제 해결 지식을 지렛대로 삼는다
▒ 리눅스 문제 해결 도구 중에서 가장 널리 사용하는 strace로 문제를 찾는 방법을 배운다
▒ /proc을 활용해서 하드웨어, 커널, 프로세스에 얽힌 중요한 정보를 찾아낸다
▒ 오픈 소스 응용 프로그램에 디버그 정보를 붙여서 새로 컴파일한다
▒ C++와 스레드 응용 프로그램을 포함하여 gdb로 응용 프로그램을 디버그한다
▒ 커널 비정상 종료와 정지를 한번에 한 단계씩 디버깅한다
▒ ELF를 이해하고 더 효율적인 디버깅 과정에 이 지식을 활용한다
▒ 중요한 임무에 투입한 리눅스 시스템을 디버깅하는 과정에서 몇 시간이나 며칠을 절약하도록 상용 환경에 바로 투입 가능한 자료 수집 스크립트를 제공한다


Quote:이 책의 구성


이 책은 리눅스 환경에서 발생하는 문제를 효과적이면서도 효율적으로 진단하는 방법을 다룬다. 인터넷 상에 있는 정보와 자원을 활용하는 방법 등 우수한 조사 기법을 소개하고, 리눅스가 제공하는 가장 중요한 문제 진단 분석과 해결 도구의 사용법을 상세히 다룬다.

1장은 효과적인 문제 진단 분석과 해결 기법을 다루는 집중 강좌이다. 이 장을 익히고 나면 전문가처럼 문제를 진단할 수 있다. 흔히 발생하는 문제 유형을 조사하는 방법과 더불어, 인터넷 어디에서 어떻게 정보를 찾아야 하는지를 설명한다.

2장은 리눅스에서 문제 진단 분석과 해결 과정에 가장 흔히 사용하는 도구인 strace를 다룬다. 2장에서는 strace가 동작하는 방식을 상세히 소개할 뿐만 아니라 실용적인 사용법 정보도 다룬다. 또한 간단한 strace 도구의 소스코드를 소개하며, 기반 기능인 ptrace 인터페이스를 통해 커널과 동작하는 방식을 상세히 설명한다.

3장은 현재 시스템에서 실행 중인 하드웨어, 커널, 프로세스에 관련하여 방대한 정보를 포함하는 /proc 파일 시스템에 관한 내용이다. 주로 문제 진단 분석과 해결을 비롯하여 시스템 진단에 관련한 고급 기능과 기교를 소개하고 살펴본다. 예를 들어, /proc/sys/kernel/sysrq로 SysRq 커널 마법 키를 사용하는 방법을 다룬다.

4장은 컴파일을 다룬다. 디버깅 정보를 포함하도록 오픈 소스 응용 프로그램을 다시 컴파일해야 할지(대개는 다시 컴파일해야 한다), 어려운 문제일 경우 어셈블리 코드 목록을 생성해야 할지(이 방법으로 트랩이 걸린 코드 행을 찾는다), 리눅스 커널 자체를 다시 컴파일하는 과정에서 어떤 문제가 발생하는지 등에 관해 긴요한 정보를 제공한다.

5장은 컴퓨터 시스템에서 가장 중요하고도 기본적인 개념 중 하나인 스택을 속속들이 살펴본다. (리눅스 전문가라면 반드시 알아야 할) 스택 구조체를 상세히 설명하며, 또한 독자가 자신의 도구와 응용 프로그램에서 스택 추적을 생성하기 위해 사용할 수 있는 소스 코드를 소개하고 설명한다.

6장은 GNU 디버거인 GDB로 응용 프로그램을 디버깅하는 방법을 상세하고도 심도 있게 살펴본다. 또한 그래픽 유저 인터페이스인 DDD(Data Display Debugger)도 간략하게 소개한다. 또한 C++ 응용 프로그램 디버깅, 스레드 응용 프로그램 디버깅, 다양한 최고 디버깅 기법 등 흔히 접하기 어려운 정보를 상세히 다룬다.

7장은 시스템 충돌과 중단을 상세히 살펴본다. ‘직렬 콘솔을 연결하는 방법’부터 ‘커널 트랩(“웁스 Oops”)을 사용하여 코드 행을 찾는 방법’까지 필요한 내용을 다룬다.

8장은 커널 디버깅, 즉 커널 디버거 kdb를 사용한 디버깅을 좀더 상세히 다룬다. 시스템에서 kdb를 환경 설정하고 활성화하는 방법을 설명하며, 커널 전문가가 되지 않고도 대다수 리눅스 사용자가 활용할 수 있는 실용적인 명령을 소개한다.

9장은 ELF(Executable and Linking Format)를 상세하게 파헤친다. 기본적인 ELF 파일 형식에 관해 자세하고도 실용적인 정보를 제공하며, 극소수 개발자만이 알고 있는 비결과 기교를 소개한다. 심지어 LD_PRELOAD(으)로 함수를 재정의하는 법, GOT(global offset table)와 GDB 디버거로 함수를 직접 가로채서 디버그 버전으로 보내는 법 등을 예제 코드와 더불어 단계별로 설명한다.

부록 A는 리눅스에서 가장 유용한 도구, 기능, 파일을 개괄적으로 소개하는 디버깅 도구 상자이다. 각 도구마다 언제 사용하면 좋은지 그리고 어디서 최신 버전을 얻을 수 있는지를 설명하고 있다.

부록 B는 곧바로 사용할 수 있는 자료 수집 스크립트를 제공한다. 주요 핵심 업무를 다루는 시스템이나 리눅스 상에서 원격으로 고객을 지원하는 사용자에게 특히 유용하다. 자료 수집 스크립트만 있어도, 원격에서 발생한 문제를 디버깅하는 데 드는 시간을 크게 줄일 수 있다.



Quote:이 책의 대상


이 책은 모든 리눅스 사용자에게 유용한 정보를 제공하지만, 특히 리눅스 전문가를 염두에 두고 있다. 여기에는 리눅스 고급 사용자, 리눅스 관리자, 리눅스용 소프트웨어 개발자, 리눅스 제품 지원 인력 등이 포함된다. 가정에서 재미삼아 리눅스를 사용하는 독자에게도 도움이 된다. 물론 리눅스에 대한 기본적인 이해가 있거나 적어도 배우려는 의지가 있어야 한다. 여기서 후자가 더 중요하다.


Quote:저자 서문


리눅스는 일반 가정과 사무실에서 사용하기에 최적인 운영체제이다. 강력하며, 여느 상용 운영체제 못지 않게 안정적이고, 보안이 뛰어나며, 무엇보다도 오픈 소스이다. 하지만 가정이나 사무실에서 리눅스를 사용할지 말지를 결정하는 가장 큰 요인 중 하나는 서비스와 지원이다. 리눅스는 세계 도처에 있는 자원 봉사자 수천 명이 개발하기 때문에 문제 발생 시 누구에게 도움을 청해야 할지가 분명하지 않다.

진정한 리눅스 정신에 의거하여, 리눅스는 상용 운영체제와는 다소 상이한 지원 방식을 채택하고 있다. 전대 미문의 전문가 커뮤니티가 존재하며, 최첨단 문제 진단 분석과 해결 도구를 제공할 뿐만 아니라, 당연히 제품 자체에도 소스 코드가 들어 있다. 이러한 자원 외에도 IBM과 같은 회사에서 내놓은 전문 리눅스 지원 서비스와 레드햇이나 노벨/수세와 같은 리눅스 판매업체가 여럿 존재한다. 하지만 전문 서비스나 판매업체를 거치지 않고 리눅스에서 제공하는 자원을 최대한 “스스로 활용하는” 방법을 이 책에서 주요 주제로 다룬다.

리눅스를 “스스로 활용한다”라는 의미는 사람마다 다르다. 가정에서 리눅스를 사용하는 사람에게는 리눅스 사용이 한층 즐거워진다는 뜻이다. 사무실에서 리눅스를 사용하는 사람에게는 리눅스 관련 문제를 신속하고 효과적으로 진단함으로써 조직 내 자신의 가치와 시장성을 높일 수 있다는 뜻이다. 기업 전략의 일부로 리눅스를 채택해야 할지를 고민하는 기업에게는 리눅스 채택 전략에 따른 운영 경비 감소와 투자 수익(ROI, Return of Investment) 증가를 뜻한다. 어느 유형에 속하는 사용자이든, 리눅스 사용 경험과 투자로부터 최대한 많은 이익을 얻어내야 한다는 점이 중요하다.


Quote:저자 소개


마크 윌딩
마크 윌딩은 현재 유닉스와 리눅스 편의성 기술을 전문적으로 연구하는 선임 개발자로 IBM에서 근무하고 있다. 15년 이상 소프트웨어 개발 경험을 토대로, 운영체제, 네트워크, C/C++ 개발, 편의성, 품질 공학, 컴퓨터 하드웨어 부문에서 다양한 경험을 쌓아왔다.

댄 버만
댄 버만은 토론토 IBM 소프트웨어 연구실에서 리눅스 플랫폼 개발을 위한 DB2 UDB 개발팀 일원으로 근무하고 있다. 리눅스 10년 이상 경력을 자랑하며, x86-64, z시리즈, 파워 플랫폼을 포함한 리눅스가 지원하는 최신 아키텍처에 DB2 UDB를 이식하고 동작하는 작업에 참여했다.


Quote:역자 서문


전문적인 개발자라면 이구동성으로 코드를 쓰는 작업보다 읽는 작업에 더 많은 시간을 투입한다고 이야기한다. 다시 말해서, 코드 작성보다 작성 후 개선/검토/디버깅에 훨씬 많은 노력이 들어가며 이런 과정은 취미 생활이나 학교 과제로 프로그램을 작성하지 않는 이상 상용 제품을 만드는 과정에서 필수라고 보여진다. 하지만 유감스럽게도 대학교나 컴퓨터 학원에서 디버깅을 전문적으로 가르친다는 말은 한번도 들어보지 못했다. 가장 시간을 많이 쏟는 분야에 대한 체계적인 지식 습득 경로가 없다는 사실은 사뭇 충격적이기까지 하다.

과거 유닉스 시절에는 모든 시스템 프로그래머가 바로 시스템 관리자였고 시스템 관리자가 바로 시스템 프로그래머였는데, 요즘 들어와서 명확한 선이 그어지면서 갈수록 시스템 관리자와 프로그래머 업무가 분리되면서, 좀더 전문적으로 자신이 맡은 작업을 진행할 수 있다는 장점이 있는 반면에 학제간 연구를 통한 통합적인 문제 분석이 어렵다는 단점이 나타나고 있다. 시스템 관리자는 과연 스크립트 언어를 벗어난 본격적인 프로그램 분석 실력이 필요 없을까? 프로그래머는 기초적인 명령어 사용법 이외에 시스템 관리자의 전유물이라고 여기던 프로세스나 목적 파일에 대한 정보 확인 명령에 숨겨진 의미를 파악할 필요가 없을까?

이렇게 모순적이고 어려운 현실에 직면한 개발자들에게 도움을 주기 위해 올해 초에 에이콘 출판사를 통해 『리눅스 디버깅과 성능 튜닝』이라는 제목을 붙인 번역서를 출간했었다. 『리눅스 디버깅과 성능 튜닝』은 현장에서 바로 써먹을 수 있도록 리눅스에서 제공하는 다양한 도구 사용법과 활용 방안을 예를 통해 설명하고 있다. 하지만 『리눅스 디버깅과 성능 튜닝』은 방대한 도구를 한정된 지면에 다루고 있기에 아무래도 폭에 비해 깊이가 얕다는 문제점이 있었으며, 이런 단점을 보완할만한 다른 책에 대한 요구가 커지고 있다.

이와 같은 상황에서 마침 프렌티스 홀에서 출간한 『Self-Service Linux』를 접하게 되었고, 책 내용을 검토한 결과 『리눅스 디버깅과 성능 튜닝』과 비교해서 다루는 도구의 폭은 좁지만 아무도 가르쳐주지 않았던 비밀스러운 활용 방안을 충분한 깊이로 다루고 있다는 결론을 내려서 번역 작업을 서두르게 되었다.

이 책은 단순한 옵션 나열이나 피상적인 명령어 사용법을 다루는 책이 아니다. 마치 고급 시스템 관리자를 위한 문제 해결 서적이라고 착각하기 쉽지만, 실제로 리눅스 전문 개발자들이 반드시 알고 넘어가야 하는 핵심적인 지식을 담고 있는 알짜 서적이다.

하나같이 유익한 내용들이지만, 특히 1장, 5장, 6장, 9장을 눈여겨보기 바란다. 다른 책에서 쉽게 접하지 못하는 전반적인 문제 해결 전략을 1장에서 다루고 있으며, 스택에 대한 명쾌한 설명이 5장에서 전개된다. 심지어 원시 코드가 없을 경우에도 문제 원인을 gdb로 추적하는 방법을 6장에서 실제 예를 들고 있으며, 마지막으로 중요한 정보를 담고 있음에도 불구하고 개발자 사이에서 외면 받고 있는 ELF에 대한 설명이 9장에 나온다. 커널 단으로 내려가지 않고서도 리눅스 내부 구조를 이렇게 명쾌하게 그릴 수 있다는 사실이 놀라울 따름이다.

- 박재호


이 책에서 가장 감동적이고 핵심적인 장을 꼽으라면 1장 “우수 문제 해결 기법과 초반 조사”이다. 리눅스 환경에서 개발하는 사람이라면, 반드시 읽어야 할 장이다. 1장 내용만 충분히 숙지하여 머리와 가슴에 넣어도, 이 책 값어치 중에서 80%는 얻어냈다고 생각한다.

흔히 “실력 있는 사람”과 “사실을 많이 습득한 사람”을 혼동한다. 특히나 개발 분야에서는 더욱 그렇다. API를 좔좔 외우고 명령 옵션을 쫙 꿰고 있는 사람을 실력이 있다고 여긴다. 하지만 습득한 사실만으로 해결할 수 있는 문제에는 한계가 있다. 문제를 해결하는 능력, 즉 실력은 단순한 지식 이상이 필요하다. (참고로, 반드시 자신의 힘으로 문제를 해결해야 한다는 뜻은 아니다. 올바른 사람을 찾아서 원하는 답을 얻어내는 기술도 능력이고 실력이다.)

제목 그대로, 이 책은 리눅스 시스템을 스스로 운영하는 방법, 즉 리눅스 시스템이라는 영역에서 문제를 해결하는 능력을 키우는 방법을 소개한다. strace(2장)에서 GDB(6장)을 짚고, ELF(9장)에 이르기까지, 이 책에서 다루는 지식은 방대하다. 자칫하면, 여기에 묻혀 중요한 줄기를 놓칠 수 있다. 예를 들면, 이 책은 GDB 최적화 옵션도 설명하지만, 동시에 어떤 문제와 어떤 상황에서 GDB를 사용하는지도 설명한다. 리눅스 상에서 문제를 디버깅하려는 개발자라면, 어떤 도구가 어떤 상황에 적합한지 이해해야 한다. 하지만 최적화 옵션을 일부러 하나하나 암기할 필요는 없다고 생각한다. 최적화 옵션이 무엇인지 그리고 어떤 문제를 일으킬 수 있는지만 이해한다면, 각 옵션마다 내재된 있는 정확한 의미는 필요할 때 찾아보면 된다.

도서관에 있는 책 내용을 몽땅 암기하는 능력보다는 원하는 책과 정보를 빠르고 신속하고 정확하게 찾아낼 수 있는 능력이 더 유용하다. 책을 읽으면서 이런 점을 염두에 두었으면 한다. 그리고 가능하다면 서문과 1장에 충분한 시간을 할애하기 바란다. 좀 딱딱하다 싶을 내용이지만, 의외로 재미있고 활기차다. 이왕이면 독자 여러분이 즐겁게 읽었으면 좋겠다.

- 이해영


Quote:목차


1장 문제 해결 우수 기법과 초반 조사
1.1 시작
1.2 효과적으로 문제를 분석하기 위한 시스템 준비
1.3 네 단계 조사 과정
1.3.1 1단계: 자기 힘으로 초반 조사 수행
1.3.2 2단계: 효과적인 인터넷 검색
1.3.3 3단계: 심도 있는 조사 수행 (우수한 문제 조사 기법)
1.3.4 4단계: 도움/아이디어 얻기
1.4 기술적 조사
1.4.1 증상과 원인
1.5 상용제품 문제해결 방법
1.6 결론

2장 strace와 시스템 호출 추적
2.1 개요
2.2 strace란?
2.2.1 커널 측면에서 이해하기
2.2.2 언제 strace를 사용할까?
2.2.3 간단한 예제
2.2.4 동일한 예제를 정적으로 빌드한 경우
2.3 주요 strace 옵션
2.3.1 자식 프로세스 추적
2.3.2 시스템 호출 활동 시간 측정
2.3.3 상세 출력 모드
2.3.4 실행 중인 프로세스 추적
2.4 strace 영향과 고려 사항
2.4.1 strace와 EINTR
2.5 디버깅 실례
2.5.1 LD_LIBRARY_PATH 경로를 수정하여 시작 시간 줄이기
2.5.2 PATH 환경 변수
2.5.3 inetd 또는 xinetd (수퍼 서버) 추적하기
2.5.4 통신 오류
2.5.5 strace로 정지 상태 조사하기
2.5.6 역공학 (strace 도구가 동작하는 방식)
2.6 시스템 호출 추적 예제
2.6.1 예제 코드
2.6.2 시스템 호출 추적 코드 설명
2.7 결론

3장 /proc 파일시스템
3.1 개요
3.2 프로세스 정보
3.2.1 /proc/self
3.2.2 /proc/ 세부 사항
3.2.3 /proc//cmdline
3.2.4 /proc//environ
3.2.5 /proc//mem
3.2.6 /proc//fd
3.2.7 /proc//mapped_base
3.3 커널 정보와 조작
3.3.1 /proc/cmdline
3.3.2 /proc/config.gz 또는 /proc/sys/config.gz
3.3.3 /proc/cpufreq
3.3.4 /proc/cpuinfo
3.3.5 /proc/devices
3.3.6 /proc/kcore
3.3.7 /proc/locks
3.3.8 /proc/meminfo
3.3.9 /proc/mm
3.3.10 /proc/modules
3.3.11 /proc/net
3.3.12 /proc/partitions
3.3.13 /proc/pci
3.3.14 /proc/slabinfo
3.4 시스템 정보와 조작
3.4.1 /proc/sys/fs
3.4.2 /proc/sys/kernel
3.4.3 /proc/sys/vm
3.5 결론

4장 컴파일
4.1 개요
4.2 GCC
4.2.1 GCC의 간단한 역사
4.2.2 GCC 버전 호환성
4.3 기타 컴파일러
4.4 리눅스 커널 컴파일
4.4.1 커널 원시 코드 얻기
4.4.2 아키텍처 관련 원시 코드
4.4.3 커널 컴파일 오류 처리하기
4.4.4 일반적인 컴파일 문제
4.5 어셈블리 목록
4.5.1 어셈블리 목록의 목적
4.5.2 어셈블리 목록 생성하기
4.5.3 어셈블리 목록 읽기와 이해하기
4.6 컴파일러 최적화
4.7 결론

5장 스택
5.1 개요
5.2 실생활에 비유한 예제
5.3 x86/x86-64 아키텍처 스택
5.4 스택 프레임이란?
5.5 스택 동작 방식
5.5.1 BP와 SP 레지스터
5.5.2 함수 호출 규약
5.6 스택 자료 참조와 수정
5.7 디버거로 스택 보기
5.8 스택 이해하기
5.8.1 직접 설계한 스택 역추적 기능
5.9 결론

6장 GNU 디버거(GDB)
6.1 개요
6.2 디버거를 사용하는 시점
6.3 명령행 편집
6.4 GDB로 프로세스 제어하기
6.4.1 GDB 명령행에서 프로그램 실행하기
6.4.2 GDB에 실행 중인 프로세스 붙이기
6.4.3 core 파일 사용하기
6.5 데이터, 메모리, 레지스터 확인하기
6.5.1 메모리 맵
6.5.2 스택
6.5.3 메모리와 변수 확인하기
6.5.4 레지스터 덤프
6.6 실행
6.6.1 기본 명령
6.6.2 실행 제어 명령을 위한 환경설정
6.6.3 정지점
6.6.4 감시점
6.6.5 정지 시 표현식 출력
6.6.6 공유 라이브러리로 작업하기
6.7 원시 코드
6.8 어셈블리 언어
6.9 팁과 기교
6.9.1 프로세스 붙이기: 다시 한번 돌아보기
6.9.2 변수와 함수의 주소 찾기
6.9.3 디버그 심볼이 없는 프로그램에서 구조체 보기
6.9.4 엔디언 방식 이해하고 다루기
6.10 C++ 디버깅
6.10.1 전역 생성자와 소멸자
6.10.2 인라인 함수
6.10.3 예외
6.11 스레드
6.11.1 스택 공간 부족
6.12 DDD
6.12.1 데이터 표시 윈도우
6.12.2 원시 코드 윈도우
6.12.3 기계어 윈도우
6.12.4 GDB 콘솔 윈도우
6.13 결론

7장 리눅스 시스템 비정상 종료와 정지
7.1 개요
7.2 정보 수집
7.2.1 syslog 설명
7.2.2 직렬 콘솔 준비하기
7.2.3 직렬 널 모뎀 케이블 연결하기
7.2.4 컴퓨터 시작 과정에서 직렬 콘솔 활성화하기
7.2.5 SysRq 커널 마법 키 활용하기
7.2.6 웁스 보고서
7.2.7 수동 커널 트랩 추가하기
7.2.8 웁스 보고서 검사하기
7.2.9 실패한 코드 행 찾아내기
7.2.10 커널 웁스와 하드웨어
7.2.11 cscope로 커널 원시 코드 색인하기
7.3 결론

8장 KDB를 사용한 커널 디버깅
8.1 개요
8.2 KDB 활성화하기
8.3 KDB 활용하기
8.3.1 KDB 시작하기
8.3.2 일반 동작으로 복귀하기
8.3.3 기본적인 명령어
8.4 결론

9장 ELF
9.1 개요
9.2 개념과 정의
9.2.1 심볼
9.2.2 목적 파일, 공유 라이브러리, 실행 파일, 코어 파일
9.2.3 링킹
9.2.4 런타임 링킹
9.2.5 프로그램 인터프리터/런타임 링커
9.3 ELF 헤더
9.4 세그먼트와 섹션 개괄
9.5 세그먼트와 프로그램 헤더 테이블
9.5.1 텍스트와 데이터 세그먼트
9.6 섹션과 섹션 헤더 테이블
9.6.1 문자열 테이블 형식
9.6.2 심볼 테이블 형식
9.6.3 섹션 이름과 유형
9.7 재배치와 위치 독립 코드
9.7.1 PIC와 PIC가 아닌 경우 비교
9.7.2 재배치와 위치 독립 코드
9.7.3 재배치와 링킹
9.8 ELF 목적파일에서 디버깅 정보 제거하기
9.9 프로그램 해석기
9.9.1 링크 지도
9.10 심볼 결정
9.11 문제 분석을 위한 약한 심볼 활용
9.12 GOT를 활용한 고급 가로채기
9.13 원시 파일
9.14 ELF API
9.15 기타 정보
9.16 결론

부록 A 디버깅 도구 상자
A.1 개요
A.2 프로세스 정보와 디버깅
A.2.1 도구: GDB
A.2.2 도구: ps
A.2.3 도구: strace (system call tracer)
A.2.4 도구: /proc 파일시스템
A.2.5 도구: DDD (Data Display Debugger)
A.2.6 도구: lsof (List Open Files)
A.2.7 도구: ltrace (library call tracer)
A.2.8 도구: time
A.2.9 도구: top
A.2.10 도구: pstree
A.3 네트워크
A.3.1 도구: traceroute
A.3.2 File: /etc/hosts
A.3.3 File: /etc/services
A.3.4 도구: netstat
A.3.5 도구: ping
A.3.6 도구: telnet
A.3.7 도구: host/nslookup
A.3.8 도구: ethtool
A.3.9 도구: ethereal
A.3.10 File: /etc/nsswitch.conf
A.3.11 File: /etc/resolv.conf
A.4 시스템 정보
A.4.1 도구: vmstat
A.4.2 도구: iostat
A.4.3 도구: nfsstat
A.4.4 도구: sar
A.4.5 도구: syslogd
A.4.6 도구: dmesg
A.4.7 도구: mpstat
A.4.8 도구: procinfo
A.4.9 도구: xosview
A.5 파일과 목적 파일
A.5.1 도구: file
A.5.2 도구: ldd
A.5.3 도구: nm
A.5.4 도구: objdump
A.5.5 도구: od
A.5.6 도구: stat
A.5.7 도구: readelf
A.5.8 도구: strings
A.6 커널
A.6.1 도구: KDB
A.6.2 도구: KGDB
A.6.3 도구: ksymoops
A.7 기타
A.7.1 도구: VMWare 워크스테이션
A.7.2 도구: VNC 서버
A.7.3 도구: VNC 뷰어

부록 B 자료 수집 스크립트
B.1 개요
B.1.1 -thorough
B.1.2 -perf, -hang , -trap, -error
B.2 스크립트 돌리기
B.3 스크립트 소스코드
B.4 면책



[ 미디어 서평 ]

리눅스 운영체제와 관련 소프트웨어에서 나타나는 문제점과 버그를 스스로 찾아내어 문제를 해결해주는 길잡이를 하는 책이다. 소프트웨어나 하드웨어와 관련한 잠재적인 리눅스 문제를 디버깅하는 다양한 방법을 설명하고 있다.
- PC Burn 서평 / pcburn.com

이 책은 시스템 관리자, 컴퓨터 문제 해결사, 개발자에게 꼭 필요한, 구글조차도 풀어주지 못하는 난이도 높은 문제를 추적해나가는 첨단 기법을 풀어서 소개하고 있다.
- TechBookReport 서평 / www.techbookreport.com

이 책은 문제 진단과 해결을 위한 실질적인 접근 방법을 택하고 있으며, 복잡한 유행어를 최소로 사용하면서 간단하고 명료한 방법으로 개념을 설명한다.
- All about Linux / linuxhelp.blogspot.com

시스템 문제를 디버깅하기 위한 아주 잘 정리된 방법론에서 시작하는 첫 40페이지는 압권이며, 리눅스 프로그래머는 물론이고 다른 모든 시스템 개발자에게도 훌륭하게 적용이 가능한 내용을 담고 있다.
- Duffbert's Random Musings / hostit1.connectria.com

이 책은 하나 이상 시스템에서 매일 리눅스를 사용하는 누구에게나 적합한 책이다. 예제는 아주 상세해서 명령, 옵션, 출력, 예제 코드, 다양한 시나리오에 접하도록 만들어준다. 이 책은 현실적이면서도 실질적인 문제 해결 접근 방법을 택하고 있으며, 우리 모두를 위한 문제 해결사 구실을 할 것이다.
- 슬래시닷 / books.slashdot.org


[ 아마존 독자서평 ]

★★★★★ 저는 함부로 별을 다섯 개 주지 않습니다.
- 안토니 로렌스(유닉스, 리눅스, 맥OS X 전문가)

★★★★★ 고차원적인 소프트웨어 디버깅과 문제 해결사
- 닐스 발렌틴

★★★★★ 고급 사용자와 관리자를 위한 필수서적
- 해롤드 맥파랜드(상위 50 리뷰자)

★★★★★ GDB에 대한 멋진 참고서
- W 보바일(상위 50 리뷰자)


p.viii 끝에서 두 번째 문단 4행
(주의: 달리 원서 예제는 → (주의: 원서 예제는 번역서와는 달리

p.xxi 참고 2행 마침표 삭제
http://www.phptr.com/title/013147751X. → http://www.phptr.com/title/013147751X

p.93 세 번째 문단 2-3행
/bin/bash에, 주소 공간 0x08048000-01080b6000으로 사상되어
→ /bin/bash 실행파일이 주소 공간 0x08048000-01080b6000으로 사상되어

p.177 아래에서 네 번째 행
네 번째 워드는 주소가 0xbffff228c, 값은
→ 네 번째 워드는 주소가 0xbffff22c, 값은

p.178 첫 번째 코드 4행
mov %esp, %ebp → movl %esp, %ebp

p.178 페이지 첫 번째 코드 8행
0x08048424 <function2+16>: lea 0xfffffffc(%ebp), %eax
→ 0x08048424 <function2+16>: leal 0xfffffffc(%ebp), %eax

p.179 두 번째 문단
0xbffff234, 0xbffff238, 0xbffff23c, 0xbffff40에 저장된
→ 0xbffff234, 0xbffff238, 0xbffff23c, 0xbffff240에 저장된

p.179 두 번째 문단 2행
스택 포인터를 옮기는 subl 명령 두 개를 보면
→ 스택 포인터를 옮기는 sub 명령 두 개를 보면

p.183 2행, 4행
-export-dynamic → --export-dynamic

p.183 1-3행에 대한 역자주 추가
(독자 김홍숙님께서 의견 주셨습니다.)
-rdynamic 스위치는 gcc의 specs파일에 저장된 내용에 따라 링커 옵션 --export-dynamic 으로 변경된다. 다음과 같은 명령을 통해 확인할수 있다.
gcc -dumpspecs | grep rdynamic
%{!static:--eh-frame-hdr} -m %(link_emulation) %{shared:-shared} %{!shared: %{!ibcs: %{!static: %{rdynamic:-export-dynamic} %{!dynamic-linker:-dynamic-linker %(dynamic_linker)}} %{static:-static}}}

p.198 마지막 코드 아래에서 4행
(gdb) unset envrionment FOOs → (gdb) unset envrionment FOO

p.201 아래에서 11행
현재 설정을 전부 보려면 -u 인수를 사용한다.
→ 현재 설정을 전부 보려면 -a 인수를 사용한다.

p.203 마지막 행
core-pattern에 대한 자세한 설명은
→ core_pattern에 대한 자세한 설명은

p.247 코드 네 번째 행 foo함수의 return직전 문장
pEmp->manager_emp_no=10;
→ pEmp->is_ceo=1;

p.248 아래에서 3행
0x08048372 : movl $0x10, 0x4 (%eax)
→ 0x08048372 : movl $0x1, 0x4 (%eax)

p.295 마지막 행
cscope -d -P /usr/src/$dbpath -p 20 -f /usr/src/$dbpath/cscope.out fi
→ cscope -d -P /usr/src/$dbpath -p 20 -f /usr/src/$dbpath/cscope.out
fi

p.315 마지막 행
g++ -o foo main.o -L. -Wl,-rpath, -lfoo
→ g++ -o foo main.o -L. -Wl,-rpath,. -lfoo

p.344 표 1행 1열
값 숫자 → 값 번호

p.344 두 번째 코드 1행
penguin> readelf -S foo
→ penguin> readelf -S libfoo.so

p.344 두 번째 문단
주소 4에서 8까지는 0x796에서 0x7d6까지 아우르며,
→ 4번째 주소에 있는 값에서 8번째 주소에 있는 값은 0x796에서 0x7d6까지 아우르며,

p.354 두 번째 문단
첫 번째 명령은 주소 0x8049924로 건너뛰는 jmp이다.
→ 첫 번째 명령은 주소 0x8049924에 저장된 내용을 주소로 해석하여 해당 주소로 건너뛰는 jmp이다.

p.360 그림 9.4
데이터 섹션 → 데이터 세그먼트

p.361 4행
함수는 우선 PLT로 가서 → 함수 참조는 우선 PLT로 가서

p.362 아래에서 7-8행
static myClass myObj ;
myClass myObj2 ;
→ int glob_int = 5;
static int static_int =5;

p.367 9.7.3 재배치와 링킹 절
링킹은 유형과 이름이 동일하며 정의된 심볼로 정의되지 않은 심볼을 일치시켜 묶는 과정이다.
→ 링킹은 정의되지 않은 심볼을 유형과 이름이 동일한 정의된 심볼로 매칭, 바인딩시키는 과정이다.

p.368 참고 아래 실행예 2행
penguin> readelf -r pic.o
→ penguin> readelf -r pic

p.372 '프로그램 해석기' 절 아래 문단 역자주 추가
export LD_SHOW_AUXV=true로 보조벡터를 볼 수 있도록 설정하고 있다. 보조 벡터 정보를 더 이상 안보고자 한다면 unset LD_SHOW_AUXV명령으로 환경변수 LD_SHOW_AUXV를 해제한다.


p.384 intercept.C 코드 앞에 한 행 추가
intercept.C:
→ int printf(const char *format, ...);
intercept.C:

  • 첨부 파일: Self-ServiceLinux.gif Self-ServiceLinux.gif (37 KiB(37,691 Bytes))

    [Image Size 253 x 300]
    Self-ServiceLinux.gif



  • 관련 링크
  • [분류: 책소개 인쇄용 페이지 본문 email로 보내기 ]

    <  Linux Tuning for Web Server(WEB) AND WebLogic Server(WAS) | 리눅스 디버깅과 성능 튜닝  >
    리눅스 문제 분석과 해결 | 답장: 1개 | 본문에 답장
    정렬 :  
    답장 EzDoum 2007년 02월 28일 오후 03:42 [ 이글에 답장 | 본문에 답장 | 책갈피 ]
    동작상태를 수집하는 스크립트 vacuum 
    
    #!/bin/bash
    
    ################################################################################
    #
    #  This script captures basic information for when a problem occurs. It can 
    #  be used any time a problem occurs, as root or as a mortal user. There are a
    #  few modes of operation: 
    #
    ################################################################################
    
    usage="Usage: vacuum [ -thorough | -perf | -hang <pid> | -trap | -error <cmd> ]"
    mode_thorough=0
    mode_perf=0
    mode_hang=0
    mode_trap=0
    mode_error=0
    topdir=""          # The data collection directory
    
    if [ -n $HOME ]
    then 
       topdir=$HOME/investigations 
    else
       topdir=~/investigations/$i 
    fi 
    
    if [ $# -gt 0 ]
    then
       while true ; do
          case $1 in
             "-thorough" )
                mode_thorough=1
                shift
             ;;
             "-perf" )
                mode_perf=1
                mode="PERF"
                shift
             ;;
             "-hang" )
                mode_hang=1
                shift
                if [ $# -le 0 ]
                then
                   echo $usage 
                   exit 2 
                fi
                pid=$1
             shift 
             ;;
             "-trap" )
                mode_trap=1
                shift
                ;;
             "-error" )
                mode_error=1
                shift 
                if [ $# -le 0 ]
                then
                   echo $usage 
                   exit 2 
                fi
                cmd=$1
                shift 
             ;; 
             * )
                echo $usage 
                exit 2
             ;; 
          esac
    
          if [ $# -le 0 ]
          then
             break ;
          fi
       done
    fi
    
    if [ ! -n $USER ]
    then
       USER=`whoami`
    fi
    
    ################################################################################
    ##  Create the appropriate directory for this problem
    ################################################################################
       
    i=0 
    invdir=$topdir/$i 
    
    while [ -d $invdir ]
    do
       let "i = i + 1" 
       invdir=$topdir/$i 
    done
    
    echo Investigation directory: $invdir 
    
    ################################################################################
    ##  Create data directory, src directory and the investigation log
    ################################################################################
     
    mkdir $invdir
    mkdir $invdir/src
    datadir=$invdir/data
    invlog=$invdir/inv.txt
    mkdir $datadir
    touch $invlog
    echo "################################################################################" >> $invlog
    echo "##                                   Header                                   ##" >> $invlog
    echo "################################################################################" >> $invlog
    echo "Problem number                : $i" >> $invlog
    echo -n "Time of data collector run    : " >> $invlog
    date >> $invlog
    echo "Data collector run as         : \"$0 $1 $2\" " >> $invlog
    
    ################################################################################
    ##  Ready to go...
    ################################################################################
    
    function collectFile
    {
       local comment=$1
       local fileName=$2
       local output=""
    
       echo -n "COLLECT: $fileName ($comment) ... " >> $invlog
    
       output=`cp $fileName $datadir 2>&1`
    
       if [ $? -ne 0 ]
       then
          echo "failed." >> $invlog
          echo "output from copy:" >> $invlog
          echo '{' >> $invlog
          echo $output >> $invlog
          echo '}' >> $invlog
    
       else
          echo "success." >> $invlog
       fi
    
       echo >> $invlog
    
    }
    
    function runCommand
    {
       local comment=$1
       local cmd=$2
    
       echo "RUNCMD: $cmd ($comment) ... " >> $invlog
    
       echo '{' >> $invlog
       $cmd 2>&1 >> $invlog 2>&1
       echo '}' >> $invlog
       echo >> $invlog
    
    }
    
    function doQuickCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                                  Quick Collect                             ##" >> $invlog
       echo "################################################################################" >> $invlog
    
       #Environmental information
       runCommand  "Environment variables"                   "/usr/bin/env"
    
       #Network information
       collectFile "DNS resolution configuration file"       "/etc/resolv.conf"
       collectFile "Name service switch configuration file"  "/etc/nsswitch.conf"
       collectFile "Static table lookup file"                "/etc/hosts"
       collectFile "TCP/IP services file"                    "/etc/services"
       runCommand  "Interface information"                   "ifconfig -a"
       runCommand  "Interface information (no DNS)"          "/bin/netstat -i -n"
       runCommand  "Socket information"                      "/bin/netstat -an"
       runCommand  "Extended socket information"             "/bin/netstat -avn"
       runCommand  "Socket owner information"                "/bin/netstat -p"
       runCommand  "Network routing table"                   "/bin/netstat -rn"
       runCommand  "Network statistics"                      "/bin/netstat -s"
       runCommand  "Extended routing information"            "/bin/netstat -rvn"
       ## the grep commands below look odd but it is a simple trick to get the contents of 
       ## everything under specific directories
       runCommand  "Network information from /proc" "/usr/bin/find /proc/net -type f -exec /bin/grep -Hv '^$' {} "
       runCommand  "System information from /proc" "/usr/bin/find /proc/sys -type f -exec /bin/grep -Hv '^$' {} "
       runCommand  "SYSV IPC info from /proc" '/usr/bin/find /proc/sysvipc -type f -exec /bin/grep -Hv ^$ {} ;'
    
       #File system information
       runCommand  "Type information"                        "/bin/df -lT"
       runCommand  "Usage information"                       "/bin/df -lk"
       runCommand  "Inode information"                       "/bin/df -li"
       runCommand  "Share information"                       "/usr/sbin/showmount -e"
       runCommand  "SCSI and IDE disk partition tables"      "/sbin/fdisk -l /dev/sd* /dev/hd*"
       runCommand  "NFS statistic"                           "/usr/sbin/nfsstat -cnrs"
       collectFile "Filesystems supported by the kernel"     "/proc/filesystems"
       collectFile "Export file"                             "/etc/exports"
       collectFile "Mount file"                              "/etc/fstab"
       collectFile "Partition information"                   "/proc/partitions"
    
       #Kernel information
       runCommand "User (resource) limits"                  "ulimit -a"
       runCommand "IPC information"                         "/usr/bin/ipcs -a"
       runCommand "Loaded module info"                      "/sbin/lsmod"
       runCommand "IPC resource limits"                     "/usr/bin/ipcs -l"
       runCommand "Kernel information"                      "/sbin/sysctl -a"
       runCommand "Memory usage"                            "/usr/bin/free"
       runCommand "Uptime"                                  "/usr/bin/uptime"
       runCommand "System name, etc"                        "/bin/uname -a"
       runCommand "Current users"                           "/usr/bin/w"
       runCommand "Process listing"                         "/bin/ps auwx"
       runCommand "Recent users"                            "/usr/bin/last|/usr/bin/head -100"
       runCommand "Contents of home directory"              "/bin/ls -lda $HOME"
       runCommand "Host ID"                                 "/usr/bin/hostid"
       collectFile "Kernel limits specified by the user"    "/etc/sysctl.conf"
       collectFile "Load average"                           "/proc/loadavg"
       collectFile "I/O memory map"                         "/proc/iomap"
       collectFile "I/O port regions"                       "/proc/ioports"
       collectFile "Interrupts per each IRQ"                "/proc/interupts"
       collectFile "CPU status"                             "/proc/cpuinfo"
       collectFile "Memory usage"                           "/proc/meminfo"
       collectFile "Swap partition information"             "/proc/swaps"
       collectFile "Slab information"                       "/proc/slabinfo"
       collectFile "Lock information"                       "/proc/locks"
       collectFile "Module information"                     "/proc/modules"
       collectFile "Version information"                    "/proc/version"
       collectFile "System status information"              "/proc/stat"
       collectFile "PCI information"                        "/proc/pci"
    
       #Version information
       runCommand "Package information"                     "/bin/rpm -qa"
    
       #Misc
       collectFile "Main syslog file"                       "/var/log/messages"
       collectFile "Syslog configuration file"              "/etc/syslog.conf"
    
    
    }
    
    function doThoroughCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                                Thorough Collect                            ##" >> $invlog
       echo "################################################################################" >> $invlog
       
       runCommand "Virtual memory statistics"                  "/usr/bin/vmstat 2 5"
       runCommand "I/O statistics"                             "/usr/bin/iostat 2 5"
       runCommand "Extended I/O statistics"                    "/usr/bin/iostat -x 2 5"
       runCommand "CPU statistics"                             "/usr/bin/mpstat -P ALL 2 5"
       runCommand "System activity"                            "/usr/bin/sar -A 2 5"
    
    }
    
    function doPerfCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                                Performance Collect                         ##" >> $invlog
       echo "################################################################################" >> $invlog
    
       # Add specific commands here
    
    }
    
    function doHangCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                              Hang Collect                                  ##" >> $invlog
       echo "################################################################################" >> $invlog
    
       # NOTE: $pid contains the process ID of the process that is hanging
    
       ## check whether the process actually exists
       kill -0 $pid 2>/dev/null 1>/dev/null
       if [ ! $? -eq 0 ]
       then
          echo "Process ID \"$pid\" not found."
          exit 3
       fi 
    
       # Add specific commands here
    
    }
    
    function doErrorCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                                Error Collect                               ##" >> $invlog
       echo "################################################################################" >> $invlog
    
       # NOTE: $cmd contains the name of the command line that apparently produces an error
    
       # Add specific commands here
    }
    
    function doTrapCollect
    {
       echo >> $invlog
       echo "################################################################################" >> $invlog
       echo "##                                Trap Collect                                ##" >> $invlog
       echo "################################################################################" >> $invlog
    
       # Add specific commands here
    }
    
    ################################## MAIN SCRIPT BODY ######################################
    
    ## Do the basics first, then anything else that might be needed
    ##
    doQuickCollect 
    
    if [ $mode_thorough -eq 1 ]
    then
       echo "Collecting thorough information"
       doThoroughCollect
    fi
    
    if [ $mode_perf -eq 1 ]
    then
       echo "Collecting perf information"
       doPerfCollect
    fi
    
    if [ $mode_hang -eq 1 ]
    then
       echo "Collecting hang information"
       doHangCollect
    fi
    
    if [ $mode_trap -eq 1 ]
    then
       echo "Collecting trap information"
       doTrapCollect
    fi
    
    if [ $mode_error -eq 1 ]
    then
       echo "Collecting error information"
       doErrorCollect
    fi
    
    echo >> $invlog
    echo "################################################################################" >> $invlog
    echo "##         End of Data Collection (the rest is for user investigation)        ##" >> $invlog
    echo "################################################################################" >> $invlog
    



    [수정]

    리눅스 문제 분석과 해결 | 답장: 1개 | 본문에 답장
    정렬 :  

    답장 쓰기
    글을 올리시려면 로그인 (사용자 등록) 하셔야 합니다.

    검색
    Google

    분류
    ·공지 (6)
    ·인터넷 (87)
    ·하드웨어 (260)
    ·C/C++ (65)
    ·어셈블리 (7)
    ·리눅스 (136)
    ·리눅스 커널 (67)
    ·윈도우즈 (25)
    ·데이터베이스 (20)
    ·보안 (16)
    ·.NET (25)
    ·그래픽 (13)
    ·책소개 (42)
    ·호기심 천국 (80)
    ·잡담 (111)
    ·사랑 (3)

    전체 본문수: 963
    전체 답장수: 525


    분류 : 책소개
    최근글
    최근글
    가장 많이 읽은 글
    ·STL 튜토리얼 및 레퍼런스 가이드 (제2판) (6)
    뜨거운 감자
    ·STL 튜토리얼 및 레퍼런스 가이드 (제2판) (6)

    EzDoum투표
    이지도움 어때요?
    이게 뭐야. 다시 안올란다. --;
    아이 좋아라~ +_+;
    관심없다.
    먼가는 있는거 같은데 뭐하는 곳이지?
    기타 (자유게시판에 글로 남겨 주세요)
    [ 결과 | 투표 ]

    랜덤 링크
    http://kldp.net


     Home ^ BACK TO TOP ^ EzDoum - 도움이 필요하세요~??
     Powered by KorWeblog 1.5.8 Copyleft © 2001 EzDoum, 관리자: EzDoum