ラベル 例解UNIX の投稿を表示しています。 すべての投稿を表示
ラベル 例解UNIX の投稿を表示しています。 すべての投稿を表示

2008年9月22日月曜日

【例解UNIX】低水準入出力 (その3)

一週間ぶりにちょっとだけできる。せめて一週間に二回はやらないとあかんな。
3.18 章末問題。

  • 三つ星はやらない。
  • プロセスの後にやるとした節に関係する問題はやらない。
  • という方針にて。

  • 1. 私家版catをつくる。(約30分)

    • シプサでTuring機械をああだこうだやるなかで、オブジェクトの表現とアルゴリズムとを分離して考えて、なおかつそれを抽象的に解決した上で、プログラミング言語での表現を組み立てる、というのが頭に染み付いてきたきがする。
    • 書いてて気がついたのだが、これがいわゆる、データ構造とアルゴリズムということだよね。。。そうか、そういうことだったのか。
    • だからアルゴリズムの本のなかには、特定のプログラミング言語ではなく自然言語に近い形で書くものがあるんだな。


  • 2. 穴をもつファイルをいろいろつくる。(約30分)

    • あんま、おもしろくなかった。


  • 6. ファイルの操作手順の必要性について。(約5分)

    • open/closeが存在しない場合、read/writeなどがそれらを内包することになる。それは毎回read/writeするたびにopenとcloseをするか、read/writeにそのopen/close処理の指示を与えるかのどちらになる。前者は効率がわるく、後者はopen/closeのロジック記述がread/writeの引数に場所を移しただけなので、得るものがないことにくわえて、OS作成者もアプリ作成者も手間が増える。てな感じではなかろうか。


次回は第四章 標準入出力ライブラリ。

2008年9月14日日曜日

【例解UNIX】低水準入出力 (その2)

こつこつ。今回は「3.10 位置決め:lseek」から。

  • whence: どこから(from where, from what place)
  • システムコール、便利だなぁ。ファイルが自動的に長くなっていってくれたり。やはりOSというのはfacilityであることを実感。やばい、OSの勉強をそろそろ初めないと。

  • 電話帳プログラムで、いちいちmemset(rec, 0, sizeof(rec))というように領域の0初期化を実施しているんだけど、これ、宣言時に、char rec[RECLEN+1] = { 0 }とするだけでいいんじゃないかなぁ。

  • 3.12まで完了。
  • 電話帳プログラム2を演習ですんなり書けたのが嬉しかった。
  • 3.13以降は5章でプロセスをやってからやるとよいということなので、素直に従う。

次回は、3章の章末問題。

2008年9月13日土曜日

【例解UNIX】低水準入出力

虚心坦懐、こつこつ。

  • とりあえず、「3.9 標準入力、標準出力、標準エラー出力」まで終わった。
  • 病みあがりなので、無理しない。

次回は、「3.10 位置決め:lseek」から。

2008年9月6日土曜日

【例解UNIX】Cの復習(2):ポインタ、バイトオーダ、複雑な型 (その4)

