<rdar://problem/12953853>

Setting breakpoints using "breakpoint set --selector <SEL>" previously didn't when there was no dSYM file.

Also fixed issues in the test suite that arose after fixing the bug.

Also fixed the log channels to properly ref count the log streams using weak pointers to the streams. This fixes a test suite problem that would happen when you specified a full path to the compiler with the "--compiler" option.

llvm-svn: 171816
This commit is contained in:
Greg Clayton 2013-01-08 00:01:36 +00:00
parent b9eb593e50
commit c1b2ccfd34
13 changed files with 141 additions and 19 deletions

View File

@ -369,7 +369,7 @@ protected:
InputReaderStack m_input_reader_stack;
std::string m_input_reader_data;
typedef std::map<std::string, lldb::StreamSP> LogStreamMap;
typedef std::map<std::string, lldb::StreamWP> LogStreamMap;
LogStreamMap m_log_streams;
lldb::StreamSP m_log_callback_stream_sp;
ConstString m_instance_name;

View File

@ -173,8 +173,9 @@ public:
virtual void
DumpSymbolContext (Stream *s);
//------------------------------------------------------------------
/// Find a symbol in the object files symbol table.
/// Find a symbol in the object file's symbol table.
///
/// @param[in] name
/// The name of the symbol that we are looking for.
@ -203,6 +204,28 @@ public:
lldb::SymbolType symbol_type,
SymbolContextList &sc_list);
//------------------------------------------------------------------
/// Find a funciton symbols in the object file's symbol table.
///
/// @param[in] name
/// The name of the symbol that we are looking for.
///
/// @param[in] name_type_mask
/// A mask that has one or more bitwise OR'ed values from the
/// lldb::FunctionNameType enumeration type that indicate what
/// kind of names we are looking for.
///
/// @param[out] sc_list
/// A list to append any matching symbol contexts to.
///
/// @return
/// The number of symbol contexts that were added to \a sc_list
//------------------------------------------------------------------
size_t
FindFunctionSymbols (const ConstString &name,
uint32_t name_type_mask,
SymbolContextList& sc_list);
//------------------------------------------------------------------
/// Find compile units by partial or full path.
///

View File

@ -56,7 +56,6 @@ public:
Symbol * SymbolAtIndex (uint32_t idx);
const Symbol * SymbolAtIndex (uint32_t idx) const;
Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx);
// const Symbol * FindSymbolWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx) const;
uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
uint32_t AppendSymbolIndexesWithTypeAndFlagsValue (lldb::SymbolType symbol_type, uint32_t flags_value, std::vector<uint32_t>& indexes, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
uint32_t AppendSymbolIndexesWithType (lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& matches, uint32_t start_idx = 0, uint32_t end_index = UINT32_MAX) const;
@ -71,10 +70,9 @@ public:
size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression &regex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes);
Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility);
Symbol * FindSymbolWithFileAddress (lldb::addr_t file_addr);
// Symbol * FindSymbolContainingAddress (const Address& value, const uint32_t* indexes, uint32_t num_indexes);
// Symbol * FindSymbolContainingAddress (const Address& value);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes);
Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr);
size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list);
size_t CalculateSymbolSize (Symbol *symbol);
void SortSymbolIndexesByValue (std::vector<uint32_t>& indexes, bool remove_duplicates) const;
@ -109,6 +107,7 @@ protected:
collection m_symbols;
std::vector<uint32_t> m_addr_indexes;
UniqueCStringMap<uint32_t> m_name_to_index;
UniqueCStringMap<uint32_t> m_selector_to_index;
mutable Mutex m_mutex; // Provide thread safety for this symbol table
bool m_addr_indexes_computed:1,
m_name_indexes_computed:1;
@ -147,6 +146,9 @@ private:
return false;
}
void
SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes,
SymbolContextList &sc_list);
DISALLOW_COPY_AND_ASSIGN (Symtab);
};

View File

