Life/Society

I am not scared. I just wish I had more time...

I am not scared. I just wish I had more time. To show mommy and daddy how much I love them.

- "Who is the most interesting person you've ever sat next to on an airplane?" 질문의 최고의 답변 중에서...

저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Practice/Emacs

CentOS 7 emacs-25.1 64bits RPM

GUI 환경에서 GNU Emacs


터미널 환경에서 GNU Emacs


2015/06/01 - [Practice/Emacs] - CentOS 5 emacs-24.5 64bits RPM

2015/05/28 - [Practice/Emacs] - CentOS 6 emacs-24.5 64bits RPM

  1. <pre class="brush: plain">cat emacs-common-25.1-3.el7.centos.x86_64.rpm-a* &gt; emacs-common-25.1-3.el7.centos.x86_64.rpm</pre> [본문으로]
저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
Practice/C & C++

C언어에서 struct 정의 그대로 이진 데이터로 만들기

C의 struct를 이진 데이터로 저장하고 불러오는데 원하는대로 되지 않을 때가 있다.
예를 들어, 2 바이트 이후에 적혀야 하는데 4바이트 뒤에 위치하는 경우이다.


예상한 이진 데이터의 구조:


실제 이진 데이터의 구조 (목표 머신-target machine-을 64 bits로 컴파일한 경우):


이는 데이터 구조체 정렬(data structure alignment) 때문에 발생한다.
데이타 구조체 정렬이란 해당 머신의 읽고 쓰는 단위 크기의 배수로 데이타를 할당하는 것을 말한다.
데이터가 이 배수값보다 작으면 데이터 구조체 패딩(data structure padding)을 해준다.


현대의 컴퓨터는 성능을 높이기 위해서 이런 방식을 기본으로 사용한다.
따라서, 프로그래머가 정확한 이진 데이터를 생성하려면 이 기능을 꺼야 한다.


GCC에서는 __attribute__((packed)) 키워드를 사용하여 가장 작은 데이타를 만든다.
즉, padding이 들어가지 않도록 한다.

typedef struct __attribute__((__packed__)) seg_info_s {
    uint64_t stt;
    uint32_t seq;
    uint64_t dur;
    uint8_t  flags;
    uint64_t offset;
    uint32_t size;
    uint8_t  key_id[16];
    char     path[PATH_MAX+1];
} seg_info_t;


Visual C에서는 #pragma pack(1) 지시어를 사용하여 1 바이트 경계에 정렬하도록 명시한다.

#pragma pack(1)

typedef struct seg_info_s {
    uint64_t stt;
    uint32_t seq;
    uint64_t dur;
    uint8_t  flags;
    uint64_t offset;
    uint32_t size;
    uint8_t  key_id[16];
    char     path[PATH_MAX+1];
} seg_info_t;


저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License

'Practice > C & C++' 카테고리의 다른 글

C언어에서 struct 정의 그대로 이진 데이터로 만들기  (0) 2017.01.13
strspn/strcspn  (0) 2013.07.09
Practice/Debugging

교착상태(deadlock)를 프로세스 상태와 디버거를 사용해서 찾아내기

멀티미디어(multimedia) 소스를 입력을 받아서 가공하여 출력하는 프로그램을 개발하고 있었다.
얼마간 동작하다가 아무것도 출력하지 못하는 문제를 일으켰다.
로그를 살펴보니 입력 모듈이 돌아가는 쓰레드(thread)에서 데이타를 읽지 않고 있었다.


무한 루프에 빠져서 기능이 중단되었을 수 있다.
이는 프로세스가 CPU를 과도하게 점유하는지를 살펴보면 알 수 있다.
top 유틸리티로 확인해보니 오히려 CPU 점유율이 정상보다 더 낮았다.


다음으로 교착상태(deadlock)를 의심할 수 있다.
프로세스 상태를 보면 더 의심이 간다.


문제의 상태에 진입한 프로세스를 gdb에 붙여서 상태를 확인했다.

$ gdb -p <PID>

쓰레드 목록을 얻고, 각 쓰레드의 콜스택(call stack)을 살펴봤다.

