何年にもわたって、ITの世界、特にLinuxでソフトウェア関連の問題をトラブルシューティングする方法について長い間書いてきました。結局のところ、これは長い間私のパンとバターであり、私はまだ問題解決の芸術に非常に熱心です。私が多用したトピックの1つは、典型的なソフトウェアデバッガーであるgdbです。唯一の問題は、勝つために初期化する必要があるということです。
これが意味すること-問題を再現できれば、gdbは優れています。ただし、本番環境でソフトウェアを実行している場合は、問題を何度も引き起こし続ける余裕がない可能性があります。バグをキャプチャして再生する機能は大きな資産であり、ソフトウェアの記録された実行を正確で決定論的な方法でデバッグするのに役立つように設計されたツールであるRRの形式で提供されます。何が得られるか見てみましょう。
RReady、安定、設定
本質的に、RRはgdbであり、gdbはRRです。アイデアはシンプルで、実装はエレガントです。 rrを使用してツールを実行し、実行(および失敗)をキャプチャしてから、本番環境から離れて、必要な回数だけ記録を再生します。さらに、とらえどころのない問題がある場合は、繰り返し可能なシナリオを取得して、根本的な原因をより迅速に特定し、問題を修正できる可能性があります。
RRをFedora32にインストールして構成しました。非常に簡単です。さて、実行には細部への注意が必要です。プログラムを通常のユーザーとして実行すると、RRが特権カーネルイベントを実際に取得できないという警告が表示される場合があります。これを変更できれば、sudoは必要ありません。私たちがperfで実際に見たものと似ています。甘い。
rr record ./seg
rrには/proc/ sys / kernel / perf_event_paranoid <=1が必要ですが、2です。
1に変更するか、「rr record -n」(遅い)を使用します。
/etc/sysctl.confに「kernel.perf_event_paranoid=1」を入れることを検討してください
これを変更する方法はたくさんあります。値を/procに割り当て、sysctl -wを使用して値を書き込み、/ etc / sysctl.confファイルを手動で編集してから、構成を再ロードします。どちらの方法を選択しても、パフォーマンスが向上し、必要なすべてのイベントを追跡できるようになります。
sudo sysctl -w kernel.perf_event_paranoid =1
セグメンテーション違反の例
RRがどれほど実用的で有用かを確認するために、gdbチュートリアルと同じsegfaultの例を使用することにしました。基本的に、セグメンテーション違反につながるmalloc()のループ:
#include
#include
main()
{
int * pointer;
int i;
ポインタ=malloc(sizeof(int));
for(i =0; 1; i ++)
{
ポインタ[i]=i;
printf( "pointer [%d] =%d \ n"、i、pointer [i]);
}
return(0);
}
gcc -g seg.c -o seg
seg.c:4:1:警告:戻り値のタイプはデフォルトで「int」になります[-Wimplicit-int]
4 | main()
| ^ ~~~
RRレコードとRRリプレイ
RRが使用する2つの主な機能-記録と再生。
rrレコード./seg
...
ポインター[33621]=33621
ポインター[33622]=33622
ポインター[33623]=33623
セグメンテーション違反(コアダンプされた)
実際の実行は通常より遅くなることに注意してください。これは、時間に依存する問題がある場合、RRが役に立たない可能性があることを意味します。 straceで実際に見たものと非常によく似ています。確実に複製できる(つまり、適切な条件下で)決定論的な問題が必要です。
とにかく、問題を記録したら、それを再生できます:
rrリプレイ
RRを初めてロードしたときに、デバッグシンボルが使用できないという警告が表示されました。これは、問題のトラブルシューティングを本当に実行できるようにする場合に非常に重要です。 RRに固有のものではありませんが、これは考慮に入れるべきことです。必要に応じて、不足しているパッケージをインストールできます。プログラムには、それを実行するために使用できる正確なコマンドもリストされています。
127.0.0.1:7747を使用したリモートデバッグ
/lib64/ld-linux-x86-64.so.2からシンボルを読み取っています...
(/ lib64/ld-linux-x86にデバッグシンボルが見つかりません-64.so.2)
0x00007f25ce73e110 in _start()from /lib64/ld-linux-x86-64.so.2
個別のdebuginfoがない場合は、次を使用します:dnf debuginfo-install glibc-2.31-2 .fc32.x86_64--詳細を表示するには
RRインターフェースがロードされると、gdbランドに移動します。コマンドは同じです。ブレークポイントを設定し、それらのブレークポイントを実際にアクティブにしてタスクの実行を停止する条件を使用できます。
ブレーク10
条件1i==33610
続行
また、デバッグセッションは次のようになります。
(rr)next
ポインター[33611]=33611
9 for(i =0; 1; i ++)
(rr)next
11ポインター[i]=i;
(rr)next
プログラム受信信号SIGSEGV、セグメンテーション違反。
0x000000000040116a in main()at seg.c:11
11ポインタ[i]=i;
これで、さらに深く掘り下げて、追加のチェックを実行できます。主な違いは、これらすべてがソフトウェアの記録されたインスタンスで発生するため、サービスやアプリケーションの実際の使用を妨げる可能性がないことです。理想的には、問題を自動的に検出して記録できる巧妙な設定が必要ですが、それはまったく別の話です。
結論
RRを使うのにあまり時間をかけたことはありませんが、私は自分が見ているものが好きです。このプログラムは、gdbの使い慣れた堅牢な基礎を使用しています。つまり、Linuxのトラブルシューティングを最初からやり直す必要はありません。さらに、強力な柔軟性のレイヤーが追加され、ソフトウェアのクラッシュなど、ITの問題に関連することが多い時間のプレッシャーを最小限に抑えることができます。自分の都合の良いときに録音して再生することができます。これは、特に複雑で長時間のタスクの実行を扱っている場合に、問題を見つける可能性が高いことも意味します。
うまくいけば、この短いチュートリアルがお役に立てば幸いです。すべての食事に10人のシェフがいて、すべてのニーズに50の冗長なLinuxツールがある世界では、同じ古いものを再ハッシュするのではなく、意味のある追加機能を提供するソフトウェアを見るのは素晴らしいことです。さて、あなたは今あなたの武器庫に別のユーティリティを持っています、それはまたそれらの厄介なソフトウェアの問題を十分に速く解決することができないための1つの言い訳が少ないことを意味します。それがその仕組みです、いいえ。