'Programming'에 해당되는 글 58건

  1. 2010.09.08 gdb에서 core dump 디버깅 2
  2. 2010.08.18 gdb 에서 thread 생성/종료 메세지 안나오게 하기 2
  3. 2010.08.16 간단한 디버그 함수
  4. 2010.07.30 외부 Thread에서 GTK 위젯 제어할시 동기화 문제 해결 5
  5. 2010.06.24 오늘도 실수.. iconv

gdb에서 core dump 디버깅

일단 dump파일을 쓸수 있는 환경 인지 조사해 본다

ulimit -c

만약 "0"라면 크기를 늘립시다..... 한.. 100000? 뭐 값은 알아서.....ㅋ

아마.. 따로 설정하지 않는이상 어지간한 배포판에서는 "0"로 설정되어 있을겁니다....

(특정배포판에 따라서.... 이 값이 고정되어 있을수도 있으므로 주의하자. 특히 레뎃, 페도라는......)

ulimit -c 100000

자..... 이젠 세그멘테이션 폴트를 일으키면 덤프파일을 내뱉게 됩니다 >_<

그담엔 gcc에서 실행하는 방법...

순서대로 적어야된다는.....  안그럼 에러(?) 뜬다는.....

gcc <exec_filename> <dump_filename>

그름 인제 다음과 같이 심볼 읽어들은 다음에, 틀린부분을 뱉어줍니다.

ps; 여러분! gcc컴파일할때 디버그 정보를 보려면 '-g' 옵션을 붙이는것은 다 아시죠? (네에~)

