【Linux】よく使うツール(その2)

1. Linuxプロジェクト自動ビルドツール - make/Makefile

プロジェクト内のソース ファイルはカウントされません。ソース ファイルは、タイプ、機能、モジュールに応じて複数のディレクトリに配置されます。メイクファイルは、どのファイルを最初にコンパイルする必要があるか、どのファイルを後でコンパイルする必要があるかを指定する一連のルールを定義します。コンパイルし、より複雑な機能操作を実行することもできます。

vs2019コンパイラなどのWindowsオペレーティング システムでは、グラフィカル インターフェイスを使用して、ワンクリックでソリューションを直接生成、つまりコンパイルできますが、Linuxシステムでは、 gcc または g++を使用して手動でコンパイルする必要があります。コンパイルする必要があるファイルが増えると、作業効率が低下します。

それでは、次はツールのmake と Makefileについて学びましょう

  • Makefileによってもたらされる利点は、 「自動コンパイル」です。一度作成すると、必要なmakeコマンドは1 つだけで、プロジェクト全体が完全に自動的にコンパイルされるため、ソフトウェア開発の効率が大幅に向上します。
  • makeは、 Makefile内の命令を解釈するコマンド ツールです。一般に、ほとんどの IDE にはこのコマンドがあります。

1. 依存関係と依存関係メソッド

make と Makefileの使用法を簡単に見てみましょう; 最初にMakefileファイルと通常のファイルに触れます

ここに画像の説明を挿入します

test.cファイルにコードを書いてみましょう

ここに画像の説明を挿入します

次に、 Makefileを入力し依存関係と依存メソッドを記述します。

ここに画像の説明を挿入します

このうち、生成される実行プログラムmytestが test.cファイルに依存していることを示し、対応する依存関係依存方法、つまり解決策、つまりtest.cを取得させる方法mytest:test.cを示しています。私のテスト。gcc test.c -o mytest

.PHONY擬似ターゲット cleanを定義するもので、常に実行される擬似ターゲットの特性は後ほど紹介します。

次に、clean には依存関係がなく、その依存関係メソッドは であることclean:が示され、このステップでプロジェクトがクリーンアップされます。rm -f mytest

コマンドラインでmakeを実行します。これは、プロジェクトをコンパイルすることを意味します。

ここに画像の説明を挿入します

次に、このプログラムを実行して次のことを観察します。

ここに画像の説明を挿入します

正常に実行されたことがわかります。その後、プロジェクトをクリーンアップします。

ここに画像の説明を挿入します

これでプロジェクトのコンパイルとクリーンアップが完了しました。makeを使用すると、最初の依存関係とメソッドがデフォルトで実行され、後続のものは自分で指定する必要があることに注意してください。たとえば、上記の依存関係と依存関係メソッドを逆にします。コンパイルとクリーニング。図に示すように、ここに来てください。

ここに画像の説明を挿入します

次に、make を実行して結果を観察します。

ここに画像の説明を挿入します

最初の依存関係がデフォルトで実行され、次にコンパイルされた依存関係とメソッドが実行されることがわかります。

ここに画像の説明を挿入します

これも通常に使用できますが、通常は最初の方法、つまり先頭でコンパイルし、最後にクリーニングを使用します。

2. 誤った目標

上で述べたことの.PHONY:後には、疑似ターゲットが続きます。通常、クリーンなターゲット ファイルの場合、それを疑似ターゲットとして設定し、次.PHONYのように変更します。疑似ターゲットの特徴は次のとおりです:常に実行されます。

  • (1) 常に実行されることをどのように理解すればよいでしょうか?

まず、 make Observation を複数回実行してみます。

ここに画像の説明を挿入します

プログラムはmake が初めて実行されたときにのみコンパイルされ、その後はコンパイルされないことがわかりました。プログラムを複数回クリーンアップした場合はどうなるでしょうか? 私たちの観察:

ここに画像の説明を挿入します

プログラムが実行されるたびにクリーンアップされることがわかります。これは、プログラムが常に実行されることmake cleanを理解するための方法です。クリーンは擬似ターゲットであるため、常に実行されます。

  • (2) では、疑似目標ではない場合、なぜ常に実行できないのでしょうか?

まず、ファイルのACM時間を理解しましょう。以下に示すように、ファイルのACMstat + 文件名時間を確認できます。

ここに画像の説明を挿入します

このうち、アクセス時間はこのファイルにアクセスした最新の時間、変更時間はこのファイルの内容を変更した最新の時間変更時間はこのファイルの属性を変更した最新の時間です。

