[コードのデバッグ]いくつかの実用的なLinuxアプリケーションのデバッグスキル



1前に書く

  テクニカルエクスチェンジグループで、小さなパートナーが異常な問題を提起し、オープンソースソフトウェアを自分のUbuntuに移植しました。実行すると、「そのようなファイルはありません」というプロンプトが表示されます。「ls -l」で確認してください。ファイルは存在します。この小さなパートナーも、権限の問題を除外するように変更されています。私が与えた提案の実行は、“file file-name”ファイル情報と“uname -a”現在のシステム情報表示する実装を実行し、実行可能ファイルとシステムバージョンが一致するかどうかを確認することです。案の定、実行可能ファイルはX86形式(32ビットシステム)であり、システムはX64であるため、必然的に実行エラーが発生します。しかし、このヒントは誤解を招くものです。この実行可能ファイルもソースコードフォルダーから移植されたものであり、作成者がコンパイルしたファイルである可能性があります。その後、小規模なパートナーがパッチの形で問題を解決し、ソースコードが利用可能になったので、自分のマシンで実行可能ファイルを再コンパイルすることができます。


2ケース分析

  基本的なプログラムtest.cを記述し、さまざまなシステムやアーキテクチャの実行可能ファイルをコンパイルして実行します。

#include <stdio.h>

int main(int argc, char *argv[])
{
    
    
	printf("Hello acuity\r\n");

	return 0;
}

異なる数字のオペレーティングシステム

64ビットUbuntu16および32ビットUbuntu10でそれぞれコンパイルおよび実行します。

  • 64ビットUbuntu16でコンパイルされたファイルはtest0
  • 32ビットUbuntu10でコンパイルされたファイルはtest1

ここに画像の説明を挿入

ファイルタイプ

  二つのプログラムは、2つのシステム上で実行された、test0test1の両方がUbuntu16 -64上で正常に実行することができ、test0実行がUbuntu10 -32に失敗しました。
ここに画像の説明を挿入

Ubuntu16 -64で実行

ここに画像の説明を挿入

Ubuntu10 -32で実行

  2つの実行の結果、64ビットシステムがX86およびX64 CPUの32ビットシステムプログラムと互換性があるか、またはそれらのほとんどが互換性があることは避けられません。ただし、32ビットシステムは64ビットプログラムと互換性がなく、理解できます。ビッグはスモールと互換性があり、スモールはビッグと互換性がありません。ただし、64ビットシステムは必ずしも32ビットアプリケーションと完全に互換性があるわけではありません。この記事に記載されている現象は非互換性の例であり、gccコンパイラのバージョンに関連している可能性があります。そのため、異なるシステムで同じコードを再コンパイルして実行することをお勧めします。ファイル。


異なるアーキテクチャのCPU

  クロスコンパイラを使用して“aarch64-linux-gnu-gcc”、ARMアーキテクチャcpuの実行可能ファイルコンパイルしますtest2

ここに画像の説明を挿入

コンパイル後のARM64ファイル

  X64 cpuマシンで実行すると、実行が失敗することは間違いありません。関連するダイナミックライブラリはありません。関連するダイナミックスがあっても実行できません。逆に、X86およびX64 CPU実行可能プログラムは、ARMアーキテクチャCPUでは正常に実行できません。これは、一部の人々がファイルがすでにボード上にあるが実行できないことをはっきりと遭遇するという問題でもあります。

ここに画像の説明を挿入

X64マシンでARMプログラムを実行する

  同様の問題については、以下の同様のデバッグおよびトラブルシューティングの手法を合計すると、半分の労力で2倍の結果が得られます。


3デバッグスキルの拡張

3.1システム情報を表示する

コマンド:uname -a

  システム情報を使用して、ドライバーとアプリケーションソフトウェアがシステムと一致するかどうかを判断できます。たとえば、ドライバーのコンパイルに使用されるカーネルが現在のシステムカーネルと一致しない場合、ドライバーの読み込みに失敗します。

acuity@ubuntu:/mnt/hgfs/LSW/test$ uname -a
Linux ubuntu 4.15.0-101-generic #102~16.04.1-Ubuntu SMP Mon May 11 11:38:16 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

3.2ファイル情報を表示する

コマンド:file file-name

  実行ファイルについては、ファイル情報を使用して、現在の実行システム環境と一致するかどうかを判断します。上記の例を参照してください。

実行ファイルteset0情報を表示します。

acuity@ubuntu:/mnt/hgfs/LSW/test$ file test0
test0: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=8c9c6802aff5fc032c8cf947f7f09124ed03872c, not stripped
  • フォーマット:ELF64
  • スモールエンディアン:リトルエンディアン
  • システム環境:64ビット(X86-64)

実行不可能なファイル情報を表示します。

acuity@ubuntu:/mnt/hgfs/LSW/test$ file test.c 
test.c: C source, ASCII text, with CRLF line terminators

3.3ファイルヘッダーの表示

コマンド:readelf -h file-name

  ファイルヘッダー情報を表示すると、ファイルの種類、システムの種類、依存関係の情報などをより直感的に確認でき、読みやすさが向上します。ファイルが実行システム環境と一致するかどうかを比較すると便利です。

acuity@ubuntu:/mnt/hgfs/LSW/test$ readelf -h test0
ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x400430
  Start of program headers:          64 (bytes into file)
  Start of section headers:          6616 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         9
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 28

  もちろん、非実行可能ファイルの場合、ファイルヘッダー情報はなく、このコマンドは失敗を返します。