@ -350,6 +350,7 @@ namespace lldb {
typedef STD_SHARED_PTR(lldb_private::StopInfo) StopInfoSP;
typedef STD_SHARED_PTR(lldb_private::StoppointLocation) StoppointLocationSP;
typedef STD_SHARED_PTR(lldb_private::Stream) StreamSP;
typedef STD_WEAK_PTR (lldb_private::Stream) StreamWP;
typedef STD_SHARED_PTR(lldb_private::StringSummaryFormat) StringTypeSummaryImplSP;
typedef STD_SHARED_PTR(lldb_private::SymbolFile) SymbolFileSP;
typedef STD_SHARED_PTR(lldb_private::SymbolFileType) SymbolFileTypeSP;

View File

@ -182,8 +182,7 @@ BreakpointResolverName::SearchCallback
if (num_functions == 0 && !filter_by_cu)
{
if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
context.module_sp->FindSymbolsWithNameAndType (m_func_names[j], eSymbolTypeCode, sym_list);
context.module_sp->FindFunctionSymbols (m_func_names[j], m_func_name_type_mask, sym_list);
}
}
}

View File

@ -2614,13 +2614,13 @@ Debugger::EnableLog (const char *channel, const char **categories, const char *l
else
{
LogStreamMap::iterator pos = m_log_streams.find(log_file);
if (pos == m_log_streams.end())
if (pos != m_log_streams.end())
log_stream_sp = pos->second.lock();
if (!log_stream_sp)
{
log_stream_sp.reset (new StreamFile (log_file));
m_log_streams[log_file] = log_stream_sp;
}
else
log_stream_sp = pos->second;
}
assert (log_stream_sp.get());

View File

@ -1063,6 +1063,25 @@ Module::SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector<uint32_t>
}
}
size_t
Module::FindFunctionSymbols (const ConstString &name,
uint32_t name_type_mask,
SymbolContextList& sc_list)
{
Timer scoped_timer(__PRETTY_FUNCTION__,
"Module::FindSymbolsFunctions (name = %s, mask = 0x%8.8x)",
name.AsCString(),
name_type_mask);
ObjectFile *objfile = GetObjectFile ();
if (objfile)
{
Symtab *symtab = objfile->GetSymtab();
if (symtab)
return symtab->FindFunctionSymbols (name, name_type_mask, sc_list);
}
return 0;
}
size_t
Module::FindSymbolsWithNameAndType (const ConstString &name, SymbolType symbol_type, SymbolContextList &sc_list)
{

View File

@ -13,6 +13,7 @@
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Symtab.h"
#include "lldb/Target/ObjCLanguageRuntime.h"
@ -309,20 +310,25 @@ Symtab::InitNameIndexes()
// If the demangled name turns out to be an ObjC name, and
// is a category name, add the version without categories to the index too.
ConstString objc_selector_name;
ConstString objc_base_name;
if (ObjCLanguageRuntime::ParseMethodName (entry.cstring,
NULL,
NULL,
&objc_selector_name,
&objc_base_name,
NULL))
{
entry.cstring = objc_base_name.GetCString();
m_name_to_index.Append (entry);
entry.cstring = objc_selector_name.GetCString();
m_selector_to_index.Append (entry);
}
}
m_name_to_index.Sort();
m_name_to_index.SizeToFit();
m_selector_to_index.Sort();
m_selector_to_index.SizeToFit();
}
}
@ -979,3 +985,64 @@ Symtab::FindSymbolContainingFileAddress (addr_t file_addr)
return FindSymbolContainingFileAddress (file_addr, &m_addr_indexes[0], m_addr_indexes.size());
}
void
Symtab::SymbolIndicesToSymbolContextList (std::vector<uint32_t> &symbol_indexes, SymbolContextList &sc_list)
{
// No need to protect this call using m_mutex all other method calls are
// already thread safe.
size_t num_indices = symbol_indexes.size();
if (num_indices > 0)
{
SymbolContext sc;
sc.module_sp = m_objfile->GetModule();
for (size_t i = 0; i < num_indices; i++)
{
sc.symbol = SymbolAtIndex (symbol_indexes[i]);
if (sc.symbol)
sc_list.Append (sc);
}
}
}
size_t
Symtab::FindFunctionSymbols (const ConstString &name,
uint32_t name_type_mask,
SymbolContextList& sc_list)
{
size_t count = 0;
std::vector<uint32_t> symbol_indexes;
if (name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeAuto))
{
FindAllSymbolsWithNameAndType (name, eSymbolTypeCode, symbol_indexes);
}
if (name_type_mask & eFunctionNameTypeSelector)
{
if (!m_name_indexes_computed)
InitNameIndexes();
if (!m_selector_to_index.IsEmpty())
{
const UniqueCStringMap<uint32_t>::Entry *match;
for (match = m_selector_to_index.FindFirstValueForName(name.AsCString());
match != NULL;
match = m_selector_to_index.FindNextValueForName(match))
{
symbol_indexes.push_back(match->value);
}
}
}
if (!symbol_indexes.empty())
{
std::sort(symbol_indexes.begin(), symbol_indexes.end());
symbol_indexes.erase(std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end());
count = symbol_indexes.size();
SymbolIndicesToSymbolContextList (symbol_indexes, sc_list);
}
return count;
}