実際、Makefile と make では、ファイルのコンテンツ変更時間を通じてコードを再コンパイルすることはできません。これは、ファイルがすでに最新であり、再度コンパイルする必要がないためです。

詳細な説明は次のとおりです。 ソース ファイルtest.cMakefileがあるとします。

ここに画像の説明を挿入します

初めてコンパイルするときは、まずソース ファイル (上記のtest.c ) が必要です。この時点ではまだコンパイルされておらず、ターゲット ファイル ( mytestファイル)が存在していない必要があります。次のように成功します。

ここに画像の説明を挿入します

mytestファイルがある場合mytestファイルの変更時間 > test.cファイルの変更時間になります。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

n 回目のコンパイル時に、 test.cを変更しなかった場合、 mytestファイルの変更時間は依然としてtest.cファイルの変更時間より大きく、以下に示すように、この時点でコンパイルは失敗します。 :

ここに画像の説明を挿入します

test.cファイルを変更してその変更時刻を更新すると ( test.cの変更時刻> mytestの変更時刻)、次のようにこの時点で再コンパイルは成功します。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

  • (3)アクセスタイムの特徴

初めてコンパイルすると次の現象が発生します。

ここに画像の説明を挿入します

test.cだけを表示したい場合はアクセス時間を次のように変更します。

ここに画像の説明を挿入します

アクセス時間が変更されていないことがわかりました。これはなぜですか?

一般に、ファイルが表示される頻度は非常に高く、私たちが目にするファイルはすべてディスクに保存されており、ファイル= コンテンツ + 属性であるため、ファイル時刻を変更する本質は、実際にディスクにアクセスし、ファイルにアクセスすることです。ディスク効率が非常に低いため、効率を向上させるために、 Linux はアクセス時間のアクセス間隔を変更するか、制限を追加します。そのため、アクセスtouch + 文件時間をすぐに更新したい場合は、次のように直接実行できます。

ここに画像の説明を挿入します

3. make/Makefile には依存関係導出機能 (構文拡張) があります。

make/Makefile には依存関係を導出する機能があり、Makefileファイルには次のコードが含まれていますが、これは実際にはプログラムのコンパイル プロセスです。

ここに画像の説明を挿入します

コンパイル後は次のようになります。
ここに画像の説明を挿入します

これがプログラムをコンパイルするプロセスであることがわかります。実行して観察してみましょう。

ここに画像の説明を挿入します

ただし、 gcc を直接使用して実行可能プログラムを直接形成できるため、この方法を使用してコンパイルすることはお勧めできません。

次のような他の構文拡張もあります。

ここに画像の説明を挿入します

このうちgcc -o $@ $^、 は依存関係におけるコロンより左側のすべてのファイルを$@表します; は依存関係におけるコロンより右側のすべてのファイルを表します; コンパイル後、次のように置き換えられます。$^

ここに画像の説明を挿入します

4.進行状況バーコードを書き込む

(1) バッファー

次のコードを見てみましょう。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 
		  4 int main()
		  5 {
		  6     printf("hello, world\n");
		  7     sleep(3);                                                                                                                     
		  8     return 0;
		  9 }

「hello, world」を出力してから行を折り返し、sleep(3);を実行してプログラムを 3 秒間停止してから続行します。

最初の実行は次のようになります。

ここに画像の説明を挿入します

3秒後:

ここに画像の説明を挿入します

プログラムがコマンド ラインを再表示するまでに 3 秒かかったことがわかりました。

もう一度次のコードを見てみましょう。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 
		  4 int main()
		  5 {
		  6     printf("hello, world");
		  7     sleep(3);                                                                                                                     
		  8     return 0;
		  9 }

上記のコードでは、コードの最初のセクションにある\n を削除し、次のコードを実行して結果を観察しました。

実行後:
ここに画像の説明を挿入します

3秒後:

ここに画像の説明を挿入します

プログラムの実行後、 hello, world が画面に表示されず、3 秒後に表示されることがわかりました。まず、プログラムは上から下に実行され、printfステートメントは確実に最初に実行されましたが、表示されませんでした。まず、これはなぜでしょうか?次に、緩衝地帯という概念を紹介します

実際、上記の現象では、プログラムがprintfを実行した後、printfによって出力された内容がバッファーに格納されます。C /C++では、標準出力用のデフォルトのバッファーが提供されますが、バッファーが更新される前に、内容は出力されません。

