2015年1月24日土曜日

gentooでglibcをgdbする

gentooならglibcのデバッグも安全快適にできる


いつも周囲から、「なぜ、今時gentooをつかうのか?」とか「yumな時代に、いまどき時間かけてコンパイルってどうなの?」とか色々言われますが、僕は小声でいいたい

Oh、マイ、ガッ!、君はコンパイルしてる意味が分からないの?、、こんなに安全に、ソースから色々なことができるのに、なぜそれが理解できないの?」...外人風に...

といような、前置きを考えるのに何時間も使ってしまうので最近面倒、ブログって大変。
ということで、gentooなら簡単に?glibcのデバッグが出きることを紹介します。



意外と自分のプログラムはデバッグするけど共有ライブラリなんかデバックしないから案外、「そこどうなってんだろ?」って疑問に感じたときにツッコミにくい所だったりしますよね、でもgentooなら出きるんです。

glibcをデバックオプション付きでビルドする


なにせ、熱いglibcをビルドするので、仮想環境などでやった方が良いと思われますので、実機でやる場合は、ご注意ください。
portageのビルドの設定をチョットいじる、ファイル名は何でもいいということです

/etc/portage/env/debug-cflags
CFLAGS="-O2 -ggdb -pipe"
FEATURES="${FEATURES} splitdebug nostrip"
それから以下のファイルに、先ほど書いたファイル名のパッケージ名の次に書く

/etc/portage/package.env
sys-libs/glibc debug-cflags
そしたら、debug付きでglibcをビルドする
karky7 ~ # USE="debug" emerge sys-libs/glibc
これで、デバック情報の追加されたglibcが展開されます

ソースを持ってくる


emergeしたglibcのソースコードを持ってくる、コードを持ってきてパッチまで当ててくれる
karky7 ~ # ebuild /usr/portage/sys-libs/glibc/glibc-2.17.ebuild unpack
 * glibc-2.17.tar.xz SHA256 SHA512 WHIRLPOOL size ;-) ...                    [ ok ]
 * glibc-2.17-patches-8.tar.bz2 SHA256 SHA512 WHIRLPOOL size ;-) ...         [ ok ]
 * checking ebuild checksums ;-) ...                                         [ ok ]
 * checking auxfile checksums ;-) ...                                        [ ok ]
 * checking miscfile checksums ;-) ...  
...
...
...
そのまま自分のhomeへコピー、そのままでもいいけど消えちゃう場合があるので...
karky7 ~ # mkdir /home/cuomo/src
karky7 ~ # cp -rf /var/tmp/portage/sys-libs/glibc-2.17/work/glibc-2.17/ /home/cuomo/src/
karky7 ~ # chown -R cuomo:cuomo /home/cuomo/src/

.gdbinitファイルへソースファイル情報を追加


gdbが参照できるようにソース情報を作成する
cuomo@karky7 ~/src/glibc-2.17 $ find /home/cuomo/src/glibc-2.17 -type d | xargs -i echo "dir {}" >> ~/.gdbinit
cuomo@karky7 ~/src/glibc-2.17 $ cat ~/.gdbinit | head -n 10
dir /home/cuomo/src/glibc-2.17/posix
dir /home/cuomo/src/glibc-2.17/posix/rxspencer
dir /home/cuomo/src/glibc-2.17/posix/bits
dir /home/cuomo/src/glibc-2.17/posix/sys
dir /home/cuomo/src/glibc-2.17/grp
dir /home/cuomo/src/glibc-2.17/localedata
dir /home/cuomo/src/glibc-2.17/localedata/charmaps
dir /home/cuomo/src/glibc-2.17/localedata/tst-fmon-locales
dir /home/cuomo/src/glibc-2.17/localedata/locales
dir /home/cuomo/src/glibc-2.17/localedata/tests-mbwc
cuomo@localhost ~/src/glibc-2.17 $

サンプルコードで試す


サンプルコード
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
  char *p = NULL;

  p = (char*)malloc(sizeof(char) * 1024);
  if(p) {
    strcpy(p, "OK マロックさんが着ました\n");
    puts(p);
  } else {
    puts("無理っす\n");
  }
  return 0;
}
そしてビルド
cuomo@karky7 ~ $ gcc -g malloc_test.c -o malloc_test

emacsからgdb起動


emacsを起動してから「M-x gdb」でgdbして、breakをmallocに設定する
Current directory is ~/src/
GNU gdb (Gentoo 7.6.2 p1) 7.6.2
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type \"show copying\"
and \"show warranty\" for details.
This GDB was configured as \"x86_64-pc-linux-gnu\".
For bug reporting instructions, please see:
<http://bugs.gentoo.org/>...
Warning: /home/cuomo/src/glibc-2.17/autom4te.cache: \\343\\201\\235\\343\\201...
Reading symbols from /home/cuomo/src/malloc_test...done.
(gdb) l
1   #include <stdio.h>
2   #include <stdlib.h>
3   #include <string.h>
4
5   int main(void)
6   {
7     char *p = NULL;
8
9     p = (char*)malloc(sizeof(char) * 1024);
10    if(p) {
(gdb) b malloc
Breakpoint 1 at 0x400530
(gdb)
で動かすと
(gdb) r
Starting program: /home/cuomo/src/malloc_test
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
(gdb) 
そうするとglibcの中のmalloc関数でブレークする、emacsの別フレームにブレークしたソース箇所が表示さる
...
...
    alloc_last_block = (void *) alloc_ptr;
    alloc_ptr += n;
    return alloc_last_block;
  }

  void * weak_function
  malloc (size_t n)
  {
B =>return __libc_memalign (sizeof (double), n);
  }

  /* We use this function occasionally since the real implementation may
     be optimized when it can assume the memory it returns already is
     set to NUL.  */
  void * weak_function
...
...
と言う感じでmallocで停止してくれる、これは便利、他のパッケージでも同じ、これならいろんなコードを読めて動かせる

gentooって素晴らしい...すいません、チョットふざけ過ぎました。


0 件のコメント:

コメントを投稿