今回はよく行っているデバッグ方法を3つ上げてみました。
これ以外の方法ではデバッグしていないと思います。いろんな言語や環境で行っている共通のやり方です。
1文字間違うだけでも、バグが出てよく考えると結構大変な作業ですよね😅
対象はバグを初めて直し始めた人や、デバッグの流れについて知りたい初心者さんです。
バグ・デバッグについて
デバッグは作ったプログラムが上手く動かなかったり、
思った通りに動いていないときにする作業です。
バグ(虫)を取り除いて、おかしなところをなくし仕様通りに動作するようにしていきます。
なんでプログラムの不具合を修正するのが、バグ(虫)取りになったのか調べてみると。。
よくわかりませんでした😅 諸説あるようです。
デバッグ手法
実際に現場でやっている3パターンと、バグが起きたときの実例を書いています。
画面やファイル出力で確認
画面やファイル(ログ)に変数の値を出力して、想定通りの値が入っているか確認します。
わざわざ、デバッグ用のコードを書いておかないといけないので、基本的にはブレークポイントを貼ってデバッグする方が楽です。
ブレークポイントを貼って、デバッグできる環境がない場合や、
本番環境で動いているプログラムでエラーが出た場合にログをみて、バグを確認して直したりします。
例
実際に稼働中のWebシステムを使っている途中に画面が真っ白になった。
=> ログを確認して、バグ対応を行う。
ブレークポイントを貼る
ブレークポイントを貼るとプログラムを実行しているときに、
プログラムの途中で処理を止めてバグの原因を突き止めるができます。
ブレークポイントが使えない環境もあるので、ブレークポイントが使えるか確認する必要があります。
例
プログラムの実装中に動作確認したところ、想定した通りに動いてないんだけど?
=> 気になるところにブレークポイントを貼って、想定通りに動いているか確認する
最終奥義・力技デバッグ
ブレイクポイントを貼ったり、プログラムを動かしてみても特に原因がつかめない時は
対象のソースをコメントアウトして、流れている処理のフローで1つずつコメントアウトを解除していき、
実際にどこで処理がうまくいっていないのか確認することがあります。
例
エラーも出ずに、ブレークポイントを貼って一つずつ処理を確認しているけど問題ないのに対象画面が真っ白になった。
=> 本当に書いているコードに問題ないか、怪しい場所をコメントアウトして、処理が流れている最初の方から少しずつ解除して確認する。
デバッグやってみる
実際にvisual stadioを使ってデバッグをする場合の例です。
上記のデバッグ手法の1と2だけやってみます。
画面・ファイル出力で確認
C#でバグが存在するプログラムを書いてみました。
FizzBuzzのプログラムですが、結果をoutputsという配列に入れて出力しています。
プログラムやっている方は、見ればどこがエラーになるかわかると思いますが…
例なのでご了承ください…😅
class Program
{
static void Main(string[] args)
{
string[] outputs = new string[10];
for (var i = 1; i < 50; i++) {
if (i % 15 == 0)
{
outputs[i] = i.ToString() + ": FizzBuzz";
}
else if (i % 3 == 0)
{
outputs[i] = i.ToString() + ": Fizz";
}
else if (i % 5 == 0)
{
outputs[i] = i.ToString() + ": Buzz";
}
else
{
outputs[i] = i.ToString();
}
}
foreach (var output in outputs) {
Console.WriteLine(output);
}
}
}
そして実行すると。。エラーになりました。
実際にエラーを見れば分かるかと思いますが、あえて下記のように画面出力を仕込んでみました。
class Program
{
static void Main(string[] args)
{
string[] outputs = new string[50];
Console.WriteLine("for文スタート");
for (var i = 1; i < 50; i++) {
if (i % 15 == 0)
{
outputs[i] = i.ToString() + ": FizzBuzz";
}
else if (i % 3 == 0)
{
outputs[i] = i.ToString() + ": Fizz";
}
else if (i % 5 == 0)
{
outputs[i] = i.ToString() + ": Buzz";
}
else
{
outputs[i] = i.ToString();
}
Console.WriteLine("出力値" + i);
}
Console.WriteLine("for文終了");
foreach (var output in outputs) {
Console.WriteLine(output);
}
}
}
for文の開始と終了、そしてループが一回まわるごとに値を出力しています。
出力結果をみると・・・・
for文スタート
出力値1
出力値2
出力値3
出力値4
出力値5
出力値6
出力値7
出力値8
出力値9
for文が開始されていますが、値が9までしか出ていないので..
10回目にエラーになったことがわかります。
そして、なんで10回目エラーになったかというと、outputsの配列が9個しかないため、
10個目を入れようとするときにエラーになったのがわかります!
このエラーは、50個を配列定義しておくと解消します。
string[] outputs = new string[50];
ブレークポイントを貼る
visual stadioは総合開発環境(IDE)と呼ばれていますが、
同様にIDEでプログラムを書く場合はブレークポイントでデバッグできる機能がほとんどついているかと思います。
さきほど作ったプログラムのfor文の開始にブレークポイントを置いて開始してみました。
エディタの左側をクリックすることで、赤丸が表示されます。(こんな感じになります)
実行すると下記のように、実行途中で止まって変数の中身が確認できます。
こうやって1行づつ実行して、変数の中身や処理内容を確認することで、
どこでエラーがあるかわかるので、発見次第、修正するといった感じです。
もしかして、原因はライブラリかも??
最近つまずいたことで、しっかり実装したはずなのに上手く動かないことがありました。
具体的にはsocket.ioを使用した検証用のプログラムを書いていたのですが、データを受信する方の処理が動かず…
いろいろと調べてみました。
そうすると、クライアント側のライブラリとサーバー側のライブラリのバージョンの差異によって、動いていませんでした。
クライアント側のライブラリが自動的に最新になってしまっていた感じです。
このように、ライブラリなど参照しているプログラムや外部サービスによって問題が出ている場合もあります。
完全に詰まった場合は、ライブラリ周りなどから、ひとつずつ見直していくなどしても良いかと思います。
コメント