\n更新戦略です -- 行の更新です。したがって、 \nを追加すると、バッファが更新され、内容が出力されます。

\nを使用しない場合、バッファーは更新されませんがfflush(stdout)、次のように、 \n を使用してバッファーを強制的に更新してコンテンツを出力することができます。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 
		  4 int main()
		  5 {
		  6     printf("hello, world");
		  7     fflush(stdout);    
		  8     sleep(3);                                                                                                           
		  9     return 0;
		 10 }

出力結果:

ここに画像の説明を挿入します

3秒後:

ここに画像の説明を挿入します

バッファの内容が強制的に更新されていることがわかります。

(2)\n および\r

まず、次のような簡単なカウントダウン プログラムを作成します。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 
		  4 int main()
		  5 {
		  6     int cnt = 10;
		  7     while(cnt >= 0)
		  8     {
		  9         printf("%d\n", cnt);
		 10         cnt--;                                                                                                                    
		 11         sleep(1);                                                       
		 12     }                                                                   
		 13                                                                         
		 14     return 0;                                                           
		 15 } 

観察結果:

ここに画像の説明を挿入します

しかし、これは私たちが望んでいるカウントダウンではありません。同じ行に表示されることを期待しているので、\nを使用すべきではありません。実際、\nはいわゆるキャリッジ リターンであり、カーソルが行を変更して戻ることになります。その行の先頭に移動します。位置; 現時点では\rを使用する必要があります。\rはカーソルを現在の行の最初の位置に戻すだけです。上記のコードを次のように変更します。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 
		  4 int main()
		  5 {
		  6     int cnt = 10;
		  7     while(cnt >= 0)
		  8     {
		  9         printf("%d\r", cnt);
		 10		    fflush(stdout); 
		 11         cnt--;                                                                                                                    
		 12         sleep(1);                                                       
		 13     }                                                                   
		 14                                                                         
		 15     return 0;                                                           
		 16 } 

実行結果は以下の通りです。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

上記の結果から、カウントダウンは同じ行にありますが、出力形式にまだ問題があることがわかります。デフォルトでは%d は1 文字として出力されますが、これを 2 文字として出力したいためです。行 9 を次のように変更するだけです。

		  9         printf("%2d\r", cnt);

結果は次のとおりです。

ここに画像の説明を挿入します
ここに画像の説明を挿入します

この時点で、基本的にカウントダウンは完了していますが、カウントダウンが 1 桁になると、前に空の文字が表示され、あまり美しくありません。これは、%2d がデフォルトで右揃えになっているためです。マイナス記号を追加します。その前にあるのは左揃えなので、引き続き変更を加えます。

		  9         printf("%-2d\r", cnt);

結果は次のとおりです。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

この時点でカウントダウンは完了です。

(3) プログレスバーコード

  • 簡易バージョン:

まず、次のように、 MakefileProgressBarヘッダー ファイル、関数実装ファイル、および main 関数ファイルを新しいディレクトリに作成します。

ここに画像の説明を挿入します

まずMakefile を編集して、依存関係と依存メソッドを確立します。

		  1 ProgressBar:main.c ProgressBar.c
		  2     gcc -o $@ $^
		  3 .PHONY:clean
		  4 clean:
		  5     rm -f ProgressBar     

次に main 関数を作成します。main 関数では、次のようにプログレス バー関数を呼び出すだけです。

		#include "ProgressBar.h"
		
		int main()
		{
		    ProgressBar_v1();
		    return 0;
		}

次に、関数の宣言部分に入り、使用する必要がある変数と関数を宣言します。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 #include <string.h>
		  4 
		  5 void ProgressBar_v1();
		  6 #define SIZE 101      //数组大小
		  7 #define MAX_RATE 100  //加载进度最大值
		  8 #define STYLE '#'     //加载符号
		  9 #define STIME 1000*40 //时间

すべての変数を宣言した後、関数の実装部分に入ります。

		  1 #include "ProgressBar.h"
		  2 const char *str = "|/-\\"; // 加载光标
		  3 
		  4 void ProgressBar_v1()
		  5 {
		  6     // 当前进度
		  7     int rate = 0;
		  8     char bar[SIZE];
		  9     memset(bar, '\0', sizeof(bar));
		 10     
		 11     // 加载光标的数组长度
		 12     int num = strlen(str);
		 13     
		 14     // 当进度没有加载满
		 15     while(rate <= MAX_RATE)
		 16     {
		 17         printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate % num]);
		 18         fflush(stdout);
		 19         usleep(STIME);                    
		 20         bar[rate++] = STYLE;              
		 21     }
		 22     printf("\n");                         
		 23 }

