diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -491,6 +491,9 @@ auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser, DIDumpOptions DumpOpts, Optional DumpOffset) { + // Flush immediately to ensure error messages from parsing are printed after + // any existing output. + OS.flush(); while (!Parser.done()) { if (DumpOffset && Parser.getOffset() != *DumpOffset) { Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler); @@ -498,6 +501,8 @@ } OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset()) << "]\n"; + // Flush after the table header is printed to ensure error messages for + // this table are printed after it. OS.flush(); if (DumpOpts.Verbose) { Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS); @@ -506,6 +511,8 @@ Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler); LineTable.dump(OS, DumpOpts); } + // Flush now to ensure later error output does not get mixed in with the + // line table output. OS.flush(); } }; diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_line_invalid.test @@ -4,40 +4,43 @@ ## Show that a bad length stops parsing of the section. # RUN: llvm-mc -triple x86_64-pc-linux %S/Inputs/debug_line_reserved_length.s -filetype=obj -o %t-reserved.o # RUN: llvm-dwarfdump -debug-line %t-reserved.o 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL,RESERVED +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,FATAL,RESERVED # RUN: llvm-dwarfdump -debug-line %t-reserved.o -verbose 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=FIRST,FATAL,RESERVED +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,FATAL,RESERVED ## We only produce warnings for malformed tables after the specified unit if ## parsing can continue. # RUN: llvm-dwarfdump -debug-line=0 %t-reserved.o 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER,RESERVED +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NOLATER,RESERVED ## Stop looking for the specified unit, if a fatally-bad prologue is detected. # RUN: llvm-dwarfdump -debug-line=0x4b %t-reserved.o 2>&1 \ -# RUN: | FileCheck %s --check-prefixes=NOFIRST,NOLATER,RESERVED +# RUN: | FileCheck %s --check-prefixes=HEADER,NOFIRST,NOLATER,RESERVED ## Show that non-fatal errors do not prevent parsing the rest of the section. # RUN: llvm-mc -triple x86_64-pc-linux %S/Inputs/debug_line_malformed.s -filetype=obj -o %t-malformed.o # RUN: llvm-dwarfdump -debug-line %t-malformed.o 2> %t-malformed.err \ -# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' # RUN: FileCheck %s --input-file=%t-malformed.err --check-prefixes=ALL,OTHER # RUN: llvm-dwarfdump -debug-line %t-malformed.o -verbose 2> %t-malformed-verbose.err \ -# RUN: | FileCheck %s --check-prefixes=FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NONFATAL,LAST --implicit-check-not='debug_line[{{.*}}]' # RUN: FileCheck %s --input-file=%t-malformed-verbose.err --check-prefixes=ALL,OTHER ## We should still produce warnings for malformed tables after the specified unit. # RUN: llvm-dwarfdump -debug-line=0 %t-malformed.o 2> %t-malformed-off-first.err \ -# RUN: | FileCheck %s --check-prefixes=FIRST,NOLATER +# RUN: | FileCheck %s --check-prefixes=HEADER,FIRST,NOLATER # RUN: FileCheck %s --input-file=%t-malformed-off-first.err --check-prefix=ALL ## Don't stop looking for the later unit if non-fatal issues are found. # RUN: llvm-dwarfdump -debug-line=0x3c9 %t-malformed.o 2> %t-malformed-off-last.err \ -# RUN: | FileCheck %s --check-prefix=LAST --implicit-check-not='debug_line[{{.*}}]' +# RUN: | FileCheck %s --check-prefixes=HEADER,LAST --implicit-check-not='debug_line[{{.*}}]' # RUN: FileCheck %s --input-file=%t-malformed-off-last.err --check-prefix=ALL +# HEADER: .debug_line contents: + # FIRST: debug_line[0x00000000] # FIRST: 0x000000000badbeef {{.*}} end_sequence +# FIRST-EMPTY: # NOFIRST-NOT: debug_line[0x00000000] # NOFIRST-NOT: 0x000000000badbeef {{.*}} end_sequence # NOLATER-NOT: debug_line[{{.*}}] @@ -45,8 +48,7 @@ ## For fatal issues, the following table(s) should not be dumped: # FATAL: debug_line[0x00000048] -# RESERVED-NOT: prologue -# RESERVED: warning: parsing line table prologue at offset 0x00000048: unsupported reserved unit length of value 0xfffffffe +# RESERVED-NEXT: warning: parsing line table prologue at offset 0x00000048: unsupported reserved unit length of value 0xfffffffe # RESERVED-NOT: prologue # FATAL-NOT: debug_line