Reading symbols from /usr/lib/libpng14.so.14...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libpng14.so.14
......
Reading symbols from /usr/lib/libXdmcp.so.6...(no debugging symbols found)...done.
Loaded symbols for /usr/lib/libXdmcp.so.6
Core was generated by `./qq'.
Program terminated with signal 11, Segmentation fault.
#0  main (argc=1, argv=0xbfdae444) at /tmp/qq.c:26
26          *a= 3;

이리 쉬운걸 몰라쓰까여......  분명

"세그멘테이션 폴트 일어나면 덤프파일을 만든다" 까지는 알고 있었는데....

(어연 옛날? 학교 유닉스 서버에서는 분명이 덤프파일이 떳었던걸로 기억하는지라 그때부터 알았는데..... )

왜 눅스에서는 덤프파일은 안나오지... 이상하다.. 라고 "생각" 만 했었거든요 -_-....

(분명히 설정값 건드리면 나올거라고 생각은 했는데)

왜 GDB랑 생각을 안했는지 미스테리...

ulimit 명령어가 있었다는것도 지금 알았네요.... GDB는 초보라능.....

- 지금 프로그램 띠워나서... 세그폴트날때까지 기대리고 있는데... 안죽네여 아놔.. 아깐 그렇게 잘 죽더니만

gdb 에서 thread 생성/종료 메세지 안나오게 하기

GDB랑 멀티스레드랑 같이 사용하면 스레드 관련 메세지가 나온다

문제는 스레드가 매우자주 (뭐 1초라던가) 생겼다 없어지는 프로그램이라면...

화면에  아래와 같은 문자가 계속나와서 ...... 기존의 디버그 메세지조차 다 없애 버린다는거.....

......
[New Thread 0xb52ceb70 (LWP 30665)]
[Thread 0xb52ceb70 (LWP 30665) exited]
[New Thread 0xb52ceb70 (LWP 30666)]
[Thread 0xb52ceb70 (LWP 30666) exited]
[New Thread 0xb52ceb70 (LWP 30667)]
[Thread 0xb52ceb70 (LWP 30667) exited]
[New Thread 0xb52ceb70 (LWP 30668)]
[Thread 0xb52ceb70 (LWP 30668) exited]
[New Thread 0xb52ceb70 (LWP 30669)]
[Thread 0xb52ceb70 (LWP 30669) exited]
[New Thread 0xb52ceb70 (LWP 30670)]
[Thread 0xb52ceb70 (LWP 30670) exited]
[New Thread 0xb52ceb70 (LWP 30671)]
......
^C
Program received signal SIGINT, Interrupt.
0xb7fe1424 in __kernel_vsyscall ()
(gdb)

이것도 찾아보면 금방나오네여...

(사실 저번에도 찾았는데... 그렇게 안찾이던게(?) 오늘은 한방에 찾아지네여 신기해라...

대체 저번엔 구글에서 무슨 키워드로 검색했길래 못 찾았지 ㅠㅠ)

뭐 어떤애들은 GDB소스를 뜯어고쳐서 해결하라는 -_- 애들도 있긴하던데...

이건 좀 무리... 무리...... 수정후 리컴파일은 복잡하자나.......

그래서 다음과 같은 방법을 찾음..

역시 길은 있다는.. 못찾을 뿐이지...

$gdb ./program
Reading symbols from /home/lowid/program ...done
(gdb) set print thread-events off
(gdb) run

이제 스레드 생성/종료 이벤트 알림 메세지가 더이상 나오지 않습니다 만세!

--------------------------------------------------------------------------------------------------

GDB에서 Thread 디버깅할때 ...... 더 자세한 내용은 역시 메뉴얼 페이지를 읽어보는것이 제일 낫다..

관심있다면 한번 읽어보세요

http://sourceware.org/gdb/current/onlinedocs/gdb/Threads.html

간단한 디버그 함수

간단히 디버그를 하기위해 사용하는 함수

맨날 생각은 했는데 귀찮아서 안만들다가 시간 나는대로 만드러봐써여.

가변인자랑, C언어 내장 매크로 (정확히 하면 __FUNCTION__은 아니지만)를 사용하여 만듬.

사실 저 매크로는 많이쓰니깐 익숙한데... 가변인자는 오랜만에 보니깐 몇줄은 안되지만.... 또 새롭네 (......)

버퍼크기랑, 스레드 문제만 조금 손보면 어느정도 사용가능할듯 합니다만.....

소스>
#define     DEBUG_MSG(printf_format, args...) DebugMessage(__FILE__, __FUNCTION__, __LINE__, __TIME__, printf_format, ##args)
#define     DEBUG_MAX_BUFFER_SIZE     5000

void DebugMessage (const char *source_filename, const char *function, const int line, const char *time, const char *format, ...)
{
    char buffer[DEBUG_MAX_BUFFER_SIZE];
    va_list arg_list;
    int read_len;

    va_start(arg_list, format);
    read_len  = vsnprintf(buffer, DEBUG_MAX_BUFFER_SIZE, format, arg_list);
       
    printf("[%s] - {%s}(%s:%d)\n%s\n", time, source_filename, function, line, buffer);

   // 필요에 따라서, 로그를 파일로 기록함. (알아서 만드셈 -_-)
    File_Write(DEBUG_LOGFILE_PATH, buffer, read_len);

    va_end(arg_list);
}       /* -----  end of function DebugMessage  ----- */

사용>
DEBUG_MSG("play file path: %s\n", music_data->filepath);

결과 예시>
[15:55:42] - {mpd_check.c}(mpd_check_data_init:197)
play file path: /data/mp3/rock-kor/레이지본/레이지본 2집/03 DO IT YOURSELF.mp3

아 그리고 ## 매크로에 대해서 추가작성.......

"##" 매크로는....... 그러니까

"아규먼트로 넘어온 것을 string으로 그대로 컴파일러에서 사용한다" 정도로 생각하면 될것 같다

"args..." 로 넘어온 문자열 (("%s", a1, a2) 같은 -)을 그대로 사용한다 라고 보면 될듯.

몰라... 귀찮아,... 설명이 제대로 안되 ㅠㅠ 자세한건...패스하져..

음...매크로에 관심있으면 다음글도 한번 읽어보세요... 잘 써놓으신듯.

http://www.jiniya.net/tt/528

ps1: VS6에서는 기본적으로 __FUNCTION__ 이 지원되지 않습니다

ps2: VS6에서는 가변인자 메크로가 먹히지 않습니다(??),
그나마 2003부터인가는 사용이 가능하다고 하는데... 그것도 소스 수정을 좀 해야합니다.
직접해보지는 않았습니다만, 다음과 같이 하면 된다네요.

#define     DEBUG_MSG(printf_format, ...) DebugMessage(__FILE__, __FUNCTION__, __LINE__, __TIME__, printf_format, __VA_ARGS__)
// 2010, 9 15 내용 추가


ps2: Windows환경이면.....  GetLastError()함수도 뒤에 넣어서 사용해도 되겠져...

'Programming > C' 카테고리의 다른 글

포인터 연습  (6) 2011.05.27
오늘도 실수.. iconv  (0) 2010.06.24
아아 또 실수~!  (4) 2009.06.22
주의력 부족  (2) 2009.06.22
이진트리를 만들고나서....아 망했어요...  (2) 2009.05.25

외부 Thread에서 GTK 위젯 제어할시 동기화 문제 해결

내가 만드는 삽질 프로그램이 하나 있는데...

얘가 원래 터미널용 프로그램이라서.. 좀 뽀대나게 겉모습을 "Music Player"같이 변모시켜보고자

Front End를 좀 만들기로 했었다.

근데 하나의 프로세스에다가

"(터미널때) 원래 실행되는 루틴 + Gui Event 콜백(Gtk 므로  gtk_main(); )을 넣다보니......

원래 진행되어야 하는 부분이 gtk_main() 때문에 수행이 되지 않으므로.......

할수 없이 pthread를 사용해서 그 두 부분을 분리하기로 했다

(난 개인적으로 스레드 정말 싫어해서... 터미널용 프로그램에서도 다행히(?)도 스레드 사용을 안했

아 하나 했었다... timer 관련해서 0.01초마다 카운터 올리는 콜백(?)함수를 사용했지...

사실 이부분도 더 신경써서 고쳐야되는데 아직도 방치중이다 아아...)

              main();
                           |
                   pthread_create();
                           |
            ------------------------------
           |                                            |
terminal_program                       create_gtk_widgets
          |                                             |
          |                                      gtk_main();
    emit gtk signal ---------------------|     
거지같아서 그림으로 대체

DIA로 열심히 그렸는데... 일헌 그림이 짤려버렸군여..

사용자 삽입 이미지

확실히 텍스트로 찍찍 그어서 만든 조합보단 훨씬 멋있다!

처음엔 신경쓰다가 결국엔 대충 그렸으니깐 "저거 이상해여" 테클걸진 말아달라는,.

코드는 기껏해야 몇천줄인데 저렇게 보니깐 엄청 뭔가 한것같이 느껴지네...ㅋ 그림의 위엄 ㅋ

처음에 분기하는 부분은 pthreaad로 내가 직접 생성한거구

Terminal Thread를 나눈건.. 내가 직접 나눈것이 아니라, Timer라이브러리에서 Thread를 나누는것.

(이 부분은 별 신경 안썼다... )

내가 원하는건 왼쪽 (MPD Event Callback이랑 Timer Callback)에서 Gtk한테

"라벨 위젯 글자좀 바꿔주셈" 이라고 요청한것...

근데 그냥 이렇게 하면.. 몇십초 동안 프로그램이 잘 동작하다가 갑자기 죽어버리거나,

갱신이 안되고 계속 멍때리고 있는 문제가 발생한다..... (

처음엔 내가 만들었던 소스코드가 문제가 있나싶어서 열심히 뒤졌지만... 그래도 안나오는거짐..

gdb로 디버깅해도 이상한데서 죽어버리거나, 프로그램은 잘 살아 있는데도 글자갱신이 안되는

문제가 그대로 발생했었다..

이게 뭔가... 분명 GUI 씌우기 전에는 제대로 동작을 했었는데.. 씌우고 나서 안되니..

음.... 그러다가 갑자기 thread에 feel이 와서 구글을 찾아보니 왠걸..

http://library.gnome.org/devel/gdk/stable/gdk-Threads.html

역시 매뉴얼을 잘 읽어봐야 한다 -_-.......................

Gtk랑 pthread랑 같이 사용한다면..

gdk_threads_enter();

GTK_SourceCode;

gdk_threads_leave();

왜 같이 사용해야한다...

즉 다른 thread에서 GTK 사용할때는 gdk내부에 크리티컬섹션을 만들어 줘야 함

(외부 thread에서 gtk 함수 콜하는 모든 부분을 저렇게 보호)

근데 원인이 뭘까?

위젯값들은 전역에 static으로 선언 해서 위젯 포인터 받은이후는 바뀔일은 없을텐데...

gdk 이벤트 관련해서 문제가 생기나....

으아아아아...

핀트는 좀 다르지만.
3년전에 내 블로그에 이 내용 썼구나...

바보 인증 ㅠㅠ
http://lowid.tistory.com/entry/gtk-Thread

다음 부터는 내 블로그 먼저 검색해봐야 겠다.......

7월 18일 "제목" 작성, 7월 31일 발행

오늘도 실수.. iconv

문자열을 변환하는데.. "춏" 이런 글자가 나오면 문제가 생기길래..

로케일 문자에러가 생긴다는 생각은 했는데...

암튼 막 문제가 생기는거 같은 부분을 쭉쭉 타고 역으로 올라가다보니깐 (한시간 더 찾았다 -_-)

perror(); 써서 확인해보니깐
"부적절하거나 불완전한 다중바이트 또는 광역 문자" 라는 메세지가 뜨고.....

그래서 설마 하며 #define한걸 보니

#define LRC_FILE_LOCALE    "EUCKR //IGNORE"         /*  */
#define PRINTED_LOCALE     "UTF8"          /*  */

UTF8 => EUCKR로 변환하는건 옵션을 붙였는데
EUCKR=> UTF8로 변환할때는 옵션을 안붙였네 아놔...

아나 iconv_open 하는 부분의 //IGNORE 가  빠져 있음 ....

//IGNORE  추가....
#define PRINTED_LOCALE     "UTF8 //IGNORE"          /*  */

결국엔

iconv_open("EUCKR //IGNORE", "UTF8 //IGNORE"); // 이런식이 되시겠다.... 맞나 이게...

맨 페이지 아저씨는 이렇게 말씀하셧따.

       //TRANSLIT
              When  the  string  "//TRANSLIT"  is appended to tocode, transliteration is activated.  This means that when a character cannot be represented in the target
              character set, it can be approximated through one or several similarly looking characters.

       //IGNORE
              When the string "//IGNORE" is appended to tocode, characters that cannot be represented in the target character set will be silently discarded.

- 요약하자면... 그냥 로게일 뒤에
"//IGNORE" 써주면 인식 못하는 문자는 무시한다는거구
"//TRANSLIT"는  iconv_open이 비슷한 문자를 알아서 때려넣어(?) 준다는것

오늘의 병신짓 ㅜㅜ.. 이젠 출력되다가 중간에 끊어먹는 버그 해결

에휴 시간 아까워...

'Programming > C' 카테고리의 다른 글

포인터 연습  (6) 2011.05.27
간단한 디버그 함수  (0) 2010.08.16
아아 또 실수~!  (4) 2009.06.22
주의력 부족  (2) 2009.06.22
이진트리를 만들고나서....아 망했어요...  (2) 2009.05.25
prev 1 2 3 4 5 6 ··· 12 next