acuity@ubuntu:/mnt/hgfs/LSW/test$ readelf -h test.c 
readelf: Error: Not an ELF file - it has the wrong magic bytes at the start

3.4ファイルが占めるスペースを表示する

コマンド:size file-name

  IEDを使用してMCUプログラムを開発する場合、コンパイル済みファイルの各セグメントの占有率を表示できます。同様に、Linuxでもコマンドを実行するだけで可能です。各段落の情報に従って、コードを最適化できます。
ここに画像の説明を挿入

IDEビューファイルセグメント情報
acuity@ubuntu:/mnt/hgfs/LSW/test$ size test0
   text    data     bss     dec     hex filename
   1200     552       8    1760     6e0 test0
  • テキスト、コードセグメント、コード、および定数領域
  • データ、データセグメント、初期化されたグローバル変数の格納、グローバルまたはローカルの静的変数
  • bss、bssセグメント、初期化されていないグローバル変数を格納します(通常は0で埋められます)
  • 10進数、10進数、テキスト、データ、およびbssの合計の10進数形式
  • 16進数、16進数、テキスト、データ、bssの合計の16進数形式

3.5ファイル実行権限を表示する

コマンド:ls -l file-name

  プログラムが実行に失敗した場合、最も一般的な失敗の原因は、アクセス許可の問題、実行属性がない、または実行ユーザーの権限が不十分であることです。

acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 8600 5月  30 10:51 test0

注:ファイル許可コマンドの変更chmod 777 test0など
chmod mode file-name


3.6ファイルを表示するために必要な動的ライブラリ

コマンド:ldd file-name

  プログラムを実行すると、ライブラリファイルが不足しているという狂気のケースが多くあります。現時点では、まず実行可能ファイルがどのライブラリファイルに依存しているかをコマンドで確認し、すべてのライブラリの問題を1つのステップで解決できます。

acuity@ubuntu:/mnt/hgfs/LSW/test$ ldd test0
        linux-vdso.so.1 =>  (0x00007fff46285000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f804405e000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8044428000)

  前の例のARM cpuで実行可能ファイルtest2を確認してください。これは、現在のマシンの実行可能ファイルではありません。

acuity@ubuntu:/mnt/hgfs/LSW/test$ ldd test2
        not a dynamic executable

3.7文書検証

  ファイルの転送またはコピー後、ファイルが破損しているか、誤って変更されているかが不明な場合は、チェック値で確認できます。一般的に使用されるチェックは、サムチェック(sum)、CRCチェック(cksum)、md5sumです。チェック値を比較することで、ファイルが改ざんされていないかをすばやく確認できます。

  • 和、sum [-r/-s] file-name

[-r]オプションは、1kバイトを使用してsystem vアルゴリズムを使用することを意味します。デフォルト値が選択されている場合、system vアルゴリズムがデフォルトで使用されます

[-s]オプション、BSDアルゴリズムを使用することを意味し、512バイトを使用します

sum test0
32142     9
  • CRC、cksum file-name
acuity@ubuntu:/mnt/hgfs/LSW/test$ cksum test0
525748358 8600 test0
  • md5sum;md5sum file-name
acuity@ubuntu:/mnt/hgfs/LSW/test$ md5sum test0
cb245018f7f9e0a3d938ec363495e9be  test0

3.8ファイルシンボルテーブルの表示

コマンド: nm file-name |grep [fun/variable]

  強迫性障害がある場合、このコマンドを使用して、関数または変数がコンパイルされているかどうか、およびそれらの実行アドレスを確認できます。test0実行ファイルのmain関数を確認してください。

acuity@ubuntu:/mnt/hgfs/LSW/test$ nm test0|grep main
                 U __libc_start_main@@GLIBC_2.2.5
0000000000400526 T main

3.9ファイル内の文字列を表示する

コマンド: strings file-name|grep string-name

   このコマンドを使用すると、定数文字がターゲットファイルにコンパイルされているかどうかを確認できます。最も実用的なのは、ファイルバージョン情報(文字タイプ)を確認することです。もちろん、バイナリ表示ツール(UEなど)を使用して実行可能ファイルを開き、ターゲット文字ファイルを直接検索することもできます。

  test0ファイルの「Hello」文字を確認します。

acuity@ubuntu:/mnt/hgfs/LSW/test$ strings test0|grep Hello
Hello acuity

  バイナリファイル読み取りツールで文字を検索します。
ここに画像の説明を挿入

3.10ファイルスペースの最適化

コマンド:strip file-name
  このコマンドは、実行可能ファイルの一部のシンボル情報とデバッグ情報(gdb)を最適化および削除してスペースを節約できますが、最適化後、プログラムは異常になり、一部の参照情報を記録および生成できなくなります。通常、ソフトウェアのリリース時にスペースの最適化と削減が行われます。

test0ファイルの最適化前後のスペース:

acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 8600 5月  31 00:09 test0
acuity@ubuntu:/mnt/hgfs/LSW/test$ strip test0
acuity@ubuntu:/mnt/hgfs/LSW/test$ ls -l test0
-rwxrwxrwx 1 root root 6320 5月  31 00:09 test0

おすすめ

転載: blog.csdn.net/qq_20553613/article/details/106440641