ミドルウェア: abrtd

abrtd の素振りログを残す。調べてみてもあんまりエントリ無いので、ここに書いたことで誰かの何かの足しになろう

abrtd を使うことで SIGSEGV を受けたプロセスのコアの収集や、カーネルパニックを起こした際の vmcore の収集を自動化できる

検証環境

リファレンス

https://access.redhat.com/documentation/ja-JP/Red_Hat_Enterprise_Linux/7/html/System_Administrators_Guide/ch-abrt.html

インストールと起動

sudo yum install abrt-cli
sudo systemctl enable abrtd.service
sudo systemctl start abrtd
UNIT FILE                                     STATE   
abrt-ccpp.service                             enabled 
abrt-oops.service                             enabled 
abrt-pstoreoops.service                       disabled
abrt-vmcore.service                           enabled 
abrt-xorg.service                             enabled 
abrtd.service                                 enabled 

検証なので puppet や chef は使わずに手作業でペペっと

プロセスを SIGSEGV で kill する

22.2. ABRT のインストールとそのサービスの起動 の手順をなぞって試す。sleep プロセスを SIGSEGV で kill して動作を確かめるとよいらしい

$ sleep 100 &
[1] 2954
$ kill -SEGV 2954
$ fg
-bash: fg: job has terminated
[1]+  Segmentation fault      (core dumped) sleep 100

/var/log/messages にログが残る

Dec 15 10:53:21 localhost abrt-hook-ccpp: Process 2954 (sleep) of user 1000 killed by SIGSEGV - dumping core

abrt-cli list で abrtd がキャッチしたクラッシュを一覧できる

$ sudo abrt-cli list
id 3cd5767798e6794fa2593aa1ee29f52c91e41818
reason:         sleep killed by SIGSEGV
time:           Thu Dec 15 10:53:21 2016
cmdline:        sleep 100
package:        coreutils-8.22-18.el7
uid:            1000 (vagrant)
count:          1
Directory:      /var/spool/abrt/ccpp-2016-12-15-10:53:21-2954

The Autoreporting feature is disabled. Please consider enabling it by issuing
'abrt-auto-reporting enabled' as a user with root privileges

さらに /var/spool/abrt/ にプロセス実行時のあれこれのデータが残る

