私はesp32プロジェクトを進行中で、すべてのesp32 uartデバッグ出力を複数のファイルに記録しています。ある時点で以前のバージョンがクラッシュし、出力は次のようになります。
エキスパート瞑想エラー:コア0でパニックが発生しました(キャッシュは無効になっていますが、キャッシュメモリ領域にアクセスしました)。
コア 0 レジスタダンプ: PC: 0x40008150 PS: 0x00060034 A0: 0x8008225c A1: 0x3ffb0670 A2: 0x3f40117c A3:
0x00000000 A4: 0x0 00000
0 A7: 0xffffffff7 A8: 0x00000000 A9: 0x00000000
A10: 0x000000ad A11: 0x00000000 A12: 0x800861de A13: 0x3ffbb010
A14: 0x00000003 A15: 0x00060a23 SAR: 0x00000020 理由: 0x00000007
EXCVADDR: 0x00000000000 f 6 LCOUNT: 0x00000000
ISR コンテキストで実行されるコア 0: EPC1: 0x4008a2e8 EPC2: 0x00000000 EPC3: 0x00000000 EPC4: 0x40008150逆追跡: 0x4000814d: 0x3ffb0670 0x40082259: 0x3ffb0700 0x400833b9: 0x3ffb0720 0x400833e2: 0x3ffb0740 0x000 2e 5: 0x3 ffbb0a0 0x4008438d:0x3ffbb0c0 0x400830ed:0x3ffbb0e0 0x40083271:0x3ffbb110 0x400de4b1:0x3ffbb130 0x4 :0x3ff bb170 0 x 400de175:0x3ffbb1d0 0x400dccf2:0x3ffbb240 0x400dcedf:0x3ffbb2a0 0x400dcf47 :0x3ffbb2d0 0x400dbebf:0x3ffbb2f0 0x400dbed2:0x3ffbb310 0x400d757a:0x3ffbb3300300 a66:0x3ffbb380
ELFファイルSHA256: c278c3c874dd3748
再起動中...
この時点でトレースバックが指すコードチェックを開始できます。
addr2line xtensa-esp32- -pfiaC -e project.elf 0x400d3a66 0x400d770a 0x400d757a ...(the remaining addresses of the backtrace)
出力は次のとおりです。
0x400d3a66: root_task は $somePATH/build/../main/main.c:163 にあります。
0x400d770a: $somePATH/build/../main/init_app.c:122 で初期化中
0x400d757a: init_nvs_app は $somePATH/build/../main/init_app.c:47 にあります。
(インライン) init_nvs_app は /$somePATH/build/../main/init_app.c:34 にあります。
それは退屈。そのため、自動化する必要がありますが、シェルスクリプトの経験はあまりありません(Linuxに初めて触れます)。
これを達成する方法も何百万ものあります。経験豊富な人が「マスター瞑想エラー:」と「再起動...」の間のテキストを把握するのに役立ちますか?トレースバックからPC(プログラムカウンタ)アドレスを1行に分割し、SP(スタック)を無視する最善の方法は何ですか?ポインタ)(この特別な場合、SPアドレスは0x3ffで始まります)。 grep regexとawkでいくつか試しましたが、十分ではありません。
答え1
sed
バージョン:
sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt
これは、「Backtrace:」で始まらない行をすべて無視し、2つの検索規則と置換規則を使用して、出力を印刷する前に一致する行を変更します。
これs/:0x3ff[^ ]* */ /g
は次に始まり、その後:0x3ff
にゼロ個以上の空白以外の文字([^ ]*
)が続き、その後にゼロ個以上の空白(*
)が続くすべてのテキストを一致させ、見つかった一致を単一の空白文字に置き換えます。グローバル検索と置換(/g
)なので影響を与えます。みんな最初の一致だけでなく、オンラインで見つけた一致です。
「Guru Meditation」と「Reboot」の操作を制限しようとしません。入力に「Backtrace:」で始まる他の行がない場合、または一度に1つの入力ファイルしか提供されていない場合は、この方法で十分です。
複数の実行で一定でない場合は、コロンと1つ以上の16進数が続く正規表現0x3ff
に変更できます。0x
例えば
s/:0x[0-9a-f]+//gi
この変更は、必要に応じてデフォルトのawkおよびPerlバージョンでも機能します。
awk
バージョン:
awk -v SKIP=1 '/^Guru Meditation Error/ { SKIP=0 };
/^Rebooting\.\.\./ { SKIP=1} ;
SKIP==1 || ! /^Backtrace:/ { next };
{
sub("^Backtrace:","");
gsub(":0x3ff[^ ]* *"," ");
print
}
' input.txt
これは、「Guru Meditation」と「Rebooting」行の間にないすべての入力と、「Backtrace:」で始まらないすべての入力をスキップします。次に、修正された行を印刷する前にスキップsub()
されていない行を修正するために、2つの検索と置換操作(および)を使用します。gsub()
パールバージョン:
perl -lne 'BEGIN {$SKIP=1};
$SKIP=0 if (m/^Guru Meditation Error/);
$SKIP=1 if (m/^Rebooting\.\.\./);
next if ($SKIP || ! m/^Backtrace:/);
s/Backtrace://;
s/:0x3ff\H*\h*/ /g;
print' input.txt
これは awk バージョンと同様に機能しますが、コードは awk と sed バージョンの間の交差のように見えます (perl は awk 様および sed 様構文などが可能です)。
最後の操作は、スペース(タブやスペースなど)だけでなく、Perl(非水平スペース文字)と(水平スペース文字)の一致をs//g
使用するように変更されました。詳細については、「空白」セクションを参照して検索してください。\H
\h
man perlrecharclass
3つのバージョンすべての出力は同じです。
0x4000814d 0x40082259 0x400833b9 0x400833e2 0x40081e6a 0x4008a2e5 0x4008438d 0x400830ed 0x40083271 0x400de4b1 0x400dd525 0x400dd7c5 0x400de175 0x400dccf2 0x400dcedf 0x400dcf47 0x400dbebf 0x400dbed2 0x400d757a 0x400d770a 0x400d3a66
3つのバージョンすべてが、標準入力またはコマンドラインの1つ以上のファイル名から入力を受け取ることができます。上記の例では使用しますinput.txt
(例入力をコピーして貼り付けたテキストファイルです)。
どちらもstdoutとして出力するので、コマンドの置き換えに使用できます。例えば
addr2line xtensa-esp32- -pfiaC -e project.elf $(sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt)