저는 esp32 프로젝트를 진행 중이며 모든 esp32 uart 디버그 출력을 여러 파일에 기록하고 있습니다. 어느 시점에서 이전 버전이 충돌하고 출력은 다음과 같습니다.
전문가 명상 오류: 코어 0에서 패닉이 발생했습니다(캐싱이 비활성화되었지만 캐시 메모리 영역에 액세스했습니다).
코어 0 레지스터 덤프: PC: 0x40008150 PS: 0x00060034 A0: 0x8008225c A1: 0x3ffb0670 A2: 0x3f40117c A3:
0x00000000 A4: 0x00000004 A5: 0x00000000
A6: 000000 0 A7: 0xffffffff7 A8: 0x00000000 A9: 0x00000000
A10: 0x000000ad A11: 0x00000000 A12: 0x800861de A13: 0x3ffbb010
A14: 0x00000003 A15: 0x00060a23 SAR: 0x00000020 이유: 0x00000007
EXCVADDR: 0x00000000 LBEG: 0x4000c2e0 대출: 0x4000 c2f 6 LCOUNT: 0x00000000
ISR 컨텍스트에서 실행되는 코어 0: EPC1: 0x4008a2e8 EPC2: 0x00000000 EPC3: 0x00000000 EPC4: 0x40008150역추적: 0x4000814d: 0x3ffb0670 0x40082259: 0x3ffb0700 0x400833b9: 0x3ffb0720 0x400833e2: 0x3ffb0740 0x40081e6a: 0x3ffb0760 0x4008a2e 5: 0x3 ffbb0a0 0x4008438d:0x3ffbb0c0 0x400830ed:0x3ffbb0e0 0x40083271:0x3ffbb110 0x400de4b1:0x3ffbb130 0x400dd525:0x3ffbb150 0x400dd7c5:0x3ff bb170 0 x 400de175:0x3ffbb1d0 0x400dccf2:0x3ffbb240 0x400dcedf:0x3ffbb2a0 0x400dcf47 :0x3ffbb2d0 0x400dbebf:0x3ffbb2f0 0x400dbed2:0x3ffbb310 0x400d757a:0x3ffbb330 0x400d770a:0x3ffbb360 0x400d3a66: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(프로그램 카운터) 주소를 한 줄로 분리하고 SP(스택)를 무시하는 가장 좋은 방법은 무엇입니까? 포인터)(이 특별한 경우 SP 주소는 0x3ff로 시작합니다). grep regex와 awk로 몇 가지를 시도했지만 충분하지 않습니다.
답변1
sed
버전:
sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt
이는 "Backtrace:"로 시작하지 않는 모든 줄을 무시하고 두 개의 검색 및 바꾸기 규칙을 사용하여 출력을 인쇄하기 전에 일치하는 줄을 수정합니다.
이 s/:0x3ff[^ ]* */ /g
작업은 다음으로 시작하고 그 :0x3ff
뒤에 0개 이상의 공백이 아닌 문자( [^ ]*
)가 오고 그 뒤에 0개 이상의 공백( *
)이 오는 모든 텍스트를 일치시키고 발견된 일치 항목을 단일 공백 문자로 바꿉니다. 전역 검색 및 바꾸기( /g
)이므로 영향을 미칩니다.모두첫 번째 일치 항목뿐만 아니라 온라인에서 찾은 일치 항목입니다.
"Guru Meditation" 및 "Reboot"에 대한 작업을 제한하려고 시도하지 않습니다. 입력에 "Backtrace:"로 시작하는 다른 줄이 없거나 한 번에 하나의 입력 파일만 제공되는 경우 이 방법으로 충분합니다.
여러 실행에서 일정하지 않은 경우 콜론과 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()
건너뛰지 않은 줄을 수정하기 위해 두 가지 검색 및 바꾸기 작업(및) 을 사용합니다.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
세 가지 버전 모두의 출력은 동일합니다.
0x4000814d 0x40082259 0x400833b9 0x400833e2 0x40081e6a 0x4008a2e5 0x4008438d 0x400830ed 0x40083271 0x400de4b1 0x400dd525 0x400dd7c5 0x400de175 0x400dccf2 0x400dcedf 0x400dcf47 0x400dbebf 0x400dbed2 0x400d757a 0x400d770a 0x400d3a66
세 가지 버전 모두 표준 입력이나 명령줄의 하나 이상의 파일 이름에서 입력을 받을 수 있습니다. 위의 예에서는 사용합니다 input.txt
(예제 입력을 복사하여 붙여넣은 텍스트 파일입니다).
둘 다 stdout으로 출력하므로 명령 대체에 사용할 수 있습니다. 예를 들어
addr2line xtensa-esp32- -pfiaC -e project.elf $(sed -n -E -e '/^Backtrace:/ {s/Backtrace://; s/:0x3ff[^ ]* */ /g; p}' input.txt)