bashソースのデバッグ方法

3593 ワード

前言


バージョンbashを変更して、同僚に長い時間を費やして、今更に何かを追加する必要があって、突然gdbが付加したことを発見して、正常に入力したshellコマンドをデバッグすることができませんでした.
原版で試してみると、単一のソースコードでデバッグできます.それは改版されたbashかもしれませんが、ユーザー入力コマンドを処理する前に、処理中にshellコマンドを自分で実行して他の仕事をして、bashサブプロセスを確立して有効にデバッグできないことを引き起こしました.
オリジナルbashの単一ステップデバッグの手順を記録します.

じっけん


bash-4.4.tar.gzはdebian仮想マシンの実験ディレクトリにアップロードされます.解凍
tar -xzvf ./bash-4.4.tar.gz
cd /home/dev/bash-4.4

デバッグ版としてconfigureを設定する

export CFLAGS='-DGCC_HASCLASSVISIBILITY -g -Wall -W'
./configure --enable-debug
  ./configure --help,   --enable-debug  
 CFLAGS -g 
make clean
 , si 。

これが実験のバージョンであることをマークするために、versionの実装を変更することができ、bashを再実行すると、自分が変更したバージョンであることを確認することができます.
/* Give version information about this shell. */
char *
shell_version_string ()
{
  const char* psz_my_ver = "ls_2019_0422_1354"; // @note   >= 32

  static char tt[32 * 2] = { '\0' };

  if (tt[0] == '\0')
    {
      if (release_status)
#if HAVE_SNPRINTF
	snprintf (tt, sizeof (tt), "%s_%s.%d(%d)-%s", psz_my_ver, dist_version, patch_level, build_version, release_status);
#else
	sprintf (tt, "%s_%s.%d(%d)-%s", psz_my_ver, dist_version, patch_level, build_version, release_status);
#endif
      else
#if HAVE_SNPRINTF
	snprintf (tt, sizeof (tt), "%s_%s.%d(%d)", psz_my_ver, dist_version, patch_level, build_version);
#else
	sprintf (tt, "%s_%s.%d(%d)", psz_my_ver, dist_version, patch_level, build_version);
#endif
    }
  return tt;
}

make
 , , bash.

新しいbashのインストール

make install
 , debian8.8 , /bin 。
 ,bash bash,  .
 , 。
 make install , bash /usr/local/lib/ , bash /bin/bash
installing example loadable builtins in /usr/local/lib/bash

gdbで別のbashを添付する場合、break mainまたはすでに存在するfile:lineの場合、エラーが発生した場合は、bashが私たちがコンパイルしたバージョンではない可能性があることを示します.
cmpコマンドで検証します.
cmp -l /bin/bash ./bash | gawk '{printf "%08X %02X %02X
", $1, strtonum(0$2), strtonum(0$3)}'

bashがシステムbash位置に置き換えられた場合、cmpコマンドラインが実行されると、結果は空になります(出力されません).現在コンパイルされているbashがシステムと異なる場合、cmpコマンドラインはそれらのバイトを出力します.make installでbashをインストールできなかった場合は、bashを手動で交換する必要があります.
mv /bin/bash /bin/bash.org.bk
cp ./bash /bin/

bashのデバッグ


開発ディレクトリのSecureCRTコンソールで、ttyと入力し、まず自分のtty番号を見てみましょう.次に、ps aux|grep bashで現在のすべてのbashをリストする.
新しいSecureCRTコンソールを開いて、ttyでtty番号を見てください.次に、開発ディレクトリがあるコンソールに戻り、現在のすべてのbashをps aux|grep bashで再リストします.新しいbashはわかりやすく、そのbashのプロセスIDは2列目にあります.
新しいコンソールウィンドウのbashプロセスIDを取得すると、gdbでソースデバッグができます.開発ディレクトリのコンソールで、次のコマンドを入力して追加のデバッグを行います.
gdb -tui -p new_bash_pid
 :
*  , 。
*  bash ( bash),  。

 , c 。
 bash , , bash 。
 s, n  。

2019_0423


原版と修正版を比べて、修正版がなぜコンパイルできないのか知っています.仮想マシンやワークコントローラでコンパイルされているので、ローカルに返信する前に(bashソースコードを修正したので)、先にmake clean.bashのmake cleanは、クリアされません./support/man2html.o異なるコンピュータ上でコンパイル後、アーカイブするとman 2 htmlになる.o現在のコンピュータでコンパイルされたものではありません.アーキテクチャの異なるコンピュータ上でコンパイルする場合、コンパイラのコンパイル時にman 2 htmlは更新されない.o(現在の時間よりも時間が古いかもしれませんが)は、コンパイル用に直接含まれています.これでコンパイルできません.
コンパイルbashのスクリプトを書いたので、bashエンジニアリングrebuildを正しくコンパイルする方法を忘れません.sh
root@localhost:/home/dev/bash-4.4# vi ./rebuild.sh            

#! /bin/sh
export CFLAGS='-DGCC_HASCLASSVISIBILITY -g -Wall'
./configure --enable-debug
make clean
rm -f ./support/man2html.o
make
make install
mv /bin/bash /bin/bash.bk_$(date "+%Y%m%e_%H%M%S_%s")
cp ./bash /bin/