summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorJim Ingham <jingham@apple.com>2016-04-28 01:40:57 +0000
committerJim Ingham <jingham@apple.com>2016-04-28 01:40:57 +0000
commit76bb8d6719c2f664a69c4e2e89664c230f807a3b (patch)
tree23cecaf99000645d1da0f8027fa7b2cd61e843ae /lldb/source
parent8bdcd522510f923185cdfaec66c4a78d0a0d38c0 (diff)
downloadbcm5719-llvm-76bb8d6719c2f664a69c4e2e89664c230f807a3b.tar.gz
bcm5719-llvm-76bb8d6719c2f664a69c4e2e89664c230f807a3b.zip
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. llvm-svn: 267834
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/API/SBStringList.cpp10
-rw-r--r--lldb/source/API/SBTarget.cpp59
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp38
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp12
-rw-r--r--lldb/source/Target/Target.cpp7
5 files changed, 93 insertions, 33 deletions
diff --git a/lldb/source/API/SBStringList.cpp b/lldb/source/API/SBStringList.cpp
index 129d2f4c11f..f469bc4336f 100644
--- a/lldb/source/API/SBStringList.cpp
+++ b/lldb/source/API/SBStringList.cpp
@@ -126,6 +126,16 @@ SBStringList::GetStringAtIndex (size_t idx)
return NULL;
}
+const char *
+SBStringList::GetStringAtIndex (size_t idx) const
+{
+ if (IsValid())
+ {
+ return m_opaque_ap->GetStringAtIndex (idx);
+ }
+ return NULL;
+}
+
void
SBStringList::Clear ()
{
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 2ef8bcdf39a..220e136430d 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -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 char *source_regex,
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 char *source_regex,
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 char *source_regex,
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)
diff --git a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
index e7bce0524c5..ae7f58acb91 100644
--- a/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp
@@ -30,11 +30,13 @@ BreakpointResolverFileRegex::BreakpointResolverFileRegex
(
Breakpoint *bkpt,
RegularExpression &regex,
+ 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::SearchCallback
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 (Stream *s) const
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);
+}
+
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index 8d4ec9535ff..b7ed2a2547c 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -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::CommandOptions::g_option_table[] =
{ 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::CommandOptions::g_option_table[] =
"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. "
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 6edb1450872..cae0a8d49a9 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -326,6 +326,7 @@ Target::GetBreakpointByID (break_id_t break_id)
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 (const FileSpecList *containingModules,
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);
}
OpenPOWER on IntegriCloud