<rdar://problem/11791234>

Fixed an issue that could cause references the shared data for an object file to stay around longer than intended and could cause memory bloat when debugging multiple times.

llvm-svn: 161716
This commit is contained in:
Greg Clayton 2012-08-10 23:33:27 +00:00
parent a423e4c022
commit 8179bcac55
3 changed files with 42 additions and 3 deletions

View File

@ -186,6 +186,36 @@ public:
void
SetOpcodeData(const DataExtractor& data, uint32_t data_offset, uint32_t data_length);
//------------------------------------------------------------------
/// Copy the DWARF location expression into a local buffer.
///
/// It is a good idea to copy the data so we don't keep the entire
/// object file worth of data around just for a few bytes of location
/// expression. LLDB typically will mmap the entire contents of debug
/// information files, and if we use SetOpcodeData, it will get a
/// shared reference to all of this data for the and cause the object
/// file to have to stay around. Even worse, a very very large ".a"
/// that contains one or more .o files could end up being referenced.
/// Location lists are typically small so even though we are copying
/// the data, it shouldn't amount to that much for the variables we
/// end up parsing.
///
/// @param[in] data
/// A data extractor configured to read and copy the DWARF
/// location expression's bytecode.
///
/// @param[in] data_offset
/// The offset of the location expression in the extractor.
///
/// @param[in] data_length
/// The byte length of the location expression.
//------------------------------------------------------------------
void
CopyOpcodeData (const DataExtractor& data,
uint32_t data_offset,
uint32_t data_length);
//------------------------------------------------------------------
/// Tells the expression that it refers to a location list.
///

View File

@ -260,6 +260,13 @@ DWARFExpression::SetOpcodeData (const DataExtractor& data)
m_data = data;
}
void
DWARFExpression::CopyOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
{
const uint8_t *bytes = data.PeekData(data_offset, data_length);
m_data.SetData(DataBufferSP(new DataBufferHeap(bytes, data_length)));
}
void
DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
{

View File

@ -1012,7 +1012,9 @@ ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& sta
// this address is resolved. If they are the same, then the
// function for this address didn't make it into the final
// executable.
bool curr_in_final_executable = info->curr_section_sp->GetLinkedSection ();
bool curr_in_final_executable = false;
if (info->curr_section_sp->GetLinkedSection ())
curr_in_final_executable = true;
// If we are doing DWARF with debug map, then we need to carefully
// add each line table entry as there may be gaps as functions
@ -6542,7 +6544,7 @@ SymbolFileDWARF::ParseVariableDIE
uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
uint32_t block_length = form_value.Unsigned();
location.SetOpcodeData(get_debug_info_data(), block_offset, block_length);
location.CopyOpcodeData(get_debug_info_data(), block_offset, block_length);
}
else
{
@ -6552,7 +6554,7 @@ SymbolFileDWARF::ParseVariableDIE
size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
if (loc_list_length > 0)
{
location.SetOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
location.CopyOpcodeData(debug_loc_data, debug_loc_offset, loc_list_length);
assert (func_low_pc != LLDB_INVALID_ADDRESS);
location.SetLocationListSlide (func_low_pc - dwarf_cu->GetBaseAddress());
}