このうち、usleep遅延関数を使用する場合に使用する関数ですが、sleepと比較すると単位sleeps、単位はususleepになります

次に、make を実行して実行可能プログラムを生成し、それを実行して結果を観察します。

ここに画像の説明を挿入します

読み込みが完了すると上の画像のようになります。これはプログレスバーを実装した簡易版ですが、以下ではこのプログレスバーをさらに改良していきます。

  • 応用編(実践編)

実際のアプリケーションでは、プログレス バーは通常、ソフトウェアのダウンロードに使用されます。ソフトウェアのダウンロードを例として、このコードを簡単に実装してみましょう。

まず、関数の実装部分を実装します。

		 // 不能一次将进度条打印完毕,否则无法平滑的和场景结合                                            
		 // 该函数,应该根据rate,自动的打一次                                                 
		 void ProgressBar_v2(int rate)                                                                
		 {                                                                        
		     // 设置为静态数组,每次进来不会清零                                                                                
		     static char bar[SIZE] = {0};                                                          
		                                                                     
		     // 加载光标的数组长度                                                                                                         
		     int num = strlen(str);                                                                 
		                                                                     
		     // 当进度没有加载满                                                                            
		     if(rate >= 0 && rate <= MAX_RATE)                                                                   
		     {                                                                                            
		         printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate % num]);
		         fflush(stdout);                                                              
		         bar[rate] = STYLE;                                           
		     }                                                               
		 }   

宣言部分をもう一度見てみましょう。ここでは、ダウンロード ターゲットのサイズとダウンロード速度を毎回増加させています。

		  1 #include <stdio.h>
		  2 #include <unistd.h>
		  3 #include <string.h>
		  4 
		  5 void ProgressBar_v1();
		  6 void ProgressBar_v2(int);
		  7 #define SIZE 101      //数组大小
		  8 #define MAX_RATE 100  //加载进度最大值
		  9 #define STYLE '#'     //加载符号
		 10 #define STIME 1000*40 //时间
		 11 
		 12 #define TARGET_RATE 1024*1024   //下载目标的大小 1MB
		 13 #define DSIZE 1024*10   //下载速度

最後に、メイン関数部分を見てみましょう。

		  1 #include "ProgressBar.h"
		  2 
		  3 void download()
		  4 {
		  5     int target = TARGET_RATE;
		  6     int total = 0;
		  7     while(total < target)
		  8     {
		  9         // 用简单的休眠时间,模拟本轮下载花费的时间
		 10         usleep(STIME);
		 11 
		 12         // 每次加上下载速度
		 13         total += DSIZE;
		 14 
		 15         // 按百分比传入 v2 函数
		 16         int rate = total*100/target;
		 17         ProgressBar_v2(rate);
		 18     }                                                                                                                             
		 19     printf("\n");
		 20 }
		 21 
		 22 int main()
		 23 {
		 24     // 下载的软件
		 25     download();
		 26     return 0;
		 27 }

これは実用的なアプリケーションのための単純な進行状況バーコードです。メイン関数部分では、次のように最適化のためにコールバック関数を使用することもできます。

まず、関数ポインタの宣言を関数宣言に追加します。

		typedef void (*callback_t)(int); // 函数指针  

次に、メイン関数部分を変更します。

		  1 #include "ProgressBar.h"
		  2 
		  3 void download(callback_t cb)
		  4 {
		  5     int target = TARGET_RATE;
		  6     int total = 0;
		  7     while(total < target)
		  8     {
		  9         // 用简单的休眠时间,模拟本轮下载花费的时间
		 10         usleep(STIME);
		 11 
		 12         // 每次加上下载速度
		 13         total += DSIZE;
		 14 
		 15         int rate = total*100/target;
		 16         cb(rate); // 回调函数                                                                                                     
		 17     }
		 18     printf("\n");
		 19 }

上記のプログレスバー操作の結果は、次の図に示すようになります。

ここに画像の説明を挿入します

2. Linux版controller-git

いわゆるバージョンコントローラーとは、簡単に言うと、管理されているコンテンツ(テキスト)やプログラムを変更に応じて管理するソフトウェアであり、最終的には希望するバージョンのテキストやプログラムを提供できるようにすることを目的としています。

私たちがよく使うgitee/github は、バージョンを視覚化することを目的として、gitソフトウェアに基づいて構築された Web サイトです。

Linuxにgit がインストールされていない場合、それを実行してインストールできますsudo yum install -y git