$ sudo ls -hal /var/spool/abrt/ccpp-2016-12-15-10:53:21-2954
total 312K
drwxr-x---. 2 root abrt 4.0K Dec 15 11:08 .
drwxr-x--x. 4 root abrt   94 Dec 15 11:03 ..
-rw-r-----. 1 root abrt    6 Dec 15 10:53 abrt_version
-rw-r-----. 1 root abrt    4 Dec 15 10:53 analyzer
-rw-r-----. 1 root abrt    6 Dec 15 10:53 architecture
-rw-r-----. 1 root abrt  190 Dec 15 10:53 cgroup
-rw-r-----. 1 root abrt    9 Dec 15 10:53 cmdline
-rw-r-----. 1 root abrt    9 Dec 15 10:53 component
-rw-r-----. 1 root abrt 1.3K Dec 15 10:53 core_backtrace
-rw-r-----. 1 root abrt 376K Dec 15 10:53 coredump
-rw-r-----. 1 root abrt    1 Dec 15 10:55 count
-rw-r-----. 1 root abrt  298 Dec 15 10:53 dso_list
-rw-r-----. 1 root abrt 2.3K Dec 15 10:53 environ
-rw-r-----. 1 root abrt    0 Dec 15 10:53 event_log
-rw-r-----. 1 root abrt   14 Dec 15 10:53 executable
-rw-r-----. 1 root abrt    4 Dec 15 10:53 global_pid
-rw-r-----. 1 root abrt   21 Dec 15 10:53 hostname
-rw-r-----. 1 root abrt   25 Dec 15 10:53 kernel
-rw-r-----. 1 root abrt   10 Dec 15 10:55 last_occurrence
-rw-r-----. 1 root abrt 1.3K Dec 15 10:53 limits
-rw-r-----. 1 root abrt  135 Dec 15 10:53 machineid
-rw-r-----. 1 root abrt 1.6K Dec 15 10:53 maps
-rw-r-----. 1 root abrt  138 Dec 15 10:53 open_fds
-rw-r-----. 1 root abrt  393 Dec 15 10:53 os_info
-rw-r-----. 1 root abrt   37 Dec 15 10:53 os_release
-rw-r-----. 1 root abrt   21 Dec 15 10:53 package
-rw-r-----. 1 root abrt    4 Dec 15 10:53 pid
-rw-r-----. 1 root abrt    6 Dec 15 10:53 pkg_arch
-rw-r-----. 1 root abrt    1 Dec 15 10:53 pkg_epoch
-rw-r-----. 1 root abrt   19 Dec 15 10:53 pkg_fingerprint
-rw-r-----. 1 root abrt    9 Dec 15 10:53 pkg_name
-rw-r-----. 1 root abrt    6 Dec 15 10:53 pkg_release
-rw-r-----. 1 root abrt    6 Dec 15 10:53 pkg_vendor
-rw-r-----. 1 root abrt    4 Dec 15 10:53 pkg_version
-rw-r-----. 1 root abrt 1.2K Dec 15 10:53 proc_pid_status
-rw-r-----. 1 root abrt   13 Dec 15 10:53 pwd
-rw-r-----. 1 root abrt   23 Dec 15 10:53 reason
-rw-r-----. 1 root abrt    4 Dec 15 10:53 runlevel
-rw-r-----. 1 root abrt   10 Dec 15 10:53 time
-rw-r-----. 1 root abrt    4 Dec 15 10:53 type
-rw-r-----. 1 root abrt    4 Dec 15 10:53 uid
-rw-r-----. 1 root abrt    8 Dec 15 10:53 username
-rw-r-----. 1 root abrt   40 Dec 15 10:53 uuid
-rw-r-----. 1 root abrt  155 Dec 15 10:53 var_log_messages

各ファイルの詳細は長いので gist にまとめた https://gist.github.com/hiboma/5b7caa8e0a4a9e3254aeda9d86b86a72

自作のバイナリでのテスト

こんな C のコードを書いてテストをした

static int i = 0;

int main() {
    char buffer[16];

    for(;;) 
        buffer[i++] = 'a';
}

実行するとインデックスでの参照がスタック領域を超えページフォルトを起こし、SIGSEGV で kill される

/var/log/messages にログが残るが、先ほどとは内容が違う

Dec 15 10:57:09 localhost kernel: a.out[3057]: segfault at 7fff75726000 ip 0000000000400502 sp 00007fff75724710 error 6 in a.out[400000+1000]
Dec 15 10:57:09 localhost abrt-hook-ccpp: Process 3057 (a.out) of user 1000 killed by SIGSEGV - dumping core
Dec 15 10:57:09 localhost abrt-hook-ccpp: Failed to create core_backtrace: dwfl_getthread_frames failed: No DWARF information found
Dec 15 10:57:09 localhost abrt-server: Executable '/home/vagrant/a.out' doesn't belong to any package and ProcessUnpackaged is set to 'no'
Dec 15 10:57:09 localhost abrt-server: 'post-create' on '/var/spool/abrt/ccpp-2016-12-15-10:57:09-3057' exited with 1
Dec 15 10:57:09 localhost abrt-server: Deleting problem directory '/var/spool/abrt/ccpp-2016-12-15-10:57:09-3057'

RPM として提供されていないバイナリの場合は ProcessUnpackaged を yes にしておかないと abrtd の採取対象とならないようだ

$ sudo perl -i'' -nlpe 's/ProcessUnpackaged = no/ProcessUnpackaged = yes/' /etc/abrt/abrt-action-save-package-data.conf

再度同じ手順を踏むと abrtd がキャッチしてくれた (設定変更後の abrtd の再起動はいらないみたい)

