4288786 105072031

2016-07-31 _ksss_Created on 2016-07-31 by _ksss_

    mrubyでのforkのバグを直した。

    https://github.com/iij/mruby-process/pull/7

    引数に初期化されてない変数がブロック引数に渡されているので、
    これをmruby側で参照すると死ぬ。

    そもそもforkにブロック引数はいらない。

    mrubyのC側でブロック引数を無くす方法は2つ

    • mrb_yield(mrb, block, mrb_nil_value())
    • mrb_yield_argv(mrb, block, 0, NULL)

    mrb_yieldmrb_yield_argvはほぼ同じ関数だが、ブロック引数の取り方に違いがある。
    mrb_yieldはブロック引数を1つだけ指定できる。
    mrb_yield_argvは0〜いくらでも指定できる。
    関数の中身もほぼ同じ

    MRB_API mrb_value
    mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv)
    {
      struct RProc *p = mrb_proc_ptr(b);
    
      return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
    }
    
    MRB_API mrb_value
    mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg)
    {
      struct RProc *p = mrb_proc_ptr(b);
    
      return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
    }
    

    https://github.com/mruby/mruby/blob/eb7422af581edff0dd4b1f8259598677b4d32793/src/vm.c#L657-L671

    要約すると、mrb_yieldではどんなにがんばっても引数を一つ与えていることになるので、意味的にはおかしい。
    ブロック引数を0個にしたければ、mrb_yield_argv(mrb, block, 0, NULL)を使うほうがヨサゲ。

    どうやってこのバグを発見したかというと、単にコンパイルしたらclangがwarningで教えてくれただけだ。

    つまりコンパイルさえすれば発見できる状態にあるが、2年近く放置されていたことになる。(ブロック引数なんかつけなきゃ問題ないので)

    そしてこんなミミッチイ事を気にするのは、世界で僕ぐらいだったようである。

    おしまい。

    4288786 105072031
    Commented on 2016-07-31

    テキストが中央揃えになってしまうのはなぜでしょう……。

    4288786 105072031
    Commented on 2016-08-01

    ---が文章内にあると、そこで枠が分割されてテキストが中央揃えになるようです。

    4288786 105072031
    Commented on 2016-08-01

    image

    Yc98ejtq
    Commented on 2016-08-01

    スライドモードが悪さしてそうな気がしますね(そもそもこんなページがあったのか……)。
    https://nippo.wikihub.io/@_ksss_/20160731140352/presentation