Changeset View
Changeset View
Standalone View
Standalone View
source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
Show All 33 Lines | |||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
DWARFDebugInfo::DWARFDebugInfo() | DWARFDebugInfo::DWARFDebugInfo() | ||||
: m_dwarf2Data(NULL), m_compile_units(), m_cu_aranges_ap() {} | : m_dwarf2Data(NULL), m_compile_units(), m_cu_aranges_ap() {} | ||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
// SetDwarfData | // SetDwarfData | ||||
//---------------------------------------------------------------------- | //---------------------------------------------------------------------- | ||||
void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { | void DWARFDebugInfo::SetDwarfData(SymbolFileDWARF *dwarf2Data) { | ||||
// C++14: std::lock_guard<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
m_dwarf2Data = dwarf2Data; | m_dwarf2Data = dwarf2Data; | ||||
m_compile_units.clear(); | m_compile_units.clear(); | ||||
} | } | ||||
DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() { | DWARFDebugAranges &DWARFDebugInfo::GetCompileUnitAranges() { | ||||
if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) { | if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) { | ||||
Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); | Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_ARANGES)); | ||||
Show All 39 Lines | if (m_cu_aranges_ap.get() == NULL && m_dwarf2Data) { | ||||
const bool minimize = true; | const bool minimize = true; | ||||
m_cu_aranges_ap->Sort(minimize); | m_cu_aranges_ap->Sort(minimize); | ||||
} | } | ||||
return *m_cu_aranges_ap.get(); | return *m_cu_aranges_ap.get(); | ||||
} | } | ||||
void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { | void DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() { | ||||
if (m_compile_units.empty()) { | { | ||||
if (m_dwarf2Data != NULL) { | // C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | ||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
if (!m_compile_units.empty()) | |||||
return; | |||||
} | |||||
if (m_dwarf2Data == NULL) | |||||
return; | |||||
lldb::offset_t file_offset = 0; | lldb::offset_t file_offset = 0; | ||||
for (;;) { | for (;;) { | ||||
DWARFCompileUnitSP cu_sp = | DWARFCompileUnitSP cu_sp = | ||||
DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset); | DWARFCompileUnit::Extract(m_dwarf2Data, &file_offset); | ||||
if (cu_sp.get() == NULL) | if (cu_sp.get() == NULL) | ||||
break; | break; | ||||
{ | |||||
// C++14: std::lock_guard<std::shared_timed_mutex> | |||||
// guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
m_compile_units.push_back(cu_sp); | m_compile_units.push_back(cu_sp); | ||||
} | |||||
clayborg: So if some code calls DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() after this loop has… | |||||
file_offset = cu_sp->GetNextCompileUnitFileOffset(); | file_offset = cu_sp->GetNextCompileUnitFileOffset(); | ||||
} | } | ||||
} | } | ||||
} | |||||
} | |||||
size_t DWARFDebugInfo::GetNumCompileUnits() { | size_t DWARFDebugInfo::GetNumCompileUnits() { | ||||
ParseCompileUnitHeadersIfNeeded(); | ParseCompileUnitHeadersIfNeeded(); | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
return m_compile_units.size(); | return m_compile_units.size(); | ||||
} | } | ||||
DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) { | DWARFCompileUnit *DWARFDebugInfo::GetCompileUnitAtIndex(uint32_t idx) { | ||||
DWARFCompileUnit *cu = NULL; | DWARFCompileUnit *cu = NULL; | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
if (idx < GetNumCompileUnits()) | if (idx < GetNumCompileUnits()) | ||||
cu = m_compile_units[idx].get(); | cu = m_compile_units[idx].get(); | ||||
return cu; | return cu; | ||||
} | } | ||||
bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const { | bool DWARFDebugInfo::ContainsCompileUnit(const DWARFCompileUnit *cu) const { | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
// Not a verify efficient function, but it is handy for use in assertions | // Not a verify efficient function, but it is handy for use in assertions | ||||
// to make sure that a compile unit comes from a debug information file. | // to make sure that a compile unit comes from a debug information file. | ||||
CompileUnitColl::const_iterator end_pos = m_compile_units.end(); | CompileUnitColl::const_iterator end_pos = m_compile_units.end(); | ||||
CompileUnitColl::const_iterator pos; | CompileUnitColl::const_iterator pos; | ||||
for (pos = m_compile_units.begin(); pos != end_pos; ++pos) { | for (pos = m_compile_units.begin(); pos != end_pos; ++pos) { | ||||
if (pos->get() == cu) | if (pos->get() == cu) | ||||
return true; | return true; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset( | bool DWARFDebugInfo::OffsetLessThanCompileUnitOffset( | ||||
dw_offset_t offset, const DWARFCompileUnitSP &cu_sp) { | dw_offset_t offset, const DWARFCompileUnitSP &cu_sp) { | ||||
return offset < cu_sp->GetOffset(); | return offset < cu_sp->GetOffset(); | ||||
} | } | ||||
DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, | DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(dw_offset_t cu_offset, | ||||
uint32_t *idx_ptr) { | uint32_t *idx_ptr) { | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
DWARFCompileUnitSP cu_sp; | DWARFCompileUnitSP cu_sp; | ||||
uint32_t cu_idx = DW_INVALID_INDEX; | uint32_t cu_idx = DW_INVALID_INDEX; | ||||
if (cu_offset != DW_INVALID_OFFSET) { | if (cu_offset != DW_INVALID_OFFSET) { | ||||
ParseCompileUnitHeadersIfNeeded(); | ParseCompileUnitHeadersIfNeeded(); | ||||
// Watch out for single compile unit executable as they are pretty common | // Watch out for single compile unit executable as they are pretty common | ||||
const size_t num_cus = m_compile_units.size(); | const size_t num_cus = m_compile_units.size(); | ||||
if (num_cus == 1) { | if (num_cus == 1) { | ||||
Show All 26 Lines | DWARFCompileUnit *DWARFDebugInfo::GetCompileUnit(const DIERef &die_ref) { | ||||
else | else | ||||
return GetCompileUnit(die_ref.cu_offset); | return GetCompileUnit(die_ref.cu_offset); | ||||
} | } | ||||
DWARFCompileUnit * | DWARFCompileUnit * | ||||
DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { | DWARFDebugInfo::GetCompileUnitContainingDIEOffset(dw_offset_t die_offset) { | ||||
ParseCompileUnitHeadersIfNeeded(); | ParseCompileUnitHeadersIfNeeded(); | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
DWARFCompileUnitSP cu_sp; | DWARFCompileUnitSP cu_sp; | ||||
// Watch out for single compile unit executable as they are pretty common | // Watch out for single compile unit executable as they are pretty common | ||||
const size_t num_cus = m_compile_units.size(); | const size_t num_cus = m_compile_units.size(); | ||||
if (num_cus == 1) { | if (num_cus == 1) { | ||||
if (m_compile_units[0]->ContainsDIEOffset(die_offset)) | if (m_compile_units[0]->ContainsDIEOffset(die_offset)) | ||||
return m_compile_units[0].get(); | return m_compile_units[0].get(); | ||||
} else if (num_cus) { | } else if (num_cus) { | ||||
▲ Show 20 Lines • Show All 293 Lines • ▼ Show 20 Lines | void DWARFDebugInfo::Dump(Stream *s, const uint32_t die_offset, | ||||
const uint32_t recurse_depth) { | const uint32_t recurse_depth) { | ||||
DumpInfo dumpInfo(s, die_offset, recurse_depth); | DumpInfo dumpInfo(s, die_offset, recurse_depth); | ||||
s->PutCString("Dumping .debug_info section from internal representation\n"); | s->PutCString("Dumping .debug_info section from internal representation\n"); | ||||
CompileUnitColl::const_iterator pos; | CompileUnitColl::const_iterator pos; | ||||
uint32_t curr_depth = 0; | uint32_t curr_depth = 0; | ||||
ParseCompileUnitHeadersIfNeeded(); | ParseCompileUnitHeadersIfNeeded(); | ||||
// C++14: std::shared_lock<std::shared_timed_mutex> guard(m_dwz_uniq_mutex); | |||||
std::lock_guard<std::recursive_mutex> guard(m_dwz_uniq_mutex); | |||||
for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) { | for (pos = m_compile_units.begin(); pos != m_compile_units.end(); ++pos) { | ||||
DWARFCompileUnit *cu = pos->get(); | DWARFCompileUnit *cu = pos->get(); | ||||
DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo); | DumpCallback(m_dwarf2Data, cu, NULL, 0, curr_depth, &dumpInfo); | ||||
const DWARFDIE die = cu->DIE(); | const DWARFDIE die = cu->DIE(); | ||||
if (die) | if (die) | ||||
die.Dump(s, recurse_depth); | die.Dump(s, recurse_depth); | ||||
} | } | ||||
} | } |
So if some code calls DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded() after this loop has added 1 compile unit they will return and be able to proceed? This doesn't make sense.