$ sudo abrt-cli list
id 856651691a20719d3e5387eda67265af645f64da
reason:         a.out killed by SIGSEGV
time:           Thu Dec 15 11:02:27 2016
cmdline:        aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
uid:            1000 (vagrant)
count:          2
Directory:      /var/spool/abrt/ccpp-2016-12-15-11:02:27-3114

The Autoreporting feature is disabled. Please consider enabling it by issuing
'abrt-auto-reporting enabled' as a user with root privileges

おおっと cmdline: が aaaaaa … になっている。バッファオーバーフローで argv[0] のスタックまで破壊してしまったせいだろう。これはこれで知見だ


abrtd には様々なオプションや拡張が用意されているが とりあえずここまで

ソースコードリーディング: static void init_once(void *foo)

カーネルトリビア

Linux カーネルのソース (CentOS7) を読んでいると、下記のようなコードを見つけた

static void init_once(void *foo)
{
         struct socket_alloc *ei = (struct socket_alloc *)foo;
 
         inode_init_once(&ei->vfs_inode);
}

変数名が foo とは ... 何とも適当ぽい。もうちょっと調べてみると他の箇所にもある

static void init_once(void *foo)
{
        struct ext4_inode_info *ei = (struct ext4_inode_info *) foo;

        INIT_LIST_HEAD(&ei->i_orphan);
        init_rwsem(&ei->xattr_sem);
        init_rwsem(&ei->i_data_sem);
        init_rwsem(&ei->i_mmap_sem);
        inode_init_once(&ei->vfs_inode);
}

GNU global でリストしてみると いろんなファイルシステムで同様の宣言が見られる

init_once         262 fs/adfs/super.c  static void init_once(void *foo)
init_once         127 fs/affs/super.c  static void init_once(void *foo)
init_once         298 fs/befs/linuxvfs.c static void init_once(void *foo)
init_once         262 fs/bfs/inode.c   static void init_once(void *foo)
init_once         412 fs/block_dev.c   static void init_once(void *foo)
init_once        8670 fs/btrfs/inode.c static void init_once(void *foo)
init_once          69 fs/coda/inode.c  static void init_once(void *foo)
init_once          80 fs/efs/super.c   static void init_once(void *foo)
init_once         183 fs/ext2/super.c  static void init_once(void *foo)
init_once         506 fs/ext3/super.c  static void init_once(void *foo)
init_once         936 fs/ext4/super.c  static void init_once(void *foo)
init_once          72 fs/f2fs/super.c  static void init_once(void *foo)
init_once          40 fs/fat/cache.c   static void init_once(void *foo)
init_once         594 fs/fat/inode.c   static void init_once(void *foo)
init_once         192 fs/hpfs/super.c  static void init_once(void *foo)
init_once         711 fs/hugetlbfs/inode.c static void init_once(void *foo)
init_once         383 fs/inode.c       static void init_once(void *foo)
init_once          89 fs/isofs/inode.c static void init_once(void *foo)
init_once         186 fs/jfs/jfs_metapage.c static void init_once(void *foo)
init_once         860 fs/jfs/super.c   static void init_once(void *foo)
init_once          82 fs/minix/inode.c static void init_once(void *foo)
init_once          70 fs/ncpfs/inode.c static void init_once(void *foo)
init_once        1832 fs/nfs/inode.c   static void init_once(void *foo)
init_once          94 fs/proc/inode.c  static void init_once(void *foo)
init_once         373 fs/qnx4/inode.c  static void init_once(void *foo)
init_once         633 fs/qnx6/inode.c  static void init_once(void *foo)
init_once         589 fs/reiserfs/super.c static void init_once(void *foo)
init_once         408 fs/squashfs/super.c static void init_once(void *foo)
init_once         332 fs/sysv/inode.c  static void init_once(void *p)
init_once         155 fs/udf/super.c   static void init_once(void *foo)
init_once        1449 fs/ufs/super.c   static void init_once(void *foo)
init_once         346 ipc/mqueue.c     static void init_once(void *foo)
init_once         282 net/socket.c     static void init_once(void *foo)
init_once        1495 net/sunrpc/rpc_pipe.c init_once(void *foo)
init_once         148 security/integrity/iint.c static void init_once(void *foo)