こつこつ。2.8 章末問題

  • 1 (5分くらい)

    • 特になし。

  • 2 (20分くらい)

    • 問題文を理解していなくて、単にm * nの領域をとって2次元配列的に使う実装をしてしまった。そこから修正。

  • 3 (180分くらい)

    • うお。OSXにもUbuntuにも、デフォルトではlibmudflapが入ってない。

    • Ubuntuにはパッケージがあるようだ。Ubuntuにする。いれる。 sudo aptitude install libmudflap0。

    • ぬお。Ubuntu上でleak.cをコンパイルしようとするとstdlib.hが無いと言われる。locateしてみるとたしかに無い? stdlib.hってそういうものなんだ。man mallocでヘッダを確認。あり? stdlib.hじゃん。なんで無いの? man stdlib.h しても有益な情報はなし。
    • find / -name "*.h" してみると、Ubuntuにはデフォルトで開発用ヘッダが入っていないような、という感じ。

      /usr/lib/gcc/i486-linux-gnu/4.2/include/decfloat.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/unwind.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/limits.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/linux/a.out.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/pmmintrin.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/emmintrin.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/mm3dnow.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/asm/posix_types.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/varargs.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/iso646.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/mmintrin.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/stdbool.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/float.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/omp.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/mm_malloc.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/xmmintrin.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/stdarg.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/syslimits.h
      /usr/lib/gcc/i486-linux-gnu/4.2/include/stddef.h


    • aptitude search gcc。この結果から、gcc-multilibとかにいるのかなと思って、パッケージ落として中身をみてみた(dpkg-deb --contents )が、いない。

    • Ubuntuのサイトでパッケージの中身検索をしようと思ったが、どこでできるのかわからない。
    • しょうがないのでdebian.orgで検索。
    • 検索結果から、そもそもlibc関係のファイルが足りてないのか、と推察。
    • apptitude search libc6。libc6-devのステイタスが"pi"だ。なんじゃこりゃ? man apptitude。「存在していないけど、インストール予定」とな。誰が予定したか、わけわからん。しかしこれだろう。
    • sudo apptitude install libc6-dev。libc6-devとlinux-libc-devが入った。
    • を、/usr/includeにわんさかできた。
    • stdlib.hが無いとは言われなくなった。

    • "cc1: error: mf-runtime.h: No such file or directory"とおっしゃる。(gcc)
    • たしかにfindしてもいない。
    • ああ、Ubuntu(debian)では、開発者はdevをいれねばならんのか。
    • sudo aptitude -s install libmudflap0-dev。おお、これはgcc-4.1用なのね。
    • sudo aptitude -s install libmudflap0-4.2-dev。ok。
    • sudo aptitude install libmudflap0-4.2-dev。ok。findすると、いるいる。

    • ヘッダが無い、とはいわれなくなったが、__mf*的なメッセージがごちゃごちゃでてコンパイルが失敗する。
    • これは、leak.cでもそうだし、他のソース(メモリ操作を含まない)でもそうだった。単純にライブラリの場所をしらんのかな。
    • gcc -Wall -g leaks -fmudflap -lmudflap。ok。
    • MUDFLAP_OPTIONS="-help" ./a.out。ok。次のヘルプがでる。

      This is a single-threaded thread-unaware GCC "mudflap" memory-checked binary.
      Mudflap is Copyright (C) 2002-2004 Free Software Foundation, Inc.

      The mudflap code can be controlled by an environment variable:

      $ export MUDFLAP_OPTIONS=''
      $

      where is a space-separated list of
      any of the following options. Use `-no-OPTION' to disable options.

      -mode-nop mudflaps do nothing
      -mode-populate mudflaps populate object tree
      -mode-check mudflaps check for memory violations [active]
      -mode-violate mudflaps always cause violations (diagnostic)
      -viol-nop violations do not change program execution [active]
      -viol-abort violations cause a call to abort()
      -viol-segv violations are promoted to SIGSEGV signals
      -viol-gdb violations fork a gdb process attached to current program
      -trace-calls trace calls to mudflap runtime library
      -verbose-trace trace internal events within mudflap runtime library
      -collect-stats collect statistics on mudflap's operation
      -sigusr1-report print report upon SIGUSR1
      -internal-checking perform more expensive internal checking
      -print-leaks print any memory leaks at program shutdown
      -check-initialization detect uninitialized object reads
      -verbose-violations print verbose messages when memory violations occur [active]
      -abbreviate abbreviate repetitive listings [active]
      -timestamps track object lifetime timestamps [active]
      -ignore-reads ignore read accesses - assume okay
      -wipe-stack wipe stack objects at unwind
      -wipe-heap wipe heap objects at free
      -heur-proc-map support /proc/self/map heuristics
      -heur-stack-bound enable a simple upper stack bound heuristic
      -heur-start-end support _start.._end heuristics
      -heur-stdlib register standard library data (argv, errno, stdin, ...) [active]
      -free-queue-length=N queue N deferred free() calls before performing them [4]
      -persistent-count=N keep a history of N unregistered regions [100]
      -crumple-zone=N surround allocations with crumple zones of N bytes [32]
      -lc-adapt=N adapt mask/shift parameters after N cache misses [1000003]
      -backtrace=N keep an N-level stack trace of each call context [4]

    • しかし、leak.cは何もいってくれない。
    • dangling.cはいってくれる。

      *******
      mudflap violation 1 (check/write): time=1220683685.027955 ptr=0x80cac98 size=4
      pc=0xb7efb7bd location=`dangling.c:9 (main)'
      /usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7efb7bd]
      ./a.out(main+0x9a) [0x80487be]
      /usr/lib/libmudflap.so.0(__wrap_main+0x49) [0xb7efb259]
      Nearby object 1: checked region begins 4729B after and ends 4732B after
      mudflap object 0x80ca028: name=`__mf_lookup_cache'
      bounds=[0x8049a20,0x80c9a1f] size=524288 area=no-access check=0r/0w liveness=0
      alloc time=1220683685.024966 pc=0xb7efb1fd
      Nearby object 2: checked region begins 0B into and ends 3B into
      mudflap dead object 0x80cace0: name=`malloc region'
      bounds=[0x80cac98,0x80cac9b] size=4 area=heap check=0r/0w liveness=0
      alloc time=1220683685.025568 pc=0xb7efb1fd
      /usr/lib/libmudflap.so.0(__mf_register+0x3d) [0xb7efb1fd]
      /usr/lib/libmudflap.so.0(__wrap_malloc+0xde) [0xb7efc72e]
      ./a.out(main+0x2c) [0x8048750]
      /usr/lib/libmudflap.so.0(__wrap_main+0x49) [0xb7efb259]
      dealloc time=1220683685.027660 pc=0xb7efb1a6
      /usr/lib/libmudflap.so.0(__mf_unregister+0x36) [0xb7efb1a6]
      /usr/lib/libmudflap.so.0(__real_free+0x88) [0xb7efbff8]
      ./a.out(main+0x3a) [0x804875e]
      /usr/lib/libmudflap.so.0(__wrap_main+0x49) [0xb7efb259]
      number of nearby objects: 2

    • overrun.cもいってくれるな。
    • うむ。3時間もつかってしまった。でも勉強になった。

  • 4

    • これは三つ星なので、パス!