View File

@ -32,13 +32,13 @@ class DeadStripTestCase(TestBase):
self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
# Break by function name f1 (live code).
lldbutil.run_break_set_by_symbol (self, "f1", extra_options="-s a.out", num_expected_locations=1, module_name="a.out")
lldbutil.run_break_set_by_symbol (self, "f1", num_expected_locations=1, module_name="a.out")
# Break by function name f2 (dead code).
lldbutil.run_break_set_by_symbol (self, "f2", extra_options="-s a.out", num_expected_locations=0)
lldbutil.run_break_set_by_symbol (self, "f2", num_expected_locations=0, module_name="a.out")
# Break by function name f3 (live code).
lldbutil.run_break_set_by_symbol (self, "f3", extra_options="-s a.out", num_expected_locations=1, module_name="a.out")
lldbutil.run_break_set_by_symbol (self, "f3", num_expected_locations=1, module_name="a.out")
self.runCmd("run", RUN_SUCCEEDED)

View File

@ -81,7 +81,7 @@ class FoundationDisassembleTestCase(TestBase):
lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
# Stop at the "description" selector.
lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1)
lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
# Stop at -[NSAutoreleasePool release].
break_results = lldbutil.run_break_set_command (self, "_regexp-break -[NSAutoreleasePool release]")

View File

@ -69,7 +69,7 @@ class FoundationTestCase(TestBase):
lldbutil.run_break_set_by_symbol (self, '-[MyString initWithNSString:]', num_expected_locations=1, sym_exact=True)
# Stop at the "description" selector.
lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1)
lldbutil.run_break_set_by_selector (self, 'description', num_expected_locations=1, module_name='a.out')
# Stop at -[NSAutoreleasePool release].
break_results = lldbutil.run_break_set_command(self, "_regexp-break -[NSAutoreleasePool release]")

View File

@ -275,6 +275,9 @@ def run_break_set_by_file_and_line (test, file_name, line_number, extra_options
else:
command = 'breakpoint set -f "%s" -l %d'%(file_name, line_number)
if module_name:
command += " --shlib '%s'" % (module_name)
if extra_options:
command += " " + extra_options
@ -292,6 +295,10 @@ def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_lo
If sym_exact is true, then the output symbol must match the input exactly, otherwise we do a substring match."""
command = 'breakpoint set -n "%s"'%(symbol)
if module_name:
command += " --shlib '%s'" % (module_name)
if extra_options:
command += " " + extra_options
@ -307,7 +314,11 @@ def run_break_set_by_symbol (test, symbol, extra_options = None, num_expected_lo
def run_break_set_by_selector (test, selector, extra_options = None, num_expected_locations = -1, module_name=None):
"""Set a breakpoint by selector. Common options are the same as run_break_set_by_file_and_line."""
command = 'breakpoint set -S "%s"'%(selector)
command = 'breakpoint set -S "%s"' % (selector)
if module_name:
command += ' --shlib "%s"' % (module_name)
if extra_options:
command += " " + extra_options

View File

@ -28,13 +28,13 @@ class LogTestCase(TestBase):
patterns = [ "Current executable set to .*a.out" ])
log_file = os.path.join (os.getcwd(), "lldb-commands-log-%s-%s-%s.txt" % (type,
self.getCompiler(),
os.path.basename(self.getCompiler()),
self.getArchitecture()))
if (os.path.exists (log_file)):
os.remove (log_file)
self.runCmd ("log enable lldb commands -f " + log_file)
self.runCmd ("log enable -f '%s' lldb commands" % (log_file))
self.runCmd ("command alias bp breakpoint")