static void init_once(void *foo) は kmem_cache_create() に渡す関数ポインタとして利用されていて、みな同じ宣言になっている。

所謂 foo bar foo なんだろうけど、他になんか意味があるのかなぁ ... とか勘ぐりを入れてしまう。ただ単に最初にコミットされたコードが そのまま伝染しているのかもしれない。いや、やっぱり foo は構成員のみが知り得る特殊な暗号としての意味が潜んでいて ... (考え過ぎ)

Linux カーネルと言えど「あれ、こんなんでいいのかな???」という変数名 やコメント(時にはジョーク) が混じっていたりして おおらかな気分になれる。他にもいろいろあった気がしたので、思い出したらここに書こう

man-pages 4.09 のリリース

ちょっと前から linux-man の ML を読み始めたのだけど、 man-pages 4.09 のリリースがお知らせされていた

linux-man-pages.blogspot.jp

リリースの内容

詳細はリンク先をみてもらえばよいが、更新内容は Linux Kernel 4.9 で追加された新しいシステムコールを対象にした man もあれば、新しいものに限らず下のように広範なトピックがはいっている。コミットだけで見ると typo fix やスタイル調整も結構な量があるようだ

自分の関心をひいたのは以下の更新

A new pkey_alloc(2) page, written by Dave Hansen, documents the pkey_alloc() and pkey_free() system calls added in Linux 4.9.

4.9 で追加された pkey_alloc(2) 共有ホスティングのようなとこで何か利用できないか? (e.g. mod_process_security )

A new fuse(4) page, written by Keno Fischer, partially documents the /dev/fuse device.

/dev/fuse について。ここ最近、社内外で fuse をハックした実装をよく見かけていたが /dev/fuse そのもの実装をおいたかったのでタイムリ

A new sock_diag(7) page, written by Pavel Emelyanov and Dmitry V. Levin, documents the NETLINK_SOCK_DIAG interface.

sock_diag(7) - Linux manual page socket の内部情報を取るための NETLINK_SOCK_DIAG インタフェースについて。UNIX ドメインソケットのバックログサイズを netlink インタフェースで計測してみたかったのだけど使い方がわからず頓挫していた調査があったので、これもタイムリ

A new tmpfs(5) page, written by me, provides an overview of the tmpfs filesystem.

tmpfs について。内部実装は System V 共有メモリの anon なページの mmap(2) でも使われている点への言及など

リリースの間隔

man-pages の過去リリースを見ると、 kernel のマイナーバージョン更新 (今回は 4.8 -> 4.9 ) にタイミングを合わせているよな感じ

kernel man-pages
4.9 - Sun, 11 Dec 2016 4.09 - Mon, 12 Dec 2016
4.8 - Sun, 2 Oct 2016 4.08 - Sat, 8 Oct 2016
4.7 - Sun, 24 Jul 2016 4.07 - Sun, 17 Jul 2016
4.6 - Sun, 15 May 2016 4.06 - Wed, 11 May 2016

📝 バージョニングも揃ってるぽいので、後で過去ログを調べてみよう

man-pages のメンテナについて

このエントリを書くまで認知していなかったのだが、 man-pages のメンテンナである Michael Kerrisk さんは 『Linuxプログラミングインタフェース』本の著者でもあって「ああ なるほど」である

Linuxプログラミングインタフェース

Linuxプログラミングインタフェース

厚い

デバッグ: gdb で ruby のバックトレースを自動で採取

とある Rails / Unicorn サーバで perf top を眺めていたら、やたらと bcrypt_ext.soBF_crypt が高いオーバーヘッドを示しているのを発見した。ひゃぁ