1. gitクローン

私たちは主にgitを使用して独自のコードをリモート ウェアハウスに保存します。ここではgitee をリモート ウェアハウスとして使用し、独自のコードをLinuxにアップロードします。まず、次のようにgiteeにウェアハウスを作成する必要があります。

ここに画像の説明を挿入します

次に、ウェアハウスのアドレスをコピーし、Linuxで次のコマンドを実行します。

	git clone https://gitee.com/YoungMLet/temp

次のように:

ここに画像の説明を挿入します

次にメールアドレスとユーザー名の入力を求められるので、メールアドレスとユーザー名の設定方法を紹介します。

2.git構成

コマンドgit config を使用して、電子メール アドレスとユーザー名を設定できます。たとえば、ユーザー名を設定する必要があります。

		git config --global user.name "xxx" 

電子メール アドレスを構成する必要がある場合は、次のコマンドを実行できます。

		git config --global user.email "[email protected]"

ここでのユーザー名と電子メール アドレスは、リモート ウェアハウスのユーザー名と電子メール アドレスと一致している必要があることに注意してください。

次のコマンドを使用して、現在の構成情報を表示できます

		git config -l

電子メール アドレスユーザー名を変更する必要がある場合は、次の方法があります。まず、電子メール アドレスとユーザー名を削除し、さらにユーザー名を削除する必要があります。

		git config --global --unset user.name

メールアドレスを削除します:

		git config --global --unset user.email

次にgit Sanbanaxeを学習します。

3. git add

まず、ワークスペース、一時記憶領域、バージョン ライブラリという 3 つの用語を簡単に理解しましょう。

ワークスペースはコードを記述するディレクトリです。ステージング領域はgit add を使用した後にコードが一時的に保存される領域です。バージョン ライブラリはステージング領域 (つまり、 git)からコードが送信された後にコードが送信される領域です。コミット)。

コードをワークスペースのリモート ウェアハウスに送信する必要がある場合は、まずコードをステージング領域にgit add する必要があります。このとき、git add以下に示すようにコマンドを実行する必要があります。

ここに画像の説明を挿入します

このコマンドを実行するだけで、ワークスペースのstudy5をステージング領域に送信できます。このとき、git status次のようにコマンドを使用して、現時点でのウェアハウスのステータスを表示できます。

ここに画像の説明を挿入します

これは追加が成功したことを意味します。この時点で、コードをリポジトリに送信する必要があります。

4. gitコミット

コードがすでにステージング領域にある場合は、コードをリポジトリに送信する必要があり、このとき、次のコマンドを実行する必要があります。

		git commmit -m "这里写上日志"

ここに追加する必要があることに注意してください-m

次のように、上で書いた進行状況バーをリポジトリに送信するとします。

ここに画像の説明を挿入します

git logこのコマンドを使用して、送信したログを表示することもできます。コードをリポジトリに送信した後、最後のステップでコードをリモート ウェアハウスにアップロードします。

5. gitプッシュ

この時点で必要なのは、次のコマンドを実行してコードをリモート ウェアハウスにアップロードすることだけです。

		git push

この時点で、ユーザー名とパスワードを入力する必要があります。次のように入力できます。

ここに画像の説明を挿入します

この時点で、コードはリモート ウェアハウスにアップロードされます。

6. git プル

場合によっては、私たちの多くがプロジェクトで共同作業しているとき、私たちが提出したコードと他の人が提出したコードによって、ローカル ウェアハウスとリモート ウェアハウスが同期しなくなることがあります。このとき、 を実行して同期する必要がありますgit pull

3. Linux デバッガ-gdb

プログラムをリリースするには、デバッグモードとリリースモードの 2 つの方法があります。Linux gcc / g++でコンパイルされたバイナリ プログラムはデフォルトでリリースモードになります。gdb デバッグを使用するには、ソース コードからバイナリ プログラムを生成するときに-gオプションを追加する必要があります。次のように、Makefileを編集するとき、依存関係メソッドを確立するときに、実行可能プログラムに-gオプションを追加する必要があります。

ここに画像の説明を挿入します

この時点で、次のようにMakefileを終了し、make を実行してから、mytest実行可能ファイルを実行してデバッグします。gdb mytest

ここに画像の説明を挿入します

上の図に示すように、 gdb デバッグ モードに入り、デバッグq または quitを終了して、デバッグにgdbの使用を開始します。

1. 説明を見る

