summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBTarget.h12
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointResolverName.h10
-rw-r--r--lldb/include/lldb/Target/LanguageRuntime.h6
-rw-r--r--lldb/include/lldb/Target/Target.h8
-rw-r--r--lldb/include/lldb/lldb-defines.h1
-rw-r--r--lldb/include/lldb/lldb-enumerations.h3
-rw-r--r--lldb/scripts/Python/interface/SBTarget.i12
-rw-r--r--lldb/source/API/SBTarget.cpp72
-rw-r--r--lldb/source/Breakpoint/Breakpoint.cpp5
-rw-r--r--lldb/source/Breakpoint/BreakpointResolverName.cpp18
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp101
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.h8
-rw-r--r--lldb/source/Interpreter/CommandObject.cpp1
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp3
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp4
-rw-r--r--lldb/source/Target/LanguageRuntime.cpp52
-rw-r--r--lldb/source/Target/Target.cpp25
-rw-r--r--lldb/tools/driver/Driver.cpp3
18 files changed, 317 insertions, 27 deletions
diff --git a/lldb/include/lldb/API/SBTarget.h b/lldb/include/lldb/API/SBTarget.h
index 98a2712c2bf..2e5ed6d2a17 100644
--- a/lldb/include/lldb/API/SBTarget.h
+++ b/lldb/include/lldb/API/SBTarget.h
@@ -623,6 +623,13 @@ public:
const SBFileSpecList &comp_unit_list);
lldb::SBBreakpoint
+ BreakpointCreateByNames (const char *symbol_name[],
+ uint32_t num_names,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
lldb::SBBreakpoint
@@ -639,6 +646,11 @@ public:
BreakpointCreateBySourceRegex (const char *source_regex,
const SBFileSpecList &module_list,
const lldb::SBFileSpecList &source_file);
+
+ lldb::SBBreakpoint
+ BreakpointCreateForException (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp);
lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
diff --git a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
index 6804b9c226f..8a76233b47b 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointResolverName.h
@@ -12,6 +12,8 @@
// C Includes
// C++ Includes
+#include <vector>
+#include <string>
// Other libraries and framework includes
// Project includes
#include "lldb/Breakpoint/BreakpointResolver.h"
@@ -35,13 +37,19 @@ public:
Breakpoint::MatchType type,
bool skip_prologue);
- // This one takes an array of names. It is always MatchType = Name.
+ // This one takes an array of names. It is always MatchType = Exact.
BreakpointResolverName (Breakpoint *bkpt,
const char *names[],
size_t num_names,
uint32_t name_type_mask,
bool skip_prologue);
+ // This one takes a C++ array of names. It is always MatchType = Exact.
+ BreakpointResolverName (Breakpoint *bkpt,
+ std::vector<std::string> names,
+ uint32_t name_type_mask,
+ bool skip_prologue);
+
// Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex.
BreakpointResolverName (Breakpoint *bkpt,
RegularExpression &func_regex,
diff --git a/lldb/include/lldb/Target/LanguageRuntime.h b/lldb/include/lldb/Target/LanguageRuntime.h
index 368806e9838..9d56fee86e9 100644
--- a/lldb/include/lldb/Target/LanguageRuntime.h
+++ b/lldb/include/lldb/Target/LanguageRuntime.h
@@ -77,6 +77,12 @@ public:
bool catch_bp,
bool throw_bp,
bool is_internal = false);
+
+ static lldb::LanguageType
+ GetLanguageTypeFromString (const char *string);
+
+ static const char *
+ GetNameForLanguageType (lldb::LanguageType language);
protected:
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 5b7f36c7fb1..f06c72b9bf3 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -484,6 +484,14 @@ public:
bool internal = false,
LazyBool skip_prologue = eLazyBoolCalculate);
+ lldb::BreakpointSP
+ CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ std::vector<std::string> func_names,
+ uint32_t func_name_type_mask,
+ bool internal = false,
+ LazyBool skip_prologue = eLazyBoolCalculate);
+
// Use this to create a general breakpoint:
lldb::BreakpointSP
diff --git a/lldb/include/lldb/lldb-defines.h b/lldb/include/lldb/lldb-defines.h
index 42474b6b996..447237121f6 100644
--- a/lldb/include/lldb/lldb-defines.h
+++ b/lldb/include/lldb/lldb-defines.h
@@ -102,6 +102,7 @@
#define LLDB_OPT_SET_7 (1U << 6)
#define LLDB_OPT_SET_8 (1U << 7)
#define LLDB_OPT_SET_9 (1U << 8)
+#define LLDB_OPT_SET_10 (1U << 9)
#if defined(__cplusplus)
diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 8e1f0e9f299..9c3a8c2e487 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -301,6 +301,8 @@ namespace lldb {
///
/// These enumerations use the same language enumerations as the DWARF
/// specification for ease of use and consistency.
+ /// The enum -> string code is in LanguageRuntime.cpp, don't change this
+ /// table without updating that code as well.
//----------------------------------------------------------------------
typedef enum LanguageType
{
@@ -373,6 +375,7 @@ namespace lldb {
eArgTypeFunctionName,
eArgTypeGDBFormat,
eArgTypeIndex,
+ eArgTypeLanguage,
eArgTypeLineNum,
eArgTypeLogCategory,
eArgTypeLogChannel,
diff --git a/lldb/scripts/Python/interface/SBTarget.i b/lldb/scripts/Python/interface/SBTarget.i
index a66131bf77f..b6333d44d9f 100644
--- a/lldb/scripts/Python/interface/SBTarget.i
+++ b/lldb/scripts/Python/interface/SBTarget.i
@@ -596,12 +596,24 @@ public:
const SBFileSpecList &comp_unit_list);
lldb::SBBreakpoint
+ BreakpointCreateByNames (const char *symbol_name[],
+ uint32_t num_names,
+ uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list);
+
+ lldb::SBBreakpoint
BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = NULL);
lldb::SBBreakpoint
BreakpointCreateBySourceRegex (const char *source_regex, const lldb::SBFileSpec &source_file, const char *module_name = NULL);
lldb::SBBreakpoint
+ BreakpointCreateForException (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp);
+
+ lldb::SBBreakpoint
BreakpointCreateByAddress (addr_t address);
uint32_t
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index d4810f580db..8f8d75ec6db 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -41,6 +41,7 @@
#include "lldb/Interpreter/Args.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
+#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/TargetList.h"
@@ -1237,6 +1238,49 @@ SBTarget::BreakpointCreateByName (const char *symbol_name,
return sb_bp;
}
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateByNames (const char *symbol_names[],
+ uint32_t num_names,
+ uint32_t name_type_mask,
+ const SBFileSpecList &module_list,
+ const SBFileSpecList &comp_unit_list)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ SBBreakpoint sb_bp;
+ TargetSP target_sp(GetSP());
+ if (target_sp && num_names > 0)
+ {
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ *sb_bp = target_sp->CreateBreakpoint (module_list.get(),
+ comp_unit_list.get(),
+ symbol_names,
+ num_names,
+ name_type_mask,
+ false);
+ }
+
+ if (log)
+ {
+ log->Printf ("SBTarget(%p)::BreakpointCreateByName (symbols={", target_sp.get());
+ for (uint32_t i = 0 ; i < num_names; i++)
+ {
+ char sep;
+ if (i < num_names - 1)
+ sep = ',';
+ else
+ sep = '}';
+ if (symbol_names[i] != NULL)
+ log->Printf ("\"%s\"%c ", symbol_names[i], sep);
+ else
+ log->Printf ("\"<NULL>\"%c ", sep);
+
+ }
+ log->Printf ("name_type: %d) => SBBreakpoint(%p)", name_type_mask, sb_bp.get());
+ }
+
+ return sb_bp;
+}
SBBreakpoint
SBTarget::BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name)
@@ -1382,6 +1426,34 @@ SBTarget::BreakpointCreateBySourceRegex (const char *source_regex,
return sb_bp;
}
+lldb::SBBreakpoint
+SBTarget::BreakpointCreateForException (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp)
+{
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+
+ SBBreakpoint sb_bp;
+ TargetSP target_sp(GetSP());
+ if (target_sp)
+ {
+ Mutex::Locker api_locker (target_sp->GetAPIMutex());
+ *sb_bp = target_sp->CreateExceptionBreakpoint (language, catch_bp, throw_bp);
+ }
+
+ if (log)
+ {
+ log->Printf ("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: %s throw: %s) => SBBreakpoint(%p)",
+ target_sp.get(),
+ LanguageRuntime::GetNameForLanguageType(language),
+ catch_bp ? "on" : "off",
+ throw_bp ? "on" : "off",
+ sb_bp.get());
+ }
+
+ return sb_bp;
+}
+
uint32_t
SBTarget::GetNumBreakpoints () const
{
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index 4d37a7a7edd..7a897661e76 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -487,7 +487,10 @@ Breakpoint::GetDescription (Stream *s, lldb::DescriptionLevel level, bool show_l
}
else
{
- s->Printf(", locations = 0 (pending)");
+ // Don't print the pending notification for exception resolvers since we don't generally
+ // know how to set them until the target is run.
+ if (m_resolver_sp->getResolverID() != BreakpointResolver::ExceptionResolver)
+ s->Printf(", locations = 0 (pending)");
}
GetOptions()->GetDescription(s, level);
diff --git a/lldb/source/Breakpoint/BreakpointResolverName.cpp b/lldb/source/Breakpoint/BreakpointResolverName.cpp
index 7b7e7a4f8d0..616307a0906 100644
--- a/lldb/source/Breakpoint/BreakpointResolverName.cpp
+++ b/lldb/source/Breakpoint/BreakpointResolverName.cpp
@@ -61,6 +61,7 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
bool skip_prologue) :
BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
m_func_name_type_mask (name_type_mask),
+ m_match_type (Breakpoint::Exact),
m_skip_prologue (skip_prologue)
{
for (size_t i = 0; i < num_names; i++)
@@ -69,6 +70,23 @@ BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
}
}
+BreakpointResolverName::BreakpointResolverName (Breakpoint *bkpt,
+ std::vector<std::string> names,
+ uint32_t name_type_mask,
+ bool skip_prologue) :
+ BreakpointResolver (bkpt, BreakpointResolver::NameResolver),
+ m_func_name_type_mask (name_type_mask),
+ m_match_type (Breakpoint::Exact),
+ m_skip_prologue (skip_prologue)
+{
+ size_t num_names = names.size();
+
+ for (size_t i = 0; i < num_names; i++)
+ {
+ m_func_names.push_back (ConstString (names[i].c_str()));
+ }
+}
+
BreakpointResolverName::BreakpointResolverName
(
Breakpoint *bkpt,
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index d3a110ca654..a23e43c29a6 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -53,8 +53,8 @@ CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &i
m_line_num (0),
m_column (0),
m_check_inlines (true),
- m_func_name (),
- m_func_name_type_mask (0),
+ m_func_names (),
+ m_func_name_type_mask (eFunctionNameTypeNone),
m_func_regexp (),
m_source_text_regexp(),
m_modules (),
@@ -63,7 +63,10 @@ CommandObjectBreakpointSet::CommandOptions::CommandOptions(CommandInterpreter &i
m_thread_id(LLDB_INVALID_THREAD_ID),
m_thread_index (UINT32_MAX),
m_thread_name(),
- m_queue_name()
+ m_queue_name(),
+ m_catch_bp (false),
+ m_throw_bp (false),
+ m_language (eLanguageTypeUnknown)
{
}
@@ -71,12 +74,13 @@ CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
{
}
-#define LLDB_OPT_FILE (LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5 | LLDB_OPT_SET_6 | LLDB_OPT_SET_7 | LLDB_OPT_SET_8 | LLDB_OPT_SET_9 )
+#define LLDB_OPT_FILE ( LLDB_OPT_SET_1 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5 | LLDB_OPT_SET_6 | LLDB_OPT_SET_7 | LLDB_OPT_SET_8 | LLDB_OPT_SET_9 )
+#define LLDB_OPT_NOT_10 ( LLDB_OPT_SET_ALL & ~LLDB_OPT_SET_10 )
OptionDefinition
CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
+ { LLDB_OPT_NOT_10, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
"Set the breakpoint only in this shared library (can use this option multiple times for multiple shlibs)."},
{ LLDB_OPT_SET_ALL, false, "ignore-count", 'i', required_argument, NULL, 0, eArgTypeCount,
@@ -130,6 +134,14 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ 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." },
+ { LLDB_OPT_SET_10, true, "language-exception", 'E', required_argument, NULL, 0, eArgTypeLanguage,
+ "Set the breakpoint on exceptions thrown by the specified language (without options, on throw but not catch.)" },
+
+ { LLDB_OPT_SET_10, false, "on-throw", 'w', required_argument, NULL, 0, eArgTypeBoolean,
+ "Set the breakpoint on exception throW." },
+
+ { LLDB_OPT_SET_10, false, "on-catch", 'h', required_argument, NULL, 0, eArgTypeBoolean,
+ "Set the breakpoint on exception catcH." },
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
@@ -170,27 +182,27 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
break;
case 'b':
- m_func_name.assign (option_arg);
+ m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeBase;
break;
case 'n':
- m_func_name.assign (option_arg);
+ m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeAuto;
break;
case 'F':
- m_func_name.assign (option_arg);
+ m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeFull;
break;
case 'S':
- m_func_name.assign (option_arg);
+ m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeSelector;
break;
case 'M':
- m_func_name.assign (option_arg);
+ m_func_names.push_back (option_arg);
m_func_name_type_mask |= eFunctionNameTypeMethod;
break;
@@ -235,6 +247,50 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (uint32_t option_idx,
}
break;
+ case 'E':
+ {
+ LanguageType language = LanguageRuntime::GetLanguageTypeFromString (option_arg);
+
+ switch (language)
+ {
+ case eLanguageTypeC89:
+ case eLanguageTypeC:
+ case eLanguageTypeC99:
+ m_language = eLanguageTypeC;
+ break;
+ case eLanguageTypeC_plus_plus:
+ m_language = eLanguageTypeC_plus_plus;
+ break;
+ case eLanguageTypeObjC:
+ m_language = eLanguageTypeObjC;
+ break;
+ case eLanguageTypeObjC_plus_plus:
+ error.SetErrorStringWithFormat ("Set exception breakpoints separately for c++ and objective-c");
+ break;
+ case eLanguageTypeUnknown:
+ error.SetErrorStringWithFormat ("Unknown language type: '%s' for exception breakpoint", option_arg);
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unsupported language type: '%s' for exception breakpoint", option_arg);
+ }
+ }
+ break;
+ case 'w':
+ {
+ bool success;
+ m_throw_bp = Args::StringToBoolean (option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat ("Invalid boolean value for on-throw option: '%s'", option_arg);
+ }
+ break;
+ case 'h':
+ {
+ bool success;
+ m_catch_bp = Args::StringToBoolean (option_arg, true, &success);
+ if (!success)
+ error.SetErrorStringWithFormat ("Invalid boolean value for on-catch option: '%s'", option_arg);
+ }
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -249,7 +305,7 @@ CommandObjectBreakpointSet::CommandOptions::OptionParsingStarting ()
m_filenames.Clear();
m_line_num = 0;
m_column = 0;
- m_func_name.clear();
+ m_func_names.clear();
m_func_name_type_mask = 0;
m_func_regexp.clear();
m_load_addr = LLDB_INVALID_ADDRESS;
@@ -259,6 +315,9 @@ CommandObjectBreakpointSet::CommandOptions::OptionParsingStarting ()
m_thread_index = UINT32_MAX;
m_thread_name.clear();
m_queue_name.clear();
+ m_language = eLanguageTypeUnknown;
+ m_catch_bp = false;
+ m_throw_bp = true;
}
//-------------------------------------------------------------------------
@@ -345,6 +404,7 @@ CommandObjectBreakpointSet::Execute
// 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)
+ // 6). -E [-w -h] (setting a breakpoint for exceptions for a given language.)
BreakpointSetType break_type = eSetTypeInvalid;
@@ -352,12 +412,14 @@ CommandObjectBreakpointSet::Execute
break_type = eSetTypeFileAndLine;
else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS)
break_type = eSetTypeAddress;
- else if (!m_options.m_func_name.empty())
+ else if (!m_options.m_func_names.empty())
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;
+ else if (m_options.m_language != eLanguageTypeUnknown)
+ break_type = eSetTypeException;
Breakpoint *bp = NULL;
FileSpec module_spec;
@@ -408,11 +470,11 @@ CommandObjectBreakpointSet::Execute
if (name_type_mask == 0)
name_type_mask = eFunctionNameTypeAuto;
-
+
bp = target->CreateBreakpoint (&(m_options.m_modules),
&(m_options.m_filenames),
- m_options.m_func_name.c_str(),
- name_type_mask,
+ m_options.m_func_names,
+ name_type_mask,
Breakpoint::Exact).get();
}
break;
@@ -465,6 +527,11 @@ CommandObjectBreakpointSet::Execute
bp = target->CreateSourceRegexBreakpoint (&(m_options.m_modules), &(m_options.m_filenames), regexp).get();
}
break;
+ case eSetTypeException:
+ {
+ bp = target->CreateExceptionBreakpoint (m_options.m_language, m_options.m_catch_bp, m_options.m_throw_bp).get();
+ }
+ break;
default:
break;
}
@@ -494,7 +561,9 @@ CommandObjectBreakpointSet::Execute
output_stream.Printf ("Breakpoint created: ");
bp->GetDescription(&output_stream, lldb::eDescriptionLevelBrief);
output_stream.EOL();
- if (bp->GetNumLocations() == 0)
+ // Don't print out this warning for exception breakpoints. They can get set before the target
+ // is set, but we won't know how to actually set the breakpoint till we run.
+ if (bp->GetNumLocations() == 0 && break_type != eSetTypeException)
output_stream.Printf ("WARNING: Unable to resolve breakpoint to any actual locations.\n");
result.SetStatus (eReturnStatusSuccessFinishResult);
}
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index b032319d167..df96b04c66a 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -58,7 +58,8 @@ public:
eSetTypeAddress,
eSetTypeFunctionName,
eSetTypeFunctionRegexp,
- eSetTypeSourceRegexp
+ eSetTypeSourceRegexp,
+ eSetTypeException
} BreakpointSetType;
CommandObjectBreakpointSet (CommandInterpreter &interpreter);
@@ -101,7 +102,7 @@ public:
uint32_t m_line_num;
uint32_t m_column;
bool m_check_inlines;
- std::string m_func_name;
+ std::vector<std::string> m_func_names;
uint32_t m_func_name_type_mask;
std::string m_func_regexp;
std::string m_source_text_regexp;
@@ -112,6 +113,9 @@ public:
uint32_t m_thread_index;
std::string m_thread_name;
std::string m_queue_name;
+ bool m_catch_bp;
+ bool m_throw_bp;
+ lldb::LanguageType m_language;
};
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index 9502ad9619e..a087eca1eec 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -870,6 +870,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeFunctionName, "function-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a function." },
{ eArgTypeGDBFormat, "gdb-format", CommandCompletions::eNoCompletion, { GDBFormatHelpTextCallback, true }, NULL },
{ eArgTypeIndex, "index", CommandCompletions::eNoCompletion, { NULL, false }, "An index into a list." },
+ { eArgTypeLanguage, "language", CommandCompletions::eNoCompletion, { NULL, false }, "A source language name." },
{ eArgTypeLineNum, "linenum", CommandCompletions::eNoCompletion, { NULL, false }, "Line number in a source file." },
{ eArgTypeLogCategory, "log-category", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a category within a log channel, e.g. all (try \"log list\" to see a list of all channels and their categories." },
{ eArgTypeLogChannel, "log-channel", CommandCompletions::eNoCompletion, { NULL, false }, "The name of a log channel, e.g. process.gdb-remote (try \"log list\" to see a list of all channels and their categories)." },
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 09dc6d135e7..a811710c1a8 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -109,12 +109,13 @@ AppleObjCRuntimeV1::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
{
BreakpointResolverSP resolver_sp;
- if (catch_bp && throw_bp)
+ if (throw_bp)
resolver_sp.reset (new BreakpointResolverName (bkpt,
"objc_exception_throw",
eFunctionNameTypeBase,
Breakpoint::Exact,
eLazyBoolNo));
+ // FIXME: don't do catch yet.
return resolver_sp;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 2134f3b2656..eccec263fb8 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -449,12 +449,14 @@ AppleObjCRuntimeV2::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bo
{
BreakpointResolverSP resolver_sp;
- if (catch_bp && throw_bp)
+ if (throw_bp)
resolver_sp.reset (new BreakpointResolverName (bkpt,
"objc_exception_throw",
eFunctionNameTypeBase,
Breakpoint::Exact,
eLazyBoolNo));
+ // FIXME: We don't do catch breakpoints for ObjC yet.
+ // Should there be some way for the runtime to specify what it can do in this regard?
return resolver_sp;
}
diff --git a/lldb/source/Target/LanguageRuntime.cpp b/lldb/source/Target/LanguageRuntime.cpp
index b6a9a5793b4..3891d81d167 100644
--- a/lldb/source/Target/LanguageRuntime.cpp
+++ b/lldb/source/Target/LanguageRuntime.cpp
@@ -69,7 +69,7 @@ LanguageRuntime::ExceptionBreakpointResolver::ExceptionBreakpointResolver (Break
LanguageType language,
bool catch_bp,
bool throw_bp) :
- BreakpointResolver (bkpt, ExceptionResolver),
+ BreakpointResolver (bkpt, BreakpointResolver::ExceptionResolver),
m_language (language),
m_catch_bp (catch_bp),
m_throw_bp (throw_bp)
@@ -80,7 +80,7 @@ LanguageRuntime::ExceptionBreakpointResolver::ExceptionBreakpointResolver (Break
void
LanguageRuntime::ExceptionBreakpointResolver::GetDescription (Stream *s)
{
- s->Printf ("Exception breakpoint (catch: %s throw: %s) using: ",
+ s->Printf ("Exception breakpoint (catch: %s throw: %s)",
m_catch_bp ? "on" : "off",
m_throw_bp ? "on" : "off");
@@ -91,7 +91,7 @@ LanguageRuntime::ExceptionBreakpointResolver::GetDescription (Stream *s)
m_actual_resolver_sp->GetDescription (s);
}
else
- s->Printf (".");
+ s->Printf (" the correct runtime exception handler will be determined when you run");
}
bool
@@ -162,3 +162,49 @@ LanguageRuntime::ExceptionBreakpointResolver::GetDepth ()
return m_actual_resolver_sp->GetDepth();
}
+static const char *language_names[] =
+{
+ "unknown",
+ "c89",
+ "c",
+ "ada83",
+ "c++",
+ "cobol74",
+ "cobol85",
+ "fortran77",
+ "fortran90",
+ "pascal83",
+ "modula2",
+ "java",
+ "c99",
+ "ada95",
+ "fortran95",
+ "pli",
+ "objective-c",
+ "objective-c++",
+ "upc",
+ "d",
+ "python"
+};
+static uint32_t num_languages = sizeof(language_names) / sizeof (char *);
+
+LanguageType
+LanguageRuntime::GetLanguageTypeFromString (const char *string)
+{
+ for (uint32_t i = 0; i < num_languages; i++)
+ {
+ if (strcmp (language_names[i], string) == 0)
+ return (LanguageType) i;
+ }
+ return eLanguageTypeUnknown;
+}
+
+const char *
+LanguageRuntime::GetNameForLanguageType (LanguageType language)
+{
+ if (language < num_languages)
+ return language_names[language];
+ else
+ return language_names[eLanguageTypeUnknown];
+}
+
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index f3b8a7832ab..ae69e5d3b6a 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -287,6 +287,29 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
return bp_sp;
}
+lldb::BreakpointSP
+Target::CreateBreakpoint (const FileSpecList *containingModules,
+ const FileSpecList *containingSourceFiles,
+ std::vector<std::string> func_names,
+ uint32_t func_name_type_mask,
+ bool internal,
+ LazyBool skip_prologue)
+{
+ BreakpointSP bp_sp;
+ size_t num_names = func_names.size();
+ if (num_names > 0)
+ {
+ SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList (containingModules, containingSourceFiles));
+
+ BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
+ func_names,
+ func_name_type_mask,
+ skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
+ bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
+ }
+ return bp_sp;
+}
+
BreakpointSP
Target::CreateBreakpoint (const FileSpecList *containingModules,
const FileSpecList *containingSourceFiles,
@@ -304,7 +327,7 @@ Target::CreateBreakpoint (const FileSpecList *containingModules,
BreakpointResolverSP resolver_sp (new BreakpointResolverName (NULL,
func_names,
num_names,
- func_name_type_mask,
+ func_name_type_mask,
skip_prologue == eLazyBoolCalculate ? GetSkipPrologue() : skip_prologue));
bp_sp = CreateBreakpoint (filter_sp, resolver_sp, internal);
}
diff --git a/lldb/tools/driver/Driver.cpp b/lldb/tools/driver/Driver.cpp
index 17bb0e2b320..63844af8afd 100644
--- a/lldb/tools/driver/Driver.cpp
+++ b/lldb/tools/driver/Driver.cpp
@@ -850,8 +850,9 @@ Driver::HandleBreakpointEvent (const SBEvent &event)
if (num_new_locations > 0)
{
SBBreakpoint breakpoint = SBBreakpoint::GetBreakpointFromEvent(event);
- int message_len = ::snprintf (message, sizeof(message), "%d locations added to breakpoint %d\n",
+ int message_len = ::snprintf (message, sizeof(message), "%d location%s added to breakpoint %d\n",
num_new_locations,
+ num_new_locations == 1 ? " " : "s ",
breakpoint.GetID());
m_io_channel_ap->OutWrite(message, message_len, ASYNC);
}
OpenPOWER on IntegriCloud