forked from OSchip/llvm-project
Add a new breakpoint type "break by source regular expression".
Fix the RegularExpression class so it has a real copy constructor. Fix the breakpoint setting with multiple shared libraries so it makes one breakpoint not one per shared library. Add SBFileSpecList, to be used to expose the above to the SB interface (not done yet.) llvm-svn: 140225
This commit is contained in:
parent
699128e58a
commit
969795f14b
|
@ -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:
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
private:
|
||||
friend class SBBlock;
|
||||
friend class SBCompileUnit;
|
||||
friend class SBFileSpecList;
|
||||
friend class SBHostOS;
|
||||
friend class SBLineEntry;
|
||||
friend class SBModule;
|
||||
|
|
|
@ -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_
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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 ®ex);
|
||||
|
||||
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_
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
|
@ -371,6 +371,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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 ()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ®ex
|
||||
) :
|
||||
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
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -104,7 +104,6 @@ BreakpointResolverName::BreakpointResolverName
|
|||
m_match_type (Breakpoint::Regexp),
|
||||
m_skip_prologue (skip_prologue)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BreakpointResolverName::BreakpointResolverName
|
||||
|
|
|
@ -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;
|
||||
|
@ -274,6 +283,52 @@ CommandObjectBreakpointSet::GetOptions ()
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
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
|
||||
(
|
||||
|
@ -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: ");
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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,12 +32,42 @@ 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
|
||||
//
|
||||
|
@ -60,10 +91,18 @@ RegularExpression::~RegularExpression()
|
|||
// True of the refular expression compiles successfully, false
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue