Open Source WEB



2005-09-30 [MySQL] 主キーがなくて重複したレコードを削除し、ALTER TABLEで主キーを追加する

主キーがないテーブルだといくらでも重複できてしまう。

mysql> CREATE TABLE duptest (id INT);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO duptest VALUES (100);
Query OK, 1 row affected (0.01 sec)

mysql> INSERT INTO duptest VALUES (100);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM duptest;
+------+
| id   |
+------+
|  100 |
|  100 |
+------+
2 rows in set (0.00 sec)

こりゃまずいと思って、 ALTER TABLEで主キーを追加しようと思っても、 すでに重複行があるとエラーが発生する。

mysql> ALTER TABLE duptest ADD PRIMARY KEY (id);
ERROR 1062: Duplicate entry '100' for key 1

かといって

DELETE FROM duptest WHERE id=100;

としてしまうと、重複したすべての行が消えてしまう。

こんなときはMySQLの邪悪なオプション、LIMITを使う。

mysql> DELETE FROM duptest WHERE id=100 LIMIT 1;
Query OK, 1 row affected (0.00 sec)

LIMIT 1とすれば1行だけ削除できる。 (ただし、どの行が削除されるかは分からない)

mysql> ALTER TABLE duptest ADD PRIMARY KEY (id);
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

--yasuyuki


2005-09-29 [Linux] 直前に実行したプログラムの終了コード

直前に実行したプログラムの終了コードを知るには,

% echo $?
0

知らんかった...

--nobsun


Name:
Comment:

There is no comment.


2005-09-28 [Emacs] metaキー

メタキーを押しながら x

M-x

の代りに

Esc + x

Esc キーを押してから x というのは知っていたんだけど,