Samples: 168K of event 'cycles', Event count (approx.): 50386752987
Overhead  Shared Object             Symbol
  36.61%  bcrypt_ext.so             [.] BF_crypt 🔥
   7.83%  ruby                      [.] vm_exec_core
   3.66%  ruby                      [.] st_lookup
   3.55%  ruby                      [.] mix_id_table_lookup
   2.44%  ruby                      [.] vm_search_method.isra.79
   1.87%  libc-2.17.so              [.] _int_malloc

gdb で調査

BF_crypt の呼び出し元を探るべく gdbunicorn にアタッチして rb_backtrace() でバックトレースを採取するのを試行錯誤していたが、ブレークする度にリクエストを止めていることに気がついたのでこりゃマズいと、採取方法を変えた。

gdb で調査

command を使って自動化した

$ sudo gdb -p <unicorn の pid>

(gdb) b BF_crypt
Breakpoint 1 at 0x7f8452663350: file crypt_blowfish.c, line 569.

(gdb) command 1
Type commands for breakpoint(s) 1, one per line.
End with a line saying just "end".
>call rb_backtrace()
>continue
>end
(gdb) c
Continuing.

gdbunicorn にアタッチして

  • BF_crypt で 停止する
  • call rb_backtrace() でバックトレースを stderr に出力する
  • gdb を 再開する

という command をセットした。 ブレークポイントで停止してバックトレースを出して自動で再開することで、停止時間を極力短くすることができる。

one more

更に自動化、手順をファイルに書き出して stdin から読み込ませて手作業を減らした

break BF_crypt
command 1
  call rb_backtrace()
  continue
end
continue

こんな感じで扱える

sudo gdb -p <unicorn worker の pid>  < gdb-BF_crypt-of-unicorn

( これを実行すると unicorn worker プロセスが生きている限りバックトレースの採取が続いてしまう。「 n回 command を実行したら quit する」を実現するにはどうしたらよいのだろう? )

実行

gdb でアタッチして unicorn のログを tail していると、下記のようなバックトレースがバンバン採取できた

 from /path/to/current/vendor/bundle/ruby/2.3.0/bin/unicorn:23:in `<main>'
    from /path/to/current/vendor/bundle/ruby/2.3.0/bin/unicorn:23:in `load'
    from /path/to/current/vendor/bundle/ruby/2.3.0/gems/unicorn-5.2.0/bin/unicorn:126:in `<top (required)>'
略 ... 
    from /path/to/releases/2016120******/app/controllers/concerns/foo.rb:32:in `block in bar' 
    from /path/to/releases/2016120******/vendor/bundle/ruby/2.3.0/gems/devise-4.2.0/lib/devise/models/database_authenticatable.rb:45:in `valid_password?'
    from /path/to/releases/2016120******/vendor/bundle/ruby/2.3.0/gems/devise-4.2.0/lib/devise/encryptor.rb:18:in `compare'
    from /path/to/current/vendor/bundle/ruby/2.3.0/gems/bcrypt-3.1.11/lib/bcrypt/engine.rb:51:in `hash_secret'
    from /path/to/current/vendor/bundle/ruby/2.3.0/gems/bcrypt-3.1.11/lib/bcrypt/engine.rb:51:in `__bc_crypt'

(  大量のバックトレースがでてくるので、一部だけ )

採取できたバックトレースを比較してみて、とある concerrs 経由での呼び出しなのを特定できた。

アプリケーションをよく見知った人であれば Rails, BCrypt から devise の存在を連想してどこが怪しいかをポイントすることも可能だろう ( 実際にそういうレビューをもらえた 😊 )。デバッグツールによって推測を実証にできた。

rb_backtrace について

ruby のソース vm_backtrace.c を除くと下記のようなコードだった

void
rb_backtrace(void)
{
    vm_backtrace_print(stderr);
}

vm_backtrace_print() は下記の通り

static void
vm_backtrace_print(FILE *fp)
{   
    struct oldbt_arg arg;
    
    arg.func = oldbt_print;
    arg.data = (void *)fp;
    backtrace_each(GET_THREAD(),
                   oldbt_init,
                   oldbt_iter_iseq,
                   oldbt_iter_cfunc,
                   &arg);
}   