- 쓰레드 목록 얻기 :

(gdb) info thread

- 쓰레드 이동 하기 :

(gdb) thread <THREAD-ID>

- 콜스택 보기 :

(gdb) bt


문제의 모듈이 속한 쓰레드를 발견하였다.
예상대로 잠그려고 대기중인 상태를 보여주었다.
더불어, 잠금을 획득하고 멈춰있는 다른 쓰레드-이후 잠금 요청을 대기하게 만든 쓰레드-까지 발견했다.


잠금을 획득하고 멈춰있는 쓰레드의 콜스택과 코드를 자세히 분석했다.
잠금을 걸고 네트워크를 통해서 요청을 보낸 후에 응답을 받는 부분에서 멈추었다.


멈춘 싯점에서 로그를 역순을 분석하였다.
문제와 연관된 네트워크 세션의 로그와 관련 코드를 중점적으로 살펴봤다.
네트워크 세션을 잠금을 사용하지 않고 접근하여 오염시키는 코드를 찾았다.
이 코드를 수정하여 문제를 해결하였다.

저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
  1. M/D Reply

    비밀댓글입니다

Practice/Debugging

버젼 관리 시스템을 사용하여 문제를 해결하기

초반에는 문제의 원인을 충분히 넓게 잡아라."에서 중요한 디버깅 기법 하나를 간단하게 언급하고 넘어갔다.

분석의 과정이 없이 추론에 근거하여 새로 추가된 원격 기능과 캐싱 알고리즘만을 의심했다.
코드를 수정해도 상태가 개선되지 않았다.
... 중략 ...
이전 버젼과 차이점을 면밀하게 비교하면서 비로서 문제의 원인을 발견했다.
같은 환경과 같은 기능(즉, 로컬 파일 읽기)에서도 새 버젼에서 동일한 문제가 일어났다.
즉, 새로운 기능이 동작할 때 발생하는 것이 아니란 의미이다.
로깅 시스템을 리펙토링을 했는데, 이와 연관이 깊을 것으로 추정했고 다양한 테스트로 이를 검증했다.

- 2014/07/15 - [Practice/Debugging] - 초반에는 문제의 원인을 충분히 넓게 잡아라.


문제가 되는 변경 이력을 찾는 것이 목표이다.


문제 상황을 재현하면서 범위를 좁혀나간다.
버젼 23에서 재현되었다면, 버젼 22, 버젼 21 로 차차 올라가면서 발생하지 않는 버젼을 찾는다.
버젼 19에서 문제가 나타나지 않았다면, 버젼 19와 20를 비교 분석해본다.


문제를 둘러싼 환경을 잘 분석하면 많은 도움이 된다.
버그가 발생하기 시작한 시기를 조사하면, 문제의 시기를 대략 파악할 수 있다.
장비에 설치된 버젼이 다르다면, 문제가 발생하는 버젼과 아닌 버젼의 범위를 상당히 좁힐 수 있다.


커밋 로그를 잘 작성했다면 이를 최대한 활용한다.
문제가 될만한 변경 이력을 참고하면 원인을 빨리 추측할 수 있다.
원인으로 지목된 커밋 로그의 앞/뒤 버젼에서 문제가 재현되는지 확인한다.[각주:1]


  1. "<a href="http://unipro.tistory.com/156" target="_blank">현상을 분석하여 문제의 원인을 찾아내라</a>"에서 언급했듯이 문제를 재현하여 원인을 확실하게 증명해야 한다. [본문으로]
저작자 표시 변경 금지
신고
크리에이티브 커먼즈 라이선스
Creative Commons License
 [ 1 ]  [ 2 ]  [ 3 ]  [ 4 ]  [ 5 ]  [ 6 ]  [ ··· ]  [ 36 ] 

알림

이 블로그는 구글에서 제공한 크롬에 최적화 되어있고, 네이버에서 제공한 나눔글꼴이 적용되어 있습니다.

카운터

Today : 78
Yesterday : 122
Total : 164,454

티스토리 툴바