summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBCommandInterpreter.h10
-rw-r--r--lldb/include/lldb/API/SBFileSpec.h1
-rw-r--r--lldb/include/lldb/API/SBFileSpecList.h76
-rw-r--r--lldb/include/lldb/API/SBTarget.h3
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolver.h3
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h70
-rw-r--r--lldb/include/lldb/Core/RegularExpression.h23
-rw-r--r--lldb/include/lldb/Core/SearchFilter.h58
-rw-r--r--lldb/include/lldb/Core/SourceManager.h15
-rw-r--r--lldb/include/lldb/Interpreter/CommandInterpreter.h2
-rw-r--r--lldb/include/lldb/Target/Target.h16
-rw-r--r--lldb/include/lldb/lldb-defines.h1
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj16
-rw-r--r--lldb/scripts/Python/interface/SBCommandInterpreter.i3
-rw-r--r--lldb/scripts/Python/interface/SBFileSpecList.i45
-rw-r--r--lldb/scripts/Python/interface/SBTarget.i3
-rw-r--r--lldb/scripts/lldb.swig2
-rw-r--r--lldb/source/API/SBCommandInterpreter.cpp12
-rw-r--r--lldb/source/API/SBFileSpecList.cpp139
-rw-r--r--lldb/source/API/SBTarget.cpp46
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileLine.cpp20
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp139
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverName.cpp1
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp241
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.h7
-rw-r--r--lldb/source/Core/RegularExpression.cpp41
-rw-r--r--lldb/source/Core/SearchFilter.cpp175
-rw-r--r--lldb/source/Core/SourceManager.cpp60
-rw-r--r--lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp4
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp18
-rw-r--r--lldb/source/Target/Target.cpp45
-rw-r--r--lldb/test/lang/objc/objc-stepping/TestObjCStepping.py66
32 files changed, 1155 insertions, 206 deletions
diff --git a/lldb/include/lldb/API/SBCommandInterpreter.h b/lldb/include/lldb/API/SBCommandInterpreter.h
index c3bda082478..71a157de3a5 100644
--- a/lldb/include/lldb/API/SBCommandInterpreter.h
+++ b/lldb/include/lldb/API/SBCommandInterpreter.h
@@ -80,6 +80,9 @@ public:
lldb::ReturnStatus
HandleCommand (const char *command_line, lldb::SBCommandReturnObject &result, bool add_to_history = false);
+#ifndef SWIG
+ // This interface is not useful in SWIG, since the cursor & last_char arguments are string pointers INTO current_line
+ // and you can't do that in a scripting language interface in general...
int
HandleCompletion (const char *current_line,
const char *cursor,
@@ -87,6 +90,13 @@ public:
int match_start_point,
int max_return_elements,
lldb::SBStringList &matches);
+#endif
+ int
+ HandleCompletion (const char *current_line,
+ uint32_t cursor_pos,
+ int match_start_point,
+ int max_return_elements,
+ lldb::SBStringList &matches);
protected:
diff --git a/lldb/include/lldb/API/SBFileSpec.h b/lldb/include/lldb/API/SBFileSpec.h
index 9890d59fc33..e3a6ce2d424 100644
--- a/lldb/include/lldb/API/SBFileSpec.h
+++ b/lldb/include/lldb/API/SBFileSpec.h
@@ -59,6 +59,7 @@ public:
private:
friend class SBBlock;
friend class SBCompileUnit;
+ friend class SBFileSpecList;
friend class SBHostOS;
friend class SBLineEntry;
friend class SBModule;
diff --git a/lldb/include/lldb/API/SBFileSpecList.h b/lldb/include/lldb/API/SBFileSpecList.h
new file mode 100644
index 00000000000..720c07822b6
--- /dev/null
+++ b/lldb/include/lldb/API/SBFileSpecList.h
@@ -0,0 +1,76 @@
+//===-- SBFileSpecList.h --------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBFileSpecList_h_
+#define LLDB_SBFileSpecList_h_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class SBFileSpecList
+{
+public:
+ SBFileSpecList ();
+
+ SBFileSpecList (const lldb::SBFileSpecList &rhs);
+
+ ~SBFileSpecList ();
+
+#ifndef SWIG
+ const SBFileSpecList &
+ operator = (const lldb::SBFileSpecList &rhs);
+#endif
+
+ uint32_t
+ GetSize () const;
+
+ bool
+ GetDescription (SBStream &description) const;
+
+ void
+ Append (const SBFileSpec &sb_file);
+
+ bool
+ AppendIfUnique (const SBFileSpec &sb_file);
+
+ void
+ Clear();
+
+ uint32_t
+ FindFileIndex (uint32_t idx, const SBFileSpec &sb_file);
+
+ const SBFileSpec
+ GetFileSpecAtIndex (uint32_t idx) const;
+
+private:
+
+#ifndef SWIG
+
+ const lldb_private::FileSpecList *
+ operator->() const;
+
+ const lldb_private::FileSpecList *
+ get() const;
+
+ const lldb_private::FileSpecList &
+ operator*() const;
+
+ const lldb_private::FileSpecList &
+ ref() const;
+
+#endif
+
+ std::auto_ptr <lldb_private::FileSpecList> m_opaque_ap;
+};
+
+
+} // namespace lldb
+
+#endif // LLDB_SBFileSpecList_h_
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 4349e21e5b0..3c95969bfb6 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -316,6 +316,9 @@ public:
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);
lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
index 0c74dae4d1a..b05b8c57299 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolver.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolver.h
@@ -120,7 +120,8 @@ public:
enum ResolverTy {
FileLineResolver, // This is an instance of BreakpointResolverFileLine
AddressResolver, // This is an instance of BreakpointResolverAddress
- NameResolver // This is an instance of BreakpointResolverName
+ NameResolver, // This is an instance of BreakpointResolverName
+ FileRegexResolver
};
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
new file mode 100644
index 00000000000..22321677b59
--- /dev/null
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h
@@ -0,0 +1,70 @@
+//===-- BreakpointResolverFileRegex.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_BreakpointResolverFileRegex_h_
+#define liblldb_BreakpointResolverFileRegex_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointResolver.h"
+
+namespace lldb_private {
+
+//----------------------------------------------------------------------
+/// @class BreakpointResolverFileRegex BreakpointResolverFileRegex.h "lldb/Breakpoint/BreakpointResolverFileRegex.h"
+/// @brief This class sets breakpoints by file and line. Optionally, it will look for inlined
+/// instances of the file and line specification.
+//----------------------------------------------------------------------
+
+class BreakpointResolverFileRegex :
+ public BreakpointResolver
+{
+public:
+ BreakpointResolverFileRegex (Breakpoint *bkpt,
+ const FileSpec &resolver,
+ RegularExpression &regex);
+
+ virtual
+ ~BreakpointResolverFileRegex ();
+
+ virtual Searcher::CallbackReturn
+ SearchCallback (SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing);
+
+ virtual Searcher::Depth
+ GetDepth ();
+
+ virtual void
+ GetDescription (Stream *s);
+
+ virtual void
+ Dump (Stream *s) const;
+
+ /// Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const BreakpointResolverFileRegex *) { return true; }
+ static inline bool classof(const BreakpointResolver *V) {
+ return V->getResolverID() == BreakpointResolver::FileRegexResolver;
+ }
+
+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.
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex);
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_BreakpointResolverFileRegex_h_
diff --git a/lldb/include/lldb/Core/RegularExpression.h b/lldb/include/lldb/Core/RegularExpression.h
index b73a9d65f83..4d269a160a8 100644
--- a/lldb/include/lldb/Core/RegularExpression.h
+++ b/lldb/include/lldb/Core/RegularExpression.h
@@ -52,7 +52,11 @@ public:
/// Flags that are passed the the \c regcomp() function.
//------------------------------------------------------------------
explicit
- RegularExpression (const char* re, int flags = REG_EXTENDED);
+ RegularExpression (const char* re, int flags);
+
+ // This one uses flags = REG_EXTENDED.
+ explicit
+ RegularExpression (const char* re);
//------------------------------------------------------------------
/// Destructor.
@@ -61,6 +65,10 @@ public:
/// object will be freed.
//------------------------------------------------------------------
~RegularExpression ();
+
+ RegularExpression (const RegularExpression &rhs);
+
+ const RegularExpression & operator=(const RegularExpression &rhs);
//------------------------------------------------------------------
/// Compile a regular expression.
@@ -84,7 +92,10 @@ public:
/// \b false otherwise.
//------------------------------------------------------------------
bool
- Compile (const char* re, int flags = REG_EXTENDED);
+ Compile (const char* re);
+
+ bool
+ Compile (const char* re, int flags);
//------------------------------------------------------------------
/// Executes a regular expression.
@@ -138,6 +149,12 @@ public:
//------------------------------------------------------------------
const char*
GetText () const;
+
+ int
+ GetCompileFlags () const
+ {
+ return m_compile_flags;
+ }
//------------------------------------------------------------------
/// Test if valid.
@@ -161,7 +178,9 @@ private:
std::string m_re; ///< A copy of the original regular expression text
int m_comp_err; ///< Error code for the regular expression compilation
regex_t m_preg; ///< The compiled regular expression
+ int m_compile_flags; ///< Stores the flags from the last compile.
mutable std::vector<regmatch_t> m_matches; ///< Where parenthesized subexpressions results are stored
+
};
} // namespace lldb_private
diff --git a/lldb/include/lldb/Core/SearchFilter.h b/lldb/include/lldb/Core/SearchFilter.h
index c651b40cbda..c359cb33aa7 100644
--- a/lldb/include/lldb/Core/SearchFilter.h
+++ b/lldb/include/lldb/Core/SearchFilter.h
@@ -321,6 +321,64 @@ private:
FileSpec m_module_spec;
};
+class SearchFilterByModuleList :
+ public SearchFilter
+{
+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.
+ //------------------------------------------------------------------
+ SearchFilterByModuleList (lldb::TargetSP &targetSP,
+ const FileSpecList &module_list);
+
+ SearchFilterByModuleList (const SearchFilterByModuleList& rhs);
+
+ virtual
+ ~SearchFilterByModuleList ();
+
+ const SearchFilterByModuleList&
+ operator=(const SearchFilterByModuleList& rhs);
+
+ virtual bool
+ ModulePasses (const lldb::ModuleSP &module_sp);
+
+ virtual bool
+ ModulePasses (const FileSpec &spec);
+
+ 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 void
+ Dump (Stream *s) const;
+
+ virtual void
+ Search (Searcher &searcher);
+
+private:
+ FileSpecList m_module_spec_list;
+};
+
} // namespace lldb_private
#endif // liblldb_SearchFilter_h_
diff --git a/lldb/include/lldb/Core/SourceManager.h b/lldb/include/lldb/Core/SourceManager.h
index fd8a4ddb5c7..64f5743306c 100644
--- a/lldb/include/lldb/Core/SourceManager.h
+++ b/lldb/include/lldb/Core/SourceManager.h
@@ -40,7 +40,15 @@ public:
uint32_t context_before,
uint32_t context_after,
Stream *s);
+ void
+ FindLinesMatchingRegex (RegularExpression& regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+ bool
+ GetLine (uint32_t line_no, std::string &buffer);
+
uint32_t
GetLineOffset (uint32_t line);
@@ -151,6 +159,13 @@ public:
return (m_last_file_sp.get() != NULL);
}
+ void
+ FindLinesMatchingRegex (FileSpec &file_spec,
+ RegularExpression& regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines);
+
protected:
FileSP
diff --git a/lldb/include/lldb/Interpreter/CommandInterpreter.h b/lldb/include/lldb/Interpreter/CommandInterpreter.h
index 617285b152b..81b1ec99424 100644
--- a/lldb/include/lldb/Interpreter/CommandInterpreter.h
+++ b/lldb/include/lldb/Interpreter/CommandInterpreter.h
@@ -214,7 +214,7 @@ public:
// This handles command line completion. You are given a pointer to the command string buffer, to the current cursor,
// and to the end of the string (in case it is not NULL terminated).
- // You also passed in an Args object to fill with the returns.
+ // You also passed in an StringList object to fill with the returns.
// The first element of the array will be filled with the string that you would need to insert at
// the cursor point to complete the cursor point to the longest common matching prefix.
// If you want to limit the number of elements returned, set max_return_elements to the number of elements
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 0defa9dd310..c7696b8c514 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -244,12 +244,19 @@ public:
// Use this to create a file and line breakpoint to a given module or all module it is NULL
lldb::BreakpointSP
- CreateBreakpoint (const FileSpec *containingModule,
+ CreateBreakpoint (const FileSpecList *containingModules,
const FileSpec &file,
uint32_t line_no,
bool check_inlines,
bool internal = false);
+ // Use this to create breakpoint that matches regex against the source lines in file:
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpec &file,
+ RegularExpression &source_regex,
+ bool internal = false);
+
// Use this to create a breakpoint from a load address
lldb::BreakpointSP
CreateBreakpoint (lldb::addr_t load_addr,
@@ -264,7 +271,7 @@ public:
// When "skip_prologue is set to eLazyBoolCalculate, we use the current target
// setting, else we use the values passed in
lldb::BreakpointSP
- CreateBreakpoint (const FileSpec *containingModule,
+ CreateBreakpoint (const FileSpecList *containingModules,
RegularExpression &func_regexp,
bool internal = false,
LazyBool skip_prologue = eLazyBoolCalculate);
@@ -273,7 +280,7 @@ public:
// When "skip_prologue is set to eLazyBoolCalculate, we use the current target
// setting, else we use the values passed in
lldb::BreakpointSP
- CreateBreakpoint (const FileSpec *containingModule,
+ CreateBreakpoint (const FileSpecList *containingModules,
const char *func_name,
uint32_t func_name_type_mask,
bool internal = false,
@@ -880,6 +887,9 @@ protected:
lldb::SearchFilterSP
GetSearchFilterForModule (const FileSpec *containingModule);
+ lldb::SearchFilterSP
+ GetSearchFilterForModuleList (const FileSpecList *containingModuleList);
+
static void
ImageSearchPathsChanged (const PathMappingList &path_list,
void *baton);
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index 5e089d54425..d9db639be44 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -101,6 +101,7 @@
#define LLDB_OPT_SET_6 (1 << 5)
#define LLDB_OPT_SET_7 (1 << 6)
#define LLDB_OPT_SET_8 (1 << 7)
+#define LLDB_OPT_SET_9 (1 << 8)
#if defined(__cplusplus)
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 0a57b329df5..28b0c4f893a 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -400,6 +400,8 @@
49C8507C1384A786007DB519 /* ProcessDataAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49C850781384A0CA007DB519 /* ProcessDataAllocator.cpp */; };
49D8FB3913B5598F00411094 /* ClangASTImporter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D8FB3513B558DE00411094 /* ClangASTImporter.cpp */; };
4C74CB6312288704006A8171 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C74CB6212288704006A8171 /* Carbon.framework */; };
+ 4CAA56131422D96A001FFA01 /* BreakpointResolverFileRegex.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CAA56121422D96A001FFA01 /* BreakpointResolverFileRegex.h */; };
+ 4CAA56151422D986001FFA01 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
4CCA644D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA643D13B40B82003BDF98 /* ItaniumABILanguageRuntime.cpp */; };
4CCA645013B40B82003BDF98 /* AppleObjCRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644213B40B82003BDF98 /* AppleObjCRuntime.cpp */; };
@@ -408,6 +410,8 @@
4CCA645613B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644813B40B82003BDF98 /* AppleObjCTrampolineHandler.cpp */; };
4CCA645813B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CCA644A13B40B82003BDF98 /* AppleThreadPlanStepThroughObjCTrampoline.cpp */; };
4CD0BD0F134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */; };
+ 4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CF52AF41428291E0051E832 /* SBFileSpecList.h */; };
+ 4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
94031A9E13CF486700DCFF3C /* InputReaderEZ.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94031A9D13CF486600DCFF3C /* InputReaderEZ.cpp */; };
9415F61813B2C0EF00A52B36 /* FormatManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9415F61713B2C0EF00A52B36 /* FormatManager.cpp */; };
9443B122140C18C40013457C /* SBData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9443B121140C18C10013457C /* SBData.cpp */; };
@@ -1159,6 +1163,8 @@
4C98D3E1118FB98F00E575D0 /* RecordingMemoryManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RecordingMemoryManager.h; path = include/lldb/Expression/RecordingMemoryManager.h; sourceTree = "<group>"; };
4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandObjectApropos.cpp; path = source/Commands/CommandObjectApropos.cpp; sourceTree = "<group>"; };
4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandObjectApropos.h; path = source/Commands/CommandObjectApropos.h; sourceTree = "<group>"; };
+ 4CAA56121422D96A001FFA01 /* BreakpointResolverFileRegex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointResolverFileRegex.h; path = include/lldb/Breakpoint/BreakpointResolverFileRegex.h; sourceTree = "<group>"; };
+ 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointResolverFileRegex.cpp; path = source/Breakpoint/BreakpointResolverFileRegex.cpp; sourceTree = "<group>"; };
4CABA9DC134A8BA700539BDD /* ValueObjectMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectMemory.h; path = include/lldb/Core/ValueObjectMemory.h; sourceTree = "<group>"; };
4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectMemory.cpp; path = source/Core/ValueObjectMemory.cpp; sourceTree = "<group>"; };
4CAFCE001101216B00CA63DB /* ThreadPlanRunToAddress.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanRunToAddress.h; path = include/lldb/Target/ThreadPlanRunToAddress.h; sourceTree = "<group>"; };
@@ -1186,6 +1192,8 @@
4CD0BD0C134BFAB600CB44D4 /* ValueObjectDynamicValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ValueObjectDynamicValue.h; path = include/lldb/Core/ValueObjectDynamicValue.h; sourceTree = "<group>"; };
4CD0BD0E134BFADF00CB44D4 /* ValueObjectDynamicValue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ValueObjectDynamicValue.cpp; path = source/Core/ValueObjectDynamicValue.cpp; sourceTree = "<group>"; };
4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanStepUntil.h; path = include/lldb/Target/ThreadPlanStepUntil.h; sourceTree = "<group>"; };
+ 4CF52AF41428291E0051E832 /* SBFileSpecList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBFileSpecList.h; path = include/lldb/API/SBFileSpecList.h; sourceTree = "<group>"; };
+ 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBFileSpecList.cpp; path = source/API/SBFileSpecList.cpp; sourceTree = "<group>"; };
69A01E1B1236C5D400C660B5 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Condition.cpp; sourceTree = "<group>"; };
69A01E1C1236C5D400C660B5 /* Host.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Host.cpp; sourceTree = "<group>"; };
69A01E1E1236C5D400C660B5 /* Mutex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Mutex.cpp; sourceTree = "<group>"; };
@@ -1685,6 +1693,8 @@
9A9830FD1125FC5800A56CB0 /* SBEvent.cpp */,
26022531115F27FA00A601A2 /* SBFileSpec.h */,
26022532115F281400A601A2 /* SBFileSpec.cpp */,
+ 4CF52AF41428291E0051E832 /* SBFileSpecList.h */,
+ 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */,
9A633FE8112DCE3C001A7E43 /* SBFrame.h */,
9A633FE7112DCE3C001A7E43 /* SBFrame.cpp */,
26DE205211618FAC00A093E2 /* SBFunction.h */,
@@ -2176,6 +2186,8 @@
26D0DD5310FE555900271C65 /* BreakpointResolverAddress.cpp */,
26D0DD5110FE554D00271C65 /* BreakpointResolverFileLine.h */,
26D0DD5410FE555900271C65 /* BreakpointResolverFileLine.cpp */,
+ 4CAA56121422D96A001FFA01 /* BreakpointResolverFileRegex.h */,
+ 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */,
26D0DD5210FE554D00271C65 /* BreakpointResolverName.h */,
26D0DD5510FE555900271C65 /* BreakpointResolverName.cpp */,
26BC7CF710F1B71400F91463 /* BreakpointSite.h */,
@@ -2754,6 +2766,8 @@
9A357583116CFDEE00E8ED2F /* SBValueList.h in Headers */,
26D265A2136B40EE002EEE45 /* SharingPtr.h in Headers */,
26D265BC136B4269002EEE45 /* lldb-public.h in Headers */,
+ 4CAA56131422D96A001FFA01 /* BreakpointResolverFileRegex.h in Headers */,
+ 4CF52AF51428291E0051E832 /* SBFileSpecList.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -3037,6 +3051,8 @@
26C72C961243229A0068DC16 /* SBStream.cpp in Sources */,
26B1FA1413380E61002886E2 /* LLDBWrapPython.cpp in Sources */,
9443B122140C18C40013457C /* SBData.cpp in Sources */,
+ 4CAA56151422D986001FFA01 /* BreakpointResolverFileRegex.cpp in Sources */,
+ 4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/lldb/scripts/Python/interface/SBCommandInterpreter.i b/lldb/scripts/Python/interface/SBCommandInterpreter.i
index 81e515830ec..6a5ee2466b0 100644
--- a/lldb/scripts/Python/interface/SBCommandInterpreter.i
+++ b/lldb/scripts/Python/interface/SBCommandInterpreter.i
@@ -116,8 +116,7 @@ public:
int
HandleCompletion (const char *current_line,
- const char *cursor,
- const char *last_char,
+ uint32_t cursor_pos,
int match_start_point,
int max_return_elements,
lldb::SBStringList &matches);
diff --git a/lldb/scripts/Python/interface/SBFileSpecList.i b/lldb/scripts/Python/interface/SBFileSpecList.i
new file mode 100644
index 00000000000..5ad4742d687
--- /dev/null
+++ b/lldb/scripts/Python/interface/SBFileSpecList.i
@@ -0,0 +1,45 @@
+//===-- SWIG Interface for SBFileSpecList -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class SBFileSpecList
+{
+public:
+ SBFileSpecList ();
+
+ SBFileSpecList (const lldb::SBFileSpecList &rhs);
+
+ ~SBFileSpecList ();
+
+ uint32_t
+ GetSize () const;
+
+ bool
+ GetDescription (SBStream &description) const;
+
+ void
+ Append (const SBFileSpec &sb_file);
+
+ bool
+ AppendIfUnique (const SBFileSpec &sb_file);
+
+ void
+ Clear();
+
+ uint32_t
+ FindFileIndex (uint32_t idx, const SBFileSpec &sb_file);
+
+ const SBFileSpec
+ GetFileSpecAtIndex (uint32_t idx) const;
+
+};
+
+
+} // namespace lldb
diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i
index baa151c0101..aafc80bea39 100644
--- a/lldb/scripts/Python/interface/SBTarget.i
+++ b/lldb/scripts/Python/interface/SBTarget.i
@@ -372,6 +372,9 @@ public:
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);
+
+ lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
uint32_t
diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig
index 66ac7b67fd7..7c7d3b011f6 100644
--- a/lldb/scripts/lldb.swig
+++ b/lldb/scripts/lldb.swig
@@ -56,6 +56,7 @@ o SBLineEntry: Specifies an association with a contiguous range of instructions
#include "lldb/API/SBError.h"
#include "lldb/API/SBEvent.h"
#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBFileSpecList.h"
#include "lldb/API/SBFrame.h"
#include "lldb/API/SBFunction.h"
#include "lldb/API/SBHostOS.h"
@@ -106,6 +107,7 @@ o SBLineEntry: Specifies an association with a contiguous range of instructions
%include "./Python/interface/SBError.i"
%include "./Python/interface/SBEvent.i"
%include "./Python/interface/SBFileSpec.i"
+%include "./Python/interface/SBFileSpecList.i"
%include "./Python/interface/SBFrame.i"
%include "./Python/interface/SBFunction.i"
%include "./Python/interface/SBHostOS.i"
diff --git a/lldb/source/API/SBCommandInterpreter.cpp b/lldb/source/API/SBCommandInterpreter.cpp
index 61d0a99f975..8a15423c324 100644
--- a/lldb/source/API/SBCommandInterpreter.cpp
+++ b/lldb/source/API/SBCommandInterpreter.cpp
@@ -136,6 +136,18 @@ SBCommandInterpreter::HandleCompletion (const char *current_line,
return num_completions;
}
+int
+SBCommandInterpreter::HandleCompletion (const char *current_line,
+ uint32_t cursor_pos,
+ int match_start_point,
+ int max_return_elements,
+ lldb::SBStringList &matches)
+{
+ const char *cursor = current_line + cursor_pos;
+ const char *last_char = current_line + strlen (current_line);
+ return HandleCompletion (current_line, cursor, last_char, match_start_point, max_return_elements, matches);
+}
+
bool
SBCommandInterpreter::HasCommands ()
{
diff --git a/lldb/source/API/SBFileSpecList.cpp b/lldb/source/API/SBFileSpecList.cpp
new file mode 100644
index 00000000000..3abb4fc135b
--- /dev/null
+++ b/lldb/source/API/SBFileSpecList.cpp
@@ -0,0 +1,139 @@
+//===-- SBFileSpecListList.cpp ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <limits.h>
+
+#include "lldb/API/SBFileSpec.h"
+#include "lldb/API/SBFileSpecList.h"
+#include "lldb/API/SBStream.h"
+#include "lldb/Core/FileSpecList.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Host/FileSpec.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+
+SBFileSpecList::SBFileSpecList () :
+ m_opaque_ap(new FileSpecList())
+{
+}
+
+SBFileSpecList::SBFileSpecList (const SBFileSpecList &rhs) :
+ m_opaque_ap()
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ if (rhs.m_opaque_ap.get())
+ m_opaque_ap.reset (new FileSpecList (*(rhs.get())));
+
+ if (log)
+ {
+ log->Printf ("SBFileSpecList::SBFileSpecList (const SBFileSpecList rhs.ap=%p) => SBFileSpecList(%p): %s",
+ rhs.m_opaque_ap.get(), m_opaque_ap.get());
+ }
+}
+
+SBFileSpecList::~SBFileSpecList ()
+{
+}
+
+const SBFileSpecList &
+SBFileSpecList::operator = (const SBFileSpecList &rhs)
+{
+ if (this != &rhs)
+ {
+ m_opaque_ap.reset (new lldb_private::FileSpecList(*(rhs.get())));
+ }
+ return *this;
+}
+
+uint32_t
+SBFileSpecList::GetSize () const
+{
+ return m_opaque_ap->GetSize();
+}
+
+void
+SBFileSpecList::Append (const SBFileSpec &sb_file)
+{
+ m_opaque_ap->Append (sb_file.ref());
+}
+
+bool
+SBFileSpecList::AppendIfUnique (const SBFileSpec &sb_file)
+{
+ return m_opaque_ap->AppendIfUnique (sb_file.ref());
+}
+
+void
+SBFileSpecList::Clear()
+{
+ m_opaque_ap->Clear();
+}
+
+uint32_t
+SBFileSpecList::FindFileIndex (uint32_t idx, const SBFileSpec &sb_file)
+{
+ return m_opaque_ap->FindFileIndex (idx, sb_file.ref());
+}
+
+const SBFileSpec
+SBFileSpecList::GetFileSpecAtIndex (uint32_t idx) const
+{
+ SBFileSpec new_spec;
+ new_spec.SetFileSpec(m_opaque_ap->GetFileSpecAtIndex(idx));
+ return new_spec;
+}
+
+const lldb_private::FileSpecList *
+SBFileSpecList::operator->() const
+{
+ return m_opaque_ap.get();
+}
+
+const lldb_private::FileSpecList *
+SBFileSpecList::get() const
+{
+ return m_opaque_ap.get();
+}
+
+
+const lldb_private::FileSpecList &
+SBFileSpecList::operator*() const
+{
+ return *m_opaque_ap.get();
+}
+
+const lldb_private::FileSpecList &
+SBFileSpecList::ref() const
+{
+ return *m_opaque_ap.get();
+}
+
+bool
+SBFileSpecList::GetDescription (SBStream &description) const
+{
+ if (m_opaque_ap.get())
+ {
+ uint32_t num_files = m_opaque_ap->GetSize();
+ description.Printf ("%d files: ", num_files);
+ for (uint32_t i = 0; i < num_files; i++)
+ {
+ char path[PATH_MAX];
+ if (m_opaque_ap->GetFileSpecAtIndex(i).GetPath(path, sizeof(path)))
+ description.Printf ("\n %s", path);
+ }
+ }
+ else
+ description.Printf ("No value");
+
+ return true;
+}
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 5f3716c4e1a..4e0dac4e907 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -580,8 +580,9 @@ SBTarget::BreakpointCreateByName (const char *symbol_name, const char *module_na
Mutex::Locker api_locker (m_opaque_sp->GetAPIMutex());
if (module_name && module_name[0])
{
- FileSpec module_file_spec(module_name, false);
- *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, symbol_name, eFunctionNameTypeFull | eFunctionNameTypeBase, false);
+ 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);
}
else
{
@@ -611,9 +612,10 @@ SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *mo
if (module_name && module_name[0])
{
- FileSpec module_file_spec(module_name, false);
+ FileSpecList module_spec_list;
+ module_spec_list.Append (FileSpec (module_name, false));
- *sb_bp = m_opaque_sp->CreateBreakpoint (&module_file_spec, regexp, false);
+ *sb_bp = m_opaque_sp->CreateBreakpoint (&module_spec_list, regexp, false);
}
else
{
@@ -652,6 +654,42 @@ SBTarget::BreakpointCreateByAddress (addr_t address)
return sb_bp;
}
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name)
+{
+ 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);
+
+ 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);
+ }
+ else
+ {
+ *sb_bp = m_opaque_sp->CreateBreakpoint (NULL, source_file.ref(), regexp, false);
+ }
+ }
+
+ if (log)
+ {
+ char path[PATH_MAX];
+ source_file->GetPath (path, sizeof(path));
+ log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (source_regex=\"%s\", file=\"%s\", module_name=\"%s\") => SBBreakpoint(%p)",
+ m_opaque_sp.get(), source_regex, path, sb_bp.get());
+ }
+
+ return sb_bp;
+}
+
+
SBBreakpoint
SBTarget::FindBreakpointByID (break_id_t bp_id)
{
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
index 13eda3c5d64..224dd158f67 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp
@@ -67,12 +67,22 @@ BreakpointResolverFileLine::SearchCallback
Address line_start = sc.line_entry.range.GetBaseAddress();
if (line_start.IsValid())
{
- BreakpointLocationSP bp_loc_sp (m_breakpoint->AddLocation(line_start));
- if (log && bp_loc_sp && !m_breakpoint->IsInternal())
+ if (filter.AddressPasses(line_start))
{
- StreamString s;
- bp_loc_sp->GetDescription (&s, lldb::eDescriptionLevelVerbose);
- log->Printf ("Added location: %s\n", s.GetData());
+ 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 the filter.\n",
+ line_start.GetFileAddress(),
+ m_file_spec.GetFilename().AsCString("<Unknown>"),
+ m_line_number);
}
}
else
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
new file mode 100644
index 00000000000..238c3709354
--- /dev/null
+++ b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -0,0 +1,139 @@
+//===-- BreakpointResolverFileRegex.cpp --------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Core/SourceManager.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Target/Target.h"
+#include "lldb/lldb-private-log.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+//----------------------------------------------------------------------
+// BreakpointResolverFileRegex:
+//----------------------------------------------------------------------
+BreakpointResolverFileRegex::BreakpointResolverFileRegex
+(
+ Breakpoint *bkpt,
+ const FileSpec &file_spec,
+ RegularExpression &regex
+) :
+ BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver),
+ m_file_spec (file_spec),
+ m_regex (regex)
+{
+}
+
+BreakpointResolverFileRegex::~BreakpointResolverFileRegex ()
+{
+}
+
+Searcher::CallbackReturn
+BreakpointResolverFileRegex::SearchCallback
+(
+ SearchFilter &filter,
+ SymbolContext &context,
+ Address *addr,
+ bool containing
+)
+{
+
+ assert (m_breakpoint != NULL);
+ if (!context.target_sp)
+ return eCallbackReturnContinue;
+
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+
+ 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++)
+ {
+ uint32_t start_idx = 0;
+ while (1)
+ {
+ LineEntry line_entry;
+
+ // 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())
+ {
+ if (filter.AddressPasses(line_start))
+ {
+ 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]);
+ }
+ }
+ else
+ {
+ 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]);
+ }
+
+ }
+ }
+ assert (m_breakpoint != NULL);
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_BREAKPOINTS));
+
+
+ }
+ return Searcher::eCallbackReturnContinue;
+}
+
+Searcher::Depth
+BreakpointResolverFileRegex::GetDepth()
+{
+ return Searcher::eDepthCompUnit;
+}
+
+void
+BreakpointResolverFileRegex::GetDescription (Stream *s)
+{
+ s->Printf ("file ='%s', regular expression = \"%s\"", m_file_spec.GetFilename().AsCString(), m_regex.GetText());
+}
+
+void
+BreakpointResolverFileRegex::Dump (Stream *s) const
+{
+
+}
+
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp
index 60547c6bd78..141a15bef7d 100644
--- a/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -104,7 +104,6 @@ BreakpointResolverName::BreakpointResolverName
m_match_type (Breakpoint::Regexp),
m_skip_prologue (skip_prologue)
{
-
}
BreakpointResolverName::BreakpointResolverName
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 5c96a7f6d92..cc2051d3184 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -56,6 +56,7 @@ CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &i
m_func_name (),
m_func_name_type_mask (0),
m_func_regexp (),
+ m_source_text_regexp(),
m_modules (),
m_load_addr(),
m_ignore_count (0),
@@ -91,7 +92,7 @@ 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, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
+ { 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_SET_1, true, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
@@ -124,6 +125,10 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_8, true, "basename", 'b', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
"Set the breakpoint by function basename (C++ namespaces and arguments will be ignored)." },
+ { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', required_argument, NULL, 0, eArgTypeRegularExpression,
+ "Set the breakpoint specifying a regular expression to match a pattern in the source text in a given source file." },
+
+
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -187,6 +192,10 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
m_func_name_type_mask |= eFunctionNameTypeMethod;
break;
+ case 'p':
+ m_source_text_regexp.assign (option_arg);
+ break;
+
case 'r':
m_func_regexp.assign (option_arg);
break;
@@ -275,6 +284,52 @@ CommandObjectBreakpointSet::GetOptions ()
}
bool
+CommandObjectBreakpointSet::ChooseFile (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))
+ {
+ StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame;
+ if (cur_frame == NULL)
+ {
+ 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;
+ }
+ 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;
+}
+
+bool
CommandObjectBreakpointSet::Execute
(
Args& command,
@@ -294,6 +349,7 @@ CommandObjectBreakpointSet::Execute
// 2). -a [-s -g] (setting breakpoint by address)
// 3). -n [-s -g] (setting breakpoint by function name)
// 4). -r [-s -g] (setting breakpoint by function name regular expression)
+ // 5). -p -f (setting a breakpoint by comparing a reg-exp to source text)
BreakpointSetType break_type = eSetTypeInvalid;
@@ -305,94 +361,42 @@ CommandObjectBreakpointSet::Execute
break_type = eSetTypeFunctionName;
else if (!m_options.m_func_regexp.empty())
break_type = eSetTypeFunctionRegexp;
+ else if (!m_options.m_source_text_regexp.empty())
+ break_type = eSetTypeSourceRegexp;
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;
+
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 (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))
- {
- StackFrame *cur_frame = m_interpreter.GetExecutionContext().frame;
- if (cur_frame == NULL)
- {
- result.AppendError ("Attempting to set breakpoint by line number alone with no selected frame.");
- result.SetStatus (eReturnStatusFailed);
- break;
- }
- 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);
- break;
- }
- 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);
- break;
- }
- }
- }
- }
- else
- {
- file.SetFile(m_options.m_filename.c_str(), false);
- }
-
- if (use_module)
- {
- for (int i = 0; i < num_modules; ++i)
- {
- module_spec.SetFile(m_options.m_modules[i].c_str(), false);
- bp = target->CreateBreakpoint (&module_spec,
- file,
- m_options.m_line_num,
- m_options.m_check_inlines).get();
- if (bp)
- {
- Stream &output_stream = result.GetOutputStream();
- result.AppendMessage ("Breakpoint created: ");
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
- output_stream.EOL();
- if (bp->GetNumLocations() == 0)
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
- " locations.\n");
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
- m_options.m_modules[i].c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- bp = target->CreateBreakpoint (NULL,
- file,
- m_options.m_line_num,
- m_options.m_check_inlines).get();
+ if (!ChooseFile (target, file, result))
+ break;
+
+ bp = target->CreateBreakpoint (module_spec_list_ptr,
+ file,
+ m_options.m_line_num,
+ m_options.m_check_inlines).get();
}
break;
@@ -407,72 +411,47 @@ CommandObjectBreakpointSet::Execute
if (name_type_mask == 0)
name_type_mask = eFunctionNameTypeAuto;
- if (use_module)
- {
- for (int i = 0; i < num_modules; ++i)
- {
- module_spec.SetFile(m_options.m_modules[i].c_str(), false);
- bp = target->CreateBreakpoint (&module_spec,
- m_options.m_func_name.c_str(),
- name_type_mask,
- Breakpoint::Exact).get();
- if (bp)
- {
- Stream &output_stream = result.GetOutputStream();
- output_stream.Printf ("Breakpoint created: ");
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
- output_stream.EOL();
- if (bp->GetNumLocations() == 0)
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
- " locations.\n");
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
- m_options.m_modules[i].c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
- }
- else
- bp = target->CreateBreakpoint (NULL, m_options.m_func_name.c_str(), name_type_mask, Breakpoint::Exact).get();
+ bp = target->CreateBreakpoint (module_spec_list_ptr,
+ m_options.m_func_name.c_str(),
+ name_type_mask,
+ Breakpoint::Exact).get();
}
break;
case eSetTypeFunctionRegexp: // Breakpoint by regular expression function name
{
RegularExpression regexp(m_options.m_func_regexp.c_str());
- if (use_module)
+ if (!regexp.IsValid())
{
- for (int i = 0; i < num_modules; ++i)
- {
- module_spec.SetFile(m_options.m_modules[i].c_str(), false);
- bp = target->CreateBreakpoint (&module_spec, regexp).get();
- if (bp)
- {
- Stream &output_stream = result.GetOutputStream();
- output_stream.Printf ("Breakpoint created: ");
- bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
- output_stream.EOL();
- if (bp->GetNumLocations() == 0)
- output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual"
- " locations.\n");
- result.SetStatus (eReturnStatusSuccessFinishResult);
- }
- else
- {
- result.AppendErrorWithFormat("Breakpoint creation failed: No breakpoint created in module '%s'.\n",
- m_options.m_modules[i].c_str());
- result.SetStatus (eReturnStatusFailed);
- }
- }
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat("Function name regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
}
- else
- bp = target->CreateBreakpoint (NULL, regexp).get();
+ bp = target->CreateBreakpoint (module_spec_list_ptr, regexp).get();
}
break;
+ case eSetTypeSourceRegexp: // Breakpoint by regexp on source text.
+ {
+ FileSpec file;
+ if (!ChooseFile (target, file, result))
+ break;
+ RegularExpression regexp(m_options.m_source_text_regexp.c_str());
+ if (!regexp.IsValid())
+ {
+ char err_str[1024];
+ regexp.GetErrorAsCString(err_str, sizeof(err_str));
+ result.AppendErrorWithFormat("Source text regular expression could not be compiled: \"%s\"",
+ err_str);
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+ bp = target->CreateBreakpoint (module_spec_list_ptr, file, regexp).get();
+ }
+ break;
default:
break;
}
@@ -496,7 +475,7 @@ CommandObjectBreakpointSet::Execute
bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
}
- if (bp && !use_module)
+ if (bp)
{
Stream &output_stream = result.GetOutputStream();
output_stream.Printf ("Breakpoint created: ");
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index d8382a75c0b..9df14dafad4 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -57,7 +57,8 @@ public:
eSetTypeFileAndLine,
eSetTypeAddress,
eSetTypeFunctionName,
- eSetTypeFunctionRegexp
+ eSetTypeFunctionRegexp,
+ eSetTypeSourceRegexp
} BreakpointSetType;
CommandObjectBreakpointSet (CommandInterpreter &interpreter);
@@ -103,6 +104,7 @@ public:
std::string m_func_name;
uint32_t m_func_name_type_mask;
std::string m_func_regexp;
+ std::string m_source_text_regexp;
STLStringArray m_modules;
lldb::addr_t m_load_addr;
uint32_t m_ignore_count;
@@ -114,6 +116,9 @@ public:
};
private:
+ bool
+ ChooseFile (Target *target, FileSpec &file, CommandReturnObject &result);
+
CommandOptions m_options;
};
diff --git a/lldb/source/Core/RegularExpression.cpp b/lldb/source/Core/RegularExpression.cpp
index 6fb94d98bb5..c3953aae068 100644
--- a/lldb/source/Core/RegularExpression.cpp
+++ b/lldb/source/Core/RegularExpression.cpp
@@ -19,6 +19,7 @@ RegularExpression::RegularExpression() :
m_re(),
m_comp_err (1),
m_preg(),
+ m_compile_flags(REG_EXTENDED),
m_matches()
{
memset(&m_preg,0,sizeof(m_preg));
@@ -31,13 +32,43 @@ RegularExpression::RegularExpression() :
RegularExpression::RegularExpression(const char* re, int flags) :
m_re(),
m_comp_err (1),
+ m_compile_flags(flags),
m_preg()
{
memset(&m_preg,0,sizeof(m_preg));
- Compile(re, flags);
+ Compile(re);
}
//----------------------------------------------------------------------
+// Constructor that compiles "re" using "flags" and stores the
+// resulting compiled regular expression into this object.
+//----------------------------------------------------------------------
+RegularExpression::RegularExpression(const char* re) :
+ m_re(),
+ m_comp_err (1),
+ m_compile_flags(REG_EXTENDED),
+ m_preg()
+{
+ memset(&m_preg,0,sizeof(m_preg));
+ Compile(re);
+}
+
+RegularExpression::RegularExpression(const RegularExpression &rhs)
+{
+ memset(&m_preg,0,sizeof(m_preg));
+ Compile(rhs.GetText(), rhs.GetCompileFlags());
+}
+
+const RegularExpression &
+RegularExpression::operator= (const RegularExpression &rhs)
+{
+ if (&rhs != this)
+ {
+ Compile (rhs.GetText(), rhs.GetCompileFlags());
+ }
+ return *this;
+}
+//----------------------------------------------------------------------
// Destructor
//
// Any previosuly compiled regular expression contained in this
@@ -61,9 +92,17 @@ RegularExpression::~RegularExpression()
// otherwise.
//----------------------------------------------------------------------
bool
+RegularExpression::Compile(const char* re)
+{
+ return Compile (re, m_compile_flags);
+}
+
+bool
RegularExpression::Compile(const char* re, int flags)
{
Free();
+ m_compile_flags = flags;
+
if (re && re[0])
{
m_re = re;
diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp
index 8a9140df50d..e0521aa70e2 100644
--- a/lldb/source/Core/SearchFilter.cpp
+++ b/lldb/source/Core/SearchFilter.cpp
@@ -432,3 +432,178 @@ SearchFilterByModule::Dump (Stream *s) const
{
}
+//----------------------------------------------------------------------
+// SearchFilterByModuleList:
+// Selects a shared library matching a given file spec
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// SearchFilterByModuleList constructors
+//----------------------------------------------------------------------
+
+SearchFilterByModuleList::SearchFilterByModuleList (lldb::TargetSP &target_sp, const FileSpecList &module_list) :
+ SearchFilter (target_sp),
+ m_module_spec_list (module_list)
+{
+}
+
+
+//----------------------------------------------------------------------
+// SearchFilterByModuleList copy constructor
+//----------------------------------------------------------------------
+SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) :
+ SearchFilter (rhs),
+ m_module_spec_list (rhs.m_module_spec_list)
+{
+}
+
+//----------------------------------------------------------------------
+// SearchFilterByModuleList assignment operator
+//----------------------------------------------------------------------
+const SearchFilterByModuleList&
+SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
+{
+ m_target_sp = rhs.m_target_sp;
+ m_module_spec_list = rhs.m_module_spec_list;
+ return *this;
+}
+
+//----------------------------------------------------------------------
+// Destructor
+//----------------------------------------------------------------------
+SearchFilterByModuleList::~SearchFilterByModuleList()
+{
+}
+
+bool
+SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
+{
+ if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec()) != UINT32_MAX)
+ return true;
+ else
+ return false;
+}
+
+bool
+SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
+{
+ if (m_module_spec_list.FindFileIndex(0, spec) != UINT32_MAX)
+ return true;
+ else
+ return false;
+}
+
+bool
+SearchFilterByModuleList::SymbolContextPasses
+(
+ const SymbolContext &context,
+ lldb::SymbolContextItem scope
+ )
+{
+ if (!(scope & eSymbolContextModule))
+ return false;
+
+ if (context.module_sp && m_module_spec_list.FindFileIndex(0, context.module_sp->GetFileSpec()) != UINT32_MAX)
+ return true;
+ else
+ return false;
+}
+
+bool
+SearchFilterByModuleList::AddressPasses (Address &address)
+{
+ // FIXME: Not yet implemented
+ return true;
+}
+
+
+bool
+SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
+{
+ return true;
+}
+
+bool
+SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit)
+{
+ return true;
+}
+
+void
+SearchFilterByModuleList::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 ();
+ 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)
+ {
+ SymbolContext matchingContext(m_target_sp, ModuleSP(module));
+ Searcher::CallbackReturn shouldContinue;
+
+ shouldContinue = DoModuleIteration(matchingContext, searcher);
+ if (shouldContinue == Searcher::eCallbackReturnStop)
+ return;
+ }
+ }
+}
+
+void
+SearchFilterByModuleList::GetDescription (Stream *s)
+{
+ uint32_t num_modules = m_module_spec_list.GetSize();
+ if (num_modules == 1)
+ {
+ s->Printf (", module = ", num_modules);
+ 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
+ {
+ 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 (", ");
+ }
+ }
+}
+
+void
+SearchFilterByModuleList::Dump (Stream *s) const
+{
+
+}
diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp
index 708bf89bd99..6b0670f31b4 100644
--- a/lldb/source/Core/SourceManager.cpp
+++ b/lldb/source/Core/SourceManager.cpp
@@ -231,6 +231,19 @@ SourceManager::GetDefaultFileAndLine (FileSpec &file_spec, uint32_t &line)
return false;
}
+void
+SourceManager::FindLinesMatchingRegex (FileSpec &file_spec,
+ RegularExpression& regex,
+ uint32_t start_line,
+ uint32_t end_line,
+ std::vector<uint32_t> &match_lines)
+{
+ match_lines.clear();
+ FileSP file_sp = GetFile (file_spec);
+ if (!file_sp)
+ return;
+ return file_sp->FindLinesMatchingRegex (regex, start_line, end_line, match_lines);
+}
SourceManager::File::File(const FileSpec &file_spec, Target *target) :
m_file_spec_orig (file_spec),
@@ -368,6 +381,36 @@ SourceManager::File::DisplaySourceLines (uint32_t line, uint32_t context_before,
return 0;
}
+void
+SourceManager::File::FindLinesMatchingRegex (RegularExpression& regex, uint32_t start_line, uint32_t end_line, std::vector<uint32_t> &match_lines)
+{
+ TimeValue curr_mod_time (m_file_spec.GetModificationTime());
+ if (m_mod_time != curr_mod_time)
+ {
+ m_mod_time = curr_mod_time;
+ m_data_sp = m_file_spec.ReadFileContents ();
+ m_offsets.clear();
+ }
+
+ match_lines.clear();
+
+ if (!LineIsValid(start_line) || (end_line != UINT32_MAX && !LineIsValid(end_line)))
+ return;
+ if (start_line > end_line)
+ return;
+
+ for (uint32_t line_no = start_line; line_no < end_line; line_no++)
+ {
+ std::string buffer;
+ if (!GetLine (line_no, buffer))
+ break;
+ if (regex.Execute(buffer.c_str()))
+ {
+ match_lines.push_back(line_no);
+ }
+ }
+}
+
bool
SourceManager::File::FileSpecMatches (const FileSpec &file_spec)
{
@@ -457,6 +500,23 @@ SourceManager::File::CalculateLineOffsets (uint32_t line)
return false;
}
+bool
+SourceManager::File::GetLine (uint32_t line_no, std::string &buffer)
+{
+ if (!LineIsValid(line_no))
+ return false;
+
+ uint32_t start_offset = GetLineOffset (line_no);
+ uint32_t end_offset = GetLineOffset (line_no + 1);
+ if (end_offset == UINT32_MAX)
+ {
+ end_offset = m_data_sp->GetByteSize();
+ }
+ buffer.assign((char *) m_data_sp->GetBytes() + start_offset, end_offset - start_offset);
+
+ return true;
+}
+
void
SourceManager::SourceFileCache::AddSourceFile (const FileSP &file_sp)
{
diff --git a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
index 6628f92a10f..55e0af68cb8 100644
--- a/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
@@ -985,7 +985,9 @@ DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
const bool internal_bp = false;
const LazyBool skip_prologue = eLazyBoolNo;
- Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&m_kernel.module_sp->GetFileSpec(),
+ FileSpecList module_spec_list;
+ module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
+ Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
"OSKextLoadedKextSummariesUpdated",
eFunctionNameTypeFull,
internal_bp,
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 5148751755d..14517e605ee 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -124,7 +124,7 @@ SymbolFileSymtab::GetNumCompileUnits()
// If we don't have any source file symbols we will just have one compile unit for
// the entire object file
if (m_source_indexes.empty())
- return 1;
+ return 0;
// If we have any source file symbols we will logically orgnize the object symbols
// using these.
@@ -138,14 +138,14 @@ SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx)
// If we don't have any source file symbols we will just have one compile unit for
// the entire object file
- if (m_source_indexes.empty())
- {
- const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
- if (obj_file_spec)
- cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
-
- }
- else if (idx < m_source_indexes.size())
+// if (m_source_indexes.empty())
+// {
+// const FileSpec &obj_file_spec = m_obj_file->GetFileSpec();
+// if (obj_file_spec)
+// cu_sp.reset(new CompileUnit(m_obj_file->GetModule(), NULL, obj_file_spec, 0, eLanguageTypeUnknown));
+//
+// }
+ /* else */ if (idx < m_source_indexes.size())
{
const Symbol *cu_symbol = m_obj_file->GetSymtab()->SymbolAtIndex(m_source_indexes[idx]);
if (cu_symbol)
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 154946206d9..5fdc2333eb8 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -16,6 +16,7 @@
#include "lldb/Breakpoint/BreakpointResolver.h"
#include "lldb/Breakpoint/BreakpointResolverAddress.h"
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
+#include "lldb/Breakpoint/BreakpointResolverFileRegex.h"
#include "lldb/Breakpoint/BreakpointResolverName.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Event.h"
@@ -206,9 +207,21 @@ Target::GetBreakpointByID (break_id_t break_id)
}
BreakpointSP
-Target::CreateBreakpoint (const FileSpec *containingModule, const FileSpec &file, uint32_t line_no, bool check_inlines, bool internal)
+Target::CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpec &file,
+ RegularExpression &source_regex,
+ bool internal)
{
- SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+ SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
+ BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex (NULL, file, source_regex));
+ return CreateBreakpoint (filter_sp, resolver_sp, internal);
+}
+
+
+BreakpointSP
+Target::CreateBreakpoint (const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, bool check_inlines, bool internal)
+{
+ SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine (NULL, file, line_no, check_inlines));
return CreateBreakpoint (filter_sp, resolver_sp, internal);
}
@@ -242,7 +255,7 @@ Target::CreateBreakpoint (Address &addr, bool internal)
}
BreakpointSP
-Target::CreateBreakpoint (const FileSpec *containingModule,
+Target::CreateBreakpoint (const FileSpecList *containingModules,
const char *func_name,
uint32_t func_name_type_mask,
bool internal,
@@ -251,7 +264,7 @@ Target::CreateBreakpoint (const FileSpec *containingModule,
BreakpointSP bp_sp;
if (func_name)
{
- SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+ SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
func_name,
@@ -284,13 +297,33 @@ Target::GetSearchFilterForModule (const FileSpec *containingModule)
return filter_sp;
}
+SearchFilterSP
+Target::GetSearchFilterForModuleList (const FileSpecList *containingModules)
+{
+ SearchFilterSP filter_sp;
+ lldb::TargetSP target_sp = this->GetSP();
+ if (containingModules && containingModules->GetSize() != 0)
+ {
+ // TODO: We should look into sharing module based search filters
+ // across many breakpoints like we do for the simple target based one
+ filter_sp.reset (new SearchFilterByModuleList (target_sp, *containingModules));
+ }
+ else
+ {
+ if (m_search_filter_sp.get() == NULL)
+ m_search_filter_sp.reset (new SearchFilter (target_sp));
+ filter_sp = m_search_filter_sp;
+ }
+ return filter_sp;
+}
+
BreakpointSP
-Target::CreateBreakpoint (const FileSpec *containingModule,
+Target::CreateBreakpoint (const FileSpecList *containingModules,
RegularExpression &func_regex,
bool internal,
LazyBool skip_prologue)
{
- SearchFilterSP filter_sp(GetSearchFilterForModule (containingModule));
+ SearchFilterSP filter_sp(GetSearchFilterForModuleList (containingModules));
BreakpointResolverSP resolver_sp(new BreakpointResolverName (NULL,
func_regex,
skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
diff --git a/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py b/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py
index 67482e5256c..426f719c456 100644
--- a/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py
+++ b/lldb/test/lang/objc/objc-stepping/TestObjCStepping.py
@@ -3,6 +3,7 @@
import os, time
import unittest2
import lldb
+import lldbutil
from lldbtest import *
class TestObjCStepping(TestBase):
@@ -25,17 +26,11 @@ class TestObjCStepping(TestBase):
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
- # Find the line numbers to break inside main().
+ # Find the line numbers that we will step to in main:
self.main_source = "stepping-tests.m"
- self.line1 = line_number(self.main_source, '// Set first breakpoint here.')
- self.line2 = line_number(self.main_source, '// Set second breakpoint here.')
- self.line3 = line_number(self.main_source, '// Set third breakpoint here.')
- self.line4 = line_number(self.main_source, '// Set fourth breakpoint here.')
- self.line5 = line_number(self.main_source, '// Set fifth breakpoint here.')
self.source_randomMethod_line = line_number (self.main_source, '// Source randomMethod start line.')
self.sourceBase_randomMethod_line = line_number (self.main_source, '// SourceBase randomMethod start line.')
self.source_returnsStruct_start_line = line_number (self.main_source, '// Source returnsStruct start line.')
- self.source_returnsStruct_call_line = line_number (self.main_source, '// Source returnsStruct call line.')
self.sourceBase_returnsStruct_start_line = line_number (self.main_source, '// SourceBase returnsStruct start line.')
def objc_stepping(self):
@@ -45,22 +40,23 @@ class TestObjCStepping(TestBase):
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
- break1 = target.BreakpointCreateByLocation(self.main_source, self.line1)
+ self.main_source_spec = lldb.SBFileSpec (self.main_source)
+ break1 = target.BreakpointCreateBySourceRegex ("// Set first breakpoint here.", self.main_source_spec)
self.assertTrue(break1, VALID_BREAKPOINT)
- break2 = target.BreakpointCreateByLocation(self.main_source, self.line2)
+ break2 = target.BreakpointCreateBySourceRegex ("// Set second breakpoint here.", self.main_source_spec)
self.assertTrue(break2, VALID_BREAKPOINT)
- break3 = target.BreakpointCreateByLocation(self.main_source, self.line3)
+ break3 = target.BreakpointCreateBySourceRegex ('// Set third breakpoint here.', self.main_source_spec)
self.assertTrue(break3, VALID_BREAKPOINT)
- break4 = target.BreakpointCreateByLocation(self.main_source, self.line4)
+ break4 = target.BreakpointCreateBySourceRegex ('// Set fourth breakpoint here.', self.main_source_spec)
self.assertTrue(break4, VALID_BREAKPOINT)
- break5 = target.BreakpointCreateByLocation(self.main_source, self.line5)
+ break5 = target.BreakpointCreateBySourceRegex ('// Set fifth breakpoint here.', self.main_source_spec)
self.assertTrue(break5, VALID_BREAKPOINT)
- break_returnStruct_call_super = target.BreakpointCreateByLocation(self.main_source, self.source_returnsStruct_call_line)
+ break_returnStruct_call_super = target.BreakpointCreateBySourceRegex ('// Source returnsStruct call line.', self.main_source_spec)
self.assertTrue(break_returnStruct_call_super, VALID_BREAKPOINT)
# Now launch the process, and do not stop at entry point.
@@ -69,16 +65,11 @@ class TestObjCStepping(TestBase):
self.assertTrue(process, PROCESS_IS_VALID)
# The stop reason of the thread should be breakpoint.
- thread = process.GetThreadAtIndex(0)
- if thread.GetStopReason() != lldb.eStopReasonBreakpoint:
- from lldbutil import stop_reason_to_str
- self.fail(STOPPED_DUE_TO_BREAKPOINT_WITH_STOP_REASON_AS %
- stop_reason_to_str(thread.GetStopReason()))
+ threads = lldbutil.get_threads_stopped_at_breakpoint (process, break1)
+ if len(threads) != 1:
+ self.fail ("Failed to stop at breakpoint 1.")
- # Make sure we stopped at the first breakpoint.
-
- line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
- self.assertTrue (line_number == self.line1, "Hit the first breakpoint.")
+ thread = threads[0]
mySource = thread.GetFrameAtIndex(0).FindVariable("mySource")
self.assertTrue(mySource, "Found mySource local variable.")
@@ -100,18 +91,18 @@ class TestObjCStepping(TestBase):
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod.")
- process.Continue()
- line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
- self.assertTrue (line_number == self.line2, "Continued to second breakpoint in main.")
+ threads = lldbutil.continue_to_breakpoint (process, break2)
+ self.assertTrue (len(threads) == 1, "Continued to second breakpoint in main.")
# Again, step in twice gets us to a stret method and a stret super call:
+ thread = threads[0]
thread.StepInto()
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct.")
- process.Continue()
- line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
- self.assertTrue (line_number == self.source_returnsStruct_call_line, "Stepped to the call super line in Source returnsStruct.")
+ threads = lldbutil.continue_to_breakpoint (process, break_returnStruct_call_super)
+ self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct.")
+ thread = threads[0]
thread.StepInto()
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
@@ -120,10 +111,8 @@ class TestObjCStepping(TestBase):
# Cool now continue to get past the call that intializes the Observer, and then do our steps in again to see that
# we can find our way when we're stepping through a KVO swizzled object.
- process.Continue()
- frame = thread.GetFrameAtIndex(0)
- line_number = frame.GetLineEntry().GetLine()
- self.assertTrue (line_number == self.line3, "Continued to third breakpoint in main, our object should now be swizzled.")
+ threads = lldbutil.continue_to_breakpoint (process, break3)
+ self.assertTrue (len(threads) == 1, "Continued to third breakpoint in main, our object should now be swizzled.")
mySource_isa.GetValue ()
did_change = mySource_isa.GetValueDidChange ()
@@ -131,6 +120,7 @@ class TestObjCStepping(TestBase):
self.assertTrue (did_change, "The isa did indeed change, swizzled!")
# Now step in, that should leave us in the Source randomMethod:
+ thread = threads[0]
thread.StepInto()
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
self.assertTrue (line_number == self.source_randomMethod_line, "Stepped into Source randomMethod in swizzled object.")
@@ -140,18 +130,18 @@ class TestObjCStepping(TestBase):
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
self.assertTrue (line_number == self.sourceBase_randomMethod_line, "Stepped through super into SourceBase randomMethod in swizzled object.")
- process.Continue()
- line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
- self.assertTrue (line_number == self.line4, "Continued to fourth breakpoint in main.")
+ threads = lldbutil.continue_to_breakpoint (process, break4)
+ self.assertTrue (len(threads) == 1, "Continued to fourth breakpoint in main.")
+ thread = threads[0]
# Again, step in twice gets us to a stret method and a stret super call:
thread.StepInto()
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
self.assertTrue (line_number == self.source_returnsStruct_start_line, "Stepped into Source returnsStruct in swizzled object.")
- process.Continue()
- line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
- self.assertTrue (line_number == self.source_returnsStruct_call_line, "Stepped to the call super line in Source returnsStruct - second time.")
+ threads = lldbutil.continue_to_breakpoint(process, break_returnStruct_call_super)
+ self.assertTrue (len(threads) == 1, "Stepped to the call super line in Source returnsStruct - second time.")
+ thread = threads[0]
thread.StepInto()
line_number = thread.GetFrameAtIndex(0).GetLineEntry().GetLine()
OpenPOWER on IntegriCloud