C-[ + x

コントロールキーを押しながら [ キーを押してから,x というのは知らなんだ.

--nobsun


Name:
Comment:
shiro: (Thu Sep 29 03:34:36 2005 )
というか、ESCとC-[はそもそも区別不可能じゃ…


2005-09-27 [FYI] lighttpd

軽量の HTTP デーモン.FastCGIのモジュールなどが含まれている. Webフレームワークのプラットフォームとして使われだしているらしい.

LIGHTTPD fly light

--nobsun


Name:
Comment:

There is no comment.


2005-09-26 [command] プログラムを繰り返し実行する

watch コマンドを使う.たとえば,特定のディレクトリの中身の変化を知りた いなら,

% watch -d ls -l $HOME

などとする.

--nobsun


Name:
Comment:

There is no comment.


2005-09-22 [Gauche] カックロを素朴に解くプログラム

カックロを 単純に解くプログラム

(use srfi-1)
(use srfi-11)
(use util.combinations)


(define kakro-elems (iota 9 1))

(define kakro-size #f)
(define indices #f)

(define (set-kakro-size b)
  (set! kakro-size (list (length (car b)) (length b)))
  (set! indices
        (append-map (lambda (j)
                      (map (lambda (i) (list i j))
                           (iota (cadr kakro-size))))
                    (iota (car kakro-size))))
  'done)

(define (get-elem xs i j)
  (car (drop (car (drop xs j)) i)))

(define (put-elem xs i j x)
  (receive (ls0 ls) (split-at xs j)
    (receive (cs0 cs) (split-at (car ls) i)
      (append ls0 (cons (append cs0 (cons x (cdr cs))) (cdr ls))))))

(define (vacant? x)
  (and (integer? x) (= 0 x)))

(define (vacants b)
  (filter (lambda (ix) (vacant? (get-elem b (car ix) (cadr ix)))) indices))

(define (next-vacant b vs)
  (car (sort (map (lambda (ix) (list ix (candidate b (car ix) (cadr ix)))) vs)
             (lambda (ixs jys) (< (length (cadr ixs)) (length (cadr jys)))))))

(define (candidate b i j)
  (let*-values
      (((hw hgroup) (get-group i (car (drop b j))))
       ((vw vgroup) (get-group j (car (drop (apply zip b) i)))))
    (let* ((hwa (cadr hw))
           (vwa (car vw))
           (hfixeds (filter (lambda (x) (not (vacant? x))) hgroup))
           (vfixeds (filter (lambda (x) (not (vacant? x))) vgroup))
           (hcands (filter (cut include? hfixeds <>)
                           (kakro-calc hwa (length hgroup))))
           (vcands (filter (cut include? vfixeds <>)
                           (kakro-calc vwa (length vgroup))))
           (hcand (lset-difference
                   = (fold (cut lset-union = <> <>) '() hcands) hfixeds))
           (vcand (lset-difference
                   = (fold (cut lset-union = <> <>) '() vcands) vfixeds)))
      (lset-intersection = hcand vcand))))
  
(define (get-group i ks)
  (receive (ss ts) (split-at ks i)
    (receive (us _) (span integer? ts)
      (receive (rs ws) (span integer? (reverse ss))
        (values (car ws) (append (reverse rs) us))))))

(define (include? xs ys)
  (null? (lset-difference = xs ys)))

(define (kakro-calc s n)
  (filter (lambda (xs) (= s (apply + xs))) (combinations kakro-elems n)))

(define (kakro b)
  (let* ((vs (vacants b)))
    (if (null? vs)
        (list b)
        (let* ((ijxs (next-vacant b vs))
               (ij (car ijxs))
               (i (car ij))
               (j (cadr ij))
               (xs (cadr ijxs)))
          (append-map kakro
                      (map (lambda (x) (put-elem b i j x)) xs))))))

ニコリのページ にあるサンプルを解くと

gosh> problem
(
 ((0 0)   (0 0)  (34 0)   (4 0)  (29 0)   (0 0))
 ((0 0)   (6 7)    0       0       0      (0 0))
 ((0 17)   0       0       0       0     (17 0))
 ((0 14)   0       0     (17 16)   0       0   )
 ((0 0)   (0 30)   0       0       0       0   )
 ((0 0)   (0 23)   0       0       0      (0 0))
)
gosh> (set-kakro-size problem)
done
gosh> (kakro problem)
(
 (
  ((0 0)   (0 0)  (34 0)   (4 0)  (29 0)   (0 0))
  ((0 0)   (6 7)    4       1       2      (0 0))
  ((0 17)   1       8       3       5     (17 0))
  ((0 14)   5       9     (17 16)   7       9   )
  ((0 0)   (0 30)   7       9       6       8   )
  ((0 0)   (0 23)   6       8       9      (0 0))
 )
)

--nobsun


Name:
Comment:

There is no comment.


2005-09-21 [Gauche] Sudoku(数独)を素朴に解くプログラムをちょっと改良

Sudoku(数独)を素朴に解くプログラムをちょっ と改良

(define (sudoku-bis b)  ;; ちょい改良
  (let* ((vs (vacants b)))
    (if (null? vs)
        (list b)
        (let* ((ijxs (next-vacant b vs))
               (ij (car ijxs))
               (i (car ij))
               (j (cadr ij))
               (xs (cadr ijxs)))
          (append-map sudoku-bis
                      (map (lambda (x) (put-elem b i j x)) xs))))))

(define (next-vacant b vs) ;; 追加
  (car (sort (map (lambda (ix) (list ix (candidate b (car ix) (cadr ix)))) vs)
             (lambda (ixs jys) (< (length (cadr ixs)) (length (cadr jys)))))))

Wikipedia のページにある問題を解くと

gosh> (use gauche.time)
#<undef>
gosh> (time (sudoku problem))
;(time (sudoku problem))
; real   2.657
; user   2.660
; sys    0.000
(
((5 3 4 6 7 8 9 1 2)
 (6 7 2 1 9 5 3 4 8)
 (1 9 8 3 4 2 5 6 7)
 (8 5 9 7 6 1 4 2 3)
 (4 2 6 8 5 3 7 9 1)
 (7 1 3 9 2 4 8 5 6)
 (9 6 1 5 3 7 2 8 4)
 (2 8 7 4 1 9 6 3 5)
 (3 4 5 2 8 6 1 7 9))
)
gosh> (time (sudoku-bis problem))
;(time (sudoku-bis problem))
; real   0.545
; user   0.550
; sys    0.000
(
((5 3 4 6 7 8 9 1 2)
 (6 7 2 1 9 5 3 4 8)
 (1 9 8 3 4 2 5 6 7)
 (8 5 9 7 6 1 4 2 3)
 (4 2 6 8 5 3 7 9 1)
 (7 1 3 9 2 4 8 5 6)
 (9 6 1 5 3 7 2 8 4)
 (2 8 7 4 1 9 6 3 5)
 (3 4 5 2 8 6 1 7 9))
)

ちょい速くなった. --nobsun


Name:
Comment:

There is no comment.


2005-09-20 [Gauche] Sudoku(数独)を素朴に解くプログラム

Sudokuを単純に解くプログラム (要するにあまり速くないプログラム ^^;)

(use srfi-1)

(define indices
  (append-map (lambda (j) (map (lambda (i) (list i j)) (iota 9))) (iota 9)))

(define (get-elem xs i j)
  (car (drop (car (drop xs j)) i)))

(define (put-elem xs i j x)
  (receive (ls0 ls) (split-at xs j)
    (receive (cs0 cs) (split-at (car ls) i)
      (append ls0 (cons (append cs0 (cons x (cdr cs))) (cdr ls))))))

(define (vacants b)
  (filter (lambda (ix) (= 0 (get-elem b (car ix) (cadr ix)))) indices))
   
(define (candidate b i j)
  (define (col i) (car (drop (apply zip b) i)))
  (define (row j) (car (drop b j)))
  (define (box i j)
    (append-map (cut take <> 3)
                (map (cut drop <> (* (quotient i 3) 3))
                     (take (drop b (* (quotient j 3) 3)) 3))))
  (lset-difference = (iota 9 1) (lset-union = (col i) (row j) (box i j))))

(define (sudoku b)
  (let* ((vs (vacants b)))
    (if (null? vs)
        (list b)
        (let* ((v (car vs))
               (i (car v))
               (j (cadr v)))
          (append-map sudoku
                      (map (lambda (x) (put-elem b i j x)) (candidate b i j)))))))

Wikipedia のページにある問題を解くと

gosh> problem
((5 3 0 0 7 0 0 0 0)
 (6 0 0 1 9 5 0 0 0)
 (0 9 8 0 0 0 0 6 0)
 (8 0 0 0 6 0 0 0 3)
 (4 0 0 8 0 3 0 0 1)
 (7 0 0 0 2 0 0 0 6)
 (0 6 0 0 0 0 2 8 0)
 (0 0 0 4 1 9 0 0 5)
 (0 0 0 0 8 0 0 7 9))
gosh> (sudoku problem)
(
((5 3 4 6 7 8 9 1 2)
 (6 7 2 1 9 5 3 4 8)
 (1 9 8 3 4 2 5 6 7)
 (8 5 9 7 6 1 4 2 3)
 (4 2 6 8 5 3 7 9 1)
 (7 1 3 9 2 4 8 5 6)
 (9 6 1 5 3 7 2 8 4)
 (2 8 7 4 1 9 6 3 5)
 (3 4 5 2 8 6 1 7 9))
)

Name:
Comment:

There is no comment.


2005-09-16 [Gauche] リストのリストを2次元配列としてアクセス(その2)

(i,j)の位置の要素を指定のものに差し替える(副作用なしで).

(define (put-elem xs i j x)
  (receive (ls0 ls) (split-at xs j)
    (receive (cs0 cs) (split-at (car ls) j)
      (append ls0 (cons (append cs0 (cons x (cdr cs))) (cdr ls))))))

--nobsun


Name:
Comment:

There is no comment.


2005-09-15 [Gauche] リストのリストを2次元配列としてアクセス

(i,j)の位置の要素を取り出す

(define (get-elem xs i j)
  (car (drop (car (drop xs j)) i)))

--nobsun


Name:
Comment:

There is no comment.


2005-09-14 [Gauche]別のCGIにリダイレクトする

#!/usr/local/bin/gosh
(use www.cgi)

(define (main args)
  (cgi-main
   (lambda (params)
    `(,(cgi-header :status "302 Moved Temporarily"
       :location
        (string-append
          "http://www.example.com/cgi-bin/hogepiyo.fcgi"
          (or (cgi-get-metavariable "PATH_INFO") "")
          (or (cgi-get-metavariable "QUERI_STRYNG") "")))))))

--yasuyuki


Name:
Comment:

There is no comment.


2005-09-13 [Haskell] 簡易 tail を書く

標準入力からテキストデータを読み込んで,末尾の n 行を表示する簡易 tail コマンドを Haskell で書いてみよう.

#!/usr/local/bin/runhaskell
\begin{code}
module Main (main) where

import System

main :: IO ()
main = do { args <- getArgs
          ; case args of
              []  -> cmdTail 10
              n:_ -> cmdTail (read n)
          }

cmdTail :: Int -> IO ()
cmdTail n 
 = getContents >>= putStr . unlines . starling tailLine (drop n) . lines

starling :: (a -> b -> c) -> (a -> b) -> a -> c
starling f g x = f x (g x)

tailLine :: [String] -> [String] -> [String]
tailLine s [] = s
tailLine s t  = tailLine (tail s) (tail t)
\end{code}

上のコードを tail.lhs という名前で保存して,実行パーミッションを を立てると使えます.

% chmod +x tail.lhs
% ./tail.lhs 5 < tail.lhs

tailLine :: [String] -> [String] -> [String]
tailLine s [] = s
tailLine s t  = tailLine (tail s) (tail t)
\end{code}

肝は tailLine かな.

starling tailLine (drop n)

\ ls -> tailLine ls (drop n ls)

と同じです.starling は Sコンビネータです (SKK=I の S). ちょっと,奇を衒った感じがまた「イイッーーーー」くないですか?

--nobsun


Name:
Comment:

There is no comment.


2005-09-12 [Tips] shebang(#!)

先週末の冗句は,「shebang(#!) ってどうなってるの?」というのを調べていて 思いついたものです.よくあるシェルスクリプトの先頭行の

#!/bin/local/bin/runhaskell

というやつです.えっ.見たことない? じゃぁこれは?

#!/bin/local/bin/gosh

これならどう?これもない?やっぱり,これ?

#!/bin/sh

foo という実行パーミッションを持つファイルの先頭行が

#!/bin/bash

と行頭にあると,コマンドラインから

% ./foo

とやると,

% /bin/bash ./foo

とやるのと同じに解釈されというわけです.

--nobsun


Name:
Comment:

There is no comment.


2005-09-09 [:p] Cインタープリタのソースコード

昨日のCインタープリタのコードをチョット 見てみたいそこの貴方,恐いもの知らずですねぇ.そうですか見たいですか. 見たいよね...

しょうがない,チョットだけよぉ...

#!/usr/local/bin/runhaskell
import System
main = getArgs     >>= \ (a:as) ->
       readFile a  >>= \ cs    ->
       let cfile = a++".c" in
       writeFile cfile (unlines $ tail $ lines cs) >>
       system ("gcc " ++ cfile
              ++ "; ./a.out "++ unwords as 
              ++ "; rm -f a.out " ++ cfile)

あっ.ぶたないでぇ...冗句なんだからぁ...

--nobsun


Name:
Comment:
shiro: (Fri Sep 9 11:17:03 2005 )
gccを裏でこっそり呼び出すこと自体は、ジョークに留まらない、有用なテクニックです。

以前、STkを使ってインタラクティブなパーティクルシミュレーションシステムを作ったことがあるんですが、シミュレーションエンジン本体は速度が必要だったため、ユーザがシミュレーションの式を変更する度に、C++プログラム片を生成して外部コンパイラで.soファイルを作り、それを動的ロードしてエンジンに組み込む、ということをやってました。
cut-sea: (Fri Sep 9 11:39:51 2005 )
文言の端々にヒントがちりばめられてたのに、
きっちりつられてしまいました。orz
systemかぁ。
tahara: (Fri Sep 9 11:50:59 2005 )
なるほど...。
ある意味JITみたいなものなのかなぁ。
C#のSchemeが動的にDLLを生成してからそれを読んで実行するみたいな感じで。


2005-09-08 [:p] Haskellで書いたCインタープリタ

Pugs というのは Haskell で書いた Perl 6 のインタープリタ. 対抗して,「gcc 完全互換」の C のインタープリタを Haskell で書いた.

たとえば,hello.cs というファイルを以下のように編集しよう.

% cat hello.cs
#!/usr/local/bin/interpc.hs

#include <stdio.h>
int main (int argc, char** argv);

int
main (int argc, char** argv)
{
  printf ("Hello, world!\n");
  return 0;
}

このファイルに実行パーミッションをたてて実行してみよう.

% chmod 755 hello.cs
% ./hello.cs
Hello, world!

起動に時間がかかるけど,動作は速いよ.:p

--nobsun


Name:
Comment:
tahara: (Thu Sep 8 11:56:29 2005 )
えー、もっと詳しく知りたいです。
cut-sea: (Thu Sep 8 12:33:48 2005 )
すげぇ。
gcc完全互換てのが本気度120%ですね。
shiro: (Thu Sep 8 19:51:43 2005 )
ふふふ。なるほどね。
cut-sea: (Thu Sep 8 22:42:30 2005 )
あうあう。
…もしかして…釣られた?


2005-09-07 [sign] 署名の検証

昨日の署名付データを検証するには, OpenSSL のツールを使って以下のようにする.

% openssl smime -verify -CAfile ca.crt -in hello.hs.signed -out hello.hs.verified
Verification successful

hello.hs.verified には元のデータが入っている.

% cat hello.hs.verified
main = putStr "Hello, world!\n"

--nobsun


Name:
Comment:

There is no comment.


2005-09-06 [sign] データに署名する

データが通信途中で改竄されていないをチェックしたり,データの作成者が 特定できるようにするためには,データに電子署名をほどこします.

OpenSSL のツールを使ってデータ hello.hs に電子署名をほどこすなら,

% openssl smime -sign -in hello.hs -signer my.crt -inkey my.key -out hello.hs.signed

これで,hello.hs に電子署名が施されました.

% cat hello.hs.signed
MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg=sha1; boundary="----E968F5C7F50F6C5EB1B3B993E5262DAA"

This is an S/MIME signed message

------E968F5C7F50F6C5EB1B3B993E5262DAA
main = putStr "Hello, world!\n"

------E968F5C7F50F6C5EB1B3B993E5262DAA
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

MIIEtgYJKoZIhvcNAQcCoIIEpzCCBKMCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3
DQEHAaCCAowwggKIMIIB8QIBAzANBgkqhkiG9w0BAQQFADCBkTELMAkGA1UEBhMC
SlAxDjAMBgNVBAgTBUNoaWJhMQ4wDAYDVQQHEwVJbnphaTEZMBcGA1UEChMQUGhp
bG9Qcm9ncmFtbWluZzELMAkGA1UECxMCQ0ExGDAWBgNVBAMTD05vYnVvIFlhbWFz
aGl0YTEgMB4GCSqGSIb3DQEJARYRbm9ic3VuQHNhbXBvdS5vcmcwHhcNMDUwODE5
MDEwNjQ5WhcNMDYwODE5MDEwNjQ5WjCBhjELMAkGA1UEBhMCSlAxDjAMBgNVBAgT
BUNoaWJhMQ4wDAYDVQQHEwVJbnphaTESMBAGA1UEChMJU2FtcG91T3JnMRAwDgYD
VQQLEwdIYXNrZWxsMQ8wDQYDVQQDEwZub2JzdW4xIDAeBgkqhkiG9w0BCQEWEW5v
YnN1bkBzYW1wb3Uub3JnMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/t9vu
e1XmVv7vaVcGXL3/yA9apCU8LuvWp5JDBN3jlZfZASrOkljb6YdNE/6GMAIGiteF
ztSIBU48rm1gThVGeFk+u2t5srhPQ65M+jdje/cjU5qjDwTmIZZI1440VdhG1Vo9
y4D/Wqmv3lasJbLGxsF06EhIQ3BLEt0nTl7nKwIDAQABMA0GCSqGSIb3DQEBBAUA
A4GBAIBL3WK9xY897OSM7nxS0+DmuZV8PRWtKKhXLdx2R3VcQkArqIilrZQtnb28
F8/S4Uu2BRkKot6AoaebrlQdHmHXqVVXKpi6PNGPmeK230ydP8wyFEgVwDwy/VZp
jU/OqOP5DcpwGApWAuhvKL4gwrWU1FFjkCHQisHH2urMTbZXMYIB8jCCAe4CAQEw
gZcwgZExCzAJBgNVBAYTAkpQMQ4wDAYDVQQIEwVDaGliYTEOMAwGA1UEBxMFSW56
YWkxGTAXBgNVBAoTEFBoaWxvUHJvZ3JhbW1pbmcxCzAJBgNVBAsTAkNBMRgwFgYD
VQQDEw9Ob2J1byBZYW1hc2hpdGExIDAeBgkqhkiG9w0BCQEWEW5vYnN1bkBzYW1w
b3Uub3JnAgEDMAkGBSsOAwIaBQCggbEwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEH
ATAcBgkqhkiG9w0BCQUxDxcNMDUwOTA2MDUwMjMzWjAjBgkqhkiG9w0BCQQxFgQU
XSDi7+efiNK0T9s+rUrJW1/ws6AwUgYJKoZIhvcNAQkPMUUwQzAKBggqhkiG9w0D
BzAOBggqhkiG9w0DAgICAIAwDQYIKoZIhvcNAwICAUAwBwYFKw4DAgcwDQYIKoZI
hvcNAwICASgwDQYJKoZIhvcNAQEBBQAEgYC8KaL3gGddwEvbZkIaiAz+V5fz1OBg
1Ha92yzWjWOXbLh2a5aLHO2Xppq/IGj52QHnLF5zl27N/jSXtTKPiqlJtf2smwLw
yunAaHpQpwxMuJM8dbQMUC4Wswc9snb5o5zwhQ0Wpa79azlmQgAM25wXjNrqBMnC
godiIMSyr1KfwQ==

------E968F5C7F50F6C5EB1B3B993E5262DAA--


--nobsun


Name:
Comment:

There is no comment.


2005-09-05 [gdb] 動作しているプロセスにアタッチする

サーバプロセスなどをデバッグするときには,動作させた状態でデバッガを アタッチしたいことがある.手順は

  • gdb を起動
  • file コマンドでプロセスのシンボル情報を持っているファイルを指定
  • directory コマンドでソースパスにソースのあるディレクトリを指定
  • attach コマンドでプロセスIDを指定してアタッチ
  • backtrace コマンドで現在位置をチェック
  • いろいろデバッグ...
  • detach コマンドで接続切断
  • quit コマンドで gdb 終了

てな感じ.

% gdb
GNU gdb 5.2.1
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-vine-linux".
(gdb) file dumb
Reading symbols from dumb...done.
(gdb) directory .
Source directories searched: /home/nobsun/oneline:$cdir:$cwd
(gdb) attach 21772
Attaching to program: /home/nobsun/oneline/dumb, process 21772
Reading symbols from /lib/i686/libc.so.6...done.
Loaded symbols for /lib/i686/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0x400c8b15 in nanosleep () at tzset.c:461
461     tzset.c: No such file or directory.
        in tzset.c
(gdb) backtrace
#0  0x400c8b15 in nanosleep () at tzset.c:461
#1  0x400c897f in __sleep (seconds=1) at ../sysdeps/unix/sysv/linux/sleep.c:137
#2  0x08048402 in main (argc=1, argv=0xbffff6d4) at dumb.c:13
#3  0x40035c1f in __libc_start_main (main=0x80483b0 <main>, argc=1, 
    ubp_av=0xbffff55c, init=0x8048408 <__libc_csu_init>, 
    fini=0x8048450 <__libc_csu_fini>, rtld_fini=0xbffff5dc, 
    stack_end=0x40156968) at ../sysdeps/generic/libc-start.c:225
(gdb) 
...
(gdb) detach
Detaching from program: /home/nobsun/oneline/dumb, process 21772
(gdb) quit
%

--nobsun


Name:
Comment:
shiro: (Mon Sep 5 19:42:15 2005 )
gdb <process-id> でコマンドラインから直接attachすることもできます。


2005-09-02 [strace] システムコールのおっかけ

プログラムのデバッグ時に,システムコールを追いかけたい ことがある.そんなときには strace を使う.たとえば,

#include <stdio.h>
int
main(int argc, char** argv) 
{
        printf ("Hello, world!\n");
        return 0;
}

というプログラムをコンパイルして,

% gcc -Wall hello.c -o hello

strace から実行すると

% strace ./hello > /dev/null
execve("./hello", ["./hello"], [/* 60 vars */]) = 0
uname({sys="Linux", node="nikenike", ...}) = 0
brk(0)                                  = 0x804955c
old_mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40015000
open("/etc/ld.so.preload", O_RDONLY)    = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=38078, ...}) = 0
old_mmap(NULL, 38078, PROT_READ, MAP_PRIVATE, 3, 0) = 0x40016000
close(3)                                = 0
open("/lib/i686/libc.so.6", O_RDONLY)   = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\\\1"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=20273330, ...}) = 0
old_mmap(NULL, 1283620, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0x40020000
old_mmap(0x40154000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x134000) = 0x40154000
old_mmap(0x40157000, 9764, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40157000
close(3)                                = 0
munmap(0x40016000, 38078)               = 0
fstat64(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfffeee8) = -1 ENOTTY (Inappropriate ioctl for device)
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x40016000
write(1, "Hello, world!\n", 14)         = 14
munmap(0x40016000, 4096)                = 0
exit_group(0)                           = ?

いろんなことをやってるねぇ.

--nobsun


Name:
Comment:
び: (Sat Sep 3 13:31:20 2005 )
4.4BSD系統だと、ktrace&kdumpですかね。


2005-09-01 [Scheme] generator

pythonにあるgeneratorなんだけど、当然のようにSchemeには無い。 でもやっぱり作ればあるもん!ってことでc.l.s.あたりをまさぐると…ありまんがな。

ちょっとだけ変えてgeneratorに与える引数をクロージャではなくて、 yieldになる予約語(あくまで一個のgeneratorの内部だけ)と 任意個数 のbodyを与える。って形式にしてます。

(define-macro (store/cc name . body)
  `(call/cc (lambda (k)
              (set! ,name k) ,@body)))


(define %%next%% '%%next%%)
 
(define-macro (generator yield . routine)
  (let ((current (gensym))
        (exit (gensym))
        (value (gensym)))
    `(let ((,current (lambda (,yield) ,@routine)))
       (lambda ()
         (let ((,value (call/cc (lambda (,exit)
                                  (,current
                                   (lambda (,value)
                                     (store/cc %%next%%
                                               (,exit ,value))))
                                  (error 'dead-generator)))))
           (set! ,current %%next%%)
           ,value)))))

ではおためしでえす。

(define test
  (generator yield
             (print "1")
             (yield "Hello!")
             (print "2")
             (yield "World!")
             (print "3")
             (yield "BYE!")
             (print "Boooooooom...")
             ))

(define test2
  (generator return
             (let loop ((n 0))
                  (return (cons n (* n n)))
                  (loop (+ n 1)))))

さて、これで(test)やら(test2)やらを繰り返し呼ぶと遊べます。

まぁ%%next%%あたりが個人的にはいやんな感じで、実際自分で実装した時には ここにハマってきっちり時間を喰い潰しました。いやさ悔い潰しました。とさ。

--cut-sea


Name:
Comment:
yusei: (Mon Sep 5 23:04:04 2005 )
おお。すごい。


このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us