CubicLouve

Spring_MTの技術ブログ

壊れたgzipを調べたときのメモ

壊れたgzipがあり、展開できないと言われて調査したときにどうやったかのメモ

gzipとは

www.gzip.org

www.futomi.com

zcatで展開できるところまでしてみる

zcatは破損した位置までのデータを修復できる。

展開できたデータの最後を確認して修復する。

バイナリを見る

壊れているgzipの内容

$ od -xc data.json.gz | tail
        342 213 322 264   @ 370   D 024 365 221 243 003   )   u   3   >
2572260    346a    d38e    1aea    bcb8    7f2f    5a69    d8f8    0865
          j   4 216 323 352 032 270 274   / 177   i   Z 370 330   e  \b
2572300    0f84    f0a9    9d00    f404    03af    33e1    f451    e212
        204 017 251 360  \0 235 004 364 257 003 341   3   Q 364 022 342
2572320    e79b    818a    b9f8    6228    36a0    91d9    7edb    173c
        233 347 212 201 370 271   (   b 240   6 331 221 333   ~   < 027
2572340    20d0    f29c    ac0f    732d    b57b    4cb7    0a01
        320     234 362 017 254   -   s   { 265 267   L 001  \n
2572356

最後に改行文字が入っていた。

gzipを書き出すときに Kernel.#puts module function Kernel.#puts (Ruby 2.4.0) とかを使うと起きそう。

直してみる

Vim 上で :%!xxdをして、hexdumpする

:%!xxd -r でバイナリで書き戻して完了

$ od -xc data_zcat_json.gz | tail
        213 322 264   @ 370   D 024 365 221 243 003   )   u   3   >   j
2572300    8e34    ead3    b81a    2fbc    697f    f85a    65d8    8408
          4 216 323 352 032 270 274   / 177   i   Z 370 330   e  \b 204
2572320    a90f    00f0    049d    aff4    e103    5133    12f4    9be2
        017 251 360  \0 235 004 364 257 003 341   3   Q 364 022 342 233
2572340    8ae7    f881    28b9    a062    d936    db91    3c7e    d017
        347 212 201 370 271   (   b 240   6 331 221 333   ~   < 027 320
2572360    9c20    0ff2    2dac    7b73    b7b5    014c
            234 362 017 254   -   s   { 265 267   L 001
2572374

参照

技術/歴史/zip,gzip,zlib,bzip2 - Glamenv-Septzen.net

http://www.gzip.org/algorithm.txt

Man page of GZIP

qiita.com

CloudWatch Alarms の Treats Missing Dataの意味

よくわからかなかったので整理

docs.aws.amazon.com

configure(コンソール) configure(api) 意味 英文
Missing missing 過去に遡ってデータを見に行く the alarm looks back farther in time to find additional data points
Good notBreaching 欠落データポイントで、しきい値内であることを示す(アラート収まる) treated as a data point that is within the threshold
Bad breaching 欠落データポイントで、しきい値を超えていることを示す(アラート飛ぶ) treated as a data point that is breaching the threshold
Ignored ignore 欠落データポイントでアラーム状態の変更がトリガーされない the current alarm state is maintained

特定のJSONの圧縮効率を調べてみる(snappy、gzip、xz、lz4、zstd)

snappyが入っているのは察してほしい

データの詳細は後で書く。(これも察して欲しい。だいぶ偏ったデータではある)

これから詳細をちゃんと書くが、一旦ここにおく

マシンスペック

iMac使っています。

% system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: iMac
      Model Identifier: iMac14,2
      Processor Name: Intel Core i5
      Processor Speed: 3.2 GHz
      Number of Processors: 1
      Total Number of Cores: 4
      L2 Cache (per Core): 256 KB
      L3 Cache: 6 MB
      Memory: 8 GB
      Boot ROM Version: IM142.0118.B00

% sysctl machdep.cpu.brand_string
machdep.cpu.brand_string: Intel(R) Core(TM) i5-4570 CPU @ 3.20GHz

結果

圧縮方式 圧縮時間(秒) 伸長時間(秒) 圧縮後サイズ(KB)
なし 159320(156KB)
snappy 18913(18K)
gzip 9982(9.7K)
xz 7024(6.9K)
lz4 23095(23K)
zstd 9960(9.7K)

実行時間の結果

github.com

圧縮時

Warming up --------------------------------------
              snappy    22.000  i/100ms
                gzip    20.000  i/100ms
                  xz     2.000  i/100ms
                 lz4    24.000  i/100ms
                zstd    21.000  i/100ms
Calculating -------------------------------------
              snappy    802.750  (±115.7%) i/s -      1.254k in   5.373229s
                gzip    295.138  (±40.7%) i/s -    980.000  in   5.055020s
                  xz     22.329  (± 4.5%) i/s -    112.000  in   5.030328s
                 lz4    949.545  (±110.1%) i/s -      1.224k in   5.053683s
                zstd    892.079  (±117.1%) i/s -      1.302k in   5.069196s

伸長時

Warming up --------------------------------------
              snappy   851.000  i/100ms
                gzip   414.000  i/100ms
                  xz   111.000  i/100ms
                 lz4   861.000  i/100ms
                zstd   577.000  i/100ms
Calculating -------------------------------------
              snappy     10.356k (±16.0%) i/s -     51.060k in   5.081812s
                gzip      4.655k (±10.2%) i/s -     23.184k in   5.039399s
                  xz      1.188k (± 7.7%) i/s -      5.994k in   5.080418s
                 lz4     10.312k (±12.0%) i/s -     50.799k in   5.000477s
                zstd      6.597k (± 8.4%) i/s -     32.889k in   5.023823s

デーモンとは

メモ書き程度に

デーモン

語源は悪魔のデーモンではなく、守護神のほうらしい。 デーモン (ソフトウェア) - Wikipedia

まあ、それはそれとして デーモン(daemon)は長時間動き続けるプロセスのことです。 APUEのデーモンより

  • ファイルモード作成時マスクをumask 0でリセットする

    • プロセスがファイルを作成するとき、マスクが許可をオフにすることを避けるため
  • 新しいセッションを作成する( 制御端末から切り離し、プロセスグループのリーダとなり、セッションのリーダーとなる)

    • forkして、親をexitする
    • setsidを呼ぶ
    • 制御端末がないので、出力の表示場所がない
      • ps のTTYが ? or ?? になっている
    • エラー状態の報告はsyslogを使う等する
  • cwdをルートディレクトリ(/)に変更する

  • 不必要なファイルディスクリプタをcloseしておく

  • 標準入力、標準出力、標準エラー出力を閉じる

    • 対話的なインターフェースから入力も受けない
    • 同じ端末装置に他のユーザーがログインしても、デーモンの出力が端末に現れないようにする

rubyだとProcess.daemonを呼ぶだけでデーモンになる

Refernce

2016年おせち料理

3年連続のおせち作りです。

買い出しは12/22から開始しています。

完成品はこちら

f:id:Spring_MT:20161231165556j:plain f:id:Spring_MT:20161231165615j:plain

重箱はここのを買いました。

かまぼこ、酢だこは既成品です。

買い物

クリスマス前に済ませておきましょう。 直前になると高くなったり、高級なものしか出回らなくなるので気をつけましょう

黒豆

黒豆は日持ちするので、安く済ますのであれば予め買っておきましょう。

いりこ

年末になると、田作り用のサイズが揃った高級ないりこが並ぶようになります。 通常打っている不揃いで安いものは売り切れてしますので、それでもよいのであれば予め買っておくのがよいでしょう。

かまぼこ

これも高級なものしか出回らなくなります。あまり日持ちがしないので、ギリギリをねらって買うとよいでしょう。 クリスマス前が良いタイミングです。

野菜類

レンコン、里芋、たけのこ、ごぼうは高くなります。 気をつけましょう。

ふるさと納税

レンコン、車海老はふるさと納税でいただきました。

だし

茅乃舎のあごだしを使いました。

www.kayanoya.com

白だし

これを使いました。

おせち

数の子(下ごしらえ)

材料
塩漬け数の子 180 g

29日(晩)

  1. 水一リットル、塩小さじ1の塩水をつくって10時間ほどつけておく

30日

  1. 薄皮を取って冷蔵庫に保存しておく

松前漬

材料
スルメイカ(小ぶり) 4枚
昆布 スルメと同量くらい
人参 1/2本
下ごしらえした数の子 80gくらい(3腹)

たれ

材料
300cc
醤油(関東濃い口) 150cc
みりん 150cc

30日

  1. 酒 300cc、醤油 150cc、みりん 150ccを火にかけひと煮立ちさせて冷ましておく
  2. スルメイカ、昆布はそのままキッチンバサミで5mm幅程度に切っておく(ここは適当)
  3. 人参は千切りにしておく
  4. 数の子は1センチくらいに切っておく
  5. 上記を全部混ぜる
  6. 半日位で混ぜなおす
  7. 出来上がり

最終的な出来栄え

いつも通り。 これは定番。

黒豆

材料
黒豆 200g

煮汁

材料
砂糖 170g
800c
醤油(濃口醤油) 大さじ 1
小さじ半分

29日

  1. 煮汁を合わせておいて、沸騰させる
  2. 黒豆を流水で洗う(やさしく洗う!皮がむけてしまう)
  3. 沸騰したら火を止めて、すぐに黒豆を投入
  4. 一晩寝かせる

30日

  1. 圧力鍋で強で15分火を入れる(前回の反省を活かして)

最終的な出来栄え

薄口を間違えて濃口にしてしまった。。。 豆はちょうどよい固さで、味も問題ないので来年からは濃口で問題ないかな。

田作り

材料
田作り(いりこ) 50g位(ライフで買った。一袋まるまる入れた)

たれ

材料
大さじ2
砂糖 大さじ2
醤油(九州 甘口) 大さじ1 + 1/2
みりん 大さじ1

30日

  1. 田作りをかりかりになるまで煎る -> 冷やす
  2. たれを中火にかけて、とろみがつくまで煮込む
  3. たれができたら、煎った田作りをいれてあえる
  4. 電子レンジの天板にクッキングシートをはっておきそれに広げて冷ます

最終的な出来栄え

美味しかった。 安いいりこだったが、苦味はないが旨味はしっかりあり、今後もこのいりこを使っていきたい。

なます

材料
大根 1/4本
人参 1/3本

たれ

材料
米酢 100cc
砂糖 大さじ3
だし 100cc

30日

  1. 大根と人参を千切りにする
  2. 千切りにした大根と人参を塩を振って水出しする
  3. 水がでたら、よく絞る
  4. たれを混ぜて完了

色どり的に 大根 3: 人参 1 がよい。

最終的な出来栄え

普通。 まあ、来年も同じようなレシピで。

お煮しめ

材料
里芋 小ぶりなものが12個位
しいたけ 8個
ニンジン 2/3本
絹さや 1パック(12個くらい)
ごぼう 1/2 本
レンコン 大きいのを1ブロック
こんにゃく 一枚
豆腐 一丁(厚揚げにした)
たけのこ 穂先だけのを4つ

味付け用調味料

材料
だし 700cc
醤油(薄口) 大さじ4
醤油(濃い口) 大さじ1
大さじ3
砂糖 大さじ2
みりん 大さじ1
小さじ1/2

ニンジンと絹さやにつける出汁

材料
だし 200cc
砂糖 小さじ1
1つまみ

大分前に仕込み済

里芋

  1. 里芋を洗わずに皮をむいて、洗って半分にして下茹で
  2. 冷凍

レンコン

  1. レンコンの飾り切り、酢水(深皿に水入れて、お酢を垂らす程度)につけておく
  2. レンコン下茹で(10分位)
  3. 冷凍

30日

  1. しいたけを水でもどしておく
  2. ニンジンを飾り切りする。ニンジン絹さやを塩入れて下茹で(10分くらい)
  3. ニンジンと絹さやにつける出汁を沸騰させて、粗熱をとっておく
  4. ゆでたニンジンと絹さやをニンジンと絹さやにつける出汁に浸けて冷蔵庫にいれておく
  5. ごぼうの皮むきして下茹でしておく(10分位)
  6. こんにゃくは下茹でしておく
  7. だし3カップ半でニンジンと絹さや以外の具材を10分炊く
  8. 出汁味付け用調味料を入れて更に15分炊く

最終的な出来栄え

出汁がきいて美味しかった。 冷凍の匂いも特に気にならなかった。

ニシンの昆布巻き

材料
身欠きにしん 6本
日高昆布 6枚(昆布はすぐにもどるのでにしんの量に合わせてもどせばよい)
かんぴょう 適量

だし

材料
昆布戻し汁 600cc
米酢 大さじ2
100cc

たれ

材料
砂糖 大さじ6(きび砂糖のほうがよさそう)
本みりん 大さじ4
しょうゆ 大さじ8(九州4 関東4)

28日(晩から)

  1. 身欠きにしんを米と昆布と一緒に水につける

29日(晩)

  1. 水を替えておく

30日

  1. 昆布は表面の汚れをさっと拭き取り、3〜4カップの水で戻す。柔らかく巻けるくらいになればよい。戻しすぎない。
  2. かんぴょうはさっと洗い、塩でもんで5分くらい水につけて戻しておく。これも戻しすぎないように。
  3. にしんは、汚れ、あたま、ウロコを洗い流し、一番茶を入れた湯で沸騰したら弱火にして約12分形が崩れない程度に煮る
  4. 水でさっと洗って使う
  5. 昆布でにしんを巻き、昆布の幅に応じてかんぴょうを2〜3ヶ所、2巻きして結ぶ。(かんぴょうはゆるめに巻く。)
  6. 圧力鍋に巻いた昆布を隙間なく並べ、だしの材料を入れて蓋をする。火にかけ、沸騰したら中火にし、12分圧力をかけ、火を止める。
  7. 圧が下がったらふたを開け、たれを加え、弱火で約20分煮含める。焦げないように注意

最終的な出来栄え

ちょうどよい! これで来年も作ろう。

海老の旨煮

材料
車海老 (有頭) 7尾

出汁

材料
だし 450cc(水でも可)
醤油(薄口) 50cc
みりん 50cc
50cc
砂糖 50cc

31日

  1. エビを解凍して下ごしらえをする(背わたを取る)
  2. エビを沸騰したお湯で2分間下茹でする。
  3. 鍋にたれを入れ中火にかける。沸騰したら火を弱める。
  4. 出汁ににエビをいれて冷やして完成(冷やしている時に、味が染み込む。)

最終的な出来栄え

車海老めっちゃうまい! 来年も車海老をもらおう。

伊達巻

家の玉子焼き器で二枚分くらいのレシピ

材料
ハンペン 1枚(80g)
玉子 4個

たれ

材料
みりん 小さじ1(よりちょっと多めくらい)
砂糖 大さじ2
少々
麺つゆ(3倍濃縮) 小さじ1と1/2
だし 60 cc位いれたかな
醤油 少々

31日

  1. 卵を4つ割り入れる
  2. フードプロセッサー(ナイフカッター使用)に、卵、ハンペン(手でちぎる程度でOK)、たれをいれて一分程度ミキサーにかける
  3. アルミホイルで蓋を作っておく
  4. 玉子焼き器(テフロン加工したやつ)に卵を流し込む(だいたい半分位をいれる)
  5. 強火で10秒かけた後に、アルミホイルの蓋をかぶせて弱火で10分位火にかける(匂いでこげていそうだったら)
  6. 表側が少し凸凹でもきにしない。あまりにも火が通っていない感じがしたらひっくり返す(最終手段、火を入れちゃうと出汁のジュワッと感がへります。)
  7. 鬼簾でまく

最終的な出来栄え

これももう特に手を入れず定番に。

豚の角煮

材料
豚バラブロック 268 g
ねぎ 青い部分を一本分
生姜 チューブのものを適量

たれ

材料
煮汁 200cc たらなければ水を足す
砂糖 大さじ 1
みりん 大さじ 1
醤油(九州) 大さじ 3
大さじ 3

30日

  1. ネギ、生姜、豚バラブロック、水 1000ccを圧力鍋にいれて沸騰後20分 加圧
  2. 豚バラを取り出し、カットした上で、たれを合わせて圧力なべで沸騰後10分加圧

最終的な出来栄え

たまたま肉が余っていたので作ったけど、来年も定番で作ってよいかも。

芋きんとん

材料
安納芋 小ぶりのを5つ
有塩バター 10g位

30日

  1. 水で濡らしたキッチンペーパーとアルミホイルで包んだ安納芋をグリルで40分じっくり焼く
  2. シリコンスチーマで2分電子レンジで加熱する
  3. 皮をむく
  4. バターをいれてよく混ぜる

最終的な出来栄え

安納芋が十分甘いので砂糖はいらない。 バターもいらないかも。

味付き数の子

材料
下ごしらえした数の子 適量

出汁

材料
200cc
白だし 大さじ 2
みりん 大さじ 2
本だし 顆粒 少々

30日

  1. 出汁をひと煮立ちさせる
  2. 出しを完全に冷やす
  3. 下ごしらえした数の子をつけて冷蔵庫にいれる

最終的な出来栄え

おつまみ

数の子からしマヨネーズ和え

材料
数の子(味付き) 適量
マヨネーズ 適量
からし 少々
  1. 数の子、マヨネーズ、和からしを混ぜて完了

最終的な出来栄え

おつまみとしてはよい。

来年への課題

きび砂糖を買っておく。 来年は工程の写真取る

gdbを使ってRuby 2.4.0のライブプロセスの情報を取得してみる

Ruby 2.4.0 リリース

2.4.0がリリースされたので、

spring-mt.hatenablog.com

と同じことをやってみようかと思います。

準備

AWSamazon Linux上で試しています。

# cat /etc/system-release
Amazon Linux AMI release 2016.09

gcc4.8.3gdb7.6.1を使ってます。

$ wget https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.0.tar.gz
$ tar zxf ruby-2.4.0.tar.gz
$ cd ruby-2.4.0
$ ./configure optflags="-O0" debugflags="-ggdb3" --prefix="${HOME}/.rbenv/versions/2.4.0-O0_g3"
$ make
$ make install

configureのサマリは下記の通りです。

---
Configuration summary for ruby version 2.4.0

   * Installation prefix: /home/ec2-user/.rbenv/versions/2.4.0-O0_g3
   * exec prefix:         ${prefix}
   * arch:                x86_64-linux
   * site arch:           ${arch}
   * RUBY_BASE_NAME:      ruby
   * ruby lib prefix:     ${libdir}/${RUBY_BASE_NAME}
   * site libraries path: ${rubylibprefix}/${sitearch}
   * vendor path:         ${rubylibprefix}/vendor_ruby
   * target OS:           linux
   * compiler:            gcc
   * with pthread:        yes
   * enable shared libs:  no
   * dynamic library ext: so
   * CFLAGS:              ${optflags} ${debugflags} ${warnflags}
   * LDFLAGS:             -L. -fstack-protector -rdynamic \
                          -Wl,-export-dynamic
   * optflags:            -O0 -fno-fast-math
   * debugflags:          -ggdb3
   * warnflags:           -Wall -Wextra -Wno-unused-parameter \
                          -Wno-parentheses -Wno-long-long \
                          -Wno-missing-field-initializers \
                          -Wno-tautological-compare \
                          -Wno-parentheses-equality \
                          -Wno-constant-logical-operand -Wno-self-assign \
                          -Wunused-variable -Wimplicit-int -Wpointer-arith \
                          -Wwrite-strings -Wdeclaration-after-statement \
                          -Wimplicit-function-declaration \
                          -Wdeprecated-declarations \
                          -Wno-packed-bitfield-compat \
                          -Wsuggest-attribute=noreturn \
                          -Wsuggest-attribute=format
   * strip command:       strip -S -x
   * install doc:         yes
   * man page type:       doc

---

gdbでアタッチするRubyプロセスを作る

まずは、かんたんなhttpサーバーを立ち上げてそのプロセスにアタッチしてみます。

今回は単純なhello worldを返すだけのhttpサーバーを立ててます。(pidは控えておいてください)

ソースは下記reposにあります。

rack-hello_world

アタッチしてみる

サクッとgdbでアタッチした体でいきます。

Cの世界

(gdb) p ruby_version
$1 = "2.4.0"

スレッド情報はどうでしょう。

(gdb) info threads
  Id   Target Id         Frame 
  2    Thread 0x7fe410aad700 (LWP 17067) "ruby-timer-thr" 0x00007fe40fc5f64d in poll () at ../sysdeps/unix/syscall-template.S:81
* 1    Thread 0x7fe410aa4740 (LWP 17058) "rackup" 0x00007fe40fc613c3 in select () at ../sysdeps/unix/syscall-template.S:81

メインスレッド(Rubyのスレッド)とタイマスレッドがいますね。

ここいらでRubyの世界にいきます。

Rubyの世界へ

まずは簡単にRubyのcallbackを表示してみます。

(gdb) call rb_vmdebug_stack_dump_raw_current()

そうすると、プロセスの標準出力(今回はrackupで立ち上げたプロセス)にrubyのCの関数呼出しも含まれて標準出力に表示されます。

 from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/bin/rackup:22:in `<main>'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/bin/rackup:22:in `load'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/bin/rackup:4:in `<top (required)>'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/server.rb:147:in `start'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/server.rb:296:in `start'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/handler/webrick.rb:34:in `run'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:158:in `start'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:33:in `start'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:171:in `block in start'
    from /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:171:in `select'
-- Control frame information -----------------------------------------------
c:0011 p:---- s:0064 e:000063 CFUNC  :select
c:0010 p:0117 s:0056 e:000055 BLOCK  /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:171
c:0009 p:0006 s:0046 e:000045 METHOD /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:33
c:0008 p:0068 s:0042 e:000041 METHOD /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/2.4.0/webrick/server.rb:158
c:0007 p:0161 s:0036 e:000035 METHOD /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/handler/webrick.rb:34
c:0006 p:0231 s:0028 E:0015a8 METHOD /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/server.rb:296
c:0005 p:0016 s:0021 e:000020 METHOD /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/server.rb:147
c:0004 p:0023 s:0016 e:000015 TOP    /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/bin/rackup:4 [FINISH]
c:0003 p:---- s:0013 e:000012 CFUNC  :load
c:0002 p:0136 s:0008 E:0020a0 EVAL   /home/ec2-user/.rbenv/versions/2.4.0-O0_g3/bin/rackup:22 [FINISH]
c:0001 p:0000 s:0003 E:001850 (none) [FINISH]

最新のコールスタックの中身も見てみます。

(gdb) ruby_thread
running_thread set $ruby_thread 
(gdb) vm_frame_type $ruby_thread->cfp
There is no member named flag.

ん、cfp構造体の中からflagがなくなった?

d.hatena.ne.jp

ここで、rb_control_frame_t::flagのメンバをep[0]に移したとのこと。 https://github.com/ruby/ruby/blob/1407e52ba4915ed7f251dec548b5e68f2a5a6a6e/vm_core.h#L994

あと、vmのframe_typeの持ち方も変わっているので、前に定義したgdbvm_frame_type関数も変更しておきます。 ruby/vm_core.h at 1407e52ba4915ed7f251dec548b5e68f2a5a6a6e · ruby/ruby · GitHub

Ruby 2.4.0 for gdbinit · GitHub 再度アタッチ。 ついでにrb_vm_frame_method_entry()も一緒に見てみます。

(gdb) ruby_thread
running_thread set $ruby_thread 
(gdb) vm_frame_type $ruby_thread->cfp
vm_frame_type 55550001  CFUNC 
(gdb) rp rb_id2str(rb_vm_frame_method_entry($ruby_thread->cfp)->called_id)
[PROMOTED] T_STRING: "select" bytesize:6 (embed) encoding:2 coderange:7bit $1 = (struct RString *) 0x5635ba9a5010

ここまでくれば、2.3.3とほとんど変わってないですね。

前と同じように、4つ前のコールスタック(rubyのメソッド呼び出し)のコールスタックも見てみます。

(gdb) set $cfp = $ruby_thread->cfp + 4 # 4つ前のコールスタック
(gdb) vm_frame_type $cfp
vm_frame_type 11110001  METHOD 
(gdb) rp $cfp->iseq->body->location.path # ファイルパス
[PROMOTED] T_STRING: "/home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/handler/webrick.rb" bytesize:106 encoding:2 coderange:7bit $2 = (struct RString *) 0x5635ba951028
(gdb) p/d rb_vm_get_sourceline($cfp) # ファイルの行数
$3 = 34
(gdb) rb_p rb_iseq_disasm($cfp->iseq) # YARV命令列
(gdb) rb_p $cfp->ep[1] # 環境ポインタのデータの中身をdumpする

YARV命令列はこちら

== disasm: #<ISeq:run@/home/ec2-user/.rbenv/versions/2.4.0-O0_g3/lib/ruby/gems/2.4.0/gems/rack-2.0.1/lib/rack/handler/webrick.rb>
local table (size: 4, argc: 1 [opts: 1, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 4] app<Arg>   [ 3] options<Opt=0>[ 2] environment[ 1] default_host
0000 newhash          0                                               (  25)
0002 setlocal_OP__WC__0 5
0004 trace            8
0006 trace            1                                               (  26)
0008 getinlinecache   15, <is:0>
0011 getconstant      :ENV
0013 setinlinecache   <is:0>
0015 opt_aref_with    <callinfo!mid:[], argc:1, ARGS_SIMPLE>, <callcache>, \"RACK_ENV\"
0019 dup              
0020 branchif         25
0022 pop              
0023 putstring        \"development\"
0025 setlocal_OP__WC__0 4
0027 trace            1                                               (  27)
0029 getlocal_OP__WC__0 4
0031 putstring        \"development\"
0033 opt_eq           <callinfo!mid:==, argc:1, ARGS_SIMPLE>, <callcache>
0036 branchunless     42
0038 putstring        \"localhost\"
0040 jump             43
0042 putnil           
0043 setlocal_OP__WC__0 3
0045 trace            1                                               (  29)
0047 getlocal_OP__WC__0 5
0049 putobject        :BindAddress
0051 getlocal_OP__WC__0 5
0053 putobject        :Host
0055 opt_send_without_block <callinfo!mid:delete, argc:1, ARGS_SIMPLE>, <callcache>
0058 dup              
0059 branchif         64
0061 pop              
0062 getlocal_OP__WC__0 3
0064 opt_aset         <callinfo!mid:[]=, argc:2, ARGS_SIMPLE>, <callcache>
0067 pop              
0068 trace            1                                               (  30)
0070 getlocal_OP__WC__0 5
0072 putobject        :Port
0074 dupn             2
0076 opt_aref         <callinfo!mid:[], argc:1, ARGS_SIMPLE>, <callcache>
0079 dup              
0080 branchif         91
0082 pop              
0083 putobject        8080
0085 opt_aset         <callinfo!mid:[]=, argc:2, ARGS_SIMPLE>, <callcache>
0088 pop              
0089 jump             93
0091 adjuststack      3
0093 trace            1                                               (  31)
0095 getinlinecache   107, <is:1>
0098 pop              
0099 putobject        Object
0101 getconstant      :WEBrick
0103 getconstant      :HTTPServer
0105 setinlinecache   <is:1>
0107 getlocal_OP__WC__0 5
0109 opt_send_without_block <callinfo!mid:new, argc:1, ARGS_SIMPLE>, <callcache>
0112 setinstancevariable :@server, <is:2>
0115 trace            1                                               (  32)
0117 getinstancevariable :@server, <is:2>
0120 putstring        \"/\"
0122 getinlinecache   133, <is:3>
0125 getconstant      :Rack
0127 getconstant      :Handler
0129 getconstant      :WEBrick
0131 setinlinecache   <is:3>
0133 getlocal_OP__WC__0 6
0135 opt_send_without_block <callinfo!mid:mount, argc:3, ARGS_SIMPLE>, <callcache>
0138 pop              
0139 trace            1                                               (  33)
0141 putself          
0142 opt_send_without_block <callinfo!mid:block_given?, argc:0, FCALL|ARGS_SIMPLE>, <callcache>
0145 branchunless     153
0147 getinstancevariable :@server, <is:2>
0150 invokeblock      <callinfo!argc:1, ARGS_SIMPLE>
0152 pop              
0153 trace            1                                               (  34)
0155 getinstancevariable :@server, <is:2>
0158 opt_send_without_block <callinfo!mid:start, argc:0, ARGS_SIMPLE>, <callcache>
0161 trace            16                                              (  35)
0163 leave                                                            (  34)

データはこちら。

#<WEBrick::HTTPServer:0x005635baae7978 @config={:BindAddress=>"localhost", :Port=>9292, :MaxClients=>100, :ServerType=>nil, :Logger=>#<WEBrick::Log:0x005635baae77e8 @level=4, @log=#<IO:<STDERR>>, 
@time_format="[%Y-%m-%d %H:%M:%S]">, :ServerSoftware=>"WEBrick/1.3.1 (Ruby/2.4.0/2016-12-24)", :TempDir=>"/tmp", :DoNotListen=>false, :StartCallback=>nil, :StopCallback=>nil, :AcceptCallback=>nil, :DoNotReverseLookup=>true, :ShutdownSocketWithoutClose=>false,
:RequestTimeout=>30, :HTTPVersion=>#<WEBrick::HTTPVersion:0x005635bafca738 @minor=1, @major=1>, :AccessLog=>[], :MimeTypes=>{"ai"=>"application/postscript", "asc"=>"text/plain", "avi"=>"video/x-msvideo", "bin"=>"application/octet-stream", "bmp"=>"image/bmp", "class"=>"application/octet-stream", "cer"=>"application/pkix-cert", 
"crl"=>"application/pkix-crl", "crt"=>"application/x-x509-ca-cert", "css"=>"text/css", "dms"=>"application/octet-stream", "doc"=>"application/msword", "dvi"=>"application/x-dvi", "eps"=>"application/postscript", "etx"=>"text/x-setext", "exe"=>"application/octet-stream", "gif"=>"image/gif", "htm"=>"text/html", "html"=>"text/html", "jpe"=>"image/jpeg", "jpeg"=>"image/jpeg", "jpg"=>"image/jpeg", "js"=>"application/javascript", "lha"=>"application/octet-stream", "lzh"=>"application/octet-stream", "mov"=>"video/quicktime", "mpe"=>"video/mpeg", "mpeg"=>"video/mpeg", "mpg"=>"video/mpeg", "pbm"=>"image/x-portable-bitmap", "pdf"=>"application/pdf", "pgm"=>"image/x-portable-graymap", "png"=>"image/png", "pnm"=>"image/x-portable-anymap", "ppm"=>"image/x-portable-pixmap", "ppt"=>"application/vnd.ms-powerpoint", "ps"=>"application/postscript", "qt"=>"video/quicktime", "ras"=>"image/x-cmu-raster", "rb"=>"text/plain", "rd"=>"text/plain", "rtf"=>"application/rtf", "sgm"=>"text/sgml", "sgml"=>"text/sgml", "svg"=>"image/svg+xml", "tif"=>"image/tiff", "tiff"=>"image/tiff", "txt"=>"text/plain", "xbm"=>"image/x-xbitmap", "xhtml"=>"text/html", "xls"=>"application/vnd.ms-excel", "xml"=>"text/xml", "xpm"=>"image/x-xpixmap", "xwd"=>"image/x-xwindowdump", "zip"=>"application/zip"}, 
:DirectoryIndex=>["index.html", "index.htm", "index.cgi", "index.rhtml"], :DocumentRoot=>nil, :DocumentRootOptions=>{:FancyIndexing=>true}, :RequestCallback=>nil, :ServerAlias=>nil, :InputBufferSize=>65536, :OutputBufferSize=>65536, :ProxyAuthProc=>nil, :ProxyContentHandler=>nil, :ProxyVia=>true, :ProxyTimeout=>true, :ProxyURI=>nil, :CGIInterpreter=>nil, :CGIPathEnv=>nil, :Escape8bitURI=>false, :environment=>"development", :pid=>nil, :config=>"/home/ec2-user/rack-hell_world/config.ru"}, @status=:Running, @logger=#<WEBrick::Log:0x005635baae77e8 @level=4, @log=#<IO:<STDERR>>, @time_format="[%Y-%m-%d %H:%M:%S]">, @tokens=#<Thread::SizedQueue:0x005635baae76d0>, @listeners=[#<TCPServer:fd 7>], @shutdown_pipe=[#<IO:fd 8>, #<IO:fd 9>], 
@http_version=#<WEBrick::HTTPVersion:0x005635bafca738 @minor=1, @major=1>, @mount_tab=#<WEBrick::HTTPServer::MountTable:0x005635baae67a8 @tab={""=>[Rack::Handler::WEBrick, [#<Rack::ContentLength:0x005635baaeb488 @app=#<Rack::Chunked:0x005635baaeb730 @app=#<Rack::CommonLogger:0x005635baaeb938 @app=#<Rack::ShowExceptions:0x005635bab2dfb8 @app=#<Rack::Lint:0x005635bab2e058 @app=#<Rack::TempfileReaper:0x005635bab2e120 @app=#<Application:0x005635bab3dda0>>, @content_length=nil>>,
@logger=#<IO:<STDERR>>>>>]]}, @scanner=/^()(?=\/|$)/>, @virtual_hosts=[]>

こちらも2.3.3のときと同じ感じでいけました。

cfp周りで変更が入っていそうなので、おいおい調べられればよいなあ。。。