通常、C/C++ コードのデバッグは、主に Windows プラットフォームの VS で行います. LInux では、コードのデバッグに使用
gdb
します. LInux でコードをデバッグすることはほとんどありませんが、実際の使用では gdb を使用することはほとんどありません.さまざまな環境。この記事の目的: シングル プロセス プログラムの基本的なデバッグを実行できるようにすること、つまり、VS 2019 および VS 2022 の基本的なデバッグ機能を使用できるようにすることです。これらはすべて、Linux で gdb を使用して実装されています。
この記事では、Linux 環境でvim エディター、make/Makefile、およびgcc/g++を使用します.これら 3 つのツールに慣れていない場合は、以下のリンクをクリックして、この記事と一緒に学習できます。
vim エディタ
make/Makefile
gcc/g++
1.デバッグとリリース
Linux で gdb デバッグを使用する方法を学習する前に、デバッグ モードとリリース モードに関する次の 3 つの予備知識を習得する必要があります。
-
プログラムをリリースするには、デバッグモードとリリースモードの 2 つの方法があります。
デバッグモード: プログラマがプログラムを書きコードをデバッグするためのモード.このモードで生成される実行プログラムには, リリースモードで生成される実行プログラムよりも多くのデバッグ情報が含まれる.
リリースモード: デバッグ情報がなく、プログラムが最適化され、プログラムのサイズが縮小され、ユーザーが使用するのにより適しています。このモードで生成された実行可能プログラムは、最終的に会社が市場に投入するものであり、会社のテスターはそれが完全であるかどうかをテストし、テストに合格した後に市場に投入します。
- 注:デバッグ モードではデバッグできますが、リリース モードではデバッグできません。
下の図は、VS 2019 での 2 つのモードの選択図です.必要なモードを選択できます.
次に、Linux で 2 つのモードを変換するにはどうすればよいですか? -
Linux では、gcc/g++ によって生成されるバイナリ実行可能プログラムは、デフォルトでリリース モードになっています。
- つまり、 Linux では、従来の命令を使用して生成された実行可能プログラムはリリース モードであり、デバッグすることはできません。
//常规生成 gcc -o 可执行文件名 源代码文件 g++ -o 可执行文件名 源代码文件
-
gdb デバッグを使用するには、 gcc/g++ を使用してバイナリ プログラムを生成するときに
-g
オプションを追加する必要があります。gcc -o 可执行文件名 源代码文件 -g g++ -o 可执行文件名 源代码文件 -g
次に、次の test.c ファイルの下のテスト コードを編集してテストします.
注:コードの 7 行目は for ループ内の変数を定義していますi
. この記述方法は c99 でサポートされており、私が使用する gcc/g++ エディタはサポートしていませんこの書き方は、コマンドを実行した後に追加する必要があります-std=c99
。
Makefile は次のとおりです。
Makefile の使用方法がわからない場合は、次の 2 つの手順を直接使用してテストできます。
gcc -o MyTest-debug test.c -g -std=c99 //生成debug模式的可执行文件
gcc -o MyTest-release test.c -std=c99 //生成release模式的可执行文件
まず、リリースモードでデバッグが可能かテストします
上図のように赤枠はデバッグシンボルが見つからず、デバッグできないことを示します。
次に、デバッグモードでデバッグが可能かどうかをテストします
エラーメッセージは表示されず、正常にデバッグできます
最後に: 2 つの実行可能ファイルのボリュームを観察します。デバッグがリリースよりも大きいことは明らかです。
拡大
次のように、このコマンドを使用してreadlef
、2 つの実行可能ファイルの下にある情報を表示できます。
次のように、このコマンドを使用して 2 つのファイルの下のデバッグ情報を表示できます (grep コマンドは検索文字列コマンドです):
デバッグ情報は MyTest-debug ファイルにありますが、MyTest-release には何もありません。
2. gdb を使用してデバッグする方法
デバッガーの主な仕事: 問題の特定
次に、gdb を使用して Linux でデバッグする方法を簡単に紹介します.この段落では、順を追って説明し、gdb でのコマンドの概要を次の段落に示します.
gdb のプロパティがない場合は、次の手順に従ってください
-
デバッグに入る
以下に示すように、コマンドを使用し
gdb file
てデバッグモードに入ります。
-
デバッグするコードを表示
l/list 行号
: ファイルのソースコードを入力行番号から10行ずつ表示します。通常、デバッグを開始するときは、l 1
最初から表示してから、l
またはEnter
キーを入力して、最後の検索位置からコードを取得します
注: gdb コマンドを入力すると、Enter
キーが記録されます。つまり、コマンドを入力した後、Enter キーを入力すると、上記のアクションが繰り返されます。次のディレクティブもこの規則に従います。- gdbモードに入った後、それを単独で使用し
l
て表示すると、表示されるコードはランダムです
-
ブレークポイントを設定
-
break/b 行号
: 特定の行にブレークポイントを設定以下に示すように、19 行目にブレークポイントを設定します。
-
break/b 函数名
: 関数の先頭にブレークポイントを設定します下図のように、addTestTop 関数にブレークポイントを設定します。
5 は addTestTop 関数内のコードの最初の行の行番号です。
-
break/b 文件名:函数名
: 複数のファイルがある場合、このメソッドを使用してブレークポイントを設定できます -
info break/b
: ブレークポイント情報を表示プログラムの実行中はブレークポイントで停止し、次にブレークポイントを表示すると、ブレークポイントで停止した回数が表示されます。
注: gdb ブレークポイントのシリアル番号は増加しており、オフにしてからオンにし、再び 1 から開始するまで、使用するたびに増加し続けます。
-
-
プログラムを実行する
-
r/run: プログラムを実行します
- ブレークポイントがある場合は、ブレークポイントまで実行して停止します
- ブレークポイントがない場合は、直接実行します
- ブレークポイントがある場合は、ブレークポイントまで実行して停止します
-
注:すべてのメイン関数のすべてのコードが実行された後、実行が終了します. ブレークポイントで停止した後、他の表示命令を実行しても、このデバッグには影響しません.
-
-
ブレークポイントがあり、実行後、ステートメントごとに実行します
-
s/step
: 関数が検出されたら、その関数を入力します。
注:他の関数を入力すると、呼び出しチェーンが生成されます。つまり、1 つの関数が別の関数を呼び出し、次に他の関数を呼び出します。
bt
コマンドで閲覧可能 -
-
ブレークポイントがあり、実行後、プロセスごとに実行します
n/next
つまり、関数に遭遇すると、関数に入らずに次の命令が直接実行されます。
- 前回実行したコマンドを実行するための上記の
Enter
ボタンをか? デバッグするコンテンツが多すぎる場合は、一度押すs
かn
、ボタンをEnter
押し
-
ブレークポイントを削除
-
delete /d breakpoints: すべてのブレークポイントを削除します
-
delete/dn: シーケンス番号 n のブレークポイントを削除します
-
-
ブレークポイントのオンとオフを切り替える
ブレークポイントを使用したくない、ブレークポイントを削除したくない場合に使用します。
-
ブレークポイントを無効にする ブレークポイント番号: ブレークポイントをオフにします
-
ブレークポイントを有効にする ブレークポイント番号: ブレークポイントを有効にする
-
-
変数を表示
-
p 变量名
: この命令はチェックが必要なときに入力されます, デバッグには影響しません. 以下のように, デバッグで addTestTop 関数に入った後, いくつかのステートメントを実行して sum 変数の結果をチェックします. このとき,合計は 6 です。 -
このように見るのは効率が悪い. VS でデバッグを使用する場合, 対応する変数を一度実行してそれに応じて変更する. 直接表示することができます. このメソッドはユーザー自身が呼び出す必要があり, 不便です.次の方法を使用できます
-
-
トラック ビュー変数
-
display 变量名
: 実行後、各ステートメントの実行後に変数が表示されます -
組み込み型や構造体、stl などのカスタム型を表示できます
-
-
ブレークポイントでアントレース
-
undisplay 序号
: 変数を追跡したくない場合に使用します
-
-
指定行にジャンプ
until 行号
: 行 X にジャンプします。上記のコードにはループがあります。この命令を使用して、ループからジャンプできます。
-
関数全体を実行する
finash
:関数に入ってから実行、この関数のみ実行、実行後停止
-
あるブレークポイントから次のブレークポイントまで
-
continue/c
: 次のブレークポイントまで直接実行 -
を組み合わせる
util、finish、continue
と、基本的なデバッグ機能を実現できます
-
-
gdb を終了する
q/quit
: デバッグ中の場合は、終了する必要があるかどうかを尋ねられます
3.命令セット
gdb binFile
終了:ctrl + d
またはquit/q
デバッグコマンド:
- list/l 行番号: binFile のソースコードを表示し、最後の位置から次の位置に移動し、10 行ごとにリストします。
- list/l function name: 関数のソース コードを一覧表示します。
- r または run: プログラムを実行します。
- n または next: 単一実行。
- s または step: 関数呼び出しを入力します
- break(b) 行番号: 特定の行にブレークポイントを設定します
- break function name: 関数の先頭にブレークポイントを設定します
- info break : ブレークポイント情報を表示します。
- 終了: 現在の関数が戻るまで実行し、終了してコマンドを待ちます
- print§: 式の値を出力します。変数の値を変更したり、関数を式から呼び出すことができます
- p 変数: 変数値を出力します。
- set var: 変数の値を変更します
- continue (または c): 現在の位置からのプログラムのシングルステップ実行ではなく、連続実行
- run (または r): シングルステップではなく、最初から連続してプログラムを実行します。
- ブレークポイントの削除: すべてのブレークポイントを削除します
- delete breakpoint n: シーケンス番号 n のブレークポイントを削除します
- ブレークポイントを無効にする: ブレークポイントを無効にします
- ブレークポイントを有効にする: ブレークポイントを有効にします
- info (または i) breakpoints: 現在設定されているブレークポイントを確認します
- 変数名の表示: 変数を追跡して表示し、停止するたびにその値を表示します
- undisplay: 以前に設定された変数を非表示にします
- X 行番号まで: X 行にジャンプ
- breaktrace (または bt): すべてのレベルで関数呼び出しとパラメーターを表示する
- info(i) locals: 現在のスタック フレームのローカル変数の値を表示します
- 終了: gdb を終了します