While debugging the `X86_DECODER_SELFTEST` failure first reported in [1], we noticed that the line numbers reported by the `insn_decoder_test` tool do not correspond to the line in the output of `objdump_reformat.awk` that was causing the failure: # TEST posttest llvm-objdump -d -j .text ./vmlinux | \ awk -f ./arch/x86/tools/objdump_reformat.awk | \ arch/x86/tools/insn_decoder_test -y -v arch/x86/tools/insn_decoder_test: error: malformed line 1657116: 68db0 $ llvm-objdump -d -j .text ./vmlinux | \ awk -f ./arch/x86/tools/objdump_reformat.awk > objdump_reformat.txt $ head -n `echo 1657116+2 | bc` objdump_reformat.txt | tail -n 5 ffffffff815430b1 41 8b 47 1c movl ffffffff815430b5 89 c1 movl ffffffff815430b7 81 c9 00 40 00 00 orl ffffffff815430bd 41 89 4e 18 movl ffffffff815430c1 a8 40 testb These lines are perfectly fine. The reason is that the line count reported by the tool only includes instruction lines, i.e., it does not count symbol lines. This behavior was introduced in Commit 35039eb6b199 ("x86: Show symbol name if insn decoder test failed"), which included symbol lines in the output of the awk script. This broke the `instuction lines == total lines` property without accounting for it in `insn_decoder_test.c`. Add a new variable to count the combined (insn+symbol) line count and report this in the error message. With this patch, the line reported by the tool is the line causing the failure (long line wrapped at 75 chars): # TEST posttest llvm-objdump -d -j .text ./vmlinux | \ awk -f ./arch/x86/tools/objdump_reformat.awk | \ arch/x86/tools/insn_decoder_test -y -v arch/x86/tools/insn_decoder_test: error: malformed line 1699686: 68db0 $ head -n ` echo 1699686+2 | bc` objdump_reformat.txt | tail -n 5 ffffffff81568dac c3 retq <_RNvXsP_NtCs7qddEHlz8fK_4core3fmtRINtNtNtNtB7_4iter8adapters5chain5Chain INtNtBA_7flatten7FlattenINtNtB7_6option8IntoIterNtNtB7_4char11EscapeDebug EEINtB1a_7FlatMapNtNtNtB7_3str4iter5CharsB1T_NtB2D_23CharEscapeDebugConti nueEENtB5_5Debug3fmtB7_>:ffffffff81568db0 ffffffff81568dad 0f 1f 00 nopl ffffffff81568db0 f3 0f 1e fa endbr64 ffffffff81568db4 41 56 pushq [In this case the line causing the failure is interpreted as two lines by the tool (due to its length, but this is fixed by [1, 2]), and the second line is reported. Still the spatial closeness between the reported line and the line causing the failure would have made debugging a lot easier.] Link: https://lore.kernel.org/lkml/Y9ES4UKl%2F+DtvAVS@xxxxxxxxx/T/ [1] Link: https://lore.kernel.org/rust-for-linux/20231119180145.157455-1-sergio.collado@xxxxxxxxx/ [2] Fixes: 35039eb6b199 ("x86: Show symbol name if insn decoder test failed") Reviewed-by: Miguel Ojeda <ojeda@xxxxxxxxxx> Tested-by: Miguel Ojeda <ojeda@xxxxxxxxxx> Reported-by: John Baublitz <john.m.baublitz@xxxxxxxxx> Debugged-by: John Baublitz <john.m.baublitz@xxxxxxxxx> Signed-off-by: Valentin Obst <kernel@xxxxxxxxxxxxxxx> --- Changes in v2: - Added tags 'Reviewed-by', 'Tested-by', 'Reported-by', 'Debugged-by', 'Link', and 'Fixes'. - Explain why this patch fixes the commit mentioned in the 'Fixes' tag. - CCed the stable list and sent to all x86 maintainers. - Link to v1: https://lore.kernel.org/r/20240221-x86-insn-decoder-line-fix-v1-1-47cd5a1718c6@xxxxxxxxxxxxxxx --- arch/x86/tools/insn_decoder_test.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/x86/tools/insn_decoder_test.c b/arch/x86/tools/insn_decoder_test.c index 472540aeabc2..727017a3c3c7 100644 --- a/arch/x86/tools/insn_decoder_test.c +++ b/arch/x86/tools/insn_decoder_test.c @@ -114,6 +114,7 @@ int main(int argc, char **argv) unsigned char insn_buff[16]; struct insn insn; int insns = 0; + int lines = 0; int warnings = 0; parse_args(argc, argv); @@ -123,6 +124,8 @@ int main(int argc, char **argv) int nb = 0, ret; unsigned int b; + lines++; + if (line[0] == '<') { /* Symbol line */ strcpy(sym, line); @@ -134,12 +137,12 @@ int main(int argc, char **argv) strcpy(copy, line); tab1 = strchr(copy, '\t'); if (!tab1) - malformed_line(line, insns); + malformed_line(line, lines); s = tab1 + 1; s += strspn(s, " "); tab2 = strchr(s, '\t'); if (!tab2) - malformed_line(line, insns); + malformed_line(line, lines); *tab2 = '\0'; /* Characters beyond tab2 aren't examined */ while (s < tab2) { if (sscanf(s, "%x", &b) == 1) { --- base-commit: b401b621758e46812da61fa58a67c3fd8d91de0d change-id: 20240221-x86-insn-decoder-line-fix-7b1f2e1732ff Best regards, -- Valentin Obst <kernel@xxxxxxxxxxxxxxx>