forked from OSchip/llvm-project
[DWARF] Fix crash for DWARFDie::dump.
When DIE is extracted manually, the DieArray is empty. When dump is invoked on aforementioned DIE it tries to extract child, even if Dump options say otherwise. Resulting in crash. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D99698
This commit is contained in:
parent
8f9477b067
commit
b7459a10da
|
@ -251,9 +251,6 @@ class DWARFUnit {
|
|||
protected:
|
||||
const DWARFUnitHeader &getHeader() const { return Header; }
|
||||
|
||||
/// Size in bytes of the parsed unit header.
|
||||
uint32_t getHeaderSize() const { return Header.getSize(); }
|
||||
|
||||
/// Find the unit's contribution to the string offsets table and determine its
|
||||
/// length and form. The given offset is expected to be derived from the unit
|
||||
/// DIE's DW_AT_str_offsets_base attribute.
|
||||
|
@ -290,6 +287,8 @@ public:
|
|||
uint8_t getDwarfOffsetByteSize() const {
|
||||
return Header.getDwarfOffsetByteSize();
|
||||
}
|
||||
/// Size in bytes of the parsed unit header.
|
||||
uint32_t getHeaderSize() const { return Header.getSize(); }
|
||||
uint64_t getLength() const { return Header.getLength(); }
|
||||
dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
|
||||
uint8_t getUnitType() const { return Header.getUnitType(); }
|
||||
|
|
|
@ -635,14 +635,14 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
|
|||
for (const DWARFAttribute &AttrValue : attributes())
|
||||
dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
|
||||
|
||||
DWARFDie child = getFirstChild();
|
||||
if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
|
||||
if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0) {
|
||||
DWARFDie Child = getFirstChild();
|
||||
DumpOpts.ChildRecurseDepth--;
|
||||
DIDumpOptions ChildDumpOpts = DumpOpts;
|
||||
ChildDumpOpts.ShowParents = false;
|
||||
while (child) {
|
||||
child.dump(OS, Indent + 2, ChildDumpOpts);
|
||||
child = child.getSibling();
|
||||
while (Child) {
|
||||
Child.dump(OS, Indent + 2, ChildDumpOpts);
|
||||
Child = Child.getSibling();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -19,6 +19,7 @@ add_llvm_unittest(DebugInfoDWARFTests
|
|||
DWARFDebugInfoTest.cpp
|
||||
DWARFDebugLineTest.cpp
|
||||
DWARFDieTest.cpp
|
||||
DWARFDieManualExtractTest.cpp
|
||||
DWARFExpressionCompactPrinterTest.cpp
|
||||
DWARFFormValueTest.cpp
|
||||
DWARFListTableTest.cpp
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
//===-llvm/unittest/DebugInfo/DWARFDieManualExtractTest.cpp---------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "DwarfGenerator.h"
|
||||
#include "DwarfUtils.h"
|
||||
#include "llvm/BinaryFormat/Dwarf.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/ObjectYAML/DWARFEmitter.h"
|
||||
#include "llvm/Testing/Support/Error.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::dwarf;
|
||||
using namespace utils;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(DWARFDie, manualExtractDump) {
|
||||
typedef uint32_t AddrType;
|
||||
uint16_t Version = 4;
|
||||
Triple Triple = getDefaultTargetTripleForAddrSize(sizeof(AddrType));
|
||||
if (!isObjectEmissionSupported(Triple))
|
||||
return;
|
||||
|
||||
auto ExpectedDG = dwarfgen::Generator::create(Triple, Version);
|
||||
ASSERT_THAT_EXPECTED(ExpectedDG, Succeeded());
|
||||
dwarfgen::Generator *DG = ExpectedDG.get().get();
|
||||
dwarfgen::CompileUnit &DGCU = DG->addCompileUnit();
|
||||
dwarfgen::DIE CUDie = DGCU.getUnitDIE();
|
||||
|
||||
CUDie.addAttribute(DW_AT_name, DW_FORM_strp, "/tmp/main.c");
|
||||
CUDie.addAttribute(DW_AT_language, DW_FORM_data2, DW_LANG_C);
|
||||
|
||||
dwarfgen::DIE SubprogramDie = CUDie.addChild(DW_TAG_subprogram);
|
||||
SubprogramDie.addAttribute(DW_AT_name, DW_FORM_strp, "main");
|
||||
SubprogramDie.addAttribute(DW_AT_low_pc, DW_FORM_addr, 0x1000U);
|
||||
SubprogramDie.addAttribute(DW_AT_high_pc, DW_FORM_addr, 0x2000U);
|
||||
|
||||
StringRef FileBytes = DG->generate();
|
||||
MemoryBufferRef FileBuffer(FileBytes, "dwarf");
|
||||
auto Obj = object::ObjectFile::createObjectFile(FileBuffer);
|
||||
EXPECT_TRUE((bool)Obj);
|
||||
std::unique_ptr<DWARFContext> Ctx = DWARFContext::create(**Obj);
|
||||
|
||||
DWARFCompileUnit *CU = Ctx->getCompileUnitForOffset(0);
|
||||
ASSERT_NE(nullptr, CU);
|
||||
// Manually extracting DWARF DIE.
|
||||
uint64_t DIEOffset = CU->getOffset() + CU->getHeaderSize();
|
||||
uint64_t NextCUOffset = CU->getNextUnitOffset();
|
||||
DWARFDebugInfoEntry DieInfo;
|
||||
DWARFDataExtractor DebugInfoData = CU->getDebugInfoExtractor();
|
||||
uint32_t Depth = 0;
|
||||
ASSERT_TRUE(
|
||||
DieInfo.extractFast(*CU, &DIEOffset, DebugInfoData, NextCUOffset, Depth));
|
||||
DWARFDie Die(CU, &DieInfo);
|
||||
ASSERT_TRUE(Die.isValid());
|
||||
ASSERT_TRUE(Die.hasChildren());
|
||||
// Since we have extracted manually DieArray is empty.
|
||||
// Dump function should respect the default flags and print just current DIE,
|
||||
// and not explore children.
|
||||
SmallString<512> Output;
|
||||
raw_svector_ostream OS(Output);
|
||||
Die.dump(OS);
|
||||
constexpr size_t NumOfLines = 3;
|
||||
SmallVector<StringRef, NumOfLines> Strings;
|
||||
SmallVector<StringRef, NumOfLines> ValidStrings = {
|
||||
"0x0000000b: DW_TAG_compile_unit",
|
||||
" DW_AT_name (\"/tmp/main.c\")",
|
||||
" DW_AT_language (DW_LANG_C)"};
|
||||
StringRef(Output).split(Strings, '\n', -1, false);
|
||||
ASSERT_EQ(Strings.size(), NumOfLines);
|
||||
for (size_t I = 0; I < NumOfLines; ++I)
|
||||
EXPECT_EQ(ValidStrings[I], Strings[I]);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
Loading…
Reference in New Issue