diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp')
| -rw-r--r-- | lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 338 |
1 files changed, 266 insertions, 72 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 6e5482dba9d2..d4cc26a3c329 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -10,6 +10,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Format.h" #include "llvm/Support/Threading.h" #include "lldb/Core/Module.h" @@ -18,13 +19,13 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Progress.h" #include "lldb/Core/Section.h" -#include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timer.h" #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" @@ -45,7 +46,6 @@ #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/DebugMacros.h" #include "lldb/Symbol/LineTable.h" -#include "lldb/Symbol/LocateSymbolFile.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" @@ -59,7 +59,6 @@ #include "DWARFASTParser.h" #include "DWARFASTParserClang.h" #include "DWARFCompileUnit.h" -#include "DWARFDebugAbbrev.h" #include "DWARFDebugAranges.h" #include "DWARFDebugInfo.h" #include "DWARFDebugMacro.h" @@ -75,6 +74,7 @@ #include "SymbolFileDWARFDwo.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatVariadic.h" @@ -98,6 +98,7 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::dwarf; +using namespace lldb_private::plugin::dwarf; LLDB_PLUGIN_DEFINE(SymbolFileDWARF) @@ -115,8 +116,8 @@ enum { class PluginProperties : public Properties { public: - static ConstString GetSettingName() { - return ConstString(SymbolFileDWARF::GetPluginNameStatic()); + static llvm::StringRef GetSettingName() { + return SymbolFileDWARF::GetPluginNameStatic(); } PluginProperties() { @@ -137,9 +138,8 @@ static PluginProperties &GetGlobalPluginProperties() { } static const llvm::DWARFDebugLine::LineTable * -ParseLLVMLineTable(lldb_private::DWARFContext &context, - llvm::DWARFDebugLine &line, dw_offset_t line_offset, - dw_offset_t unit_offset) { +ParseLLVMLineTable(DWARFContext &context, llvm::DWARFDebugLine &line, + dw_offset_t line_offset, dw_offset_t unit_offset) { Log *log = GetLog(DWARFLog::DebugInfo); llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF(); @@ -160,7 +160,7 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, return *line_table; } -static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, +static bool ParseLLVMLineTablePrologue(DWARFContext &context, llvm::DWARFDebugLine::Prologue &prologue, dw_offset_t line_offset, dw_offset_t unit_offset) { @@ -210,17 +210,24 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, FileSpec::Style style, llvm::StringRef compile_dir = {}) { FileSpecList support_files; - size_t first_file = 0; - if (prologue.getVersion() <= 4) { - // File index 0 is not valid before DWARF v5. Add a dummy entry to ensure - // support file list indices match those we get from the debug info and line - // tables. + + // Handle the case where there are no files first to avoid having to special + // case this later. + if (prologue.FileNames.empty()) + return support_files; + + // Before DWARF v5, the line table indexes were one based. + const bool is_one_based = prologue.getVersion() < 5; + const size_t file_names = prologue.FileNames.size(); + const size_t first_file_idx = is_one_based ? 1 : 0; + const size_t last_file_idx = is_one_based ? file_names : file_names - 1; + + // Add a dummy entry to ensure the support file list indices match those we + // get from the debug info and line tables. + if (is_one_based) support_files.Append(FileSpec()); - first_file = 1; - } - const size_t number_of_files = prologue.FileNames.size(); - for (size_t idx = first_file; idx <= number_of_files; ++idx) { + for (size_t idx = first_file_idx; idx <= last_file_idx; ++idx) { std::string remapped_file; if (auto file_path = GetFileByIndex(prologue, idx, compile_dir, style)) { if (auto remapped = module->RemapSourceFile(llvm::StringRef(*file_path))) @@ -229,8 +236,15 @@ ParseSupportFilesFromPrologue(const lldb::ModuleSP &module, remapped_file = std::move(*file_path); } + Checksum checksum; + if (prologue.ContentTypes.HasMD5) { + const llvm::DWARFDebugLine::FileNameEntry &file_name_entry = + prologue.getFileNameEntry(idx); + checksum = file_name_entry.Checksum; + } + // Unconditionally add an entry, so the indices match up. - support_files.EmplaceBack(remapped_file, style); + support_files.EmplaceBack(remapped_file, style, checksum); } return support_files; @@ -512,6 +526,21 @@ bool SymbolFileDWARF::SupportedVersion(uint16_t version) { return version >= 2 && version <= 5; } +static std::set<dw_form_t> +GetUnsupportedForms(llvm::DWARFDebugAbbrev *debug_abbrev) { + if (!debug_abbrev) + return {}; + + std::set<dw_form_t> unsupported_forms; + for (const auto &[_, decl_set] : *debug_abbrev) + for (const auto &decl : decl_set) + for (const auto &attr : decl.attributes()) + if (!DWARFFormValue::FormIsSupported(attr.Form)) + unsupported_forms.insert(attr.Form); + + return unsupported_forms; +} + uint32_t SymbolFileDWARF::CalculateAbilities() { uint32_t abilities = 0; if (m_objfile_sp != nullptr) { @@ -540,20 +569,16 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { if (section) debug_abbrev_file_size = section->GetFileSize(); - DWARFDebugAbbrev *abbrev = DebugAbbrev(); - if (abbrev) { - std::set<dw_form_t> invalid_forms; - abbrev->GetUnsupportedForms(invalid_forms); - if (!invalid_forms.empty()) { - StreamString error; - error.Printf("unsupported DW_FORM value%s:", - invalid_forms.size() > 1 ? "s" : ""); - for (auto form : invalid_forms) - error.Printf(" %#x", form); - m_objfile_sp->GetModule()->ReportWarning( - "{0}", error.GetString().str().c_str()); - return 0; - } + llvm::DWARFDebugAbbrev *abbrev = DebugAbbrev(); + std::set<dw_form_t> unsupported_forms = GetUnsupportedForms(abbrev); + if (!unsupported_forms.empty()) { + StreamString error; + error.Printf("unsupported DW_FORM value%s:", + unsupported_forms.size() > 1 ? "s" : ""); + for (auto form : unsupported_forms) + error.Printf(" %#x", form); + m_objfile_sp->GetModule()->ReportWarning("{0}", error.GetString()); + return 0; } section = @@ -615,7 +640,7 @@ void SymbolFileDWARF::LoadSectionData(lldb::SectionType sect_type, m_objfile_sp->ReadSectionData(section_sp.get(), data); } -DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { +llvm::DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { if (m_abbr) return m_abbr.get(); @@ -623,8 +648,9 @@ DWARFDebugAbbrev *SymbolFileDWARF::DebugAbbrev() { if (debug_abbrev_data.GetByteSize() == 0) return nullptr; - auto abbr = std::make_unique<DWARFDebugAbbrev>(); - llvm::Error error = abbr->parse(debug_abbrev_data); + auto abbr = + std::make_unique<llvm::DWARFDebugAbbrev>(debug_abbrev_data.GetAsLLVM()); + llvm::Error error = abbr->parse(); if (error) { Log *log = GetLog(DWARFLog::DebugInfo); LLDB_LOG_ERROR(log, std::move(error), @@ -1441,6 +1467,17 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { return CompilerDeclContext(); } +std::vector<CompilerContext> +SymbolFileDWARF::GetCompilerContextForUID(lldb::user_id_t type_uid) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + // Anytime we have a lldb::user_id_t, we must get the DIE by calling + // SymbolFileDWARF::GetDIE(). See comments inside the + // SymbolFileDWARF::GetDIE() for details. + if (DWARFDIE die = GetDIE(type_uid)) + return die.GetDeclContext(); + return {}; +} + Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling @@ -1508,11 +1545,11 @@ Type *SymbolFileDWARF::ResolveTypeUID(const DWARFDIE &die, // This function is used when SymbolFileDWARFDebugMap owns a bunch of // SymbolFileDWARF objects to detect if this DWARF file is the one that can // resolve a compiler_type. -bool SymbolFileDWARF::HasForwardDeclForClangType( +bool SymbolFileDWARF::HasForwardDeclForCompilerType( const CompilerType &compiler_type) { CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type); - if (GetForwardDeclClangTypeToDie().count( + if (GetForwardDeclCompilerTypeToDIE().count( compiler_type_no_qualifiers.GetOpaqueQualType())) { return true; } @@ -1540,9 +1577,9 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { // We have a struct/union/class/enum that needs to be fully resolved. CompilerType compiler_type_no_qualifiers = ClangUtil::RemoveFastQualifiers(compiler_type); - auto die_it = GetForwardDeclClangTypeToDie().find( + auto die_it = GetForwardDeclCompilerTypeToDIE().find( compiler_type_no_qualifiers.GetOpaqueQualType()); - if (die_it == GetForwardDeclClangTypeToDie().end()) { + if (die_it == GetForwardDeclCompilerTypeToDIE().end()) { // We have already resolved this type... return true; } @@ -1553,7 +1590,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { // declaration map in case anyone child members or other types require this // type to get resolved. The type will get resolved when all of the calls // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done. - GetForwardDeclClangTypeToDie().erase(die_it); + GetForwardDeclCompilerTypeToDIE().erase(die_it); Type *type = GetDIEToType().lookup(dwarf_die.GetDIE()); @@ -1729,38 +1766,129 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( if (std::shared_ptr<SymbolFileDWARFDwo> dwp_sp = GetDwpSymbolFile()) return dwp_sp; - const char *comp_dir = nullptr; FileSpec dwo_file(dwo_name); FileSystem::Instance().Resolve(dwo_file); - if (dwo_file.IsRelative()) { - comp_dir = cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, - nullptr); - if (!comp_dir) { - unit.SetDwoError(Status::createWithFormat( - "unable to locate relative .dwo debug file \"{0}\" for " - "skeleton DIE {1:x16} without valid DW_AT_comp_dir " - "attribute", - dwo_name, cu_die.GetOffset())); - return nullptr; + bool found = false; + + const FileSpecList &debug_file_search_paths = + Target::GetDefaultDebugFileSearchPaths(); + size_t num_search_paths = debug_file_search_paths.GetSize(); + + // It's relative, e.g. "foo.dwo", but we just to happen to be right next to + // it. Or it's absolute. + found = FileSystem::Instance().Exists(dwo_file); + + const char *comp_dir = + cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr); + if (!found) { + // It could be a relative path that also uses DW_AT_COMP_DIR. + if (comp_dir) { + dwo_file.SetFile(comp_dir, FileSpec::Style::native); + if (!dwo_file.IsRelative()) { + FileSystem::Instance().Resolve(dwo_file); + dwo_file.AppendPathComponent(dwo_name); + found = FileSystem::Instance().Exists(dwo_file); + } else { + FileSpecList dwo_paths; + + // if DW_AT_comp_dir is relative, it should be relative to the location + // of the executable, not to the location from which the debugger was + // launched. + FileSpec relative_to_binary = dwo_file; + relative_to_binary.PrependPathComponent( + m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef()); + FileSystem::Instance().Resolve(relative_to_binary); + relative_to_binary.AppendPathComponent(dwo_name); + dwo_paths.Append(relative_to_binary); + + // Or it's relative to one of the user specified debug directories. + for (size_t idx = 0; idx < num_search_paths; ++idx) { + FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); + dirspec.AppendPathComponent(comp_dir); + FileSystem::Instance().Resolve(dirspec); + if (!FileSystem::Instance().IsDirectory(dirspec)) + continue; + + dirspec.AppendPathComponent(dwo_name); + dwo_paths.Append(dirspec); + } + + size_t num_possible = dwo_paths.GetSize(); + for (size_t idx = 0; idx < num_possible && !found; ++idx) { + FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx); + if (FileSystem::Instance().Exists(dwo_spec)) { + dwo_file = dwo_spec; + found = true; + } + } + } + } else { + Log *log = GetLog(LLDBLog::Symbols); + LLDB_LOGF(log, + "unable to locate relative .dwo debug file \"%s\" for " + "skeleton DIE 0x%016" PRIx64 " without valid DW_AT_comp_dir " + "attribute", + dwo_name, cu_die.GetOffset()); } + } + + if (!found) { + // Try adding the DW_AT_dwo_name ( e.g. "c/d/main-main.dwo"), and just the + // filename ("main-main.dwo") to binary dir and search paths. + FileSpecList dwo_paths; + FileSpec dwo_name_spec(dwo_name); + llvm::StringRef filename_only = dwo_name_spec.GetFilename(); + + FileSpec binary_directory( + m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef()); + FileSystem::Instance().Resolve(binary_directory); + + if (dwo_name_spec.IsRelative()) { + FileSpec dwo_name_binary_directory(binary_directory); + dwo_name_binary_directory.AppendPathComponent(dwo_name); + dwo_paths.Append(dwo_name_binary_directory); + } + + FileSpec filename_binary_directory(binary_directory); + filename_binary_directory.AppendPathComponent(filename_only); + dwo_paths.Append(filename_binary_directory); + + for (size_t idx = 0; idx < num_search_paths; ++idx) { + FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); + FileSystem::Instance().Resolve(dirspec); + if (!FileSystem::Instance().IsDirectory(dirspec)) + continue; + + FileSpec dwo_name_dirspec(dirspec); + dwo_name_dirspec.AppendPathComponent(dwo_name); + dwo_paths.Append(dwo_name_dirspec); - dwo_file.SetFile(comp_dir, FileSpec::Style::native); - if (dwo_file.IsRelative()) { - // if DW_AT_comp_dir is relative, it should be relative to the location - // of the executable, not to the location from which the debugger was - // launched. - dwo_file.PrependPathComponent( - m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef()); + FileSpec filename_dirspec(dirspec); + filename_dirspec.AppendPathComponent(filename_only); + dwo_paths.Append(filename_dirspec); + } + + size_t num_possible = dwo_paths.GetSize(); + for (size_t idx = 0; idx < num_possible && !found; ++idx) { + FileSpec dwo_spec = dwo_paths.GetFileSpecAtIndex(idx); + if (FileSystem::Instance().Exists(dwo_spec)) { + dwo_file = dwo_spec; + found = true; + } } - FileSystem::Instance().Resolve(dwo_file); - dwo_file.AppendPathComponent(dwo_name); } - if (!FileSystem::Instance().Exists(dwo_file)) { + if (!found) { + FileSpec error_dwo_path(dwo_name); + FileSystem::Instance().Resolve(error_dwo_path); + if (error_dwo_path.IsRelative() && comp_dir != nullptr) { + error_dwo_path.PrependPathComponent(comp_dir); + FileSystem::Instance().Resolve(error_dwo_path); + } unit.SetDwoError(Status::createWithFormat( "unable to locate .dwo debug file \"{0}\" for skeleton DIE " "{1:x16}", - dwo_file.GetPath().c_str(), cu_die.GetOffset())); + error_dwo_path.GetPath().c_str(), cu_die.GetOffset())); if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) { GetObjectFile()->GetModule()->ReportWarning( @@ -2331,7 +2459,7 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, // ...But if we are only checking root decl contexts, confirm that the // 'die' is a top-level context. if (only_root_namespaces) - return die.GetParent().Tag() == dwarf::DW_TAG_compile_unit; + return die.GetParent().Tag() == llvm::dwarf::DW_TAG_compile_unit; return true; } @@ -2611,8 +2739,7 @@ void SymbolFileDWARF::FindTypes( if (!languages[GetLanguageFamily(*die.GetCU())]) return true; - llvm::SmallVector<CompilerContext, 4> die_context; - die.GetDeclContext(die_context); + std::vector<CompilerContext> die_context = die.GetDeclContext(); if (!contextMatches(die_context, pattern)) return true; @@ -2993,7 +3120,8 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { template_params = dwarf_ast->GetDIEClassTemplateParams(die); } - m_index->GetTypes(GetDWARFDeclContext(die), [&](DWARFDIE type_die) { + const DWARFDeclContext die_dwarf_decl_ctx = GetDWARFDeclContext(die); + m_index->GetTypes(die_dwarf_decl_ctx, [&](DWARFDIE type_die) { // Make sure type_die's language matches the type system we are // looking for. We don't want to find a "Foo" type from Java if we // are looking for a "Foo" type for C, C++, ObjC, or ObjC++. @@ -3057,7 +3185,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { } // Make sure the decl contexts match all the way up - if (GetDWARFDeclContext(die) != type_dwarf_decl_ctx) + if (die_dwarf_decl_ctx != type_dwarf_decl_ctx) return true; Type *resolved_type = ResolveType(type_die, false); @@ -3437,9 +3565,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g. - // for static constexpr member variables -- DW_AT_const_value will be - // present in the class declaration and DW_AT_location in the DIE defining - // the member. + // for static constexpr member variables -- DW_AT_const_value and + // DW_AT_location will both be present in the DIE defining the member. bool location_is_const_value_data = const_value_form.IsValid() && !location_form.IsValid(); @@ -4129,6 +4256,72 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) { clang->Dump(s.AsRawOstream()); } +bool SymbolFileDWARF::GetSeparateDebugInfo(StructuredData::Dictionary &d, + bool errors_only) { + StructuredData::Array separate_debug_info_files; + DWARFDebugInfo &info = DebugInfo(); + const size_t num_cus = info.GetNumUnits(); + for (size_t cu_idx = 0; cu_idx < num_cus; cu_idx++) { + DWARFUnit *unit = info.GetUnitAtIndex(cu_idx); + DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(unit); + if (dwarf_cu == nullptr) + continue; + + // Check if this is a DWO unit by checking if it has a DWO ID. + // NOTE: it seems that `DWARFUnit::IsDWOUnit` is always false? + if (!dwarf_cu->GetDWOId().has_value()) + continue; + + StructuredData::DictionarySP dwo_data = + std::make_shared<StructuredData::Dictionary>(); + const uint64_t dwo_id = dwarf_cu->GetDWOId().value(); + dwo_data->AddIntegerItem("dwo_id", dwo_id); + + if (const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly()) { + const char *dwo_name = GetDWOName(*dwarf_cu, *die.GetDIE()); + if (dwo_name) { + dwo_data->AddStringItem("dwo_name", dwo_name); + } else { + dwo_data->AddStringItem("error", "missing dwo name"); + } + + const char *comp_dir = die.GetDIE()->GetAttributeValueAsString( + dwarf_cu, DW_AT_comp_dir, nullptr); + if (comp_dir) { + dwo_data->AddStringItem("comp_dir", comp_dir); + } + } else { + dwo_data->AddStringItem( + "error", + llvm::formatv("unable to get unit DIE for DWARFUnit at {0:x}", + dwarf_cu->GetOffset()) + .str()); + } + + // If we have a DWO symbol file, that means we were able to successfully + // load it. + SymbolFile *dwo_symfile = dwarf_cu->GetDwoSymbolFile(); + if (dwo_symfile) { + dwo_data->AddStringItem( + "resolved_dwo_path", + dwo_symfile->GetObjectFile()->GetFileSpec().GetPath()); + } else { + dwo_data->AddStringItem("error", + dwarf_cu->GetDwoError().AsCString("unknown")); + } + dwo_data->AddBooleanItem("loaded", dwo_symfile != nullptr); + if (!errors_only || dwo_data->HasKey("error")) + separate_debug_info_files.AddItem(dwo_data); + } + + d.AddStringItem("type", "dwo"); + d.AddStringItem("symfile", GetMainObjectFile()->GetFileSpec().GetPath()); + d.AddItem("separate-debug-info-files", + std::make_shared<StructuredData::Array>( + std::move(separate_debug_info_files))); + return true; +} + SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == nullptr) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); @@ -4147,9 +4340,10 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { module_spec.GetSymbolFileSpec() = FileSpec(m_objfile_sp->GetModule()->GetFileSpec().GetPath() + ".dwp"); + module_spec.GetUUID() = m_objfile_sp->GetUUID(); FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); FileSpec dwp_filespec = - Symbols::LocateExecutableSymbolFile(module_spec, search_paths); + PluginManager::LocateExecutableSymbolFile(module_spec, search_paths); if (FileSystem::Instance().Exists(dwp_filespec)) { DataBufferSP dwp_file_data_sp; lldb::offset_t dwp_file_data_offset = 0; |
