aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/lldb/API/SBCompileUnit.h6
-rw-r--r--include/lldb/API/SBFileSpecList.h4
-rw-r--r--include/lldb/API/SBTarget.h20
-rw-r--r--include/lldb/Breakpoint/BreakpointResolverFileRegex.h4
-rw-r--r--include/lldb/Core/FileSpecList.h5
-rw-r--r--include/lldb/Core/SearchFilter.h78
-rw-r--r--include/lldb/Symbol/CompileUnit.h5
-rw-r--r--include/lldb/Target/Target.h16
-rw-r--r--scripts/Python/interface/SBCompileUnit.i6
-rw-r--r--scripts/Python/interface/SBFileSpecList.i2
-rw-r--r--source/API/SBCompileUnit.cpp8
-rw-r--r--source/API/SBFileSpecList.cpp4
-rw-r--r--source/API/SBTarget.cpp90
-rw-r--r--source/Breakpoint/BreakpointResolverFileRegex.cpp88
-rw-r--r--source/Breakpoint/BreakpointResolverName.cpp34
-rw-r--r--source/Commands/CommandObjectBreakpoint.cpp141
-rw-r--r--source/Commands/CommandObjectBreakpoint.h6
-rw-r--r--source/Commands/CommandObjectThread.cpp3
-rw-r--r--source/Core/FileLineResolver.cpp4
-rw-r--r--source/Core/FileSpecList.cpp4
-rw-r--r--source/Core/SearchFilter.cpp222
-rw-r--r--source/Host/common/FileSpec.cpp6
-rw-r--r--source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp2
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp1
-rw-r--r--source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp1
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp2
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp4
-rw-r--r--source/Symbol/CompileUnit.cpp13
-rw-r--r--source/Target/Target.cpp40
-rw-r--r--test/functionalities/breakpoint/breakpoint_command/Makefile2
-rw-r--r--test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py19
-rw-r--r--test/functionalities/breakpoint/breakpoint_command/a.c9
-rw-r--r--test/functionalities/breakpoint/breakpoint_command/b.c9
34 files changed, 690 insertions, 169 deletions
diff --git a/include/lldb/API/SBCompileUnit.h b/include/lldb/API/SBCompileUnit.h
index 8d67e19e4..1312458b1 100644
--- a/include/lldb/API/SBCompileUnit.h
+++ b/include/lldb/API/SBCompileUnit.h
@@ -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
diff --git a/include/lldb/API/SBFileSpecList.h b/include/lldb/API/SBFileSpecList.h
index 720c07822..90b6798fb 100644
--- a/include/lldb/API/SBFileSpecList.h
+++ b/include/lldb/API/SBFileSpecList.h
@@ -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 *
diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h
index 3c95969bf..2aadbd1af 100644
--- a/include/lldb/API/SBTarget.h
+++ b/include/lldb/API/SBTarget.h
@@ -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 {
@@ -315,10 +316,27 @@ public:
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);
diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
index 22321677b..f1c2b1409 100644
--- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
+++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
@@ -29,7 +29,6 @@ class BreakpointResolverFileRegex :
{
public:
BreakpointResolverFileRegex (Breakpoint *bkpt,
- const FileSpec &resolver,
RegularExpression &regex);
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);
diff --git a/include/lldb/Core/FileSpecList.h b/include/lldb/Core/FileSpecList.h
index ab0e5af77..a8be828cd 100644
--- a/include/lldb/Core/FileSpecList.h
+++ b/include/lldb/Core/FileSpecList.h
@@ -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.
diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h
index c359cb33a..715acf397 100644
--- a/include/lldb/Core/SearchFilter.h
+++ b/include/lldb/Core/SearchFilter.h
@@ -217,6 +217,21 @@ public:
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.
///
/// @param[in] 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
diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h
index 98a245aa8..9767ff1ac 100644
--- a/include/lldb/Symbol/CompileUnit.h
+++ b/include/lldb/Symbol/CompileUnit.h
@@ -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);
//------------------------------------------------------------------
diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h
index c7696b8c5..22340ab03 100644
--- a/include/lldb/Target/Target.h
+++ b/include/lldb/Target/Target.h
@@ -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,
diff --git a/scripts/Python/interface/SBCompileUnit.i b/scripts/Python/interface/SBCompileUnit.i
index a9294ec5d..6b37d1d2a 100644
--- a/scripts/Python/interface/SBCompileUnit.i
+++ b/scripts/Python/interface/SBCompileUnit.i
@@ -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);
};
diff --git a/scripts/Python/interface/SBFileSpecList.i b/scripts/Python/interface/SBFileSpecList.i
index 5ad4742d6..38a6f43bd 100644
--- a/scripts/Python/interface/SBFileSpecList.i
+++ b/scripts/Python/interface/SBFileSpecList.i
@@ -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;
diff --git a/source/API/SBCompileUnit.cpp b/source/API/SBCompileUnit.cpp
index 4ff799afd..58723e5a3 100644
--- a/source/API/SBCompileUnit.cpp
+++ b/source/API/SBCompileUnit.cpp
@@ -99,6 +99,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));
uint32_t index = UINT32_MAX;
@@ -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);
}
diff --git a/source/API/SBFileSpecList.cpp b/source/API/SBFileSpecList.cpp
index af7621864..a4250bc4c 100644
--- a/source/API/SBFileSpecList.cpp
+++ b/source/API/SBFileSpecList.cpp
@@ -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
diff --git a/source/API/SBTarget.cpp b/source/API/SBTarget.cpp
index e3743e5ab..e17f258ab 100644
--- a/source/API/SBTarget.cpp
+++ b/source/API/SBTarget.cpp
@@ -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)
diff --git a/source/Breakpoint/BreakpointResolverFileRegex.cpp b/source/Breakpoint/BreakpointResolverFileRegex.cpp
index 238c37093..e4b596af5 100644
--- a/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -29,11 +29,9 @@ using namespace lldb_private;
BreakpointResolverFileRegex::BreakpointResolverFileRegex
(
Breakpoint *bkpt,
- const FileSpec &file_spec,
RegularExpression &regex
) :
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
diff --git a/source/Breakpoint/BreakpointResolverName.cpp b/source/Breakpoint/BreakpointResolverName.cpp
index 141a15bef..42889091a 100644
--- a/source/Breakpoint/BreakpointResolverName.cpp
+++ b/source/Breakpoint/BreakpointResolverName.cpp
@@ -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
diff --git a/source/Commands/CommandObjectBreakpoint.cpp b/source/Commands/CommandObjectBreakpoint.cpp
index 11e0fad2c..ffff9f63c 100644
--- a/source/Commands/CommandObjectBreakpoint.cpp
+++ b/source/Commands/CommandObjectBreakpoint.cpp
@@ -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)
+ {
+ result.AppendError ("No selected frame to use to find the default file.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ else if (!cur_frame->HasDebugInformation())
{
- StackFrame *cur_frame = m_interpreter.GetExecutionContext().GetFramePtr();
- if (cur_frame == NULL)
+ 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;
+ file = sc.line_entry.file;
}
- else if (!cur_frame->HasDebugInformation())
+ else
{
- result.AppendError ("Attempting to set breakpoint by line number alone but selected frame has no debug info.");
+ result.AppendError ("Can't find the file for the selected frame to use as the default file.");
result.SetStatus (eReturnStatusFailed);
return false;
}
- 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;
- }
- }
}
}
- 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:
diff --git a/source/Commands/CommandObjectBreakpoint.h b/source/Commands/CommandObjectBreakpoint.h
index 9df14dafa..b032319d1 100644
--- a/source/Commands/CommandObjectBreakpoint.h
+++ b/source/Commands/CommandObjectBreakpoint.h
@@ -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;
};
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 68de8724e..8e4ae8d46 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -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;
diff --git a/source/Core/FileLineResolver.cpp b/source/Core/FileLineResolver.cpp
index 9f5f3150a..8d68df292 100644
--- a/source/Core/FileLineResolver.cpp
+++ b/source/Core/FileLineResolver.cpp
@@ -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
diff --git a/source/Core/FileSpecList.cpp b/source/Core/FileSpecList.cpp
index 3ad4c6b79..ba2e95ec1 100644
--- a/source/Core/FileSpecList.cpp
+++ b/source/Core/FileSpecList.cpp
@@ -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;
}
}
diff --git a/source/Core/SearchFilter.cpp b/source/Core/SearchFilter.cpp
index 835072ad3..1fdbefe8e 100644
--- a/source/Core/SearchFilter.cpp
+++ b/source/Core/SearchFilter.cpp
@@ -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
+{
+
+}
+
diff --git a/source/Host/common/FileSpec.cpp b/source/Host/common/FileSpec.cpp
index 8f398e05a..5e034db65 100644
--- a/source/Host/common/FileSpec.cpp
+++ b/source/Host/common/FileSpec.cpp
@@ -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;
}
diff --git a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 55e0af68c..a972a3dc4 100644
--- a/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -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,
diff --git a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index 90b17d1c0..27f80cb3c 100644
--- a/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -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);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index ae5cf922c..6af8f2294 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -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);
diff --git a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index ef62462e7..28c6f4b02 100644
--- a/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -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);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 8f09fcf9d..3d263838d 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -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)
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 9a2c10e26..c10ffaad1 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -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)
{
diff --git a/source/Symbol/CompileUnit.cpp b/source/Symbol/CompileUnit.cpp
index d50ad99dc..ec383eb59 100644
--- a/source/Symbol/CompileUnit.cpp
+++ b/source/Symbol/CompileUnit.cpp
@@ -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();
diff --git a/source/Target/Target.cpp b/source/Target/Target.cpp
index 19bd7f9a4..ebaab10b0 100644
--- a/source/Target/Target.cpp
+++ b/source/Target/Target.cpp
@@ -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));
diff --git a/test/functionalities/breakpoint/breakpoint_command/Makefile b/test/functionalities/breakpoint/breakpoint_command/Makefile
index b09a57915..a6376f9b1 100644
--- a/test/functionalities/breakpoint/breakpoint_command/Makefile
+++ b/test/functionalities/breakpoint/breakpoint_command/Makefile
@@ -1,5 +1,5 @@
LEVEL = ../../../make
-C_SOURCES := main.c
+C_SOURCES := main.c a.c b.c
include $(LEVEL)/Makefile.rules
diff --git a/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
index b96d20d37..616464e21 100644
--- a/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ b/test/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -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')
diff --git a/test/functionalities/breakpoint/breakpoint_command/a.c b/test/functionalities/breakpoint/breakpoint_command/a.c
new file mode 100644
index 000000000..870e4a6ab
--- /dev/null
+++ b/test/functionalities/breakpoint/breakpoint_command/a.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+a_MyFunction ()
+{
+ // Set a breakpoint here.
+ printf ("a is about to return 10.\n");
+ return 10;
+}
diff --git a/test/functionalities/breakpoint/breakpoint_command/b.c b/test/functionalities/breakpoint/breakpoint_command/b.c
new file mode 100644
index 000000000..02b78e7bd
--- /dev/null
+++ b/test/functionalities/breakpoint/breakpoint_command/b.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+b_MyFunction ()
+{
+ // Set a breakpoint here.
+ printf ("b is about to return 20.\n");
+ return 20;
+}