Modified the host process monitor callback function Host::StartMonitoringChildProcess
to spawn a thread for each process that is being monitored. Previously
LLDB would spawn a single thread that would wait for any child process which
isn't ok to do as a shared library (LLDB.framework on Mac OSX, or lldb.so on
linux). The old single thread used to call wait4() with a pid of -1 which
could cause it to reap child processes that it shouldn't have.
Re-wrote the way Function blocks are handles. Previously I attempted to keep
all blocks in a single memory allocation (in a std::vector). This made the
code somewhat efficient, but hard to work with. I got rid of the old BlockList
class, and went to a straight parent with children relationship. This new
approach will allow for partial parsing of the blocks within a function.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@111706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index 3a132f6..28da776 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -17,47 +17,26 @@
using namespace lldb;
using namespace lldb_private;
-Block::Block(user_id_t uid, uint32_t depth, BlockList* blocks) :
+Block::Block(lldb::user_id_t uid) :
UserID(uid),
- m_block_list(blocks),
- m_depth(depth),
- m_ranges(),
- m_inlineInfoSP(),
- m_variables()
+ m_parent_scope (NULL),
+ m_sibling (NULL),
+ m_children (),
+ m_ranges (),
+ m_inlineInfoSP (),
+ m_variables (),
+ m_parsed_block_info (false),
+ m_parsed_block_variables (false),
+ m_parsed_child_blocks (false)
{
}
-Block::Block(const Block& rhs) :
- UserID(rhs),
- m_block_list(rhs.m_block_list),
- m_depth(rhs.m_depth),
- m_ranges(rhs.m_ranges),
- m_inlineInfoSP(rhs.m_inlineInfoSP),
- m_variables(rhs.m_variables)
-{
-}
-
-const Block&
-Block::operator= (const Block& rhs)
-{
- if (this != &rhs)
- {
- UserID::operator= (rhs);
- m_block_list = rhs.m_block_list;
- m_depth = rhs.m_depth;
- m_ranges = rhs.m_ranges;
- m_inlineInfoSP = rhs.m_inlineInfoSP;
- m_variables = rhs.m_variables;
- }
- return *this;
-}
-
Block::~Block ()
{
}
void
-Block::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const
+Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Process *process) const
{
size_t num_ranges = m_ranges.size();
if (num_ranges)
@@ -65,9 +44,9 @@
addr_t base_addr = LLDB_INVALID_ADDRESS;
if (process)
- base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
+ base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
if (base_addr == LLDB_INVALID_ADDRESS)
- base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetFileAddress();
+ base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
s->Printf("range%s = ", num_ranges > 1 ? "s" : "");
std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
@@ -85,9 +64,13 @@
{
if (depth < 0)
{
- // We have a depth that is less than zero, print our parent blocks
- // first
- m_block_list->Dump(s, GetParentUID(), depth + 1, show_context);
+ Block *parent = GetParent();
+ if (parent)
+ {
+ // We have a depth that is less than zero, print our parent blocks
+ // first
+ parent->Dump(s, base_addr, depth + 1, show_context);
+ }
}
s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
@@ -126,12 +109,9 @@
m_variables->Dump(s, show_context);
}
- uint32_t blockID = m_block_list->GetFirstChild(GetID());
- while (blockID != Block::InvalidID)
+ for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
{
- m_block_list->Dump(s, blockID, depth - 1, show_context);
-
- blockID = m_block_list->GetSibling(blockID);
+ child_block->Dump(s, base_addr, depth - 1, show_context);
}
s->IndentLess();
@@ -140,11 +120,28 @@
}
+Block *
+Block::FindBlockByID (user_id_t block_id)
+{
+ if (block_id == GetID())
+ return this;
+
+ Block *matching_block = NULL;
+ for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
+ {
+ matching_block = child_block->FindBlockByID (block_id);
+ if (matching_block)
+ break;
+ }
+ return matching_block;
+}
+
void
Block::CalculateSymbolContext(SymbolContext* sc)
{
+ if (m_parent_scope)
+ m_parent_scope->CalculateSymbolContext(sc);
sc->block = this;
- m_block_list->GetFunction()->CalculateSymbolContext(sc);
}
void
@@ -196,7 +193,10 @@
void
Block::DumpSymbolContext(Stream *s)
{
- m_block_list->GetFunction()->DumpSymbolContext(s);
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ if (sc.function)
+ sc.function->DumpSymbolContext(s);
s->Printf(", Block{0x%8.8x}", GetID());
}
@@ -212,37 +212,19 @@
return VMRange::ContainsRange(m_ranges, range);
}
-
-
-bool
-BlockList::BlockContainsBlockWithID (const user_id_t block_id, const user_id_t find_block_id) const
+Block *
+Block::GetParent () const
{
- if (block_id == Block::InvalidID)
- return false;
-
- if (block_id == find_block_id)
- return true;
- else
+ if (m_parent_scope)
{
- user_id_t child_block_id = GetFirstChild(block_id);
- while (child_block_id != Block::InvalidID)
- {
- if (BlockContainsBlockWithID (child_block_id, find_block_id))
- return true;
- child_block_id = GetSibling(child_block_id);
- }
+ SymbolContext sc;
+ m_parent_scope->CalculateSymbolContext(&sc);
+ if (sc.block)
+ return sc.block;
}
-
- return false;
+ return NULL;
}
-bool
-Block::ContainsBlockWithID (user_id_t block_id) const
-{
- return m_block_list->BlockContainsBlockWithID (GetID(), block_id);
-}
-
-
void
Block::AddRange(addr_t start_offset, addr_t end_offset)
{
@@ -276,45 +258,29 @@
}
Block *
-Block::GetParent () const
-{
- return m_block_list->GetBlockByID (m_block_list->GetParent(GetID()));
-}
-
-Block *
-Block::GetSibling () const
-{
- return m_block_list->GetBlockByID (m_block_list->GetSibling(GetID()));
-}
-
-Block *
Block::GetFirstChild () const
{
- return m_block_list->GetBlockByID (m_block_list->GetFirstChild(GetID()));
+ if (m_children.empty())
+ return NULL;
+ return m_children.front().get();
}
-user_id_t
-Block::GetParentUID() const
+void
+Block::AddChild(const BlockSP &child_block_sp)
{
- return m_block_list->GetParent(GetID());
-}
+ if (child_block_sp)
+ {
+ Block *block_needs_sibling = NULL;
-user_id_t
-Block::GetSiblingUID() const
-{
- return m_block_list->GetSibling(GetID());
-}
+ if (!m_children.empty())
+ block_needs_sibling = m_children.back().get();
-user_id_t
-Block::GetFirstChildUID() const
-{
- return m_block_list->GetFirstChild(GetID());
-}
+ child_block_sp->SetParentScope (this);
+ m_children.push_back (child_block_sp);
-user_id_t
-Block::AddChild(user_id_t userID)
-{
- return m_block_list->AddChild(GetID(), userID);
+ if (block_needs_sibling)
+ block_needs_sibling->SetSibling (child_block_sp.get());
+ }
}
void
@@ -329,12 +295,16 @@
Block::GetVariableList (bool get_child_variables, bool can_create)
{
VariableListSP variable_list_sp;
- if (m_variables.get() == NULL && can_create)
+ if (m_parsed_block_variables == false)
{
- SymbolContext sc;
- CalculateSymbolContext(&sc);
- assert(sc.module_sp);
- sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+ if (m_variables.get() == NULL && can_create)
+ {
+ m_parsed_block_variables = true;
+ SymbolContext sc;
+ CalculateSymbolContext(&sc);
+ assert(sc.module_sp);
+ sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+ }
}
if (m_variables.get())
@@ -387,285 +357,14 @@
m_variables = variables;
}
-uint32_t
-Block::Depth () const
-{
- return m_depth;
-}
-
-BlockList::BlockList(Function *function, const AddressRange& range) :
- m_function(function),
- m_range(range),
- m_blocks()
-{
-}
-
-BlockList::~BlockList()
-{
-}
-
-AddressRange &
-BlockList::GetAddressRange()
-{
- return m_range;
-}
-
-const AddressRange &
-BlockList::GetAddressRange() const
-{
- return m_range;
-}
-
void
-BlockList::Dump(Stream *s, user_id_t blockID, uint32_t depth, bool show_context) const
+Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
{
- const Block* block = GetBlockByID(blockID);
- if (block)
- block->Dump(s, m_range.GetBaseAddress().GetFileAddress(), depth, show_context);
-}
-
-Function *
-BlockList::GetFunction()
-{
- return m_function;
-}
-
-
-const Function *
-BlockList::GetFunction() const
-{
- return m_function;
-}
-
-user_id_t
-BlockList::GetParent(user_id_t blockID) const
-{
- collection::const_iterator end = m_blocks.end();
- collection::const_iterator begin = m_blocks.begin();
- collection::const_iterator pos = std::find_if(begin, end, UserID::IDMatches(blockID));
-
- if (pos != end && pos != begin && pos->Depth() > 0)
+ m_parsed_block_info = b;
+ if (set_children)
{
- const uint32_t parent_depth = pos->Depth() - 1;
-
- while (--pos >= begin)
- {
- if (pos->Depth() == parent_depth)
- return pos->GetID();
- }
+ m_parsed_child_blocks = true;
+ for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
+ child_block->SetBlockInfoHasBeenParsed (b, true);
}
- return Block::InvalidID;
-}
-
-user_id_t
-BlockList::GetSibling(user_id_t blockID) const
-{
- collection::const_iterator end = m_blocks.end();
- collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-
- if (pos != end)
- {
- const uint32_t sibling_depth = pos->Depth();
- while (++pos != end)
- {
- uint32_t depth = pos->Depth();
- if (depth == sibling_depth)
- return pos->GetID();
- if (depth < sibling_depth)
- break;
- }
- }
- return Block::InvalidID;
-}
-
-user_id_t
-BlockList::GetFirstChild(user_id_t blockID) const
-{
- if (!m_blocks.empty())
- {
- if (blockID == Block::RootID)
- {
- return m_blocks.front().GetID();
- }
- else
- {
- collection::const_iterator end = m_blocks.end();
- collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-
- if (pos != end)
- {
- collection::const_iterator child_pos = pos + 1;
- if (child_pos != end)
- {
- if (child_pos->Depth() == pos->Depth() + 1)
- return child_pos->GetID();
- }
- }
- }
- }
- return Block::InvalidID;
-}
-
-
-// Return the current number of bytes that this object occupies in memory
-size_t
-BlockList::MemorySize() const
-{
- size_t mem_size = sizeof(BlockList);
-
- collection::const_iterator pos, end = m_blocks.end();
- for (pos = m_blocks.begin(); pos != end; ++pos)
- mem_size += pos->MemorySize(); // Each block can vary in size
-
- return mem_size;
-
-}
-
-user_id_t
-BlockList::AddChild (user_id_t parentID, user_id_t childID)
-{
- bool added = false;
- if (parentID == Block::RootID)
- {
- assert(m_blocks.empty());
- Block block(childID, 0, this);
- m_blocks.push_back(block);
- added = true;
- }
- else
- {
- collection::iterator end = m_blocks.end();
- collection::iterator parent_pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(parentID));
- assert(parent_pos != end);
- if (parent_pos != end)
- {
- const uint32_t parent_sibling_depth = parent_pos->Depth();
-
- collection::iterator insert_pos = parent_pos;
- collection::iterator prev_sibling = end;
- while (++insert_pos != end)
- {
- if (insert_pos->Depth() <= parent_sibling_depth)
- break;
- }
-
- Block child_block(childID, parent_pos->Depth() + 1, this);
- collection::iterator child_pos = m_blocks.insert(insert_pos, child_block);
- added = true;
- }
- }
- if (added)
- return childID;
- return Block::InvalidID;
-}
-
-const Block *
-BlockList::GetBlockByID(user_id_t blockID) const
-{
- if (m_blocks.empty() || blockID == Block::InvalidID)
- return NULL;
-
- if (blockID == Block::RootID)
- blockID = m_blocks.front().GetID();
-
- collection::const_iterator end = m_blocks.end();
- collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
- if (pos != end)
- return &(*pos);
- return NULL;
-}
-
-Block *
-BlockList::GetBlockByID(user_id_t blockID)
-{
- if (m_blocks.empty() || blockID == Block::InvalidID)
- return NULL;
-
- if (blockID == Block::RootID)
- blockID = m_blocks.front().GetID();
-
- collection::iterator end = m_blocks.end();
- collection::iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
- if (pos != end)
- return &(*pos);
- return NULL;
-}
-
-bool
-BlockList::AddRange(user_id_t blockID, addr_t start_offset, addr_t end_offset)
-{
- Block *block = GetBlockByID(blockID);
-
- if (block)
- {
- block->AddRange(start_offset, end_offset);
- return true;
- }
- return false;
-}
-//
-//const Block *
-//BlockList::FindDeepestBlockForAddress (const Address &addr)
-//{
-// if (m_range.Contains(addr))
-// {
-// addr_t block_offset = addr.GetFileAddress() - m_range.GetBaseAddress().GetFileAddress();
-// collection::const_iterator pos, end = m_blocks.end();
-// collection::const_iterator deepest_match_pos = end;
-// for (pos = m_blocks.begin(); pos != end; ++pos)
-// {
-// if (pos->Contains (block_offset))
-// {
-// if (deepest_match_pos == end || deepest_match_pos->Depth() < pos->Depth())
-// deepest_match_pos = pos;
-// }
-// }
-// if (deepest_match_pos != end)
-// return &(*deepest_match_pos);
-// }
-// return NULL;
-//}
-//
-bool
-BlockList::SetInlinedFunctionInfo(user_id_t blockID, const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
-{
- Block *block = GetBlockByID(blockID);
-
- if (block)
- {
- block->SetInlinedFunctionInfo(name, mangled, decl_ptr, call_decl_ptr);
- return true;
- }
- return false;
-}
-
-VariableListSP
-BlockList::GetVariableList(user_id_t blockID, bool get_child_variables, bool can_create)
-{
- VariableListSP variable_list_sp;
- Block *block = GetBlockByID(blockID);
- if (block)
- variable_list_sp = block->GetVariableList(get_child_variables, can_create);
- return variable_list_sp;
-}
-
-bool
-BlockList::IsEmpty() const
-{
- return m_blocks.empty();
-}
-
-
-
-bool
-BlockList::SetVariableList(user_id_t blockID, VariableListSP& variables)
-{
- Block *block = GetBlockByID(blockID);
- if (block)
- {
- block->SetVariableList(variables);
- return true;
- }
- return false;
-
}