Author: jingham
Date: Wed Apr 22 14:42:18 2015
New Revision: 235538
URL: http://llvm.org/viewvc/llvm-project?rev=235538&view=rev
Log:
This is some groundwork for filtering the language Exception
breakpoints, for instance on the class of the thrown object.
This change doesn't actually make that work, the part where we
extract the thrown object type from the throw site isn't done yet.
This provides a general programmatic "precondition" that you can add
to breakpoints to give them the ability to do filtering on the LLDB
side before we pass the stop on to the user-provided conditions &
callbacks.
Modified:
lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
lldb/trunk/include/lldb/Target/LanguageRuntime.h
lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
lldb/trunk/include/lldb/Target/Target.h
lldb/trunk/include/lldb/lldb-enumerations.h
lldb/trunk/source/Breakpoint/Breakpoint.cpp
lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
lldb/trunk/source/Interpreter/CommandObject.cpp
lldb/trunk/source/Target/LanguageRuntime.cpp
lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
lldb/trunk/source/Target/Target.cpp
Modified: lldb/trunk/include/lldb/Breakpoint/Breakpoint.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/Breakpoint.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/Breakpoint.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/Breakpoint.h Wed Apr 22 14:42:18 2015
@@ -155,6 +155,23 @@ public:
};
+ class BreakpointPrecondition
+ {
+ public:
+ virtual ~BreakpointPrecondition() {}
+
+ virtual bool
+ EvaluatePrecondition(StoppointCallbackContext &context);
+
+ virtual Error
+ ConfigurePrecondition(Args &options);
+
+ virtual void
+ DescribePrecondition(Stream &stream, lldb::DescriptionLevel level);
+ };
+
+ typedef std::shared_ptr<BreakpointPrecondition> BreakpointPreconditionSP;
+
//------------------------------------------------------------------
/// Destructor.
///
@@ -665,6 +682,31 @@ public:
}
}
+ //------------------------------------------------------------------
+ /// Set a pre-condition filter that overrides all user provided
filters/callbacks etc.
+ ///
+ /// Used to define fancy breakpoints that can do dynamic hit detection
without taking up the condition slot -
+ /// which really belongs to the user anyway...
+ ///
+ /// The Precondition should not continue the target, it should return true
if the condition says to stop and
+ /// false otherwise.
+ ///
+ //------------------------------------------------------------------
+ void
+ SetPrecondition(BreakpointPreconditionSP precondition_sp)
+ {
+ m_precondition_sp = precondition_sp;
+ }
+
+ bool
+ EvaluatePrecondition (StoppointCallbackContext &context);
+
+ BreakpointPreconditionSP
+ GetPrecondition()
+ {
+ return m_precondition_sp;
+ }
+
protected:
friend class Target;
//------------------------------------------------------------------
@@ -737,13 +779,17 @@ private:
// For Breakpoint only
//------------------------------------------------------------------
bool m_being_created;
- bool m_hardware; // If this breakpoint is
required to use a hardware breakpoint
- Target &m_target; // The target that holds this
breakpoint.
+ bool m_hardware; // If this breakpoint is
required to use a hardware breakpoint
+ Target &m_target; // The target that holds this
breakpoint.
std::unordered_set<std::string> m_name_list; // If not empty, this is the
name of this breakpoint (many breakpoints can share the same name.)
- lldb::SearchFilterSP m_filter_sp; // The filter that constrains
the breakpoint's domain.
- lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines
this breakpoint.
- BreakpointOptions m_options; // Settable breakpoint options
- BreakpointLocationList m_locations; // The list of locations
currently found for this breakpoint.
+ lldb::SearchFilterSP m_filter_sp; // The filter that constrains
the breakpoint's domain.
+ lldb::BreakpointResolverSP m_resolver_sp; // The resolver that defines
this breakpoint.
+ BreakpointPreconditionSP m_precondition_sp; // The precondition is a
breakpoint-level hit filter that can be used
+ // to skip certain breakpoint
hits. For instance, exception breakpoints
+ // use this to limit the stop
to certain exception classes, while leaving
+ // the condition & callback
free for user specification.
+ BreakpointOptions m_options; // Settable breakpoint options
+ BreakpointLocationList m_locations; // The list of locations
currently found for this breakpoint.
std::string m_kind_description;
bool m_resolve_indirect_symbols;
uint32_t m_hit_count; // Number of times this
breakpoint/watchpoint has been hit. This is kept
Modified: lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h (original)
+++ lldb/trunk/include/lldb/Breakpoint/BreakpointOptions.h Wed Apr 22 14:42:18
2015
@@ -89,6 +89,9 @@ public:
// callback.
// Asynchronous callbacks get run as part of the "ShouldStop" logic in the
thread plan. The logic there is:
// a) If the breakpoint is thread specific and not for this thread,
continue w/o running the callback.
+ // NB. This is actually enforced underneath the breakpoint system,
the Process plugin is expected to
+ // call BreakpointSite::IsValidForThread, and set the thread's
StopInfo to "no reason". That way,
+ // thread displays won't show stops for breakpoints not for that
thread...
// b) If the ignore count says we shouldn't stop, then ditto.
// c) If the condition says we shouldn't stop, then ditto.
// d) Otherwise, the callback will get run, and if it returns true we
will stop, and if false we won't.
Modified: lldb/trunk/include/lldb/Target/LanguageRuntime.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/LanguageRuntime.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/LanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/LanguageRuntime.h Wed Apr 22 14:42:18 2015
@@ -80,11 +80,16 @@ public:
static lldb::BreakpointSP
CreateExceptionBreakpoint (Target &target,
- lldb::LanguageType language,
+ lldb::LanguageType language,
bool catch_bp,
bool throw_bp,
bool is_internal = false);
-
+
+ static Breakpoint::BreakpointPreconditionSP
+ CreateExceptionPrecondition (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp);
+
static lldb::LanguageType
GetLanguageTypeFromString (const char *string);
Modified: lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h (original)
+++ lldb/trunk/include/lldb/Target/ObjCLanguageRuntime.h Wed Apr 22 14:42:18
2015
@@ -289,6 +289,24 @@ public:
protected:
std::unique_ptr<ClangASTContext> m_scratch_ast_ctx_ap;
};
+
+ class ObjCExceptionPrecondition : public Breakpoint::BreakpointPrecondition
+ {
+ public:
+ ObjCExceptionPrecondition();
+
+ virtual ~ObjCExceptionPrecondition() {}
+
+ bool EvaluatePrecondition(StoppointCallbackContext &context) override;
+ void DescribePrecondition(Stream &stream, lldb::DescriptionLevel
level) override;
+ Error ConfigurePrecondition(Args &args) override;
+
+ protected:
+ void AddClassName(const char *class_name);
+
+ private:
+ std::unordered_set<std::string> m_class_names;
+ };
typedef std::shared_ptr<EncodingToType> EncodingToTypeSP;
Modified: lldb/trunk/include/lldb/Target/Target.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/Target.h (original)
+++ lldb/trunk/include/lldb/Target/Target.h Wed Apr 22 14:42:18 2015
@@ -741,7 +741,12 @@ public:
bool request_hardware);
lldb::BreakpointSP
- CreateExceptionBreakpoint (enum lldb::LanguageType language, bool
catch_bp, bool throw_bp, bool internal);
+ CreateExceptionBreakpoint (enum lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp,
+ bool internal,
+ Args *additional_args = nullptr,
+ Error *additional_args_error = nullptr);
// This is the same as the func_name breakpoint except that you can
specify a vector of names. This is cheaper
// than a regular expression breakpoint in the case where you just want to
set a breakpoint on a set of names
Modified: lldb/trunk/include/lldb/lldb-enumerations.h
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/lldb-enumerations.h?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/include/lldb/lldb-enumerations.h (original)
+++ lldb/trunk/include/lldb/lldb-enumerations.h Wed Apr 22 14:42:18 2015
@@ -521,6 +521,7 @@ namespace lldb {
eArgTypeThreadID,
eArgTypeThreadIndex,
eArgTypeThreadName,
+ eArgTypeTypeName,
eArgTypeUnsignedInteger,
eArgTypeUnixSignal,
eArgTypeVarName,
Modified: lldb/trunk/source/Breakpoint/Breakpoint.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Breakpoint/Breakpoint.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Breakpoint/Breakpoint.cpp (original)
+++ lldb/trunk/source/Breakpoint/Breakpoint.cpp Wed Apr 22 14:42:18 2015
@@ -949,6 +949,34 @@ Breakpoint::GetFilterDescription (Stream
m_filter_sp->GetDescription (s);
}
+bool
+Breakpoint::EvaluatePrecondition (StoppointCallbackContext &context)
+{
+ if (!m_precondition_sp)
+ return true;
+
+ return m_precondition_sp->EvaluatePrecondition(context);
+}
+
+bool
+Breakpoint::BreakpointPrecondition::EvaluatePrecondition(StoppointCallbackContext
&context)
+{
+ return true;
+}
+
+void
+Breakpoint::BreakpointPrecondition::DescribePrecondition(Stream &stream,
lldb::DescriptionLevel level)
+{
+}
+
+Error
+Breakpoint::BreakpointPrecondition::ConfigurePrecondition(Args &options)
+{
+ Error error;
+ error.SetErrorString("Base breakpoint precondition has no options.");
+ return error;
+}
+
void
Breakpoint::SendBreakpointChangedEvent (lldb::BreakpointEventType eventKind)
{
Modified: lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectBreakpoint.cpp Wed Apr 22 14:42:18
2015
@@ -112,7 +112,7 @@ public:
m_catch_bp (false),
m_throw_bp (true),
m_hardware (false),
- m_language (eLanguageTypeUnknown),
+ m_exception_language (eLanguageTypeUnknown),
m_skip_prologue (eLazyBoolCalculate),
m_one_shot (false),
m_all_files (false)
@@ -173,16 +173,16 @@ public:
case eLanguageTypeC:
case eLanguageTypeC99:
case eLanguageTypeC11:
- m_language = eLanguageTypeC;
+ m_exception_language = eLanguageTypeC;
break;
case eLanguageTypeC_plus_plus:
case eLanguageTypeC_plus_plus_03:
case eLanguageTypeC_plus_plus_11:
case eLanguageTypeC_plus_plus_14:
- m_language = eLanguageTypeC_plus_plus;
+ m_exception_language = eLanguageTypeC_plus_plus;
break;
case eLanguageTypeObjC:
- m_language = eLanguageTypeObjC;
+ m_exception_language = eLanguageTypeObjC;
break;
case eLanguageTypeObjC_plus_plus:
error.SetErrorStringWithFormat ("Set exception
breakpoints separately for c++ and objective-c");
@@ -268,6 +268,11 @@ public:
m_one_shot = true;
break;
+ case 'O':
+ m_exception_extra_args.AppendArgument ("-O");
+ m_exception_extra_args.AppendArgument (option_arg);
+ break;
+
case 'p':
m_source_text_regexp.assign (option_arg);
break;
@@ -349,12 +354,13 @@ public:
m_catch_bp = false;
m_throw_bp = true;
m_hardware = false;
- m_language = eLanguageTypeUnknown;
+ m_exception_language = eLanguageTypeUnknown;
m_skip_prologue = eLazyBoolCalculate;
m_one_shot = false;
m_use_dummy = false;
m_breakpoint_names.clear();
m_all_files = false;
+ m_exception_extra_args.Clear();
}
const OptionDefinition*
@@ -388,11 +394,12 @@ public:
bool m_catch_bp;
bool m_throw_bp;
bool m_hardware; // Request to use hardware breakpoints
- lldb::LanguageType m_language;
+ lldb::LanguageType m_exception_language;
LazyBool m_skip_prologue;
bool m_one_shot;
bool m_use_dummy;
bool m_all_files;
+ Args m_exception_extra_args;
};
@@ -430,7 +437,7 @@ protected:
break_type = eSetTypeFunctionRegexp;
else if (!m_options.m_source_text_regexp.empty())
break_type = eSetTypeSourceRegexp;
- else if (m_options.m_language != eLanguageTypeUnknown)
+ else if (m_options.m_exception_language != eLanguageTypeUnknown)
break_type = eSetTypeException;
Breakpoint *bp = NULL;
@@ -556,10 +563,21 @@ protected:
break;
case eSetTypeException:
{
- bp = target->CreateExceptionBreakpoint
(m_options.m_language,
+ Error precond_error;
+ bp = target->CreateExceptionBreakpoint
(m_options.m_exception_language,
m_options.m_catch_bp,
m_options.m_throw_bp,
- internal).get();
+ internal,
+
&m_options.m_exception_extra_args,
+
&precond_error).get();
+ if (precond_error.Fail())
+ {
+ result.AppendErrorWithFormat("Error setting extra
exception arguments: %s",
+
precond_error.AsCString());
+ target->RemoveBreakpointByID(bp->GetID());
+ result.SetStatus(eReturnStatusFailed);
+ return false;
+ }
}
break;
default:
@@ -758,6 +776,10 @@ CommandObjectBreakpointSet::CommandOptio
{ LLDB_OPT_SET_10, false, "on-catch", 'h',
OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
"Set the breakpoint on exception catcH." },
+// Don't add this option till it actually does something useful...
+// { LLDB_OPT_SET_10, false, "exception-typename", 'O',
OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeTypeName,
+// "The breakpoint will only stop if an exception Object of this type
is thrown. Can be repeated multiple times to stop for multiple object types" },
+
{ LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K',
OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,
"sKip the prologue if the breakpoint is at the beginning of a
function. If not set the target.skip-prologue setting is used." },
Modified: lldb/trunk/source/Interpreter/CommandObject.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandObject.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Interpreter/CommandObject.cpp (original)
+++ lldb/trunk/source/Interpreter/CommandObject.cpp Wed Apr 22 14:42:18 2015
@@ -1193,6 +1193,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeThreadID, "thread-id", CommandCompletions::eNoCompletion, {
nullptr, false }, "Thread ID number." },
{ eArgTypeThreadIndex, "thread-index", CommandCompletions::eNoCompletion,
{ nullptr, false }, "Index into the process' list of threads." },
{ eArgTypeThreadName, "thread-name", CommandCompletions::eNoCompletion, {
nullptr, false }, "The thread's name." },
+ { eArgTypeTypeName, "type-name", CommandCompletions::eNoCompletion, {
nullptr, false }, "A type name." },
{ eArgTypeUnsignedInteger, "unsigned-integer",
CommandCompletions::eNoCompletion, { nullptr, false }, "An unsigned integer." },
{ eArgTypeUnixSignal, "unix-signal", CommandCompletions::eNoCompletion, {
nullptr, false }, "A valid Unix signal name or number (e.g. SIGKILL, KILL or
9)." },
{ eArgTypeVarName, "variable-name", CommandCompletions::eNoCompletion, {
nullptr, false }, "The name of a variable in your program." },
Modified: lldb/trunk/source/Target/LanguageRuntime.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/LanguageRuntime.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Target/LanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/LanguageRuntime.cpp Wed Apr 22 14:42:18 2015
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Target/LanguageRuntime.h"
+#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/SearchFilter.h"
@@ -277,6 +278,23 @@ LanguageRuntime::~LanguageRuntime()
{
}
+Breakpoint::BreakpointPreconditionSP
+LanguageRuntime::CreateExceptionPrecondition (lldb::LanguageType language,
+ bool catch_bp,
+ bool throw_bp)
+{
+ switch (language)
+ {
+ case eLanguageTypeObjC:
+ if (throw_bp)
+ return Breakpoint::BreakpointPreconditionSP(new
ObjCLanguageRuntime::ObjCExceptionPrecondition ());
+ break;
+ default:
+ break;
+ }
+ return Breakpoint::BreakpointPreconditionSP();
+}
+
BreakpointSP
LanguageRuntime::CreateExceptionBreakpoint (Target &target,
lldb::LanguageType language,
@@ -289,8 +307,15 @@ LanguageRuntime::CreateExceptionBreakpoi
bool hardware = false;
bool resolve_indirect_functions = false;
BreakpointSP exc_breakpt_sp (target.CreateBreakpoint (filter_sp,
resolver_sp, is_internal, hardware, resolve_indirect_functions));
- if (is_internal)
- exc_breakpt_sp->SetBreakpointKind("exception");
+ if (exc_breakpt_sp)
+ {
+ Breakpoint::BreakpointPreconditionSP precondition_sp =
CreateExceptionPrecondition(language, catch_bp, throw_bp);
+ if (precondition_sp)
+ exc_breakpt_sp->SetPrecondition(precondition_sp);
+
+ if (is_internal)
+ exc_breakpt_sp->SetBreakpointKind("exception");
+ }
return exc_breakpt_sp;
}
Modified: lldb/trunk/source/Target/ObjCLanguageRuntime.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ObjCLanguageRuntime.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Target/ObjCLanguageRuntime.cpp (original)
+++ lldb/trunk/source/Target/ObjCLanguageRuntime.cpp Wed Apr 22 14:42:18 2015
@@ -670,3 +670,36 @@ ObjCLanguageRuntime::GetTypeBitSize (con
return found;
}
+
+//------------------------------------------------------------------
+// Exception breakpoint Precondition class for ObjC:
+//------------------------------------------------------------------
+void
+ObjCLanguageRuntime::ObjCExceptionPrecondition::AddClassName(const char
*class_name)
+{
+ m_class_names.insert(class_name);
+}
+
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ObjCExceptionPrecondition()
+{
+}
+
+bool
+ObjCLanguageRuntime::ObjCExceptionPrecondition::EvaluatePrecondition(StoppointCallbackContext
&context)
+{
+ return true;
+}
+
+void
+ObjCLanguageRuntime::ObjCExceptionPrecondition::DescribePrecondition(Stream
&stream, lldb::DescriptionLevel level)
+{
+}
+
+Error
+ObjCLanguageRuntime::ObjCExceptionPrecondition::ConfigurePrecondition(Args
&args)
+{
+ Error error;
+ if (args.GetArgumentCount() > 0)
+ error.SetErrorString("The ObjC Exception breakpoint doesn't support
extra options.");
+ return error;
+}
Modified: lldb/trunk/source/Target/Target.cpp
URL:
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=235538&r1=235537&r2=235538&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Wed Apr 22 14:42:18 2015
@@ -523,11 +523,23 @@ Target::CreateFuncRegexBreakpoint (const
}
lldb::BreakpointSP
-Target::CreateExceptionBreakpoint (enum lldb::LanguageType language, bool
catch_bp, bool throw_bp, bool internal)
+Target::CreateExceptionBreakpoint (enum lldb::LanguageType language, bool
catch_bp, bool throw_bp, bool internal, Args *additional_args, Error *error)
{
- return LanguageRuntime::CreateExceptionBreakpoint (*this, language,
catch_bp, throw_bp, internal);
+ BreakpointSP exc_bkpt_sp = LanguageRuntime::CreateExceptionBreakpoint
(*this, language, catch_bp, throw_bp, internal);
+ if (exc_bkpt_sp && additional_args)
+ {
+ Breakpoint::BreakpointPreconditionSP precondition_sp =
exc_bkpt_sp->GetPrecondition();
+ if (precondition_sp && additional_args)
+ {
+ if (error)
+ *error =
precondition_sp->ConfigurePrecondition(*additional_args);
+ else
+ precondition_sp->ConfigurePrecondition(*additional_args);
+ }
+ }
+ return exc_bkpt_sp;
}
-
+
BreakpointSP
Target::CreateBreakpoint (SearchFilterSP &filter_sp, BreakpointResolverSP
&resolver_sp, bool internal, bool request_hardware, bool
resolve_indirect_symbols)
{
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits