gdbを使ってsegmentation faultを調べる
いきなりsegmentation fault (core dump)と端末に表示されて異常終了をするプログラムに頭を悩まされていました。
...(順調に処理中)... /home/yuyabu/3d/bin/02.sh: 42 行: 58161 浮動小数点例外 (コアダンプ) openMVG/Linux-x86_64-RELEASE/openMVG_main_IncrementalSfM -i result/sfm_data.json -m matches -o out
C/C++でLinuxな環境であり、かつ自分で作ったファイルまたはオープンソースなどでバイナリに対応したファイルが用意できれば、gdbを使ってエラーが発生している箇所がわかるかもしれません。
ちなみに今回の対象ソースはOpenMVGという3Dを処理するOSSです。
1.core fileが作成されるように設定する
Unix系のOSではプログラムが異常終了したときにメモリなどの情報を「corefile」として吐き出す機能があります。
こちらはデフォルトの状態では出力サイズが制限されており作成されないようになっているので、ulimit -c unlimited
で
corefileを無制限に作成できるように設定します。
ulimit -a core file size (blocks, -c) unlimited data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 4124107 max locked memory (kbytes, -l) unlimited max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) 4124107 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
これでcoredump発生時に実行時のカレントディレクトリにcorefileが作成されるようになります。
2.セグメンテーションフォルトが発生するプログラムをDEBUGビルドする
エラーが発生しているバイナリのソースをデバッグビルドします デバッグビルドができるようなオプションをつけてビルドツールを実行してください。 こちらは調査対象のアプリやビルドツールによって色々なので各自調べてください。
今回私が調査したopenMVGの場合は以下ビルド方法の「3.Configure and build」のオプション-DCMAKE_BUILD_TYPE
をRELEASEからDEBUGに変えるだけです。
$ cmake -DCMAKE_BUILD_TYPE=DEBUG ../openMVG/src/ $ cmake --build . --target install
3.gdbで調べる
gdb <実行バイナリ> <corefile>
gdb ../build/openMVG/Linux-x86_64-DEBUG/openMVG_main_IncrementalSfM ./core GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>. Find the GDB manual and other documentation resources online at: <http://www.gnu.org/software/gdb/documentation/>. For help, type "help". Type "apropos word" to search for commands related to "word"... Reading symbols from ../build/openMVG/Linux-x86_64-DEBUG/openMVG_main_IncrementalSfM... done. warning: core file may not match specified executable file. [New LWP 58245] ...(略)... [New LWP 58268] [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1". Core was generated by `/home/yuyabu/3d/build/openMVG/Linux-x86_64-DEBUG/openMVG_main_IncrementalSf'. Program terminated with signal SIGFPE, Arithmetic exception. #0 0x000055dc1f18c7e6 in Eigen::internal::gebp_kernel<double, double, long, Eigen::internal::blas_data_mapper<double, long, 0, 0>, 12, 4, false, false>::operator() (this=0x7f2af88ccf0c, res=..., blockA=0x7f2af88cd340, blockB=0x7f2af88cd3a0, rows=3, depth=0, cols=3, alpha=-1, strideA=0, strideB=0, offsetA=0, offsetB=0) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h:926 926 const Index actual_panel_rows = (3*LhsProgress) * std::max<Index>(1,( (l1 - sizeof(ResScalar)*mr*nr - depth*nr*sizeof(RhsScalar)) / (depth * sizeof(LhsScalar) * 3*LhsProgress) )); [Current thread is 1 (Thread 0x7f2af88ce700 (LWP 58245))] (gdb)
backtraceを取って該当の処理がどこから呼ばれたのか?ということもある程度わかります。
(gdb) bt #0 0x000055dc1f18c7e6 in Eigen::internal::gebp_kernel<double, double, long, Eigen::internal::blas_data_mapper<double, long, 0, 0>, 12, 4, false, false>::operator() (this=0x7f2af88ccf0c, res=..., blockA=0x7f2af88cd340, blockB=0x7f2af88cd3a0, rows=3, depth=0, cols=3, alpha=-1, strideA=0, strideB=0, offsetA=0, offsetB=0) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h:926 #1 0x000055dc1f2ef74a in Eigen::internal::triangular_solve_matrix<double, long, 2, 2, false, 1, 0>::run (size=3, otherSize=3, _tri=0x7f2af88cdb30, triStride=3, _other=0x7f2af88cdd00, otherStride=3, blocking=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h:324 #2 0x000055dc1f3214ef in Eigen::internal::triangular_solve_matrix<double, long, 1, 1, false, 0, 1>::run (size=3, cols=3, tri=0x7f2af88cdb30, triStride=3, _other=0x7f2af88cdd00, otherStride=3, blocking=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h:32 #3 0x000055dc1f36ef5a in Eigen::internal::triangular_solver_selector<Eigen::Transpose<Eigen::Matrix<double, 3, 3, 1, 3, 3> const> const, Eigen::Matrix<double, 3, 3, 1, 3, 3>, 1, 1, 0, -1>::run (lhs=..., rhs=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/SolveTriangular.h:102 #4 0x000055dc1f36cf13 in Eigen::TriangularViewImpl<Eigen::Transpose<Eigen::Matrix<double, 3, 3, 1, 3, 3> const> const, 1u, Eigen::Dense>::solveInPlace<1, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (this=0x7f2af88cd4e0, _other=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/SolveTriangular.h:179 #5 0x000055dc1f36ad71 in Eigen::TriangularViewImpl<Eigen::Transpose<Eigen::Matrix<double, 3, 3, 1, 3, 3> const> const, 1u, Eigen::Dense>::solveInPlace<Eigen::Matrix<double, 3, 3, 1, 3, 3> > (this=0x7f2af88cd4e0, other=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/TriangularMatrix.h:511 #6 0x000055dc1f368157 in Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>::solveInPlace<Eigen::Matrix<double, 3, 3, 1, 3, 3> > (this=0x7f2af88cdb30, bAndX=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Cholesky/LLT.h:496 #7 0x000055dc1f366674 in Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>::_solve_impl<Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> >, Eigen::Matrix<double, 3, 3, 1, 3, 3> > (this=0x7f2af88cdb30, rhs=..., dst=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Cholesky/LLT.h:476 #8 0x000055dc1f3653de in Eigen::internal::Assignment<Eigen::Matrix<double, 3, 3, 1, 3, 3>, Eigen::Solve<Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> > >, Eigen::internal::assign_op<double, double>, Eigen::internal::Dense2Dense, void>::run (dst=..., src=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/Solve.h:147 #9 0x000055dc1f364a1d in Eigen::internal::call_assignment_no_alias<Eigen::Matrix<double, 3, 3, 1, 3, 3>, Eigen::Solve<Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> > >, Eigen::internal::assign_op<double, double> > (dst=..., src=..., func=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/AssignEvaluator.h:836 #10 0x000055dc1f363a90 in Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> >::_set_noalias<Eigen::Solve<Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> > > > (this=0x7f2af88cdd00, other=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/PlainObjectBase.h:728 #11 0x000055dc1f362cbd in Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 3, 1, 3, 3> >::PlainObjectBase<Eigen::Solve<Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> > > > (this=0x7f2af88cdd00, other=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/PlainObjectBase.h:537 #12 0x000055dc1f361f70 in Eigen::Matrix<double, 3, 3, 1, 3, 3>::Matrix<Eigen::Solve<Eigen::LLT<Eigen::Matrix<double, 3, 3, 1, 3, 3>, 2>, Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<double>, Eigen::Matrix<double, -1, -1, 1, -1, -1> > > > (this=0x7f2af88cdd00, other=...) at /home/yuyabu/3d/src/openMVG/src/third_party/eigen/Eigen/src/Core/Matrix.h:379 #13 0x000055dc1f360df1 in ceres::internal::InvertPSDMatrix<3> (assume_full_rank=true, m=...) at /home/yuyabu/3d/src/openMVG/src/third_party/ceres-solver/internal/ceres/invert_psd_matrix.h:60 #14 0x000055dc1f389aaf in ceres::internal::SchurEliminator<2, 3, 6>::Eliminate (this=0x7f2af88cdcb0, A=0x7f2af88cdd60, b=0x55dc208c71f0, D=0x55dc20595f50, lhs=0x7f2af88cdb40, rhs=0x55dc1f38b360 <ceres::internal::SchurEliminator<2, 3, 6>::ChunkDiagonalBlockAndGradient(ceres::internal::SchurEliminator<2, 3, 6>::Chunk const&, ceres::internal::BlockSparseMatrix const*, double const*, int, Eigen::Matrix<double, 3, 3, 1, 3, 3>*, double*, double*, ceres::internal::BlockRandomAccessMatrix*)+552>) at /home/yuyabu/3d/src/openMVG/src/third_party/ceres-solver/internal/ceres/schur_eliminator_impl.h:273
参考: qiita.com
なおデバッグビルドしたバイナリがなくても-cオプションでcorefileだけでgdbを起動できます。
$man gdb ...(略) OPTIONS ...(略) -core=file -c file Use file file as a core dump to examine.
ただし関数名などがわからないのでアドレスみたらわかるマンじゃないときついと思います。
$ gdb -c core ・・・(略) [New LWP 58268] Core was generated by `/home/yuyabu/3d/build/openMVG/Linux-x86_64-DEBUG/openMVG_main_IncrementalSf'. Program terminated with signal SIGFPE, Arithmetic exception. #0 0x000055dc1f18c7e6 in ?? () [Current thread is 1 (LWP 58245)]
約2年間続いた読書会で「プログラマのためのSQL」を読み終わりました
本日がラスト39回目で最終回。翻訳者のミックさんが参加され翻訳者後書きを読んでもらえました。非常に感慨深いものがありました。
初回が2017年3/1で二年と1ヶ月、全39回で読み終わりました。私は15回から参加しています。ちなみに私は目黒バイナリ勉強会で参加数2位のようです。(一位は@quwaharaさん)
meguro-binary-study.connpass.com
会場は中目黒でした。寒いためか花見客が少なかった?そうです。
打ち上げ。シリコンバレーのエンジニア事情などの話題で盛り上がりました。
本書について
- 作者: ジョー・セルコ,Joe Celko,ミック
- 出版社/メーカー: 翔泳社
- 発売日: 2013/05/24
- メディア: 大型本
- この商品を含むブログ (16件) を見る
本書はSQLをメインテーマに書かれた和書で最も分厚いと思います(多分)。
本書に掲載されているクエリからはこんなこともできるのか!と感じさせるほどSQLの威力が存分に発揮されていますが、 一方でSQLの利用はデータ取り出しにとどめておいて、複雑なことは専用のミドルウェアやアプリでやるべきという主張も読み取れます。 普段書かないようなクエリを通してSQLとは何か?に迫る本書はSQLの入門マニュアルでも百科事典でもなく、SQLのエッセンスに迫れる数少ない一冊であると思います。特にNullについて書かれている13章はSQLに関わる全エンジニアにお勧めです。
- セルコの日記のようなページ
- よくわからない雑学(グレゴリオ暦の話とか)
- かなり複雑で長いSQLがほとんど説明がなく掲載されている(しかもエラーで動かないものも多い)
- コンピュサーブ(昔のコミュニティサイト?)の投稿SQLなどが解説不足した状態で沢山掲載されている
などの一人で読むには辛い&冗長なページが沢山あるので個人で通読するにはあまり向かないような気がします。 という訳で様々なRDBベンダーのユーザーで集まってワイワイ話しながら読み進めることができたので、個人的に贅沢な読み方ができたのではないかと思います。
今から読むなら本書よりもミックさんが書かれている達人シリーズの方が本書のエッセンスが濃縮&抽出されていておすすめです。
達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ (CodeZine BOOKS)
- 作者: ミック
- 出版社/メーカー: 翔泳社
- 発売日: 2018/10/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ
- 作者: ミック
- 出版社/メーカー: 翔泳社
- 発売日: 2012/03/16
- メディア: 単行本(ソフトカバー)
- 購入: 21人 クリック: 316回
- この商品を含むブログ (24件) を見る
今後目黒バイナリ勉強会では何を読むのか?
私が決めることではありませんが多分以下の2冊が候補になっていると思います。
失敗から学ぶRDBの正しい歩き方 (Software Design plus)
- 作者: 曽根壮大
- 出版社/メーカー: 技術評論社
- 発売日: 2019/03/06
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
個人的に今後読む本
多方面から勧められていますが、今日ミックさんにも勧められたのでこの本は通読したい
- 作者: 戸田山和久
- 出版社/メーカー: 名古屋大学出版会
- 発売日: 2000/10/10
- メディア: 単行本(ソフトカバー)
- 購入: 27人 クリック: 330回
- この商品を含むブログ (108件) を見る
他
商用rdbってベンチ取ったものを公開するのNGのものが多いらしい。知らんかった
— yuYabu☕︎珈琲好き (@yuyabu2) April 2, 2019
セルコが一番使ってる可能性があるのはSQL Serverらしい
— yuYabu☕︎珈琲好き (@yuyabu2) April 2, 2019
手ぶら通勤のためサインもらえるようなものがないよ😭
— yuYabu☕︎珈琲好き (@yuyabu2) April 2, 2019
シリコンバレーのエンジニアより日本のエンジニアの方が可処分所得はたかそう。
— yuYabu☕︎珈琲好き (@yuyabu2) April 2, 2019
参加者のみなさん、主催の木村さん、翻訳者のミックさん、そして原作者のセルコさんありがとうございました&お疲れ様でした。
分散システムにおけるイベントの前後関係と論理時計・ベクトル時計について
分散システムでは時刻同期はとらずに順序同期だけをとっている、という話はよく聞きます。順序同期とはいったいどのような仕組みなのでしょうか
前提
- 各ノード間の処理の順序を適正に処理したい。
- 個々のサーバーが原子時計などの十分に正確な時計を持っていることを前提としない
- 時刻の責任を持つノード(FTPや電波時計)のある仕組みは順序同期のためには使えない(ミリ秒単位の誤差が発生するため)
前後関係とは
プロセスローカルでの順序と送受信イベントからの推移測で導かれる順序のことを前後関係といいます。 前後関係には以下のルールがあります。
(ルールH1)同一プロセス上でおこなわれたイベントeとe'に対して、eがe'の後に行われていればe→e'が成り立つ
(ルールH2)eがメッセージmの送信イベント、e'がmの受信イベントであればe→e'が成立する
(ルールH3)e→e'、e'→e''ならば、e→e''
これらのルールから察する通り、すべてのイベント間の前後関係を定義できるわけではありません。 特に、本記事で紹介するアルゴリズムでは通信が行われていないノード間ではそれぞれのイベントがどちらが先に起こったか類推することはできません。
なおここで定義した前後関係は以下の特性があるため、半順序(Partial order)になります。
- 満たしている:推移律(定義より自明)、反射率(自分自身と同値な関係)、反対象律(相違な2要素の同値な関係がない)
- 満たしていない:完全律(比較できない相違な2要素がある)
比較できない関係を「平行である」といいます。例えば下記の例だと
- b1→b2(ルールH1)
- a1→b1(ルールH2)
- c1→b2(ルールH2)
- a1→b2(ルールH3)
という前後関係を導出することができますが、 a1とc1に関しては前後関係の比較ができません。
論理時計
前後関係を実現する実装として「論理時計」というものがあります。 前後関係を定義したルール通通りそのまま実装すると、順序関係の保存と推移の計算などでパフォーマンス上あまり効率的ではありません。ローカルなイベント発生時のカウンタインクリメントと送受信イベント時のカウンターの比較・マージによって効率よくルールH1,H2,H3を満たす実装が論理時計です。
論理時計は以下のルールに沿って動作します
(ルールC1) 各プロセスは初期状態において、時計の時刻t=0である
(ルールC2) 受信以外のイベントeを行うときに、時計の時刻を1増やす
(ルールC3) メッセージ送信イベントeを行うときには、送信イベントeの発生時刻t(e)をメッセージに付加して送る
(ルールC4) メッセージ受信イベントeを行うときには、受信したメッセージに付加された時刻をt'とすると、t←max(t,t')+1として、この値をイベントeの発生時刻t(e)とする
論理時計を使うことで以下のことがわかります。
イベントeとe'でe→e'ならt(e)<t(e')
逆は成り立ちません。t(e)<t(e')ならe→e'
ということは言えません。
たとえば下記の図だとt(a1)<t(c2)ですが、a1→c2ではありません。
ベクトル時計
論理時計より強力なベクトルクロックでt(e)<t(e')ならe→e'
を成り立たせることができます。
プロセス数n,iэ{1,2,...n}の時ベクトル時計では各プロセスPiがベクトル時計Vi=(v1,v2,...vn)を持ちます。
ベクトル時計は以下のルールV1~V4で実現できます
(V1)各プロセスは初期状態において、ベクトル時計の時刻V=(0,0,...,0)である。
(V2) プロセスPiは受信以外のイベントeを行うときに、ベクトル時計の時刻V=(v1,v2,...,vn)にたいして、vi←vi + 1を行ったV'にベクトル時計の値をへんこうし、この値V'をイベントeの発生時刻V(e)とする
(V3) メッセージ送信イベントeを行うときには、送信イベントeの発生時刻V(e)をメッセージに付加して送る
(V4) プロセスPiがメッセージ受信イベントeを行うときには、受信したメッセージにふかされた時刻をV'=(v1',v2',...,vn')とすると、vj←max(vj,vj')(1<=j<=n)を実行し、さらにvi ← vi + 1を行った値にベクトル時計のアタを変更し、この時刻をイベントeの発生時刻V(e)とする
以下はこのベクトル時計Vを使う例です。ベクトル時計を青字で、論理時計を赤時で引き続き示しています。
- V(b2)=(1,2,2)とV(c2)=(0,0,2)ではV(c2)<V(b2)の大小関係があるのでc2→b2の前後関係があることがわかります。
- V(a1)=(1,0,0)とV(c2)=(0,0,2)には大小関係がありませんので、a1とc2が並行であることがわかります。
この記事は「分散システム(情報工学レクチャーシリーズ)」の第2章 時刻と時計の個人的まとめです。
- 作者: 真鍋義文
- 出版社/メーカー: 森北出版
- 発売日: 2013/09/14
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
Linuxのパフォーマンス計測ツールの違いとか
詳解システムパフォーマンス4章で学んだことや、直近で利用したツール等のざっくりしたまとめ。引用はすべて詳解システムパフォーマンスの4章のもの。
カウンタタイプ
カーネルは、イベントの回数を数えたカウンタ( counter )と呼ばれるさまざまな統計を管理し ている。
カウンタはデフォルトで有効になっており、カーネルによって継続的にメンテナンスされている ので、 「タダ」で使えると考えてよい。カウンタを使うときの唯一の追加コストは、ユーザーラン ドからの値の読み出しである(無視できる)。
カーネルはIOやCPU利用の実績を/sys
や/proc
配下のファイルに書き込んでいる。これは標準でデフォルトになっているため、読み出しコストのみで参照することができる。多くのXstat系のツールはこの形式になっている。
カウンタタイプのツールとしては
- vmstat
- iostat
- sar
などがある。個人的にはdstatというstat族のキメラ的なツールがあるでそちらを利用している。
トレーサタイプ
イベントごとのデータを集めてくるツールのこと。システムコール、ネットワークパケット、ディスクIOなどのイベント発生時の情報を収集します。頻度の高いイベントを対象にすると観測自体に負荷が高いため、それを考慮に入れること。またパフォーマンスの都合上、デフォルトで無効にされているものもあるため、利用した後は無効にするなどしてもとに戻すこと。
トレーシングはデータをキャプチャするために CPU にオーバーヘッドをかけ、保存のためにかなりの量のストレージを必要とすることがあるため、一般にデフォルトでは有効にされていない。
- ftrace カーネルトレーサ。呼び出しているカーネルのコードのスタックや引数などをトレースできる。
- gdb デバッガ。ソースコードや機械語の特定の行でのトレースを行う
- strace プロセスのシステムコール・シグナルをトレースする
プロファイラ
ある実行バイナリに異常な時間がかかっているというときはコンパイルでデバッグオプションでビルドした後、gprofで処理に時間がかかっている関数を調べることができる。
参考:gprofの使い方 https://minus9d.hatenablog.com/entry/20140112/1389502918
他:timeコマンドのvオプション
timeコマンドだけでもioの回数やswappingの発生、rssなどがわかる。
参考:https://kuenishi.hatenadiary.jp/entry/2016/11/02/131046
上記の重厚な?ツール群を試す前に/usr/bin/time -v
を使ってみるのもいいかもしれない。
詳解システムパフォーマンスおすすめです。
青汁を一週間飲み続けました
近所の世間話がきっかけで青汁やさんの回数券を買ってほぼ毎日飲むという謎ムーブをかましました。
今週は毎日青汁飲もうと思います。🤗 pic.twitter.com/sml0PHMz6R
— yuYabu☕️ (@yuyabu2) 2019年2月10日
今週は100mlの回数券を買って平常時は100ml、たまに2枚使って200mlを飲むという感じでほぼ毎日飲めました*1。
効果はあったのか
今現在身体的に特に効果は出ていません。若干乾燥が改善したくらい*2。
私は成人男性にしては野菜を食べている方だと思うので、おそらく野菜不足を解消することによって発動する効果は現れないと思います。しかしケールの絞り汁を日常的に摂取した経験はないためケール固有の効果は出るかもしれません。
個人的な生活習慣の問題はコンビニ飯やジャンクフードが多いことと運動不足なので、そちらの改善を計画的に行わないと青汁を飲む意味がないような気がします。
気づいたこと
トッピングせずに青汁を飲む人はどうも少数派のようです。 飲んでいる青汁はいままで飲んだことのないようなハードコアな味がします。 他のお客さんもだいたいゴマ、はちみつ、リンゴ酢などを入れて飲みやすくしている人が多い印象です。私も初日は鼻をつまんで無理やり流し込むというスタイルで飲んでいましたが、いまは慣れたので普通に飲めています。
今後
回数券の量を100mlから200mlに増やして日常的に200ml飲むように変えて様子を見ようと思います。あと、豆腐屋さんが作っている豆乳もいいらしいのでそちらも試すかもしれません。
virtualbox でホスト(mac)とゲスト(ubuntu)のclipbordの共有がうまくいかない(解決)
色々生産性が悪いので調査した。
バージョン
- 仮想化ソフト:Virtualbox 5.2.22
- ゲスト:ubuntu 18.04
- ホスト:macOS Mojave 10.14.1
巷ではVirtualboxの設定>一般>高度の「クリップボードの共有」を「双方向」にすることで解決するという記事が多いが、 それだけでは解決しなかった。追加でVM側にVBoxClientを導入することで解決した。
yy@yy-VirtualBox:~$ sudo apt-get install virtualbox-guest-x11 yy@yy-VirtualBox:~$ sudo VBoxClient --clipboard
早速ターミナルで試してみた所、Ctrl + vが使えなくて調べた結果。。。
ターミナルではCtrl + Shift + V
が貼り付けらしい。
https://askubuntu.com/questions/202459/keyboard-shortcut-for-pasting-on-the-gnome-terminal