gdb では、list (l と略します) でソース コードを表示できます。このうち、l +numberで行番号からコードを表示できます。さらに、gdb は最近のコマンド履歴を記録し、Enter キーを押すと前のコマンドになります。 Enter を直接押します。列は最後の位置から一度に 10 行ずつ続きます。たとえば、コードを見てください。

ここに画像の説明を挿入します

この時点では Enter キーを押し続けます。

ここに画像の説明を挿入します

完全なコードを確認してください。

ここに画像の説明を挿入します

これがviewコマンドです。

2. ブレークポイント

ブレークポイントの命令は:b + numberまたはb + function, ここで、numberは行番号、functionは関数名です。たとえば、特定の行のポイントをブレークする例として上記のコードを取り上げます。

ここに画像の説明を挿入します

info bこの時点で、次のようにブレークポイント コマンド: を確認してください。

ここに画像の説明を挿入します

ブレークポイントを削除するコマンドは です。シリアル番号はd + 序号ブレークポイントの前のNumです。たとえば、最初にさらにブレークポイントをいくつか作成してみましょう。

ここに画像の説明を挿入します

上記のように、各ブレークポイントには対応するシーケンス番号があり、特定のブレークポイントを削除する必要があるとします。

ここに画像の説明を挿入します

3. デバッグを開始する

デバッグを開始するコマンドはrun次のとおりです。つまりr、ブレークポイントがある場合、プログラムはブレークポイントに到達すると停止します。そうでない場合、プログラムは最後まで直接実行されます。

vs では、プロセスごとおよびステートメントごとのデバッグにF10 と F11を使用できます。また、この操作をgdbでも使用できます(プロセスごとが n であり、vs; ステートメントバイでは F10 です)。 -statement は s で、vs. F11 にあります。

たとえば、現在はブレークポイントが 1 つだけあり、プロセスごとおよびステートメントごとのデバッグを順番に使用します。

ここに画像の説明を挿入します

まず実行しましょう。プログラムは 16 行目で停止します。この時点で n を押します。

ここに画像の説明を挿入します

ここに画像の説明を挿入します

この時点で関数に遭遇します。s を押してステートメントごとに進みます。

ここに画像の説明を挿入します

この時点で、プログラムは関数の入り口にジャンプします。このまま下に進む場合は、n を続けてください。デバッグ中に変数名と変数のアドレスを表示したいとします。命令を使用して、それを直接使用できます。たとえば、現在ループdisplaybodyに入っているのでdisplay + 变量retの現在の値を表示したいとします。

ここに画像の説明を挿入します

retのアドレスを表示したい場合:

ここに画像の説明を挿入します

特定の変数の表示をキャンセルしたい場合は、次のように を使用できます。undisplay + 序号ここで、シリアル番号は、 display の前に表示されるシリアル番号です。

ここに画像の説明を挿入します

&retの表示は現在キャンセルされています

さらに、以下に示すように、ブレークポイントをオンまたはオフにすることもできます。Enb 列のy現在のブレークポイントがオンになっていることを示します。

ここに画像の説明を挿入します

disable + 序号このブレークポイントをオフにしたい場合は、次のようにコマンドを実行します。

ここに画像の説明を挿入します

このブレークポイントを再度開いてコマンドを実行します: enable + 序号:

ここに画像の説明を挿入します

4. その他の注意事項

ループ本体に入ったが、このループの回数が非常に多く、このループを直接スキップしたい場合は、次のコマンドを使用できます。 、指定されたuntil + 行号位置まで実行します。

finishこれを使用して、現在の関数の最後まで実行することもできます。

また、ブレークポイント間で、対応する命令を 1 つのブレークポイントから次のブレークポイントに直接実行することもできますcontinue(简写c)

btスタックを表示できます。

set varset var i = xxx ;のように、変数の値を変更できます。

5. まとめ

使用する gdb コマンドは主に一般的なものです。その他については個別に学習してください。gdb コマンドを以下にまとめます。

				查看代码:l + number
				打断点:b + number
				删断点:d + 序号
				查看断点:info b
				开始调试:r
				禁止断点:disable + 序号
				开启断点:enable + 序号
				逐过程:n
				逐语句:s
				查看变量:display + 变量
				取消查看变量:undisplay + 序号
				运行至指定的位置:until + number
				运行到当前函数的结尾:finish
				从一个断点运行至下一个断点:c
				查看调用堆栈:bt
				更改变量的值:set var + 需改变量 = 改的值
				退出gdb:q

おすすめ

転載: blog.csdn.net/YoungMLet/article/details/132913462