で、vm_backtrace.c を覗いていると rb_backtrace_print_as_bugreport() というのを見つけた

void
rb_backtrace_print_as_bugreport(void)
{   
    struct oldbt_arg arg;
    int i = 0;
    
    arg.func = oldbt_bugreport;
    arg.data = (int *)&i;

    backtrace_each(GET_THREAD(),
                   oldbt_init,
                   oldbt_iter_iseq,
                   oldbt_iter_cfunc,
                   &arg);
}

rb_backtrace_print_as_bugreport() を使ってみたらバックトレースのフォーマットが変わったのだった

-- Ruby level backtrace information ----------------------------------------
/path/to/current/vendor/bundle/ruby/2.3.0/bin/unicorn:23:in `<main>'
/path/to/current/vendor/bundle/ruby/2.3.0/bin/unicorn:23:in `load'
/path/to/current/vendor/bundle/ruby/2.3.0/gems/unicorn-5.2.0/bin/unicorn:126:in `<top (required)>'
/path/to/releases/20161208******/vendor/bundle/ruby/2.3.0/gems/unicorn-5.2.0/lib/unicorn/http_server.rb:132:in `start'

...

/path/to/20161208******/app/controllers/concerns/api/foo.rb:32:in `block in bar'
/path/to/20161208******/vendor/bundle/ruby/2.3.0/gems/devise-4.2.0/lib/devise/models/database_authenticatable.rb:45:in `valid_password?'
/path/toreleases/20161208******/vendor/bundle/ruby/2.3.0/gems/devise-4.2.0/lib/devise/encryptor.rb:18:in `compare'
/path/to/current/vendor/bundle/ruby/2.3.0/gems/bcrypt-3.1.11/lib/bcrypt/engine.rb:51:in `hash_secret'
/path/to/current/vendor/bundle/ruby/2.3.0/gems/bcrypt-3.1.11/lib/bcrypt/engine.rb:51:in `__bc_crypt'

右側の空白のオフセットが消えてログの最初にヘッダが一行入っていいるので、tail で追う際に見やすい。こっちでも問題ないだろうか

トレーニングライド

寒くなって朝の お布団峠 を越えられない

夜に1時間ほど走って終わり

練馬〜和光市〜朝霞 を往復するのがトレーニングコース。志木まで足を伸ばすこともある。陸上自衛隊朝霞駐屯地の前に 1.5 km ほどのストレート区間があり、路側帯も十分に広いので負荷をかけて走るのにちょうどよい (夜間は真っ暗な道のでつよいライトで照らそうね 🔦)

全体的にアップダウンはあまりないコース。荒川にかけて坂になってはいるが 高低差が小さいので物足りない。多摩丘陵のように緩急ついてると楽しいんだけどなぁ

公園で休憩していたら流れ星が見えた 冬本番

Google Play Music

Subsonic から Google Play Music に移行する - @banyan's blog を読んで、そういうやそんなのあったなと、 Google Play Music の存在を思い出して、家の外付けHDDで塩漬けになっていた iTunes の楽曲をアップロード祭りしている

f:id:hiboma:20161207152524p:plain

以前はアップロードの上限が2万曲だったはずで、iTunes にインポート済みの楽曲数だけで上限を超えてしまっていた。ローカルと Google Play Music の同期が中途半端になるのかな〜と思い利用していなかったのだが、上限が緩和されて5万曲になっていたのだね

f:id:hiboma:20161207153154p:plain

押し入れにしまい込んでいたインポートしていない CD の山も片付けられそうな気がする。あと 1000枚位あるので来年までかかりそうな気配

f:id:hiboma:20161207172443p:plain

アルバムの再生時に勝手に背景写真が付くけど、音源の発表と年代が近い写真が選択される仕組みがあってもいいんじゃないかな ... と思ったワンショット 😂 (メンバーも違うしね)


はせこさん、参考になりました。ありがとう 😊