diff options
-rw-r--r-- | lldb/include/lldb/API/SBTarget.h | 12 | ||||
-rw-r--r-- | lldb/include/lldb/Breakpoint/BreakpointResolverName.h | 10 | ||||
-rw-r--r-- | lldb/include/lldb/Target/LanguageRuntime.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Target.h | 8 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-defines.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 3 | ||||
-rw-r--r-- | lldb/scripts/Python/interface/SBTarget.i | 12 | ||||
-rw-r--r-- | lldb/source/API/SBTarget.cpp | 72 | ||||
-rw-r--r-- | lldb/source/Breakpoint/Breakpoint.cpp | 5 | ||||
-rw-r--r-- | lldb/source/Breakpoint/BreakpointResolverName.cpp | 18 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.cpp | 101 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectBreakpoint.h | 8 | ||||
-rw-r--r-- | lldb/source/Interpreter/CommandObject.cpp | 1 | ||||
-rw-r--r-- | lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Target/LanguageRuntime.cpp | 52 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 25 | ||||
-rw-r--r-- | lldb/tools/driver/Driver.cpp | 3 |
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); } |