forked from OSchip/llvm-project
Added the ability to restrict breakpoints by function name, function regexp, selector
etc to specific source files. Added SB API's to specify these source files & also more than one module. Added an "exact" option to CompileUnit's FindLineEntry API. llvm-svn: 140362
This commit is contained in:
parent
b9a11322b1
commit
87df91b866
|
@ -47,6 +47,12 @@ public:
|
|||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec) const;
|
||||
|
||||
uint32_t
|
||||
FindLineEntryIndex (uint32_t start_idx,
|
||||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec,
|
||||
bool exact) const;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
bool
|
||||
|
|
|
@ -44,13 +44,15 @@ public:
|
|||
Clear();
|
||||
|
||||
uint32_t
|
||||
FindFileIndex (uint32_t idx, const SBFileSpec &sb_file);
|
||||
FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full);
|
||||
|
||||
const SBFileSpec
|
||||
GetFileSpecAtIndex (uint32_t idx) const;
|
||||
|
||||
private:
|
||||
|
||||
friend class SBTarget;
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
const lldb_private::FileSpecList *
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "lldb/API/SBAddress.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBFileSpec.h"
|
||||
#include "lldb/API/SBFileSpecList.h"
|
||||
#include "lldb/API/SBType.h"
|
||||
|
||||
namespace lldb {
|
||||
|
@ -314,11 +315,28 @@ public:
|
|||
lldb::SBBreakpoint
|
||||
BreakpointCreateByName (const char *symbol_name, const char *module_name = NULL);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByName (const char *symbol_name,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name = NULL);
|
||||
BreakpointCreateByRegex (const char *symbol_name_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateBySourceRegex (const char *source_regex,
|
||||
const lldb::SBFileSpec &source_file,
|
||||
const char *module_name = NULL);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateBySourceRegex (const char *source_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const lldb::SBFileSpecList &source_file);
|
||||
|
||||
lldb::SBBreakpoint
|
||||
BreakpointCreateByAddress (addr_t address);
|
||||
|
|
|
@ -29,7 +29,6 @@ class BreakpointResolverFileRegex :
|
|||
{
|
||||
public:
|
||||
BreakpointResolverFileRegex (Breakpoint *bkpt,
|
||||
const FileSpec &resolver,
|
||||
RegularExpression ®ex);
|
||||
|
||||
virtual
|
||||
|
@ -58,8 +57,7 @@ public:
|
|||
|
||||
protected:
|
||||
friend class Breakpoint;
|
||||
FileSpec m_file_spec; // This is the file spec we are looking for.
|
||||
RegularExpression m_regex; // This is the line number that we are looking for.
|
||||
RegularExpression m_regex; // This is the line expression that we are looking for.
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);
|
||||
|
|
|
@ -116,12 +116,15 @@ public:
|
|||
/// @param[in] file
|
||||
/// The file specification to search for.
|
||||
///
|
||||
/// @param[in] full
|
||||
/// Should FileSpec::Equal be called with "full" true or false.
|
||||
///
|
||||
/// @return
|
||||
/// The index of the file that matches \a file if it is found,
|
||||
/// else UINT32_MAX is returned.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
FindFileIndex (uint32_t idx, const FileSpec &file) const;
|
||||
FindFileIndex (uint32_t idx, const FileSpec &file, bool full) const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Get file at index.
|
||||
|
|
|
@ -216,6 +216,21 @@ public:
|
|||
virtual void
|
||||
SearchInModuleList (Searcher &searcher, ModuleList &modules);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This determines which items are REQUIRED for the filter to pass.
|
||||
/// For instance, if you are filtering by Compilation Unit, obviously
|
||||
/// symbols that have no compilation unit can't pass So return eSymbolContextCU
|
||||
/// and search callbacks can then short cut the search to avoid looking at
|
||||
/// things that obviously won't pass.
|
||||
///
|
||||
/// @return
|
||||
/// The required elements for the search, which is an or'ed together
|
||||
/// set of lldb:SearchContextItem enum's.
|
||||
///
|
||||
//------------------------------------------------------------------
|
||||
virtual uint32_t
|
||||
GetFilterRequiredItems ();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Prints a canonical description for the search filter to the stream \a s.
|
||||
///
|
||||
|
@ -311,6 +326,9 @@ public:
|
|||
virtual void
|
||||
GetDescription(Stream *s);
|
||||
|
||||
virtual uint32_t
|
||||
GetFilterRequiredItems ();
|
||||
|
||||
virtual void
|
||||
Dump (Stream *s) const;
|
||||
|
||||
|
@ -369,6 +387,65 @@ public:
|
|||
virtual void
|
||||
GetDescription(Stream *s);
|
||||
|
||||
virtual uint32_t
|
||||
GetFilterRequiredItems ();
|
||||
|
||||
virtual void
|
||||
Dump (Stream *s) const;
|
||||
|
||||
virtual void
|
||||
Search (Searcher &searcher);
|
||||
|
||||
private:
|
||||
FileSpecList m_module_spec_list;
|
||||
};
|
||||
|
||||
class SearchFilterByModuleListAndCU :
|
||||
public SearchFilterByModuleList
|
||||
{
|
||||
public:
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// The basic constructor takes a Target, which gives the space to search,
|
||||
/// and the module list to restrict the search to.
|
||||
///
|
||||
/// @param[in] target
|
||||
/// The Target that provides the module list to search.
|
||||
///
|
||||
/// @param[in] module
|
||||
/// The Module that limits the search.
|
||||
//------------------------------------------------------------------
|
||||
SearchFilterByModuleListAndCU (lldb::TargetSP &targetSP,
|
||||
const FileSpecList &module_list,
|
||||
const FileSpecList &cu_list);
|
||||
|
||||
SearchFilterByModuleListAndCU (const SearchFilterByModuleListAndCU& rhs);
|
||||
|
||||
virtual
|
||||
~SearchFilterByModuleListAndCU ();
|
||||
|
||||
const SearchFilterByModuleListAndCU&
|
||||
operator=(const SearchFilterByModuleListAndCU& rhs);
|
||||
|
||||
virtual bool
|
||||
SymbolContextPasses (const SymbolContext &context,
|
||||
lldb::SymbolContextItem scope);
|
||||
|
||||
virtual bool
|
||||
AddressPasses (Address &address);
|
||||
|
||||
virtual bool
|
||||
CompUnitPasses (FileSpec &fileSpec);
|
||||
|
||||
virtual bool
|
||||
CompUnitPasses (CompileUnit &compUnit);
|
||||
|
||||
virtual void
|
||||
GetDescription(Stream *s);
|
||||
|
||||
virtual uint32_t
|
||||
GetFilterRequiredItems ();
|
||||
|
||||
virtual void
|
||||
Dump (Stream *s) const;
|
||||
|
||||
|
@ -377,6 +454,7 @@ public:
|
|||
|
||||
private:
|
||||
FileSpecList m_module_spec_list;
|
||||
FileSpecList m_cu_spec_list;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -202,6 +202,10 @@ public:
|
|||
/// else if NULL, search for line entries that match the compile
|
||||
/// unit file.
|
||||
///
|
||||
/// @param[in] exact
|
||||
/// If \btrue match only if there is a line table entry for this line number.
|
||||
/// If \bfalse, find the line table entry equal to or after this line number.
|
||||
///
|
||||
/// @param[out] line_entry
|
||||
/// If non-NULL, a copy of the line entry that was found.
|
||||
///
|
||||
|
@ -213,6 +217,7 @@ public:
|
|||
FindLineEntry (uint32_t start_idx,
|
||||
uint32_t line,
|
||||
const FileSpec* file_spec_ptr,
|
||||
bool exact,
|
||||
LineEntry *line_entry);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -250,10 +250,10 @@ public:
|
|||
bool check_inlines,
|
||||
bool internal = false);
|
||||
|
||||
// Use this to create breakpoint that matches regex against the source lines in file:
|
||||
// Use this to create breakpoint that matches regex against the source lines in files given in source_file_list:
|
||||
lldb::BreakpointSP
|
||||
CreateBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpec &file,
|
||||
CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *source_file_list,
|
||||
RegularExpression &source_regex,
|
||||
bool internal = false);
|
||||
|
||||
|
@ -267,11 +267,12 @@ public:
|
|||
CreateBreakpoint (Address &addr,
|
||||
bool internal = false);
|
||||
|
||||
// Use this to create a function breakpoint by regexp in containingModule, or all modules if it is NULL
|
||||
// Use this to create a function breakpoint by regexp in containingModule/containingSourceFiles, or all modules if it is NULL
|
||||
// When "skip_prologue is set to eLazyBoolCalculate, we use the current target
|
||||
// setting, else we use the values passed in
|
||||
lldb::BreakpointSP
|
||||
CreateBreakpoint (const FileSpecList *containingModules,
|
||||
CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *containingSourceFiles,
|
||||
RegularExpression &func_regexp,
|
||||
bool internal = false,
|
||||
LazyBool skip_prologue = eLazyBoolCalculate);
|
||||
|
@ -281,6 +282,7 @@ public:
|
|||
// setting, else we use the values passed in
|
||||
lldb::BreakpointSP
|
||||
CreateBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *containingSourceFiles,
|
||||
const char *func_name,
|
||||
uint32_t func_name_type_mask,
|
||||
bool internal = false,
|
||||
|
@ -889,6 +891,10 @@ protected:
|
|||
|
||||
lldb::SearchFilterSP
|
||||
GetSearchFilterForModuleList (const FileSpecList *containingModuleList);
|
||||
|
||||
lldb::SearchFilterSP
|
||||
GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles);
|
||||
|
||||
|
||||
static void
|
||||
ImageSearchPathsChanged (const PathMappingList &path_list,
|
||||
|
|
|
@ -71,6 +71,12 @@ public:
|
|||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec) const;
|
||||
|
||||
uint32_t
|
||||
FindLineEntryIndex (uint32_t start_idx,
|
||||
uint32_t line,
|
||||
lldb::SBFileSpec *inline_file_spec,
|
||||
bool exact) const;
|
||||
|
||||
bool
|
||||
GetDescription (lldb::SBStream &description);
|
||||
};
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
Clear();
|
||||
|
||||
uint32_t
|
||||
FindFileIndex (uint32_t idx, const SBFileSpec &sb_file);
|
||||
FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full);
|
||||
|
||||
const SBFileSpec
|
||||
GetFileSpecAtIndex (uint32_t idx) const;
|
||||
|
|
|
@ -98,6 +98,13 @@ SBCompileUnit::GetLineEntryAtIndex (uint32_t idx) const
|
|||
|
||||
uint32_t
|
||||
SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec) const
|
||||
{
|
||||
const bool exact = true;
|
||||
return FindLineEntryIndex (start_idx, line, inline_file_spec, exact);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec *inline_file_spec, bool exact) const
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
|
@ -114,6 +121,7 @@ SBCompileUnit::FindLineEntryIndex (uint32_t start_idx, uint32_t line, SBFileSpec
|
|||
index = m_opaque_ptr->FindLineEntry (start_idx,
|
||||
line,
|
||||
inline_file_spec ? inline_file_spec->get() : NULL,
|
||||
exact,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -80,9 +80,9 @@ SBFileSpecList::Clear()
|
|||
}
|
||||
|
||||
uint32_t
|
||||
SBFileSpecList::FindFileIndex (uint32_t idx, const SBFileSpec &sb_file)
|
||||
SBFileSpecList::FindFileIndex (uint32_t idx, const SBFileSpec &sb_file, bool full)
|
||||
{
|
||||
return m_opaque_ap->FindFileIndex (idx, sb_file.ref());
|
||||
return m_opaque_ap->FindFileIndex (idx, sb_file.ref(), full);
|
||||
}
|
||||
|
||||
const SBFileSpec
|
||||
|
|
|
@ -575,18 +575,18 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_na
|
|||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBBreakpoint sb_bp;
|
||||
if (m_opaque_sp.get() && symbol_name && symbol_name[0])
|
||||
if (m_opaque_sp.get())
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
|
||||
if (module_name && module_name[0])
|
||||
{
|
||||
FileSpecList module_spec_list;
|
||||
module_spec_list.Append (FileSpec (module_name, false));
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_spec_list, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_spec_list, NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, NULL, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -599,6 +599,34 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_na
|
|||
return sb_bp;
|
||||
}
|
||||
|
||||
lldb::SBBreakpoint
|
||||
SBTarget::BreakpointCreateByName (const char *symbol_name,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBBreakpoint sb_bp;
|
||||
if (m_opaque_sp.get() && symbol_name && symbol_name[0])
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (module_list.get(),
|
||||
comp_unit_list.get(),
|
||||
symbol_name,
|
||||
eFunctionNameTypeFull | eFunctionNameTypeBase,
|
||||
false);
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbol=\"%s\") => SBBreakpoint(%p)",
|
||||
m_opaque_sp.get(), symbol_name, sb_bp.get());
|
||||
}
|
||||
|
||||
return sb_bp;
|
||||
}
|
||||
|
||||
|
||||
SBBreakpoint
|
||||
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
|
||||
{
|
||||
|
@ -615,11 +643,11 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *mo
|
|||
FileSpecList module_spec_list;
|
||||
module_spec_list.Append (FileSpec (module_name, false));
|
||||
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_spec_list, regexp, false);
|
||||
*sb_bp = m_opaque_sp->CreateFuncRegexBreakpoint (&module_spec_list, NULL, regexp, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, regexp, false);
|
||||
*sb_bp = m_opaque_sp->CreateFuncRegexBreakpoint (NULL, NULL, regexp, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +660,30 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *mo
|
|||
return sb_bp;
|
||||
}
|
||||
|
||||
lldb::SBBreakpoint
|
||||
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const SBFileSpecList &comp_unit_list)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBBreakpoint sb_bp;
|
||||
if (m_opaque_sp.get() && symbol_name_regex && symbol_name_regex[0])
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
|
||||
RegularExpression regexp(symbol_name_regex);
|
||||
|
||||
*sb_bp = m_opaque_sp->CreateFuncRegexBreakpoint (module_list.get(), comp_unit_list.get(), regexp, false);
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (symbol_regex=\"%s\") => SBBreakpoint(%p)",
|
||||
m_opaque_sp.get(), symbol_name_regex, sb_bp.get());
|
||||
}
|
||||
|
||||
return sb_bp;
|
||||
}
|
||||
|
||||
SBBreakpoint
|
||||
SBTarget::BreakpointCreateByAddress (addr_t address)
|
||||
|
@ -664,17 +715,19 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::S
|
|||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
|
||||
RegularExpression regexp(source_regex);
|
||||
FileSpecList source_file_spec_list;
|
||||
source_file_spec_list.Append (source_file.ref());
|
||||
|
||||
if (module_name && module_name[0])
|
||||
{
|
||||
FileSpecList module_spec_list;
|
||||
module_spec_list.Append (FileSpec (module_name, false));
|
||||
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (&module_spec_list, source_file.ref(), regexp, false);
|
||||
*sb_bp = m_opaque_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
*sb_bp = m_opaque_sp->CreateBreakpoint (NULL, source_file.ref(), regexp, false);
|
||||
*sb_bp = m_opaque_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -689,6 +742,29 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::S
|
|||
return sb_bp;
|
||||
}
|
||||
|
||||
lldb::SBBreakpoint
|
||||
SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
|
||||
const SBFileSpecList &module_list,
|
||||
const lldb::SBFileSpecList &source_file_list)
|
||||
{
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
|
||||
|
||||
SBBreakpoint sb_bp;
|
||||
if (m_opaque_sp.get() && source_regex && source_regex[0])
|
||||
{
|
||||
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
|
||||
RegularExpression regexp(source_regex);
|
||||
*sb_bp = m_opaque_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false);
|
||||
}
|
||||
|
||||
if (log)
|
||||
{
|
||||
log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\") => SBBreakpoint(%p)",
|
||||
m_opaque_sp.get(), source_regex, sb_bp.get());
|
||||
}
|
||||
|
||||
return sb_bp;
|
||||
}
|
||||
|
||||
SBBreakpoint
|
||||
SBTarget::FindBreakpointByID (break_id_t bp_id)
|
||||
|
|
|
@ -29,11 +29,9 @@ using namespace lldb_private;
|
|||
BreakpointResolverFileRegex::BreakpointResolverFileRegex
|
||||
(
|
||||
Breakpoint *bkpt,
|
||||
const FileSpec &file_spec,
|
||||
RegularExpression ®ex
|
||||
) :
|
||||
BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
|
||||
m_file_spec (file_spec),
|
||||
m_regex (regex)
|
||||
{
|
||||
}
|
||||
|
@ -60,62 +58,58 @@ BreakpointResolverFileRegex::SearchCallback
|
|||
|
||||
CompileUnit *cu = context.comp_unit;
|
||||
FileSpec cu_file_spec = *(static_cast<FileSpec *>(cu));
|
||||
if (cu_file_spec == m_file_spec
|
||||
|| (!m_file_spec.GetDirectory() && cu_file_spec.GetFilename() == m_file_spec.GetFilename()))
|
||||
std::vector<uint32_t> line_matches;
|
||||
context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches);
|
||||
uint32_t num_matches = line_matches.size();
|
||||
for (int i = 0; i < num_matches; i++)
|
||||
{
|
||||
std::vector<uint32_t> line_matches;
|
||||
context.target_sp->GetSourceManager().FindLinesMatchingRegex(cu_file_spec, m_regex, 1, UINT32_MAX, line_matches);
|
||||
uint32_t num_matches = line_matches.size();
|
||||
for (int i = 0; i < num_matches; i++)
|
||||
uint32_t start_idx = 0;
|
||||
bool exact = false;
|
||||
while (1)
|
||||
{
|
||||
uint32_t start_idx = 0;
|
||||
while (1)
|
||||
{
|
||||
LineEntry line_entry;
|
||||
LineEntry line_entry;
|
||||
|
||||
// Cycle through all the line entries that might match this one:
|
||||
start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, exact, &line_entry);
|
||||
if (start_idx == UINT32_MAX)
|
||||
break;
|
||||
exact = true;
|
||||
start_idx++;
|
||||
|
||||
// Cycle through all the line entries that might match this one:
|
||||
start_idx = cu->FindLineEntry (start_idx, line_matches[i], NULL, &line_entry);
|
||||
if (start_idx == UINT32_MAX)
|
||||
break;
|
||||
start_idx++;
|
||||
|
||||
Address line_start = line_entry.range.GetBaseAddress();
|
||||
if (line_start.IsValid())
|
||||
Address line_start = line_entry.range.GetBaseAddress();
|
||||
if (line_start.IsValid())
|
||||
{
|
||||
if (filter.AddressPasses(line_start))
|
||||
{
|
||||
if (filter.AddressPasses(line_start))
|
||||
BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
|
||||
if (log && bp_loc_sp && !m_breakpoint->IsInternal())
|
||||
{
|
||||
BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
|
||||
if (log && bp_loc_sp && !m_breakpoint->IsInternal())
|
||||
{
|
||||
StreamString s;
|
||||
bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose);
|
||||
log->Printf ("Added location: %s\n", s.GetData());
|
||||
}
|
||||
}
|
||||
else if (log)
|
||||
{
|
||||
log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n",
|
||||
line_start.GetFileAddress(),
|
||||
m_file_spec.GetFilename().AsCString("<Unknown>"),
|
||||
line_matches[i]);
|
||||
StreamString s;
|
||||
bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose);
|
||||
log->Printf ("Added location: %s\n", s.GetData());
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (log)
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n",
|
||||
line_start.GetFileAddress(),
|
||||
m_file_spec.GetFilename().AsCString("<Unknown>"),
|
||||
line_matches[i]);
|
||||
log->Printf ("Breakpoint at file address 0x%llx for %s:%d didn't pass filter.\n",
|
||||
line_start.GetFileAddress(),
|
||||
cu_file_spec.GetFilename().AsCString("<Unknown>"),
|
||||
line_matches[i]);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (log)
|
||||
log->Printf ("error: Unable to set breakpoint at file address 0x%llx for %s:%d\n",
|
||||
line_start.GetFileAddress(),
|
||||
cu_file_spec.GetFilename().AsCString("<Unknown>"),
|
||||
line_matches[i]);
|
||||
}
|
||||
|
||||
}
|
||||
assert (m_breakpoint != NULL);
|
||||
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
|
||||
|
||||
|
||||
}
|
||||
assert (m_breakpoint != NULL);
|
||||
|
||||
return Searcher::eCallbackReturnContinue;
|
||||
}
|
||||
|
||||
|
@ -128,7 +122,7 @@ BreakpointResolverFileRegex::GetDepth()
|
|||
void
|
||||
BreakpointResolverFileRegex::GetDescription (Stream *s)
|
||||
{
|
||||
s->Printf ("file ='%s', regular expression = \"%s\"", m_file_spec.GetFilename().AsCString(), m_regex.GetText());
|
||||
s->Printf ("source regex = \"%s\"", m_regex.GetText());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -161,16 +161,22 @@ BreakpointResolverName::SearchCallback
|
|||
|
||||
const bool include_symbols = false;
|
||||
const bool append = false;
|
||||
bool filter_by_cu = (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
|
||||
|
||||
switch (m_match_type)
|
||||
{
|
||||
case Breakpoint::Exact:
|
||||
if (context.module_sp)
|
||||
{
|
||||
if (context.module_sp->FindFunctions (m_func_name,
|
||||
uint32_t num_functions = context.module_sp->FindFunctions (m_func_name,
|
||||
m_func_name_type_mask,
|
||||
include_symbols,
|
||||
append,
|
||||
func_list) == 0)
|
||||
func_list);
|
||||
// If the search filter specifies a Compilation Unit, then we don't need to bother to look in plain
|
||||
// symbols, since all the ones from a set compilation unit will have been found above already.
|
||||
|
||||
if (num_functions == 0 && !filter_by_cu)
|
||||
{
|
||||
if (m_func_name_type_mask & (eFunctionNameTypeBase | eFunctionNameTypeFull))
|
||||
context.module_sp->FindSymbolsWithNameAndType (m_func_name, eSymbolTypeCode, sym_list);
|
||||
|
@ -180,7 +186,8 @@ BreakpointResolverName::SearchCallback
|
|||
case Breakpoint::Regexp:
|
||||
if (context.module_sp)
|
||||
{
|
||||
context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
|
||||
if (!filter_by_cu)
|
||||
context.module_sp->FindSymbolsMatchingRegExAndType (m_regex, eSymbolTypeCode, sym_list);
|
||||
context.module_sp->FindFunctions (m_regex,
|
||||
include_symbols,
|
||||
append,
|
||||
|
@ -192,7 +199,26 @@ BreakpointResolverName::SearchCallback
|
|||
log->Warning ("glob is not supported yet.");
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// If the filter specifies a Compilation Unit, remove the ones that don't pass at this point.
|
||||
if (filter_by_cu)
|
||||
{
|
||||
uint32_t num_functions = func_list.GetSize();
|
||||
|
||||
for (size_t idx = 0; idx < num_functions; idx++)
|
||||
{
|
||||
SymbolContext sc;
|
||||
func_list.GetContextAtIndex(idx, sc);
|
||||
if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
|
||||
{
|
||||
func_list.RemoveContextAtIndex(idx);
|
||||
num_functions--;
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!m_basename_filter.empty())
|
||||
{
|
||||
// Filter out any matches whose names don't contain the basename filter
|
||||
|
|
|
@ -49,7 +49,7 @@ AddBreakpointDescription (Stream *s, Breakpoint *bp, lldb::DescriptionLevel leve
|
|||
|
||||
CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &interpreter) :
|
||||
Options (interpreter),
|
||||
m_filename (),
|
||||
m_filenames (),
|
||||
m_line_num (0),
|
||||
m_column (0),
|
||||
m_check_inlines (true),
|
||||
|
@ -71,6 +71,8 @@ CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
|
|||
{
|
||||
}
|
||||
|
||||
#define LLDB_OPT_FILE (LLDB_OPT_SET_ALL & ~(LLDB_OPT_SET_2))
|
||||
|
||||
OptionDefinition
|
||||
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
|
||||
{
|
||||
|
@ -92,11 +94,11 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
|
|||
{ LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
|
||||
"The breakpoint stops only for threads in the queue whose name is given by this argument."},
|
||||
|
||||
{ LLDB_OPT_SET_1 | LLDB_OPT_SET_9, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
|
||||
"Set the breakpoint by source location in this particular file."},
|
||||
{ LLDB_OPT_FILE, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
|
||||
"Specifies the source file in which to set this breakpoint."},
|
||||
|
||||
{ LLDB_OPT_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
|
||||
"Set the breakpoint by source location at this particular line."},
|
||||
"Specifies the line number on which to set this breakpoint."},
|
||||
|
||||
// Comment out this option for the moment, as we don't actually use it, but will in the future.
|
||||
// This way users won't see it, but the infrastructure is left in place.
|
||||
|
@ -160,7 +162,7 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
|
|||
break;
|
||||
|
||||
case 'f':
|
||||
m_filename.assign (option_arg);
|
||||
m_filenames.AppendIfUnique (FileSpec(option_arg, false));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
|
@ -202,7 +204,7 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
|
|||
|
||||
case 's':
|
||||
{
|
||||
m_modules.push_back (std::string (option_arg));
|
||||
m_modules.AppendIfUnique (FileSpec (option_arg, false));
|
||||
break;
|
||||
}
|
||||
case 'i':
|
||||
|
@ -244,14 +246,14 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
|
|||
void
|
||||
CommandObjectBreakpointSet::CommandOptions::OptionParsingStarting ()
|
||||
{
|
||||
m_filename.clear();
|
||||
m_filenames.Clear();
|
||||
m_line_num = 0;
|
||||
m_column = 0;
|
||||
m_func_name.clear();
|
||||
m_func_name_type_mask = 0;
|
||||
m_func_regexp.clear();
|
||||
m_load_addr = LLDB_INVALID_ADDRESS;
|
||||
m_modules.clear();
|
||||
m_modules.Clear();
|
||||
m_ignore_count = 0;
|
||||
m_thread_id = LLDB_INVALID_THREAD_ID;
|
||||
m_thread_index = UINT32_MAX;
|
||||
|
@ -284,48 +286,41 @@ CommandObjectBreakpointSet::GetOptions ()
|
|||
}
|
||||
|
||||
bool
|
||||
CommandObjectBreakpointSet::ChooseFile (Target *target, FileSpec &file, CommandReturnObject &result)
|
||||
CommandObjectBreakpointSet::GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result)
|
||||
{
|
||||
if (m_options.m_filename.empty())
|
||||
uint32_t default_line;
|
||||
// First use the Source Manager's default file.
|
||||
// Then use the current stack frame's file.
|
||||
if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
|
||||
{
|
||||
uint32_t default_line;
|
||||
// First use the Source Manager's default file.
|
||||
// Then use the current stack frame's file.
|
||||
if (!target->GetSourceManager().GetDefaultFileAndLine(file, default_line))
|
||||
StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
|
||||
if (cur_frame == NULL)
|
||||
{
|
||||
StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
|
||||
if (cur_frame == NULL)
|
||||
result.AppendError ("No selected frame to use to find the default file.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
else if (!cur_frame->HasDebugInformation())
|
||||
{
|
||||
result.AppendError ("Cannot use the selected frame to find the default file, it has no debug info.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
|
||||
if (sc.line_entry.file)
|
||||
{
|
||||
result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
else if (!cur_frame->HasDebugInformation())
|
||||
{
|
||||
result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
file = sc.line_entry.file;
|
||||
}
|
||||
else
|
||||
{
|
||||
const SymbolContext &sc = cur_frame->GetSymbolContext (eSymbolContextLineEntry);
|
||||
if (sc.line_entry.file)
|
||||
{
|
||||
file = sc.line_entry.file;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError ("Attempting to set breakpoint by line number alone but can't find the file for the selected frame.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
result.AppendError ("Can't find the file for the selected frame to use as the default file.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
file.SetFile(m_options.m_filename.c_str(), false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -367,33 +362,36 @@ CommandObjectBreakpointSet::Execute
|
|||
Breakpoint *bp = NULL;
|
||||
FileSpec module_spec;
|
||||
bool use_module = false;
|
||||
int num_modules = m_options.m_modules.size();
|
||||
|
||||
FileSpecList module_spec_list;
|
||||
FileSpecList *module_spec_list_ptr = NULL;
|
||||
int num_modules = m_options.m_modules.GetSize();
|
||||
|
||||
if ((num_modules > 0) && (break_type != eSetTypeAddress))
|
||||
use_module = true;
|
||||
|
||||
if (use_module)
|
||||
{
|
||||
module_spec_list_ptr = &module_spec_list;
|
||||
for (int i = 0; i < num_modules; ++i)
|
||||
{
|
||||
module_spec.SetFile(m_options.m_modules[i].c_str(), false);
|
||||
module_spec_list.AppendIfUnique (module_spec);
|
||||
}
|
||||
}
|
||||
|
||||
switch (break_type)
|
||||
{
|
||||
case eSetTypeFileAndLine: // Breakpoint by source position
|
||||
{
|
||||
FileSpec file;
|
||||
if (!ChooseFile (target, file, result))
|
||||
break;
|
||||
uint32_t num_files = m_options.m_filenames.GetSize();
|
||||
if (num_files == 0)
|
||||
{
|
||||
if (!GetDefaultFile (target, file, result))
|
||||
{
|
||||
result.AppendError("No file supplied and no default file available.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (num_files > 1)
|
||||
{
|
||||
result.AppendError("Only one file at a time is allowed for file and line breakpoints.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
file = m_options.m_filenames.GetFileSpecAtIndex(0);
|
||||
|
||||
bp = target->CreateBreakpoint (module_spec_list_ptr,
|
||||
bp = target->CreateBreakpoint (&(m_options.m_modules),
|
||||
file,
|
||||
m_options.m_line_num,
|
||||
m_options.m_check_inlines).get();
|
||||
|
@ -410,8 +408,9 @@ CommandObjectBreakpointSet::Execute
|
|||
|
||||
if (name_type_mask == 0)
|
||||
name_type_mask = eFunctionNameTypeAuto;
|
||||
|
||||
bp = target->CreateBreakpoint (module_spec_list_ptr,
|
||||
|
||||
bp = target->CreateBreakpoint (&(m_options.m_modules),
|
||||
&(m_options.m_filenames),
|
||||
m_options.m_func_name.c_str(),
|
||||
name_type_mask,
|
||||
Breakpoint::Exact).get();
|
||||
|
@ -430,15 +429,29 @@ CommandObjectBreakpointSet::Execute
|
|||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
bp = target->CreateBreakpoint (module_spec_list_ptr, regexp).get();
|
||||
|
||||
bp = target->CreateFuncRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
|
||||
}
|
||||
break;
|
||||
case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
|
||||
{
|
||||
FileSpec file;
|
||||
if (!ChooseFile (target, file, result))
|
||||
break;
|
||||
|
||||
int num_files = m_options.m_filenames.GetSize();
|
||||
|
||||
if (num_files == 0)
|
||||
{
|
||||
FileSpec file;
|
||||
if (!GetDefaultFile (target, file, result))
|
||||
{
|
||||
result.AppendError ("No files provided and could not find default file.");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_options.m_filenames.Append (file);
|
||||
}
|
||||
}
|
||||
|
||||
RegularExpression regexp(m_options.m_source_text_regexp.c_str());
|
||||
if (!regexp.IsValid())
|
||||
{
|
||||
|
@ -449,7 +462,7 @@ CommandObjectBreakpointSet::Execute
|
|||
result.SetStatus (eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
bp = target->CreateBreakpoint (module_spec_list_ptr, file, regexp).get();
|
||||
bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
|
||||
// Instance variables to hold the values for command options.
|
||||
|
||||
std::string m_filename;
|
||||
FileSpecList m_filenames;
|
||||
uint32_t m_line_num;
|
||||
uint32_t m_column;
|
||||
bool m_check_inlines;
|
||||
|
@ -105,7 +105,7 @@ public:
|
|||
uint32_t m_func_name_type_mask;
|
||||
std::string m_func_regexp;
|
||||
std::string m_source_text_regexp;
|
||||
STLStringArray m_modules;
|
||||
FileSpecList m_modules;
|
||||
lldb::addr_t m_load_addr;
|
||||
uint32_t m_ignore_count;
|
||||
lldb::tid_t m_thread_id;
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
|
||||
private:
|
||||
bool
|
||||
ChooseFile (Target *target, FileSpec &file, CommandReturnObject &result);
|
||||
GetDefaultFile (Target *target, FileSpec &file, CommandReturnObject &result);
|
||||
|
||||
CommandOptions m_options;
|
||||
};
|
||||
|
|
|
@ -999,7 +999,8 @@ public:
|
|||
while (index_ptr <= end_ptr)
|
||||
{
|
||||
LineEntry line_entry;
|
||||
index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, &line_entry);
|
||||
const bool exact = false;
|
||||
index_ptr = sc.comp_unit->FindLineEntry(index_ptr, line_number, sc.comp_unit, exact, &line_entry);
|
||||
if (index_ptr == UINT32_MAX)
|
||||
break;
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ FileLineResolver::SearchCallback
|
|||
if (m_inlines || m_file_spec.Compare(*cu, m_file_spec, m_file_spec.GetDirectory()))
|
||||
{
|
||||
uint32_t start_file_idx = 0;
|
||||
uint32_t file_idx = cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec);
|
||||
uint32_t file_idx = cu->GetSupportFiles().FindFileIndex(start_file_idx, m_file_spec, false);
|
||||
if (file_idx != UINT32_MAX)
|
||||
{
|
||||
LineTable *line_table = cu->GetLineTable();
|
||||
|
@ -67,7 +67,7 @@ FileLineResolver::SearchCallback
|
|||
line_table->FineLineEntriesForFileIndex (file_idx, append, m_sc_list);
|
||||
// Get the next file index in case we have multiple file
|
||||
// entries for the same file
|
||||
file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1, m_file_spec);
|
||||
file_idx = cu->GetSupportFiles().FindFileIndex(file_idx + 1, m_file_spec, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -107,7 +107,7 @@ FileSpecList::Dump(Stream *s, const char *separator_cstr) const
|
|||
// it is found, else UINT32_MAX is returned.
|
||||
//------------------------------------------------------------------
|
||||
uint32_t
|
||||
FileSpecList::FindFileIndex (uint32_t start_idx, const FileSpec &file_spec) const
|
||||
FileSpecList::FindFileIndex (uint32_t start_idx, const FileSpec &file_spec, bool full) const
|
||||
{
|
||||
const uint32_t num_files = m_files.size();
|
||||
uint32_t idx;
|
||||
|
@ -125,7 +125,7 @@ FileSpecList::FindFileIndex (uint32_t start_idx, const FileSpec &file_spec) cons
|
|||
}
|
||||
else
|
||||
{
|
||||
if (m_files[idx] == file_spec)
|
||||
if (FileSpec::Equal (m_files[idx], file_spec, full))
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,12 @@ SearchFilter::CompUnitPasses (CompileUnit &compUnit)
|
|||
return true;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SearchFilter::GetFilterRequiredItems()
|
||||
{
|
||||
return (lldb::SymbolContextItem) 0;
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilter::GetDescription (Stream *s)
|
||||
{
|
||||
|
@ -427,6 +433,12 @@ SearchFilterByModule::GetDescription (Stream *s)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SearchFilterByModule::GetFilterRequiredItems()
|
||||
{
|
||||
return eSymbolContextModule;
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilterByModule::Dump (Stream *s) const
|
||||
{
|
||||
|
@ -478,7 +490,10 @@ SearchFilterByModuleList::~SearchFilterByModuleList()
|
|||
bool
|
||||
SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
|
||||
{
|
||||
if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec()) != UINT32_MAX)
|
||||
if (m_module_spec_list.GetSize() == 0)
|
||||
return true;
|
||||
|
||||
if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -487,7 +502,10 @@ SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
|
|||
bool
|
||||
SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
|
||||
{
|
||||
if (m_module_spec_list.FindFileIndex(0, spec) != UINT32_MAX)
|
||||
if (m_module_spec_list.GetSize() == 0)
|
||||
return true;
|
||||
|
||||
if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -503,7 +521,7 @@ SearchFilterByModuleList::SymbolContextPasses
|
|||
if (!(scope & eSymbolContextModule))
|
||||
return false;
|
||||
|
||||
if (context.module_sp && m_module_spec_list.FindFileIndex(0, context.module_sp->GetFileSpec()) != UINT32_MAX)
|
||||
if (context.module_sp && m_module_spec_list.FindFileIndex(0, context.module_sp->GetFileSpec(), true) != UINT32_MAX)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
@ -551,7 +569,7 @@ SearchFilterByModuleList::Search (Searcher &searcher)
|
|||
for (size_t i = 0; i < num_modules; i++)
|
||||
{
|
||||
Module* module = m_target_sp->GetImages().GetModulePointerAtIndex(i);
|
||||
if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec()) != UINT32_MAX)
|
||||
if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX)
|
||||
{
|
||||
SymbolContext matchingContext(m_target_sp, ModuleSP(module));
|
||||
Searcher::CallbackReturn shouldContinue;
|
||||
|
@ -602,8 +620,204 @@ SearchFilterByModuleList::GetDescription (Stream *s)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SearchFilterByModuleList::GetFilterRequiredItems()
|
||||
{
|
||||
return eSymbolContextModule;
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilterByModuleList::Dump (Stream *s) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SearchFilterByModuleListAndCU:
|
||||
// Selects a shared library matching a given file spec
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SearchFilterByModuleListAndCU constructors
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (lldb::TargetSP &target_sp,
|
||||
const FileSpecList &module_list,
|
||||
const FileSpecList &cu_list) :
|
||||
SearchFilterByModuleList (target_sp, module_list),
|
||||
m_cu_spec_list (cu_list)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SearchFilterByModuleListAndCU copy constructor
|
||||
//----------------------------------------------------------------------
|
||||
SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) :
|
||||
SearchFilterByModuleList (rhs),
|
||||
m_cu_spec_list (rhs.m_cu_spec_list)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// SearchFilterByModuleListAndCU assignment operator
|
||||
//----------------------------------------------------------------------
|
||||
const SearchFilterByModuleListAndCU&
|
||||
SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
|
||||
{
|
||||
if (&rhs != this)
|
||||
{
|
||||
m_target_sp = rhs.m_target_sp;
|
||||
m_module_spec_list = rhs.m_module_spec_list;
|
||||
m_cu_spec_list = rhs.m_cu_spec_list;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
SearchFilterByModuleListAndCU::SymbolContextPasses
|
||||
(
|
||||
const SymbolContext &context,
|
||||
lldb::SymbolContextItem scope
|
||||
)
|
||||
{
|
||||
if (!SearchFilterByModuleList::SymbolContextPasses(context, scope))
|
||||
return false;
|
||||
if (!(scope & eSymbolContextCompUnit))
|
||||
return false;
|
||||
if (context.comp_unit && m_cu_spec_list.FindFileIndex(0, static_cast<FileSpec>(context.comp_unit), false) == UINT32_MAX)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
SearchFilterByModuleListAndCU::AddressPasses (Address &address)
|
||||
{
|
||||
// FIXME: Not yet implemented
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
|
||||
{
|
||||
return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
|
||||
}
|
||||
|
||||
bool
|
||||
SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit)
|
||||
{
|
||||
return m_cu_spec_list.FindFileIndex(0, static_cast<FileSpec>(compUnit), false) != UINT32_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilterByModuleListAndCU::Search (Searcher &searcher)
|
||||
{
|
||||
if (!m_target_sp)
|
||||
return;
|
||||
|
||||
if (searcher.GetDepth() == Searcher::eDepthTarget)
|
||||
{
|
||||
SymbolContext empty_sc;
|
||||
empty_sc.target_sp = m_target_sp;
|
||||
searcher.SearchCallback (*this, empty_sc, NULL, false);
|
||||
}
|
||||
|
||||
// If the module file spec is a full path, then we can just find the one
|
||||
// filespec that passes. Otherwise, we need to go through all modules and
|
||||
// find the ones that match the file name.
|
||||
|
||||
ModuleList matching_modules;
|
||||
const size_t num_modules = m_target_sp->GetImages().GetSize ();
|
||||
bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
|
||||
for (size_t i = 0; i < num_modules; i++)
|
||||
{
|
||||
lldb::ModuleSP module_sp = m_target_sp->GetImages().GetModuleAtIndex(i);
|
||||
if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
|
||||
{
|
||||
SymbolContext matchingContext(m_target_sp, module_sp);
|
||||
Searcher::CallbackReturn shouldContinue;
|
||||
|
||||
if (searcher.GetDepth() == Searcher::eDepthModule)
|
||||
{
|
||||
shouldContinue = DoModuleIteration(matchingContext, searcher);
|
||||
if (shouldContinue == Searcher::eCallbackReturnStop)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
const size_t num_cu = module_sp->GetNumCompileUnits();
|
||||
for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++)
|
||||
{
|
||||
CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
|
||||
matchingContext.comp_unit = cu_sp.get();
|
||||
if (m_cu_spec_list.FindFileIndex(0, static_cast<FileSpec>(matchingContext.comp_unit), false) != UINT32_MAX)
|
||||
{
|
||||
shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
|
||||
if (shouldContinue == Searcher::eCallbackReturnStop)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilterByModuleListAndCU::GetDescription (Stream *s)
|
||||
{
|
||||
uint32_t num_modules = m_module_spec_list.GetSize();
|
||||
if (num_modules == 1)
|
||||
{
|
||||
s->Printf (", module = ");
|
||||
if (s->GetVerbose())
|
||||
{
|
||||
char buffer[2048];
|
||||
m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
|
||||
s->PutCString(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
|
||||
}
|
||||
}
|
||||
else if (num_modules > 0)
|
||||
{
|
||||
s->Printf (", modules(%d) = ", num_modules);
|
||||
for (uint32_t i = 0; i < num_modules; i++)
|
||||
{
|
||||
if (s->GetVerbose())
|
||||
{
|
||||
char buffer[2048];
|
||||
m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
|
||||
s->PutCString(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
|
||||
}
|
||||
if (i != num_modules - 1)
|
||||
s->PutCString (", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
SearchFilterByModuleListAndCU::GetFilterRequiredItems()
|
||||
{
|
||||
return eSymbolContextModule | eSymbolContextCompUnit;
|
||||
}
|
||||
|
||||
void
|
||||
SearchFilterByModuleListAndCU::Dump (Stream *s) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -506,10 +506,10 @@ FileSpec::Compare(const FileSpec& a, const FileSpec& b, bool full)
|
|||
bool
|
||||
FileSpec::Equal (const FileSpec& a, const FileSpec& b, bool full)
|
||||
{
|
||||
if (full)
|
||||
return a == b;
|
||||
else
|
||||
if (!full && (a.GetDirectory().IsEmpty() || b.GetDirectory().IsEmpty()))
|
||||
return a.m_filename == b.m_filename;
|
||||
else
|
||||
return a == b;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -988,6 +988,7 @@ DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
|
|||
FileSpecList module_spec_list;
|
||||
module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
|
||||
Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
|
||||
NULL,
|
||||
"OSKextLoadedKextSummariesUpdated",
|
||||
eFunctionNameTypeFull,
|
||||
internal_bp,
|
||||
|
|
|
@ -262,6 +262,7 @@ ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
|
|||
|
||||
if (!m_cxx_exception_bp_sp)
|
||||
m_cxx_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
NULL,
|
||||
"__cxa_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
|
@ -270,6 +271,7 @@ ItaniumABILanguageRuntime::SetExceptionBreakpoints ()
|
|||
|
||||
if (!m_cxx_exception_alloc_bp_sp)
|
||||
m_cxx_exception_alloc_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
NULL,
|
||||
"__cxa_allocate",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
|
|
|
@ -114,6 +114,7 @@ AppleObjCRuntimeV1::SetExceptionBreakpoints ()
|
|||
if (!m_objc_exception_bp_sp)
|
||||
{
|
||||
m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
NULL,
|
||||
"objc_exception_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
|
|
|
@ -480,6 +480,7 @@ AppleObjCRuntimeV2::SetExceptionBreakpoints ()
|
|||
if (!m_objc_exception_bp_sp)
|
||||
{
|
||||
m_objc_exception_bp_sp = m_process->GetTarget().CreateBreakpoint (NULL,
|
||||
NULL,
|
||||
"__cxa_throw",
|
||||
eFunctionNameTypeBase,
|
||||
true);
|
||||
|
|
|
@ -2534,7 +2534,7 @@ ProcessGDBRemote::StartNoticingNewThreads()
|
|||
{
|
||||
for (int i = 0; bp_names[i] != NULL; i++)
|
||||
{
|
||||
Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, bp_names[i], eFunctionNameTypeFull, true).get();
|
||||
Breakpoint *breakpoint = m_target.CreateBreakpoint (NULL, NULL, bp_names[i], eFunctionNameTypeFull, true).get();
|
||||
if (breakpoint)
|
||||
{
|
||||
if (log)
|
||||
|
|
|
@ -1804,7 +1804,7 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line,
|
|||
// find it in the support files, we are done.
|
||||
if (check_inlines)
|
||||
{
|
||||
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
|
||||
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
|
||||
if (file_idx == UINT32_MAX)
|
||||
continue;
|
||||
}
|
||||
|
@ -1818,7 +1818,7 @@ SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line,
|
|||
// We will have already looked up the file index if
|
||||
// we are searching for inline entries.
|
||||
if (!check_inlines)
|
||||
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec);
|
||||
file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
|
||||
|
||||
if (file_idx != UINT32_MAX)
|
||||
{
|
||||
|
|
|
@ -253,13 +253,13 @@ CompileUnit::GetVariableList(bool can_create)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* file_spec_ptr, LineEntry *line_entry_ptr)
|
||||
CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* file_spec_ptr, bool exact, LineEntry *line_entry_ptr)
|
||||
{
|
||||
uint32_t file_idx = 0;
|
||||
|
||||
if (file_spec_ptr)
|
||||
{
|
||||
file_idx = GetSupportFiles().FindFileIndex (1, *file_spec_ptr);
|
||||
file_idx = GetSupportFiles().FindFileIndex (1, *file_spec_ptr, true);
|
||||
if (file_idx == UINT32_MAX)
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
@ -269,13 +269,14 @@ CompileUnit::FindLineEntry (uint32_t start_idx, uint32_t line, const FileSpec* f
|
|||
// Unit that is in the support files (the one at 0 was artifically added.)
|
||||
// So prefer the one further on in the support files if it exists...
|
||||
FileSpecList &support_files = GetSupportFiles();
|
||||
file_idx = support_files.FindFileIndex (1, support_files.GetFileSpecAtIndex(0));
|
||||
const bool full = true;
|
||||
file_idx = support_files.FindFileIndex (1, support_files.GetFileSpecAtIndex(0), full);
|
||||
if (file_idx == UINT32_MAX)
|
||||
file_idx = 0;
|
||||
}
|
||||
LineTable *line_table = GetLineTable();
|
||||
if (line_table)
|
||||
return line_table->FindLineEntryIndexByFileIndex (start_idx, file_idx, line, true, line_entry_ptr);
|
||||
return line_table->FindLineEntryIndexByFileIndex (start_idx, file_idx, line, exact, line_entry_ptr);
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
|
@ -304,11 +305,11 @@ CompileUnit::ResolveSymbolContext
|
|||
if (file_spec_matches_cu_file_spec == false && check_inlines == false)
|
||||
return 0;
|
||||
|
||||
uint32_t file_idx = GetSupportFiles().FindFileIndex (1, file_spec);
|
||||
uint32_t file_idx = GetSupportFiles().FindFileIndex (1, file_spec, true);
|
||||
while (file_idx != UINT32_MAX)
|
||||
{
|
||||
file_indexes.push_back (file_idx);
|
||||
file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec);
|
||||
file_idx = GetSupportFiles().FindFileIndex (file_idx + 1, file_spec, true);
|
||||
}
|
||||
|
||||
const size_t num_file_indexes = file_indexes.size();
|
||||
|
|
|
@ -207,13 +207,13 @@ Target::GetBreakpointByID (break_id_t break_id)
|
|||
}
|
||||
|
||||
BreakpointSP
|
||||
Target::CreateBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpec &file,
|
||||
Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *source_file_spec_list,
|
||||
RegularExpression &source_regex,
|
||||
bool internal)
|
||||
{
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
|
||||
BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, file, source_regex));
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list));
|
||||
BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, source_regex));
|
||||
return CreateBreakpoint (filter_sp, resolver_sp, internal);
|
||||
}
|
||||
|
||||
|
@ -255,7 +255,8 @@ Target::CreateBreakpoint (Address &addr, bool internal)
|
|||
}
|
||||
|
||||
BreakpointSP
|
||||
Target::CreateBreakpoint (const FileSpecList *containingModules,
|
||||
Target::CreateBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *containingSourceFiles,
|
||||
const char *func_name,
|
||||
uint32_t func_name_type_mask,
|
||||
bool internal,
|
||||
|
@ -264,7 +265,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
|
|||
BreakpointSP bp_sp;
|
||||
if (func_name)
|
||||
{
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
|
||||
|
||||
BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
|
||||
func_name,
|
||||
|
@ -317,13 +318,36 @@ Target::GetSearchFilterForModuleList (const FileSpecList *containingModules)
|
|||
return filter_sp;
|
||||
}
|
||||
|
||||
SearchFilterSP
|
||||
Target::GetSearchFilterForModuleAndCUList (const FileSpecList *containingModules, const FileSpecList *containingSourceFiles)
|
||||
{
|
||||
if (containingSourceFiles == NULL || containingSourceFiles->GetSize() == 0)
|
||||
return GetSearchFilterForModuleList(containingModules);
|
||||
|
||||
SearchFilterSP filter_sp;
|
||||
lldb::TargetSP target_sp = this->GetSP();
|
||||
if (containingModules == NULL)
|
||||
{
|
||||
// We could make a special "CU List only SearchFilter". Better yet was if these could be composable,
|
||||
// but that will take a little reworking.
|
||||
|
||||
filter_sp.reset (new SearchFilterByModuleListAndCU (target_sp, FileSpecList(), *containingSourceFiles));
|
||||
}
|
||||
else
|
||||
{
|
||||
filter_sp.reset (new SearchFilterByModuleListAndCU (target_sp, *containingModules, *containingSourceFiles));
|
||||
}
|
||||
return filter_sp;
|
||||
}
|
||||
|
||||
BreakpointSP
|
||||
Target::CreateBreakpoint (const FileSpecList *containingModules,
|
||||
Target::CreateFuncRegexBreakpoint (const FileSpecList *containingModules,
|
||||
const FileSpecList *containingSourceFiles,
|
||||
RegularExpression &func_regex,
|
||||
bool internal,
|
||||
LazyBool skip_prologue)
|
||||
{
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
|
||||
SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
|
||||
BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL,
|
||||
func_regex,
|
||||
skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
C_SOURCES := main.c
|
||||
C_SOURCES := main.c a.c b.c
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
||||
|
|
|
@ -77,6 +77,25 @@ class BreakpointCommandTestCase(TestBase):
|
|||
"print >> here",
|
||||
"here.close()"])
|
||||
|
||||
# Next lets try some other breakpoint kinds. First break with a regular expression
|
||||
# and then specify only one file. The first time we should get two locations,
|
||||
# the second time only one:
|
||||
self.expect ("break set -r ._MyFunction",
|
||||
patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 2"])
|
||||
|
||||
self.expect ("break set -r ._MyFunction -f a.c",
|
||||
patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 1"])
|
||||
|
||||
self.expect ("break set -r ._MyFunction -f a.c -f b.c",
|
||||
patterns = ["Breakpoint created: [0-9]+: regex = '\._MyFunction', locations = 2"])
|
||||
|
||||
# Now try a source regex breakpoint:
|
||||
self.expect ("break set -p \"is about to return [12]0\" -f a.c -f b.c",
|
||||
patterns = ["Breakpoint created: [0-9]+: source regex = \"is about to return \[12\]0\", locations = 2"])
|
||||
|
||||
self.expect ("break set -p \"is about to return [12]0\" -f a.c",
|
||||
patterns = ["Breakpoint created: [0-9]+: source regex = \"is about to return \[12\]0\", locations = 1"])
|
||||
|
||||
# Run the program. Remove 'output.txt' if it exists.
|
||||
if os.path.exists('output.txt'):
|
||||
os.remove('output.txt')
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int
|
||||
a_MyFunction ()
|
||||
{
|
||||
// Set a breakpoint here.
|
||||
printf ("a is about to return 10.\n");
|
||||
return 10;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#include <stdio.h>
|
||||
|
||||
int
|
||||
b_MyFunction ()
|
||||
{
|
||||
// Set a breakpoint here.
|
||||
printf ("b is about to return 20.\n");
|
||||
return 20;
|
||||
}
|
Loading…
Reference in New Issue