はじめに
デバッグプリント(Debug print)とは、ソフトウェアにおいて、動作を確認するためにシリアルなどに文字列を出力するものです。
ログを出力したりするためにも使います。
これらはArduinoでのSerial.print()やC言語でのprintf()などをもって実現されます。
デバッグプリントの問題点
しかしながら、これらの出力はCPUにとって負荷が高かったり、シリアルの出力が多いとこれが渋滞し、本来の動作が遅延するということが発生する場合があります。
また、本番環境でこういったものが出力されると、内容によってはノウハウが流出したり、クラックの手がかりを与えたりすることにもつながります。
一方で、どのコードをどの順番で通ったかを知るためには重要な手掛かりであり、デバッグには欠かせない機能でもあります。
デバッグプリントを簡単に切り替える方法
ここではArduinoでの例を示します。
まず、基本のSerial.print()は以下のように使います。
void setup() { Serial.begin(9600); } void loop() { Serial.println("なにか文字列や変数"); delay(1000); }
この場合loop()のなかで、デバッグ中でも本番運用中でも常に同じように出力されます。
これをこのようにします。
#define DEBUG_PRINT void debug_print(String st) { #if DEBUG_PRINT Serial.println(st); #endif } void setup() { Serial.begin(9600); } void loop() { debug_print("なにか文字列や変数"); delay(1000); }
このようにすると、本番運用時には#define DEBUG_PRINTをコメントアウトするだけで、シリアルプリントを削減することができます。
コードが複雑になったり量が増えるなどはありますが、通常はコンパイルで最適化されるので、本番運用時にこれによって大きく遅くなったりサイズが大きくなったりはしないのではないかと思います。
また、ログレベルを指定する引数を加えて
enum { TRACE, DEBUG, INFO, WARN, ERROR, FATAL } log_level; int CURRENT_LOG_LEVEL = INFO; // 現在の出力レベル設定(INFO以上のみ出力など) void debug_print(String st, int level) { #ifdef DEBUG_PRINT if (level >= CURRENT_LOG_LEVEL) { Serial.println(st); } #endif } void loop() { debug_print("なにか文字列や変数", ERROR); }
のようにすると、TRACE、DEBUG、INFO、WARN、ERROR、FATALの段階に応じてどこまで出力させるかを選択することもできます。