Cの復習はこれでおわり。
次回は、ついに本論開始。「低水準入出力」

2008年9月3日水曜日

【例解UNIX】Cの復習(2):ポインタ、バイトオーダ、複雑な型 (その2)

こつこつ。バイトオーダから。

  • リトルエンディアン:x86, MIPS
  • ビッグエンディアン:SPARC, MIPS
  • 「改行と文字コードの問題を除けば、テキストデータはとても移植性の高いデータ表現です」

  • 続いてtypedef。
  • Cには4つのタグ名がある。

    • goto文のラベル名
    • タグ名 (構造体、共用体、enum)
    • メンバ名
    • その他(変数名、関数名、型定義名)
    • 列挙定数名

  • う、5つに見えるのだが。
  • typedefの例。

    • typedef struct list list
    • listがstruct list。これは違和感なし。
    • typedef int Array[10]
    • Arrayがint [10]。違和感あり。
    • typedef int (*Func)(int)
    • Funcがint (*) (int)。違和感おおきい。

  • Array hogeがint hoge[10]ということだから、関数型マクロみたいなものと思っておくか。


  • そうか、システムデータ型の確認にはgdbが便利だ。

  • うぉー、Cの型宣言、難しすぎ。
  • int (*(*foo[])())[];
  • int の配列へのポインタを返す関数へのポインタの配列。(笑った)



    • int (*(*foo[])())[];

      分解しながら。

      int hoge; hogeはint。
      int hoge[]; hogeはintの配列。
      int (hoge)[];
      int (*hoge)[]; hogeはintの配列のポインタ。
      int (*hoge())[]; hogeはintの配列のポインタを返す関数。
      int (*(*hoge)())[]; hogeはintの配列のポインタを返す関数のポインタ。
      int (*(*hoge[])())[]; hogeはintの配列のポインタを返す関数のポインタの配列。

    • おお。一応読めた。
    • signalのプロトタイプを読む。

      void (*signal (int sig, void (*handler)(int)))(int);

      最左の識別子のみが重要。ここから考える。
      void ( *signal (int sig, void (*handler) (int) ) ) (int);

      *signal()を間違えないように *(signal())とする。
      void ( *(signal (int sig, void (*handler) (int) ) ) ) (int);

      読む。
      void hoge; hogeはvoid。
      void hoge (int); hogeはvoidを返す関数(引数はint)。
      void (*hoge) (int); hogeはvoidを返す関数(引数はint)へのポインタ。
      void (*(hoge (piyo)) (int); hogeはvoidを返す関数(引数はint)へのポインタを返す関数(引数piyo)。
      void (*(hoge (int sig, void (*handler)(int))) (int); hogeはvoidを返す関数(引数はint)へのポインタを返す関数(引数は、intと、voidを返す関数(引数int)へのポインタ)。
      こんな感じじゃろう。


  • 演習問題2.13

    • int *x1(); intへのポインタを返す関数。
    • int (*x2)(); intを返す関数へのポインタ。
    • int *(x3()); intへのポインタを返す関数。
    • int (*x4()); intへのポインタを返す関数。

  • お、読めた。
  • 関数の型もgdbのptypeでわかるのね。それぞれ、

    • int *()
    • Int (*)()

  • 演習問題2.14

    • int *x5[]; intへのポインタの配列
    • int (*x6)[]; intの配列へのポインタ
    • int *(x7[]); intへのポインタの配列
    • int (*x8[]); intへのポインタの配列

  • gdb.

    • int *[1]
    • int (*)[0]

  • う、1とか0がなぜいるのかわからない。

最後、ぐだぐだになったが、ビット演算まで終わった。
次回は可変長引数から。

2008年9月2日火曜日

【例解UNIX】Cの復習(2):ポインタ、バイトオーダ、複雑な型

こつこつ。

  • 「よくあるポインタの間違い」 はい。こういう風によく間違えてました。。。

次回は、「2.2 バイトオーダ」から

2008年9月1日月曜日

【例解UNIX】Cの復習(1):マニュアルの読み方、エラー処理、構造体、共用体 (その2)

こつこつ。章末問題開始。

  • 問題 1 (10分くらい)

    • うーん。大きな違いはない。SUSv3の方が長いといえば長い。


  • 問題 2 (10分くらい)

    • うわ、あっさり出きたけど。ポインタについて理解があやふやでgccに注意されまくりなのを直してなんとかなっている現状。まずい。
    • とりあえず、この本を読み進める中で経験値が増して解決されることを期待する。
    • それで駄目ならポインタの復習を柴田さんの本でやることにする。


  • 問題 3 (3分くらい)

    • バイトアライメント自体は固定であり、同じコンパイラ設定でコンパイルされたバイナリだけで動くなら問題ないと思うのですが。


  • 問題4 (40分くらい)

    • 探索を考えなくてよいようなので、結構シンプルだった。


双方向循環リストが課題に出てきたので、今までやってきた道筋というか準備してきたことがそんなに的外れではないように感じた。少しうれしかった。

次回は「Cの復習(2):ポインタ、バイトオーダ、複雑な型」。難易度二つ星なので、ちょっと緊張。

2008年8月31日日曜日

【例解UNIX】Cの復習(1):マニュアルの読み方、エラー処理、構造体、共用体

さあ、こつこつ。

  • この本は、POSIX準拠であり、記載ソースはLinuxとOSXにて動作確認したようだ。とりあえずOSX上で実習していくことにする。困ることがあったらUbuntuに変更することにする。
  • と、初めた途端に、nmによって表示される内容が本とOSXとでは違いすぎる。やはり本はLinuxが基本なのだ。そこで、UbuntuとOSXを併用して適宜使いわけることにする。

  • そうか、多値的なことを、Cでは(UNIXでは)外部変数というかグローバル変数に設定して実現するのか。(errno, perror)
  • この本は、関数をrmdir ("hoge")というように"("の前に空白を入れる習慣みたい。

  • う、演習1.8、shell上ではBus errorになるケースがあるのだが、同じケースについてGDBではBus errorにならない。。。こういうこともあるのだな。。。
  • 「Cのプログラムはあたかもexit(main(argc, argv))が実行されたかのように起動される」そうだったのか。
  • cf. : confer | 比較せよ、参照せよ。

うむ。やっぱりC言語自体を学ぶのと、とある環境におけるC言語の利用を学ぶのは、ずいぶん違う。しかしそこそこC言語を訓練してきたので、なんとか対応はできていると思う。しかしプログラミングの訓練にはえらい時間がかかる。やはりどこか学校に行ったほうがいいかもしれない。。。

次回は章末問題。