Author: jingham Date: Wed Apr 27 20:40:57 2016 New Revision: 267834 URL: http://llvm.org/viewvc/llvm-project?rev=267834&view=rev Log: Add the ability to limit "source regexp" breakpoints to a particular function within a source file.
This isn't done, I need to make the name match smarter (right now it requires an exact match which is annoying for methods of a class in a namespace. Also, though we use it in tests all over the place, it doesn't look like we have a test for Source Regexp breakpoints by themselves, I'll add that in a follow-on patch. Modified: lldb/trunk/include/lldb/API/SBStringList.h lldb/trunk/include/lldb/API/SBTarget.h lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/scripts/interface/SBTarget.i lldb/trunk/source/API/SBStringList.cpp lldb/trunk/source/API/SBTarget.cpp lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp lldb/trunk/source/Target/Target.cpp Modified: lldb/trunk/include/lldb/API/SBStringList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBStringList.h?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBStringList.h (original) +++ lldb/trunk/include/lldb/API/SBStringList.h Wed Apr 27 20:40:57 2016 @@ -45,6 +45,9 @@ public: const char * GetStringAtIndex (size_t idx); + const char * + GetStringAtIndex (size_t idx) const; + void Clear (); Modified: lldb/trunk/include/lldb/API/SBTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBTarget.h?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/include/lldb/API/SBTarget.h (original) +++ lldb/trunk/include/lldb/API/SBTarget.h Wed Apr 27 20:40:57 2016 @@ -694,6 +694,12 @@ public: const SBFileSpecList &source_file); lldb::SBBreakpoint + BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const SBFileSpecList &source_file, + const SBStringList &func_names); + + lldb::SBBreakpoint BreakpointCreateForException (lldb::LanguageType language, bool catch_bp, bool throw_bp); Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h (original) +++ lldb/trunk/include/lldb/Breakpoint/BreakpointResolverFileRegex.h Wed Apr 27 20:40:57 2016 @@ -12,9 +12,11 @@ // C Includes // C++ Includes +#include <set> // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/ConstString.h" namespace lldb_private { @@ -30,6 +32,7 @@ class BreakpointResolverFileRegex : public: BreakpointResolverFileRegex (Breakpoint *bkpt, RegularExpression ®ex, + const std::unordered_set<std::string> &func_name_set, bool exact_match); ~BreakpointResolverFileRegex() override; @@ -48,6 +51,9 @@ public: void Dump (Stream *s) const override; + + void + AddFunctionName(const char *func_name); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverFileRegex *) { return true; } @@ -61,7 +67,8 @@ public: protected: friend class Breakpoint; RegularExpression m_regex; // This is the line expression that we are looking for. - bool m_exact_match; + bool m_exact_match; // If true, then if the source we match is in a comment, we won't set a location there. + std::unordered_set<std::string> m_function_names; // Limit the search to functions in the comp_unit passed in. private: DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex); Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Wed Apr 27 20:40:57 2016 @@ -797,9 +797,11 @@ public: LazyBool move_to_nearest_code); // Use this to create breakpoint that matches regex against the source lines in files given in source_file_list: + // If function_names is non-empty, also filter by function after the matches are made. lldb::BreakpointSP CreateSourceRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *source_file_list, + const std::unordered_set<std::string> &function_names, RegularExpression &source_regex, bool internal, bool request_hardware, Modified: lldb/trunk/scripts/interface/SBTarget.i URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/interface/SBTarget.i?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/scripts/interface/SBTarget.i (original) +++ lldb/trunk/scripts/interface/SBTarget.i Wed Apr 27 20:40:57 2016 @@ -676,6 +676,12 @@ public: BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpecList &module_list, const lldb::SBFileSpecList &file_list); lldb::SBBreakpoint + BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const SBFileSpecList &source_file, + const SBStringList &func_names); + + lldb::SBBreakpoint BreakpointCreateForException (lldb::LanguageType language, bool catch_bp, bool throw_bp); Modified: lldb/trunk/source/API/SBStringList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBStringList.cpp?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/source/API/SBStringList.cpp (original) +++ lldb/trunk/source/API/SBStringList.cpp Wed Apr 27 20:40:57 2016 @@ -126,6 +126,16 @@ SBStringList::GetStringAtIndex (size_t i return NULL; } +const char * +SBStringList::GetStringAtIndex (size_t idx) const +{ + if (IsValid()) + { + return m_opaque_ap->GetStringAtIndex (idx); + } + return NULL; +} + void SBStringList::Clear () { Modified: lldb/trunk/source/API/SBTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBTarget.cpp?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/source/API/SBTarget.cpp (original) +++ lldb/trunk/source/API/SBTarget.cpp Wed Apr 27 20:40:57 2016 @@ -22,6 +22,7 @@ #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBProcess.h" #include "lldb/API/SBStream.h" +#include "lldb/API/SBStringList.h" #include "lldb/API/SBSymbolContextList.h" #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointIDList.h" @@ -1124,42 +1125,21 @@ SBTarget::BreakpointCreateBySourceRegex const lldb::SBFileSpec &source_file, const char *module_name) { - Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); - - SBBreakpoint sb_bp; - TargetSP target_sp(GetSP()); - if (target_sp && source_regex && source_regex[0]) - { - Mutex::Locker api_locker (target_sp->GetAPIMutex()); - RegularExpression regexp(source_regex); - FileSpecList source_file_spec_list; - const bool hardware = false; - const LazyBool move_to_nearest_code = eLazyBoolCalculate; - source_file_spec_list.Append (source_file.ref()); + SBFileSpecList module_spec_list; if (module_name && module_name[0]) { - FileSpecList module_spec_list; module_spec_list.Append (FileSpec (module_name, false)); - - *sb_bp = target_sp->CreateSourceRegexBreakpoint (&module_spec_list, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code); } - else + + SBFileSpecList source_file_list; + if (source_file.IsValid()) { - *sb_bp = target_sp->CreateSourceRegexBreakpoint (NULL, &source_file_spec_list, regexp, false, hardware, move_to_nearest_code); + source_file_list.Append(source_file); } - } - - 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)", - static_cast<void*>(target_sp.get()), source_regex, path, - module_name, static_cast<void*>(sb_bp.get())); - } + + return BreakpointCreateBySourceRegex (source_regex, module_spec_list, source_file_list); - return sb_bp; } lldb::SBBreakpoint @@ -1167,6 +1147,15 @@ SBTarget::BreakpointCreateBySourceRegex const SBFileSpecList &module_list, const lldb::SBFileSpecList &source_file_list) { + return BreakpointCreateBySourceRegex(source_regex, module_list, source_file_list, SBStringList()); +} + +lldb::SBBreakpoint +SBTarget::BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const lldb::SBFileSpecList &source_file_list, + const SBStringList &func_names) +{ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -1177,7 +1166,19 @@ SBTarget::BreakpointCreateBySourceRegex const bool hardware = false; const LazyBool move_to_nearest_code = eLazyBoolCalculate; RegularExpression regexp(source_regex); - *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), source_file_list.get(), regexp, false, hardware, move_to_nearest_code); + std::unordered_set<std::string> func_names_set; + for (size_t i = 0; i < func_names.GetSize(); i++) + { + func_names_set.insert(func_names.GetStringAtIndex(i)); + } + + *sb_bp = target_sp->CreateSourceRegexBreakpoint (module_list.get(), + source_file_list.get(), + func_names_set, + regexp, + false, + hardware, + move_to_nearest_code); } if (log) Modified: lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp (original) +++ lldb/trunk/source/Breakpoint/BreakpointResolverFileRegex.cpp Wed Apr 27 20:40:57 2016 @@ -30,11 +30,13 @@ BreakpointResolverFileRegex::BreakpointR ( Breakpoint *bkpt, RegularExpression ®ex, + const std::unordered_set<std::string> &func_names, bool exact_match ) : BreakpointResolver (bkpt, BreakpointResolver::FileLineResolver), m_regex (regex), - m_exact_match (exact_match) + m_exact_match (exact_match), + m_function_names(func_names) { } @@ -68,6 +70,32 @@ BreakpointResolverFileRegex::SearchCallb const bool search_inlines = false; cu->ResolveSymbolContext (cu_file_spec, line_matches[i], search_inlines, m_exact_match, eSymbolContextEverything, sc_list); + // Find all the function names: + if (!m_function_names.empty()) + { + std::vector<size_t> sc_to_remove; + for (size_t i = 0; i < sc_list.GetSize(); i++) + { + SymbolContext sc_ctx; + sc_list.GetContextAtIndex(i, sc_ctx); + std::string name(sc_ctx.GetFunctionName(Mangled::NamePreference::ePreferDemangledWithoutArguments).AsCString()); + if (!m_function_names.count(name)) + { + sc_to_remove.push_back(i); + } + } + + if (!sc_to_remove.empty()) + { + std::vector<size_t>::reverse_iterator iter; + std::vector<size_t>::reverse_iterator rend = sc_to_remove.rend(); + for (iter = sc_to_remove.rbegin(); iter != rend; iter++) + { + sc_list.RemoveContextAtIndex(*iter); + } + } + } + const bool skip_prologue = true; BreakpointResolver::SetSCMatchesByLine (filter, sc_list, skip_prologue, m_regex.GetText()); @@ -98,7 +126,13 @@ BreakpointResolverFileRegex::Dump (Strea lldb::BreakpointResolverSP BreakpointResolverFileRegex::CopyForBreakpoint (Breakpoint &breakpoint) { - lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_exact_match)); + lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileRegex(&breakpoint, m_regex, m_function_names, m_exact_match)); return ret_sp; } +void +BreakpointResolverFileRegex::AddFunctionName(const char *func_name) +{ + m_function_names.insert(func_name); +} + Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Wed Apr 27 20:40:57 2016 @@ -342,6 +342,10 @@ public: error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); break; + case 'X': + m_source_regex_func_names.insert(option_arg); + break; + default: error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option); break; @@ -381,6 +385,7 @@ public: m_all_files = false; m_exception_extra_args.Clear(); m_move_to_nearest_code = eLazyBoolCalculate; + m_source_regex_func_names.clear(); } const OptionDefinition* @@ -423,6 +428,7 @@ public: bool m_all_files; Args m_exception_extra_args; LazyBool m_move_to_nearest_code; + std::unordered_set<std::string> m_source_regex_func_names; }; protected: @@ -608,6 +614,7 @@ protected: } bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), + m_options.m_source_regex_func_names, regexp, internal, m_options.m_hardware, @@ -805,6 +812,9 @@ CommandObjectBreakpointSet::CommandOptio { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make one breakpoint for multiple names" }, + { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, + "When used with '-p' limits the source regex to source contained in the named functions. Can be repeated multiple times." }, + { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means namespaces and all arguments, and " "for Objective C this means a full function prototype with class and selector. " @@ -855,7 +865,7 @@ CommandObjectBreakpointSet::CommandOptio "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, - "Adds this to the list of names for this breakopint."}, + "Adds this to the list of names for this breakpoint."}, { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=267834&r1=267833&r2=267834&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Wed Apr 27 20:40:57 2016 @@ -326,6 +326,7 @@ Target::GetBreakpointByID (break_id_t br BreakpointSP Target::CreateSourceRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *source_file_spec_list, + const std::unordered_set<std::string> &function_names, RegularExpression &source_regex, bool internal, bool hardware, @@ -334,7 +335,11 @@ Target::CreateSourceRegexBreakpoint (con SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, source_file_spec_list)); if (move_to_nearest_code == eLazyBoolCalculate) move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; - BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, source_regex, !static_cast<bool>(move_to_nearest_code))); + BreakpointResolverSP resolver_sp(new BreakpointResolverFileRegex(nullptr, + source_regex, + function_names, + !static_cast<bool>(move_to_nearest_code))); + return CreateBreakpoint (filter_sp, resolver_sp, internal, hardware, true); } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits