forked from OSchip/llvm-project
Add a command and an SB API to create exception breakpoints. Make the break output prettier for Exception breakpoints.
llvm-svn: 152081
This commit is contained in:
parent
330de22fe0
commit
fab10e89ce
|
@ -622,6 +622,13 @@ public:
|
|||
const SBFileSpecList &module_list,
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -595,12 +595,24 @@ public:
|
|||
const SBFileSpecList &module_list,
|
||||
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);
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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)." },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue