forked from OSchip/llvm-project
Make breakpoint names real entities.
When introduced, breakpoint names were just tags that you could apply to breakpoints that would allow you to refer to a breakpoint when you couldn't capture the ID, or to refer to a collection of breakpoints. This change makes the names independent holders of breakpoint options that you can then apply to breakpoints when you add the name to the breakpoint. It adds the "breakpoint name configure" command to set up or reconfigure breakpoint names. There is also full support for then in the SB API, including a new SBBreakpointName class. The connection between the name and the breakpoints sharing the name remains live, so if you reconfigure the name, all the breakpoint options all change as well. This allows a quick way to share complex breakpoint behavior among a bunch of breakpoints, and a convenient way to iterate on the set. You can also create a name from a breakpoint, allowing a quick way to copy options from one breakpoint to another. I also added the ability to make hidden and delete/disable protected names. When applied to a breakpoint, you will only be able to list, delete or disable that breakpoint if you refer to it explicitly by ID. This feature will allow GUI's that need to use breakpoints for their own purposes to keep their breakpoints from getting accidentally disabled or deleted. <rdar://problem/22094452> llvm-svn: 313292
This commit is contained in:
parent
b2388c52e8
commit
b842f2ecf0
|
@ -18,6 +18,7 @@
|
|||
#include "lldb/API/SBAttachInfo.h"
|
||||
#include "lldb/API/SBBlock.h"
|
||||
#include "lldb/API/SBBreakpoint.h"
|
||||
#include "lldb/API/SBBreakpointName.h"
|
||||
#include "lldb/API/SBBreakpointLocation.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBCommandInterpreter.h"
|
||||
|
|
|
@ -18,9 +18,6 @@ namespace lldb {
|
|||
|
||||
class LLDB_API SBBreakpoint {
|
||||
public:
|
||||
typedef bool (*BreakpointHitCallback)(void *baton, SBProcess &process,
|
||||
SBThread &thread,
|
||||
lldb::SBBreakpointLocation &location);
|
||||
|
||||
SBBreakpoint();
|
||||
|
||||
|
@ -90,7 +87,7 @@ public:
|
|||
|
||||
const char *GetQueueName() const;
|
||||
|
||||
void SetCallback(BreakpointHitCallback callback, void *baton);
|
||||
void SetCallback(SBBreakpointHitCallback callback, void *baton);
|
||||
|
||||
void SetScriptCallbackFunction(const char *callback_function_name);
|
||||
|
||||
|
@ -133,14 +130,11 @@ public:
|
|||
private:
|
||||
friend class SBBreakpointList;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBBreakpointName;
|
||||
friend class SBTarget;
|
||||
|
||||
SBBreakpoint(const lldb::BreakpointSP &bp_sp);
|
||||
|
||||
static bool PrivateBreakpointHitCallback(
|
||||
void *baton, lldb_private::StoppointCallbackContext *context,
|
||||
lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
|
||||
|
||||
lldb::BreakpointSP GetSP() const;
|
||||
|
||||
lldb::BreakpointWP m_opaque_wp;
|
||||
|
|
|
@ -86,6 +86,7 @@ public:
|
|||
|
||||
private:
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointCallbackBaton;
|
||||
|
||||
void SetLocation(const lldb::BreakpointLocationSP &break_loc_sp);
|
||||
BreakpointLocationSP GetSP() const;
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
//===-- SBBreakpointName.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBreakpointName_h_
|
||||
#define LLDB_SBBreakpointName_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
class SBBreakpointNameImpl;
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class LLDB_API SBBreakpointName {
|
||||
public:
|
||||
// typedef bool (*BreakpointHitCallback)(void *baton, SBProcess &process,
|
||||
// SBThread &thread,
|
||||
// lldb::SBBreakpointLocation &location);
|
||||
|
||||
SBBreakpointName();
|
||||
|
||||
SBBreakpointName(SBTarget &target, const char *name);
|
||||
|
||||
SBBreakpointName(SBBreakpoint &bkpt, const char *name);
|
||||
|
||||
SBBreakpointName(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
~SBBreakpointName();
|
||||
|
||||
const lldb::SBBreakpointName &operator=(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
// Tests to see if the opaque breakpoint object in this object matches the
|
||||
// opaque breakpoint object in "rhs".
|
||||
bool operator==(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
bool operator!=(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
const char *GetName() const;
|
||||
|
||||
void SetEnabled(bool enable);
|
||||
|
||||
bool IsEnabled();
|
||||
|
||||
void SetOneShot(bool one_shot);
|
||||
|
||||
bool IsOneShot() const;
|
||||
|
||||
void SetIgnoreCount(uint32_t count);
|
||||
|
||||
uint32_t GetIgnoreCount() const;
|
||||
|
||||
void SetCondition(const char *condition);
|
||||
|
||||
const char *GetCondition();
|
||||
|
||||
void SetAutoContinue(bool auto_continue);
|
||||
|
||||
bool GetAutoContinue();
|
||||
|
||||
void SetThreadID(lldb::tid_t sb_thread_id);
|
||||
|
||||
lldb::tid_t GetThreadID();
|
||||
|
||||
void SetThreadIndex(uint32_t index);
|
||||
|
||||
uint32_t GetThreadIndex() const;
|
||||
|
||||
void SetThreadName(const char *thread_name);
|
||||
|
||||
const char *GetThreadName() const;
|
||||
|
||||
void SetQueueName(const char *queue_name);
|
||||
|
||||
const char *GetQueueName() const;
|
||||
|
||||
void SetCallback(SBBreakpointHitCallback callback, void *baton);
|
||||
|
||||
void SetScriptCallbackFunction(const char *callback_function_name);
|
||||
|
||||
void SetCommandLineCommands(SBStringList &commands);
|
||||
|
||||
bool GetCommandLineCommands(SBStringList &commands);
|
||||
|
||||
SBError SetScriptCallbackBody(const char *script_body_text);
|
||||
|
||||
bool GetAllowList() const;
|
||||
void SetAllowList(bool value);
|
||||
|
||||
bool GetAllowDelete();
|
||||
void SetAllowDelete(bool value);
|
||||
|
||||
bool GetAllowDisable();
|
||||
void SetAllowDisable(bool value);
|
||||
|
||||
bool GetDescription(lldb::SBStream &description);
|
||||
|
||||
private:
|
||||
friend class SBTarget;
|
||||
|
||||
lldb_private::BreakpointName *GetBreakpointName() const;
|
||||
void UpdateName(lldb_private::BreakpointName &bp_name);
|
||||
|
||||
std::unique_ptr<SBBreakpointNameImpl> m_impl_up;
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBBreakpointName_h_
|
|
@ -109,6 +109,8 @@ public:
|
|||
const char *archname);
|
||||
|
||||
lldb::SBTarget CreateTarget(const char *filename);
|
||||
|
||||
lldb::SBTarget GetDummyTarget();
|
||||
|
||||
// Return true if target is deleted from the target list of the debugger.
|
||||
bool DeleteTarget(lldb::SBTarget &target);
|
||||
|
|
|
@ -32,6 +32,8 @@ class LLDB_API SBAddress;
|
|||
class LLDB_API SBBlock;
|
||||
class LLDB_API SBBreakpoint;
|
||||
class LLDB_API SBBreakpointLocation;
|
||||
class LLDB_API SBBreakpointName;
|
||||
class LLDB_API SBBreakpointNameImpl;
|
||||
class LLDB_API SBBroadcaster;
|
||||
class LLDB_API SBCommand;
|
||||
class LLDB_API SBCommandInterpreter;
|
||||
|
@ -99,6 +101,10 @@ class LLDB_API SBValueList;
|
|||
class LLDB_API SBVariablesOptions;
|
||||
class LLDB_API SBWatchpoint;
|
||||
class LLDB_API SBUnixSignals;
|
||||
|
||||
typedef bool (*SBBreakpointHitCallback)(void *baton, SBProcess &process,
|
||||
SBThread &thread,
|
||||
lldb::SBBreakpointLocation &location);
|
||||
}
|
||||
|
||||
#endif // LLDB_SBDefines_h_
|
||||
|
|
|
@ -67,6 +67,7 @@ protected:
|
|||
friend class SBWatchpoint;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBBreakpointName;
|
||||
|
||||
lldb_private::Status *get();
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ protected:
|
|||
friend class SBBlock;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBBreakpointName;
|
||||
friend class SBCommandReturnObject;
|
||||
friend class SBCompileUnit;
|
||||
friend class SBData;
|
||||
|
|
|
@ -45,6 +45,7 @@ protected:
|
|||
friend class SBDebugger;
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBBreakpointName;
|
||||
|
||||
SBStringList(const lldb_private::StringList *lldb_strings);
|
||||
|
||||
|
|
|
@ -716,6 +716,10 @@ public:
|
|||
// Finds all breakpoints by name, returning the list in bkpt_list. Returns
|
||||
// false if the name is not a valid breakpoint name, true otherwise.
|
||||
bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
|
||||
|
||||
void GetBreakpointNames(SBStringList &names);
|
||||
|
||||
void DeleteBreakpointName(const char *name);
|
||||
|
||||
bool EnableAllBreakpoints();
|
||||
|
||||
|
@ -810,6 +814,7 @@ protected:
|
|||
friend class SBAddress;
|
||||
friend class SBBlock;
|
||||
friend class SBBreakpointList;
|
||||
friend class SBBreakpointNameImpl;
|
||||
friend class SBDebugger;
|
||||
friend class SBExecutionContext;
|
||||
friend class SBFunction;
|
||||
|
|
|
@ -196,6 +196,7 @@ public:
|
|||
protected:
|
||||
friend class SBBreakpoint;
|
||||
friend class SBBreakpointLocation;
|
||||
friend class SBBreakpointCallbackBaton;
|
||||
friend class SBExecutionContext;
|
||||
friend class SBFrame;
|
||||
friend class SBProcess;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "lldb/Breakpoint/BreakpointID.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationList.h"
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/Breakpoint/BreakpointOptions.h"
|
||||
#include "lldb/Breakpoint/Stoppoint.h"
|
||||
#include "lldb/Core/Event.h"
|
||||
|
@ -602,6 +603,16 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
BreakpointOptions *GetOptions();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the BreakpointOptions structure set at the breakpoint level.
|
||||
///
|
||||
/// Meant to be used by the BreakpointLocation class.
|
||||
///
|
||||
/// @return
|
||||
/// A pointer to this breakpoint's BreakpointOptions.
|
||||
//------------------------------------------------------------------
|
||||
const BreakpointOptions *GetOptions() const;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Invoke the callback action when the breakpoint is hit.
|
||||
///
|
||||
|
@ -625,13 +636,16 @@ public:
|
|||
|
||||
lldb::SearchFilterSP GetSearchFilter() { return m_filter_sp; }
|
||||
|
||||
bool AddName(llvm::StringRef new_name, Status &error);
|
||||
private: // The target needs to manage adding & removing names. It will do the
|
||||
// checking for name validity as well.
|
||||
bool AddName(llvm::StringRef new_name);
|
||||
|
||||
void RemoveName(const char *name_to_remove) {
|
||||
if (name_to_remove)
|
||||
m_name_list.erase(name_to_remove);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
bool MatchesName(const char *name) {
|
||||
return m_name_list.find(name) != m_name_list.end();
|
||||
}
|
||||
|
@ -663,6 +677,25 @@ public:
|
|||
bool EvaluatePrecondition(StoppointCallbackContext &context);
|
||||
|
||||
BreakpointPreconditionSP GetPrecondition() { return m_precondition_sp; }
|
||||
|
||||
// Produces the OR'ed values for all the names assigned to this breakpoint.
|
||||
const BreakpointName::Permissions &GetPermissions() const {
|
||||
return m_permissions;
|
||||
}
|
||||
|
||||
BreakpointName::Permissions &GetPermissions() {
|
||||
return m_permissions;
|
||||
}
|
||||
|
||||
bool AllowList() const {
|
||||
return GetPermissions().GetAllowList();
|
||||
}
|
||||
bool AllowDisable() const {
|
||||
return GetPermissions().GetAllowDisable();
|
||||
}
|
||||
bool AllowDelete() const {
|
||||
return GetPermissions().GetAllowDelete();
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class Target;
|
||||
|
@ -762,6 +795,7 @@ private:
|
|||
// hit. This is kept
|
||||
// separately from the locations hit counts, since locations can go away when
|
||||
// their backing library gets unloaded, and we would lose hit counts.
|
||||
BreakpointName::Permissions m_permissions;
|
||||
|
||||
void SendBreakpointChangedEvent(lldb::BreakpointEventType eventKind);
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Breakpoint/BreakpointID.h"
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/lldb-private.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
@ -64,6 +66,8 @@ public:
|
|||
|
||||
static void FindAndReplaceIDRanges(Args &old_args, Target *target,
|
||||
bool allow_locations,
|
||||
BreakpointName::Permissions
|
||||
::PermissionKinds purpose,
|
||||
CommandReturnObject &result,
|
||||
Args &new_args);
|
||||
|
||||
|
|
|
@ -154,11 +154,20 @@ public:
|
|||
|
||||
void SetEnabledAll(bool enabled);
|
||||
|
||||
void SetEnabledAllowed(bool enabled);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Removes all the breakpoints from this list.
|
||||
//------------------------------------------------------------------
|
||||
void RemoveAll(bool notify);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Removes all the breakpoints from this list - first checking the
|
||||
/// ePermDelete on the breakpoints. This call should be used unless you
|
||||
/// are shutting down and need to actually clear them all.
|
||||
//------------------------------------------------------------------
|
||||
void RemoveAllowed(bool notify);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Tell all the breakpoints to update themselves due to a change in the
|
||||
/// modules in \a module_list. \a added says whether the module was loaded
|
||||
|
|
|
@ -0,0 +1,213 @@
|
|||
//===-- BreakpointName.h --------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef liblldb_Breakpoint_Name_h_
|
||||
#define liblldb_Breakpoint_Name_h_
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Breakpoint/BreakpointID.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationList.h"
|
||||
#include "lldb/Breakpoint/BreakpointOptions.h"
|
||||
#include "lldb/Breakpoint/Stoppoint.h"
|
||||
#include "lldb/Core/Event.h"
|
||||
#include "lldb/Core/SearchFilter.h"
|
||||
#include "lldb/Utility/Flags.h"
|
||||
#include "lldb/Utility/StringList.h"
|
||||
#include "lldb/Utility/StructuredData.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
class BreakpointName {
|
||||
public:
|
||||
class Permissions
|
||||
{
|
||||
public:
|
||||
|
||||
enum PermissionKinds { listPerm = 0, disablePerm = 1,
|
||||
deletePerm = 2, allPerms = 3 };
|
||||
|
||||
Permissions(bool in_list, bool in_disable, bool in_delete)
|
||||
{
|
||||
m_permissions[listPerm] = in_list;
|
||||
m_permissions[disablePerm] = in_disable;
|
||||
m_permissions[deletePerm] = in_delete;
|
||||
m_set_mask.Set(permissions_mask[allPerms]);
|
||||
}
|
||||
|
||||
Permissions(const Permissions &rhs)
|
||||
{
|
||||
m_permissions[listPerm] = rhs.m_permissions[listPerm];
|
||||
m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
|
||||
m_permissions[deletePerm] = rhs.m_permissions[deletePerm];
|
||||
m_set_mask = rhs.m_set_mask;
|
||||
}
|
||||
|
||||
Permissions()
|
||||
{
|
||||
m_permissions[listPerm] = true;
|
||||
m_permissions[disablePerm] = true;
|
||||
m_permissions[deletePerm] = true;
|
||||
m_set_mask.Clear();
|
||||
}
|
||||
|
||||
const Permissions &operator= (const Permissions &rhs)
|
||||
{
|
||||
if (this != &rhs) {
|
||||
m_permissions[listPerm] = rhs.m_permissions[listPerm];
|
||||
m_permissions[disablePerm] = rhs.m_permissions[disablePerm];
|
||||
m_permissions[deletePerm] = rhs.m_permissions[deletePerm];
|
||||
m_set_mask = rhs.m_set_mask;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
*this = Permissions();
|
||||
}
|
||||
|
||||
// Merge the permissions from incoming into this set of permissions.
|
||||
// Only merge set permissions, and most restrictive permission wins.
|
||||
void MergeInto(const Permissions &incoming)
|
||||
{
|
||||
MergePermission(incoming, listPerm);
|
||||
MergePermission(incoming, disablePerm);
|
||||
MergePermission(incoming, deletePerm);
|
||||
}
|
||||
|
||||
bool GetAllowList() const { return GetPermission(listPerm); }
|
||||
bool SetAllowList(bool value) { return SetPermission(listPerm, value); }
|
||||
|
||||
bool GetAllowDelete() const { return GetPermission(deletePerm); }
|
||||
bool SetAllowDelete(bool value) { return SetPermission(deletePerm, value); }
|
||||
|
||||
bool GetAllowDisable() const { return GetPermission(disablePerm); }
|
||||
bool SetAllowDisable(bool value) { return SetPermission(disablePerm,
|
||||
value); }
|
||||
|
||||
bool GetPermission(enum PermissionKinds permission) const
|
||||
{
|
||||
return m_permissions[permission];
|
||||
}
|
||||
|
||||
bool GetDescription(Stream *s, lldb::DescriptionLevel level);
|
||||
|
||||
bool IsSet(enum PermissionKinds permission) const
|
||||
{
|
||||
return m_set_mask.Test(permissions_mask[permission]);
|
||||
}
|
||||
|
||||
bool AnySet() {
|
||||
return m_set_mask.AnySet(permissions_mask[allPerms]);
|
||||
}
|
||||
|
||||
private:
|
||||
static const Flags::ValueType permissions_mask[allPerms + 1];
|
||||
|
||||
bool m_permissions[allPerms];
|
||||
Flags m_set_mask;
|
||||
|
||||
bool SetPermission(enum PermissionKinds permission, bool value)
|
||||
{
|
||||
bool old_value = m_permissions[permission];
|
||||
m_permissions[permission] = value;
|
||||
m_set_mask.Set(permissions_mask[permission]);
|
||||
return old_value;
|
||||
}
|
||||
|
||||
// If either side disallows the permission, the resultant disallows it.
|
||||
void MergePermission(const Permissions &incoming,
|
||||
enum PermissionKinds permission)
|
||||
{
|
||||
if (incoming.IsSet(permission))
|
||||
{
|
||||
SetPermission(permission, !(m_permissions[permission] |
|
||||
incoming.m_permissions[permission]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BreakpointName(const ConstString &name, const char *help = nullptr) :
|
||||
m_name(name), m_options(false)
|
||||
{
|
||||
SetHelp(help);
|
||||
}
|
||||
|
||||
BreakpointName(const ConstString &name,
|
||||
BreakpointOptions &options,
|
||||
const Permissions &permissions = Permissions(),
|
||||
const char *help = nullptr) :
|
||||
m_name(name), m_options(options),
|
||||
m_permissions(permissions) {
|
||||
SetHelp(help);
|
||||
};
|
||||
|
||||
BreakpointName(const BreakpointName &rhs) :
|
||||
m_name(rhs.m_name), m_options(rhs.m_options),
|
||||
m_permissions(rhs.m_permissions), m_help(rhs.m_help)
|
||||
{}
|
||||
|
||||
BreakpointName(const ConstString &name, const Breakpoint &bkpt,
|
||||
const char *help);
|
||||
|
||||
const ConstString &GetName() const { return m_name; }
|
||||
BreakpointOptions &GetOptions() { return m_options; }
|
||||
const BreakpointOptions &GetOptions() const { return m_options; }
|
||||
|
||||
void SetOptions(const BreakpointOptions &options) {
|
||||
m_options = options;
|
||||
}
|
||||
|
||||
Permissions &GetPermissions() { return m_permissions; }
|
||||
const Permissions &GetPermissions() const { return m_permissions; }
|
||||
void SetPermissions(const Permissions &permissions) {
|
||||
m_permissions = permissions;
|
||||
}
|
||||
|
||||
bool GetPermission(Permissions::PermissionKinds permission) const
|
||||
{
|
||||
return m_permissions.GetPermission(permission);
|
||||
}
|
||||
|
||||
void SetHelp(const char *description)
|
||||
{
|
||||
if (description)
|
||||
m_help.assign(description);
|
||||
else
|
||||
m_help.clear();
|
||||
}
|
||||
|
||||
const char *GetHelp()
|
||||
{
|
||||
return m_help.c_str();
|
||||
}
|
||||
|
||||
// Returns true if any options were set in the name
|
||||
bool GetDescription(Stream *s, lldb::DescriptionLevel level);
|
||||
|
||||
void ConfigureBreakpoint(lldb::BreakpointSP bp_sp);
|
||||
|
||||
private:
|
||||
ConstString m_name;
|
||||
BreakpointOptions m_options;
|
||||
Permissions m_permissions;
|
||||
std::string m_help;
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
||||
#endif // liblldb_Breakpoint_Name_h_
|
|
@ -34,6 +34,8 @@ namespace lldb_private {
|
|||
|
||||
class BreakpointOptions {
|
||||
friend class BreakpointLocation;
|
||||
friend class BreakpointName;
|
||||
friend class lldb_private::BreakpointOptionGroup;
|
||||
friend class Breakpoint;
|
||||
|
||||
public:
|
||||
|
@ -44,7 +46,9 @@ public:
|
|||
eIgnoreCount = 1 << 3,
|
||||
eThreadSpec = 1 << 4,
|
||||
eCondition = 1 << 5,
|
||||
eAutoContinue = 1 << 6
|
||||
eAutoContinue = 1 << 6,
|
||||
eAllOptions = (eCallback | eEnabled | eOneShot | eIgnoreCount | eThreadSpec
|
||||
| eCondition | eAutoContinue)
|
||||
};
|
||||
struct CommandData {
|
||||
CommandData()
|
||||
|
@ -97,6 +101,10 @@ public:
|
|||
|
||||
typedef std::shared_ptr<CommandBaton> CommandBatonSP;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// This constructor allows you to specify all the breakpoint options
|
||||
/// except the callback. That one is more complicated, and better
|
||||
|
@ -116,6 +124,13 @@ public:
|
|||
int32_t ignore = 0, bool one_shot = false,
|
||||
bool auto_continue = false);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Breakpoints make options with all flags set. Locations and Names make options
|
||||
/// with no flags set.
|
||||
//------------------------------------------------------------------
|
||||
BreakpointOptions(bool all_flags_set);
|
||||
BreakpointOptions(const BreakpointOptions &rhs);
|
||||
|
||||
virtual ~BreakpointOptions();
|
||||
|
||||
static std::unique_ptr<BreakpointOptions>
|
||||
|
@ -131,6 +146,11 @@ public:
|
|||
// Operators
|
||||
//------------------------------------------------------------------
|
||||
const BreakpointOptions &operator=(const BreakpointOptions &rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Copy over only the options set in the incoming BreakpointOptions.
|
||||
//------------------------------------------------------------------
|
||||
void CopyOverSetOptions(const BreakpointOptions &rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Callbacks
|
||||
|
@ -387,17 +407,13 @@ public:
|
|||
//------------------------------------------------------------------
|
||||
void SetCommandDataCallback(std::unique_ptr<CommandData> &cmd_data);
|
||||
|
||||
void Clear();
|
||||
|
||||
bool AnySet() const {
|
||||
return m_set_flags.AnySet(eAllOptions);
|
||||
}
|
||||
|
||||
protected:
|
||||
//------------------------------------------------------------------
|
||||
// Constructors and Destructors
|
||||
//------------------------------------------------------------------
|
||||
//------------------------------------------------------------------
|
||||
/// Breakpoints make options with all flags set. Locations make options
|
||||
/// with no flags set. Nobody else should make breakpoint options.
|
||||
//------------------------------------------------------------------
|
||||
BreakpointOptions(bool all_flags_set);
|
||||
BreakpointOptions(const BreakpointOptions &rhs);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Classes that inherit from BreakpointOptions can see and modify these
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Breakpoint/BreakpointList.h"
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/Breakpoint/WatchpointList.h"
|
||||
#include "lldb/Core/ArchSpec.h"
|
||||
#include "lldb/Core/Broadcaster.h"
|
||||
|
@ -651,12 +652,45 @@ public:
|
|||
}
|
||||
|
||||
WatchpointList &GetWatchpointList() { return m_watchpoint_list; }
|
||||
|
||||
|
||||
// Manages breakpoint names:
|
||||
void AddNameToBreakpoint(BreakpointID &id, const char *name, Status &error);
|
||||
|
||||
void AddNameToBreakpoint(lldb::BreakpointSP &bp_sp, const char *name,
|
||||
Status &error);
|
||||
|
||||
void RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
|
||||
const ConstString &name);
|
||||
|
||||
BreakpointName *FindBreakpointName(const ConstString &name, bool can_create,
|
||||
Status &error);
|
||||
|
||||
void DeleteBreakpointName(const ConstString &name);
|
||||
|
||||
void ConfigureBreakpointName(BreakpointName &bp_name,
|
||||
const BreakpointOptions &options,
|
||||
const BreakpointName::Permissions &permissions);
|
||||
void ApplyNameToBreakpoints(BreakpointName &bp_name);
|
||||
|
||||
|
||||
// This takes ownership of the name obj passed in.
|
||||
void AddBreakpointName(BreakpointName *bp_name);
|
||||
|
||||
void GetBreakpointNames(std::vector<std::string> &names);
|
||||
|
||||
//This call removes ALL breakpoints regardless of permission.
|
||||
void RemoveAllBreakpoints(bool internal_also = false);
|
||||
|
||||
// This removes all the breakpoints, but obeys the ePermDelete on them.
|
||||
void RemoveAllowedBreakpoints();
|
||||
|
||||
void DisableAllBreakpoints(bool internal_also = false);
|
||||
|
||||
void DisableAllowedBreakpoints();
|
||||
|
||||
void EnableAllBreakpoints(bool internal_also = false);
|
||||
|
||||
void EnableAllowedBreakpoints();
|
||||
|
||||
bool DisableBreakpointByID(lldb::break_id_t break_id);
|
||||
|
||||
|
@ -1218,6 +1252,9 @@ protected:
|
|||
SectionLoadHistory m_section_load_history;
|
||||
BreakpointList m_breakpoint_list;
|
||||
BreakpointList m_internal_breakpoint_list;
|
||||
using BreakpointNameList = std::map<ConstString, BreakpointName *>;
|
||||
BreakpointNameList m_breakpoint_names;
|
||||
|
||||
lldb::BreakpointSP m_last_created_breakpoint;
|
||||
WatchpointList m_watchpoint_list;
|
||||
lldb::WatchpointSP m_last_created_watchpoint;
|
||||
|
|
|
@ -38,6 +38,8 @@ class BreakpointList;
|
|||
class BreakpointLocation;
|
||||
class BreakpointLocationCollection;
|
||||
class BreakpointLocationList;
|
||||
class BreakpointName;
|
||||
class BreakpointOptionGroup;
|
||||
class BreakpointOptions;
|
||||
class BreakpointResolver;
|
||||
class BreakpointSite;
|
||||
|
|
|
@ -714,18 +714,23 @@
|
|||
49E4F66B1C9CAD16008487EA /* DiagnosticManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E4F6681C9CAD12008487EA /* DiagnosticManager.cpp */; };
|
||||
49F811F31E931B2100F4E163 /* CPlusPlusNameParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F811EF1E931B1500F4E163 /* CPlusPlusNameParser.cpp */; };
|
||||
4C0083401B9F9BA900D5CF24 /* UtilityFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */; };
|
||||
4C05332B1F62121E00DED368 /* SBBreakpointOptionCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */; };
|
||||
4C2479BD1BA39295009C9A7B /* FunctionCaller.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083321B9A5DE200D5CF24 /* FunctionCaller.cpp */; };
|
||||
4C3ADCD61810D88B00357218 /* BreakpointResolverFileRegex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CAA56141422D986001FFA01 /* BreakpointResolverFileRegex.cpp */; };
|
||||
4C4EB7811E6A4DCC002035C0 /* DumpDataExtractor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */; };
|
||||
4C54B27B1F61CE2800D469CA /* SBBreakpointName.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C54B2781F61CE1200D469CA /* SBBreakpointName.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4C54B27E1F61CE6300D469CA /* SBBreakpointName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */; };
|
||||
4C562CC71CC07DF700C52EAC /* PDBASTParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */; };
|
||||
4C56543119D1EFAA002E9C44 /* ThreadPlanPython.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */; };
|
||||
4C56543519D2297A002E9C44 /* SBThreadPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C56543419D2297A002E9C44 /* SBThreadPlan.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4C56543719D22B32002E9C44 /* SBThreadPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C56543619D22B32002E9C44 /* SBThreadPlan.cpp */; };
|
||||
4C7D48241F5099A1005314B4 /* SymbolFileDWARFDwp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D481C1F509963005314B4 /* SymbolFileDWARFDwp.cpp */; };
|
||||
4C7D48251F5099B2005314B4 /* SymbolFileDWARFDwoDwp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D481F1F509964005314B4 /* SymbolFileDWARFDwoDwp.cpp */; };
|
||||
4C7D482C1F509CF5005314B4 /* BreakpointName.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C7D482B1F509CF5005314B4 /* BreakpointName.h */; };
|
||||
4C877B391F30EF990068FCFB /* SBProcessInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4987FB201F30EC9900E5C17D /* SBProcessInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4C88BC2A1BA3722B00AA0964 /* Expression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C88BC291BA3722B00AA0964 /* Expression.cpp */; };
|
||||
4C88BC2D1BA391B000AA0964 /* UserExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C0083331B9A5DE200D5CF24 /* UserExpression.cpp */; };
|
||||
4CAA19E61F5A40040099E692 /* BreakpointName.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D48281F509CCD005314B4 /* BreakpointName.cpp */; };
|
||||
4CABA9E0134A8BCD00539BDD /* ValueObjectMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CABA9DF134A8BCD00539BDD /* ValueObjectMemory.cpp */; };
|
||||
4CC7C6501D5298F30076FF94 /* OCamlLanguage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7C64D1D5298E20076FF94 /* OCamlLanguage.cpp */; };
|
||||
4CC7C6571D52997A0076FF94 /* OCamlASTContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC7C6551D52996C0076FF94 /* OCamlASTContext.cpp */; };
|
||||
|
@ -1230,6 +1235,7 @@
|
|||
files = (
|
||||
9A20570F1F3B821A00F6C293 /* test-dwarf.cpp in CopyFiles */,
|
||||
9A2057101F3B821A00F6C293 /* test-dwarf.exe in CopyFiles */,
|
||||
4C7D482C1F509CF5005314B4 /* BreakpointName.h in CopyFiles */,
|
||||
AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 1;
|
||||
|
@ -2523,6 +2529,8 @@
|
|||
4C00833F1B9F9BA900D5CF24 /* UtilityFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UtilityFunction.cpp; path = source/Expression/UtilityFunction.cpp; sourceTree = "<group>"; };
|
||||
4C00986F11500B4300F316B0 /* UnixSignals.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = UnixSignals.h; path = include/lldb/Target/UnixSignals.h; sourceTree = "<group>"; };
|
||||
4C00987011500B4300F316B0 /* UnixSignals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = UnixSignals.cpp; path = source/Target/UnixSignals.cpp; sourceTree = "<group>"; };
|
||||
4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBBreakpointOptionCommon.cpp; path = source/API/SBBreakpointOptionCommon.cpp; sourceTree = "<group>"; };
|
||||
4C05332C1F63092A00DED368 /* SBBreakpointName.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBBreakpointName.i; sourceTree = "<group>"; };
|
||||
4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadSpec.cpp; path = source/Target/ThreadSpec.cpp; sourceTree = "<group>"; };
|
||||
4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadSpec.h; path = include/lldb/Target/ThreadSpec.h; sourceTree = "<group>"; };
|
||||
4C09CB73116BD98B00C7A725 /* CommandCompletions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CommandCompletions.h; path = include/lldb/Interpreter/CommandCompletions.h; sourceTree = "<group>"; };
|
||||
|
@ -2539,6 +2547,9 @@
|
|||
4C43DF8A11069C3200E55CBF /* ThreadPlanStepOverRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanStepOverRange.cpp; path = source/Target/ThreadPlanStepOverRange.cpp; sourceTree = "<group>"; };
|
||||
4C4EB77F1E6A4DB8002035C0 /* DumpDataExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DumpDataExtractor.cpp; path = source/Core/DumpDataExtractor.cpp; sourceTree = "<group>"; };
|
||||
4C4EB7821E6A4DE7002035C0 /* DumpDataExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DumpDataExtractor.h; path = include/lldb/Core/DumpDataExtractor.h; sourceTree = "<group>"; };
|
||||
4C54B2781F61CE1200D469CA /* SBBreakpointName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBBreakpointName.h; path = include/lldb/API/SBBreakpointName.h; sourceTree = "<group>"; };
|
||||
4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBBreakpointName.cpp; path = source/API/SBBreakpointName.cpp; sourceTree = "<group>"; };
|
||||
4C54B2811F62081300D469CA /* SBBreakpointOptionCommon.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBBreakpointOptionCommon.h; path = include/lldb/API/SBBreakpointOptionCommon.h; sourceTree = "<group>"; };
|
||||
4C562CC21CC07DDD00C52EAC /* PDBASTParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PDBASTParser.cpp; path = PDB/PDBASTParser.cpp; sourceTree = "<group>"; };
|
||||
4C562CC31CC07DDD00C52EAC /* PDBASTParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PDBASTParser.h; path = PDB/PDBASTParser.h; sourceTree = "<group>"; };
|
||||
4C56543019D1EFAA002E9C44 /* ThreadPlanPython.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanPython.cpp; path = source/Target/ThreadPlanPython.cpp; sourceTree = "<group>"; };
|
||||
|
@ -2555,6 +2566,8 @@
|
|||
4C7D481D1F509964005314B4 /* SymbolFileDWARFDwoDwp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileDWARFDwoDwp.h; sourceTree = "<group>"; };
|
||||
4C7D481E1F509964005314B4 /* SymbolFileDWARFDwp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileDWARFDwp.h; sourceTree = "<group>"; };
|
||||
4C7D481F1F509964005314B4 /* SymbolFileDWARFDwoDwp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolFileDWARFDwoDwp.cpp; sourceTree = "<group>"; };
|
||||
4C7D48281F509CCD005314B4 /* BreakpointName.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BreakpointName.cpp; path = source/Breakpoint/BreakpointName.cpp; sourceTree = "<group>"; };
|
||||
4C7D482B1F509CF5005314B4 /* BreakpointName.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BreakpointName.h; path = include/lldb/Breakpoint/BreakpointName.h; sourceTree = "<group>"; };
|
||||
4C88BC291BA3722B00AA0964 /* Expression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Expression.cpp; path = source/Expression/Expression.cpp; sourceTree = "<group>"; };
|
||||
4C98D3DA118FB96F00E575D0 /* ClangFunctionCaller.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangFunctionCaller.cpp; path = ExpressionParser/Clang/ClangFunctionCaller.cpp; sourceTree = "<group>"; };
|
||||
4C98D3DB118FB96F00E575D0 /* IRExecutionUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRExecutionUnit.cpp; path = source/Expression/IRExecutionUnit.cpp; sourceTree = "<group>"; };
|
||||
|
@ -2575,6 +2588,7 @@
|
|||
4CB443BC1249920C00C13DC2 /* CPPLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CPPLanguageRuntime.cpp; path = source/Target/CPPLanguageRuntime.cpp; sourceTree = "<group>"; };
|
||||
4CB443F212499B5000C13DC2 /* ObjCLanguageRuntime.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCLanguageRuntime.cpp; path = source/Target/ObjCLanguageRuntime.cpp; sourceTree = "<group>"; };
|
||||
4CB443F612499B6E00C13DC2 /* ObjCLanguageRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCLanguageRuntime.h; path = include/lldb/Target/ObjCLanguageRuntime.h; sourceTree = "<group>"; };
|
||||
4CBFF0471F579A36004AFA92 /* Flags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Flags.h; path = include/lldb/Utility/Flags.h; sourceTree = "<group>"; };
|
||||
4CC2A148128C73ED001531C4 /* ThreadPlanTracer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ThreadPlanTracer.cpp; path = source/Target/ThreadPlanTracer.cpp; sourceTree = "<group>"; };
|
||||
4CC2A14C128C7409001531C4 /* ThreadPlanTracer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanTracer.h; path = include/lldb/Target/ThreadPlanTracer.h; sourceTree = "<group>"; };
|
||||
4CC7C64C1D5298E20076FF94 /* OCamlLanguage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OCamlLanguage.h; path = Language/OCaml/OCamlLanguage.h; sourceTree = "<group>"; };
|
||||
|
@ -3939,6 +3953,7 @@
|
|||
2611FEF0142D83060017FEA3 /* SBBlock.i */,
|
||||
2611FEF1142D83060017FEA3 /* SBBreakpoint.i */,
|
||||
2611FEF2142D83060017FEA3 /* SBBreakpointLocation.i */,
|
||||
4C05332C1F63092A00DED368 /* SBBreakpointName.i */,
|
||||
2611FEF3142D83060017FEA3 /* SBBroadcaster.i */,
|
||||
2611FEF4142D83060017FEA3 /* SBCommandInterpreter.i */,
|
||||
2611FEF5142D83060017FEA3 /* SBCommandReturnObject.i */,
|
||||
|
@ -4032,6 +4047,10 @@
|
|||
9AF16A9C11402D5B007A7B3F /* SBBreakpoint.cpp */,
|
||||
9AF16CC611408686007A7B3F /* SBBreakpointLocation.h */,
|
||||
9AF16CC7114086A1007A7B3F /* SBBreakpointLocation.cpp */,
|
||||
4C54B2781F61CE1200D469CA /* SBBreakpointName.h */,
|
||||
4C54B27C1F61CE5300D469CA /* SBBreakpointName.cpp */,
|
||||
4C54B2811F62081300D469CA /* SBBreakpointOptionCommon.h */,
|
||||
4C0533291F6211FB00DED368 /* SBBreakpointOptionCommon.cpp */,
|
||||
9A9830F31125FC5800A56CB0 /* SBBroadcaster.h */,
|
||||
9A9830F21125FC5800A56CB0 /* SBBroadcaster.cpp */,
|
||||
9A9830F71125FC5800A56CB0 /* SBCommandInterpreter.h */,
|
||||
|
@ -4353,6 +4372,7 @@
|
|||
26BC7DD310F1B7D500F91463 /* Endian.h */,
|
||||
AFC2DCE61E6E2ED000283714 /* FastDemangle.cpp */,
|
||||
AFC2DCED1E6E2F9800283714 /* FastDemangle.h */,
|
||||
4CBFF0471F579A36004AFA92 /* Flags.h */,
|
||||
AFC2DCF21E6E30CF00283714 /* History.cpp */,
|
||||
AFC2DCF41E6E30D800283714 /* History.h */,
|
||||
236124A61986B50E004EFC37 /* IOObject.h */,
|
||||
|
@ -5041,6 +5061,8 @@
|
|||
26BC7E0F10F1B83100F91463 /* BreakpointLocationCollection.cpp */,
|
||||
26BC7CF410F1B71400F91463 /* BreakpointLocationList.h */,
|
||||
26BC7E1010F1B83100F91463 /* BreakpointLocationList.cpp */,
|
||||
4C7D48281F509CCD005314B4 /* BreakpointName.cpp */,
|
||||
4C7D482B1F509CF5005314B4 /* BreakpointName.h */,
|
||||
26BC7CF510F1B71400F91463 /* BreakpointOptions.h */,
|
||||
26BC7E1110F1B83100F91463 /* BreakpointOptions.cpp */,
|
||||
26BC7CF610F1B71400F91463 /* BreakpointResolver.h */,
|
||||
|
@ -6662,6 +6684,7 @@
|
|||
26C72C94124322890068DC16 /* SBStream.h in Headers */,
|
||||
9A357671116E7B5200E8ED2F /* SBStringList.h in Headers */,
|
||||
26DE205B11618FF600A093E2 /* SBSymbol.h in Headers */,
|
||||
4C54B27B1F61CE2800D469CA /* SBBreakpointName.h in Headers */,
|
||||
262F12B71835469C00AEB384 /* SBPlatform.h in Headers */,
|
||||
23DCBEA31D63E71F0084C36B /* SBStructuredData.h in Headers */,
|
||||
26DE204111618AB900A093E2 /* SBSymbolContext.h in Headers */,
|
||||
|
@ -7266,6 +7289,7 @@
|
|||
2668032C116005E2008E1FE4 /* SBFrame.cpp in Sources */,
|
||||
2668032D116005E3008E1FE4 /* SBFileSpec.cpp in Sources */,
|
||||
2668032E116005E5008E1FE4 /* SBEvent.cpp in Sources */,
|
||||
4C54B27E1F61CE6300D469CA /* SBBreakpointName.cpp in Sources */,
|
||||
2668032F116005E6008E1FE4 /* SBError.cpp in Sources */,
|
||||
23DCEA461D1C4D0F00A602B4 /* SBMemoryRegionInfo.cpp in Sources */,
|
||||
26680330116005E7008E1FE4 /* SBDebugger.cpp in Sources */,
|
||||
|
@ -7289,6 +7313,7 @@
|
|||
26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */,
|
||||
9A19A6B01163BBB300E0D453 /* SBValue.cpp in Sources */,
|
||||
261744781168585B005ADD65 /* SBType.cpp in Sources */,
|
||||
4C05332B1F62121E00DED368 /* SBBreakpointOptionCommon.cpp in Sources */,
|
||||
9A35758E116CFE0F00E8ED2F /* SBValueList.cpp in Sources */,
|
||||
9A357673116E7B6400E8ED2F /* SBStringList.cpp in Sources */,
|
||||
9A1E595C1EB2B141002206A5 /* SBTrace.cpp in Sources */,
|
||||
|
@ -7629,6 +7654,7 @@
|
|||
947CF7771DC7B20D00EF980B /* ThreadMinidump.cpp in Sources */,
|
||||
268900C913353E5F00698AC0 /* NameToDIE.cpp in Sources */,
|
||||
268900CA13353E5F00698AC0 /* SymbolFileDWARF.cpp in Sources */,
|
||||
4CAA19E61F5A40040099E692 /* BreakpointName.cpp in Sources */,
|
||||
268900CB13353E5F00698AC0 /* LogChannelDWARF.cpp in Sources */,
|
||||
268900CC13353E5F00698AC0 /* SymbolFileDWARFDebugMap.cpp in Sources */,
|
||||
268900CD13353E5F00698AC0 /* UniqueDWARFASTType.cpp in Sources */,
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.GDB"
|
||||
language = ""
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
|
@ -54,6 +55,7 @@
|
|||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
displayScaleIsEnabled = "NO"
|
||||
displayScale = "1.00"
|
||||
language = ""
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
|
|
@ -73,7 +73,7 @@ class BreakpointAutoContinue(TestBase):
|
|||
self.assertEqual(bkpt.GetHitCount(), 2, "Should have run through the breakpoint twice")
|
||||
|
||||
def auto_continue_with_command(self):
|
||||
bpno = self.make_target_and_bkpt("-N BKPT -d 'break modify --auto-continue 0 BKPT'")
|
||||
bpno = self.make_target_and_bkpt("-N BKPT -C 'break modify --auto-continue 0 BKPT'")
|
||||
process = self.launch_it(lldb.eStateStopped)
|
||||
state = process.GetState()
|
||||
self.assertEqual(state, lldb.eStateStopped, "Process should be stopped")
|
||||
|
|
|
@ -287,7 +287,7 @@ class BreakpointCommandTestCase(TestBase):
|
|||
# Add a breakpoint.
|
||||
lldbutil.run_break_set_by_file_and_line(
|
||||
self, "main.c", self.line, num_expected_locations=1, loc_exact=True,
|
||||
extra_options='-d bt -d "thread list" -d continue')
|
||||
extra_options='-C bt -C "thread list" -C continue')
|
||||
|
||||
bkpt = target.FindBreakpointByID(1)
|
||||
self.assertTrue(bkpt.IsValid(), "Couldn't find breakpoint 1")
|
||||
|
|
|
@ -17,6 +17,7 @@ from lldbsuite.test import lldbutil
|
|||
class BreakpointNames(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
NO_DEBUG_INFO_TESTCASE = True
|
||||
|
||||
@add_test_categories(['pyapi'])
|
||||
def test_setting_names(self):
|
||||
|
@ -37,6 +38,25 @@ class BreakpointNames(TestBase):
|
|||
self.setup_target()
|
||||
self.do_check_using_names()
|
||||
|
||||
def test_configuring_names(self):
|
||||
"""Use Python APIs to test that configuring options on breakpoint names works correctly."""
|
||||
self.build()
|
||||
self.make_a_dummy_name()
|
||||
self.setup_target()
|
||||
self.do_check_configuring_names()
|
||||
|
||||
def test_configuring_permissions_sb(self):
|
||||
"""Use Python APIs to test that configuring permissions on names works correctly."""
|
||||
self.build()
|
||||
self.setup_target()
|
||||
self.do_check_configuring_permissions_sb()
|
||||
|
||||
def test_configuring_permissions_cli(self):
|
||||
"""Use Python APIs to test that configuring permissions on names works correctly."""
|
||||
self.build()
|
||||
self.setup_target()
|
||||
self.do_check_configuring_permissions_cli()
|
||||
|
||||
def setup_target(self):
|
||||
exe = os.path.join(os.getcwd(), "a.out")
|
||||
|
||||
|
@ -45,10 +65,35 @@ class BreakpointNames(TestBase):
|
|||
self.assertTrue(self.target, VALID_TARGET)
|
||||
self.main_file_spec = lldb.SBFileSpec(os.path.join(os.getcwd(), "main.c"))
|
||||
|
||||
def check_name_in_target(self, bkpt_name):
|
||||
name_list = lldb.SBStringList()
|
||||
self.target.GetBreakpointNames(name_list)
|
||||
found_it = False
|
||||
for name in name_list:
|
||||
if name == bkpt_name:
|
||||
found_it = True
|
||||
break
|
||||
self.assertTrue(found_it, "Didn't find the name %s in the target's name list:"%(bkpt_name))
|
||||
|
||||
def setUp(self):
|
||||
# Call super's setUp().
|
||||
TestBase.setUp(self)
|
||||
|
||||
# These are the settings we're going to be putting into names & breakpoints:
|
||||
self.bp_name_string = "ABreakpoint"
|
||||
self.is_one_shot = True
|
||||
self.ignore_count = 1000
|
||||
self.condition = "1 == 2"
|
||||
self.auto_continue = True
|
||||
self.tid = 0xaaaa
|
||||
self.tidx = 10
|
||||
self.thread_name = "Fooey"
|
||||
self.queue_name = "Blooey"
|
||||
self.cmd_list = lldb.SBStringList()
|
||||
self.cmd_list.AppendString("frame var")
|
||||
self.cmd_list.AppendString("bt")
|
||||
|
||||
|
||||
def do_check_names(self):
|
||||
"""Use Python APIs to check that we can set & retrieve breakpoint names"""
|
||||
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
|
@ -66,11 +111,15 @@ class BreakpointNames(TestBase):
|
|||
matches = bkpt.MatchesName("NotABreakpoint")
|
||||
self.assertTrue(not matches, "We matched a name we didn't set.")
|
||||
|
||||
# Make sure the name is also in the target:
|
||||
self.check_name_in_target(bkpt_name)
|
||||
|
||||
# Add another name, make sure that works too:
|
||||
bkpt.AddName(other_bkpt_name)
|
||||
|
||||
matches = bkpt.MatchesName(bkpt_name)
|
||||
self.assertTrue(matches, "Adding a name means we didn't match the name we just set")
|
||||
self.check_name_in_target(other_bkpt_name)
|
||||
|
||||
# Remove the name and make sure we no longer match it:
|
||||
bkpt.RemoveName(bkpt_name)
|
||||
|
@ -89,26 +138,21 @@ class BreakpointNames(TestBase):
|
|||
def do_check_illegal_names(self):
|
||||
"""Use Python APIs to check that we reject illegal names."""
|
||||
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
success = bkpt.AddName("-CantStartWithADash")
|
||||
self.assertTrue(not success,"We allowed a name starting with a dash.")
|
||||
bad_names = ["-CantStartWithADash",
|
||||
"1CantStartWithANumber",
|
||||
"^CantStartWithNonAlpha",
|
||||
"CantHave-ADash",
|
||||
"Cant Have Spaces"]
|
||||
for bad_name in bad_names:
|
||||
success = bkpt.AddName(bad_name)
|
||||
self.assertTrue(not success,"We allowed an illegal name: %s"%(bad_name))
|
||||
bp_name = lldb.SBBreakpointName(self.target, bad_name)
|
||||
self.assertFalse(bp_name.IsValid(), "We made a breakpoint name with an illegal name: %s"%(bad_name));
|
||||
|
||||
success = bkpt.AddName("1CantStartWithANumber")
|
||||
self.assertTrue(not success, "We allowed a name starting with a number.")
|
||||
retval =lldb.SBCommandReturnObject()
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N '%s'"%(bad_name), retval)
|
||||
self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name: %s"%(bad_name))
|
||||
|
||||
success = bkpt.AddName("^CantStartWithNonAlpha")
|
||||
self.assertTrue(not success, "We allowed a name starting with an ^.")
|
||||
|
||||
success = bkpt.AddName("CantHave-ADash")
|
||||
self.assertTrue(not success, "We allowed a name with a dash in it.")
|
||||
|
||||
success = bkpt.AddName("Cant Have Spaces")
|
||||
self.assertTrue(not success, "We allowed a name with spaces.")
|
||||
|
||||
# Check from the command line as well:
|
||||
retval =lldb.SBCommandReturnObject()
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break set -n whatever -N has-dashes", retval)
|
||||
self.assertTrue(not retval.Succeeded(), "break set succeeded with: illegal name")
|
||||
|
||||
def do_check_using_names(self):
|
||||
"""Use Python APIs to check names work in place of breakpoint ID's."""
|
||||
|
||||
|
@ -133,9 +177,174 @@ class BreakpointNames(TestBase):
|
|||
self.assertTrue(not bkpt.IsEnabled(), "We didn't disable the breakpoint.")
|
||||
|
||||
# Also make sure we don't apply commands to non-matching names:
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(bkpt_name), retval)
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break modify --one-shot 1 %s"%(other_bkpt_name), retval)
|
||||
self.assertTrue(retval.Succeeded(), "break modify failed with: %s."%(retval.GetError()))
|
||||
self.assertTrue(not bkpt.IsOneShot(), "We applied one-shot to the wrong breakpoint.")
|
||||
|
||||
def check_option_values(self, bp_object):
|
||||
self.assertEqual(bp_object.IsOneShot(), self.is_one_shot, "IsOneShot")
|
||||
self.assertEqual(bp_object.GetIgnoreCount(), self.ignore_count, "IgnoreCount")
|
||||
self.assertEqual(bp_object.GetCondition(), self.condition, "Condition")
|
||||
self.assertEqual(bp_object.GetAutoContinue(), self.auto_continue, "AutoContinue")
|
||||
self.assertEqual(bp_object.GetThreadID(), self.tid, "Thread ID")
|
||||
self.assertEqual(bp_object.GetThreadIndex(), self.tidx, "Thread Index")
|
||||
self.assertEqual(bp_object.GetThreadName(), self.thread_name, "Thread Name")
|
||||
self.assertEqual(bp_object.GetQueueName(), self.queue_name, "Queue Name")
|
||||
set_cmds = lldb.SBStringList()
|
||||
bp_object.GetCommandLineCommands(set_cmds)
|
||||
self.assertEqual(set_cmds.GetSize(), self.cmd_list.GetSize(), "Size of command line commands")
|
||||
for idx in range(0, set_cmds.GetSize()):
|
||||
self.assertEqual(self.cmd_list.GetStringAtIndex(idx), set_cmds.GetStringAtIndex(idx), "Command %d"%(idx))
|
||||
|
||||
def make_a_dummy_name(self):
|
||||
"This makes a breakpoint name in the dummy target to make sure it gets copied over"
|
||||
|
||||
dummy_target = self.dbg.GetDummyTarget()
|
||||
self.assertTrue(dummy_target.IsValid(), "Dummy target was not valid.")
|
||||
|
||||
def cleanup ():
|
||||
self.dbg.GetDummyTarget().DeleteBreakpointName(self.bp_name_string)
|
||||
|
||||
# Execute the cleanup function during test case tear down.
|
||||
self.addTearDownHook(cleanup)
|
||||
|
||||
# Now find it in the dummy target, and make sure these settings took:
|
||||
bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
|
||||
# Make sure the name is right:
|
||||
self.assertTrue (bp_name.GetName() == self.bp_name_string, "Wrong bp_name: %s"%(bp_name.GetName()))
|
||||
bp_name.SetOneShot(self.is_one_shot)
|
||||
bp_name.SetIgnoreCount(self.ignore_count)
|
||||
bp_name.SetCondition(self.condition)
|
||||
bp_name.SetAutoContinue(self.auto_continue)
|
||||
bp_name.SetThreadID(self.tid)
|
||||
bp_name.SetThreadIndex(self.tidx)
|
||||
bp_name.SetThreadName(self.thread_name)
|
||||
bp_name.SetQueueName(self.queue_name)
|
||||
bp_name.SetCommandLineCommands(self.cmd_list)
|
||||
|
||||
# Now look it up again, and make sure it got set correctly.
|
||||
bp_name = lldb.SBBreakpointName(dummy_target, self.bp_name_string)
|
||||
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
|
||||
self.check_option_values(bp_name)
|
||||
|
||||
def do_check_configuring_names(self):
|
||||
"""Use Python APIs to check that configuring breakpoint names works correctly."""
|
||||
other_bp_name_string = "AnotherBreakpointName"
|
||||
cl_bp_name_string = "CLBreakpointName"
|
||||
|
||||
# Now find the version copied in from the dummy target, and make sure these settings took:
|
||||
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
|
||||
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name.")
|
||||
self.check_option_values(bp_name)
|
||||
|
||||
# Now add this name to a breakpoint, and make sure it gets configured properly
|
||||
bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
success = bkpt.AddName(self.bp_name_string)
|
||||
self.assertTrue(success, "Couldn't add this name to the breakpoint")
|
||||
self.check_option_values(bkpt)
|
||||
|
||||
# Now make a name from this breakpoint, and make sure the new name is properly configured:
|
||||
new_name = lldb.SBBreakpointName(bkpt, other_bp_name_string)
|
||||
self.assertTrue(new_name.IsValid(), "Couldn't make a valid bp_name from a breakpoint.")
|
||||
self.check_option_values(bkpt)
|
||||
|
||||
# Now change the name's option and make sure it gets propagated to
|
||||
# the breakpoint:
|
||||
new_auto_continue = not self.auto_continue
|
||||
bp_name.SetAutoContinue(new_auto_continue)
|
||||
self.assertEqual(bp_name.GetAutoContinue(), new_auto_continue, "Couldn't change auto-continue on the name")
|
||||
self.assertEqual(bkpt.GetAutoContinue(), new_auto_continue, "Option didn't propagate to the breakpoint.")
|
||||
|
||||
# Now make this same breakpoint name - but from the command line
|
||||
cmd_str = "breakpoint name configure %s -o %d -i %d -c '%s' -G %d -t %d -x %d -T '%s' -q '%s'"%(cl_bp_name_string,
|
||||
self.is_one_shot,
|
||||
self.ignore_count,
|
||||
self.condition,
|
||||
self.auto_continue,
|
||||
self.tid,
|
||||
self.tidx,
|
||||
self.thread_name,
|
||||
self.queue_name)
|
||||
for cmd in self.cmd_list:
|
||||
cmd_str += " -C '%s'"%(cmd)
|
||||
|
||||
result = lldb.SBCommandReturnObject()
|
||||
self.dbg.GetCommandInterpreter().HandleCommand(cmd_str, result)
|
||||
self.assertTrue(result.Succeeded())
|
||||
# Now look up this name again and check its options:
|
||||
cl_name = lldb.SBBreakpointName(self.target, cl_bp_name_string)
|
||||
self.check_option_values(cl_name)
|
||||
|
||||
# We should have three names now, make sure the target can list them:
|
||||
name_list = lldb.SBStringList()
|
||||
self.target.GetBreakpointNames(name_list)
|
||||
for name_string in [self.bp_name_string, other_bp_name_string, cl_bp_name_string]:
|
||||
self.assertTrue(name_string in name_list, "Didn't find %s in names"%(name_string))
|
||||
|
||||
# Test that deleting the name we injected into the dummy target works (there's also a
|
||||
# cleanup that will do this, but that won't test the result...
|
||||
dummy_target = self.dbg.GetDummyTarget()
|
||||
dummy_target.DeleteBreakpointName(self.bp_name_string)
|
||||
name_list.Clear()
|
||||
dummy_target.GetBreakpointNames(name_list)
|
||||
self.assertTrue(self.bp_name_string not in name_list, "Didn't delete %s from the dummy target"%(self.bp_name_string))
|
||||
|
||||
def check_permission_results(self, bp_name):
|
||||
self.assertEqual(bp_name.GetAllowDelete(), False, "Didn't set allow delete.")
|
||||
protected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
protected_id = protected_bkpt.GetID()
|
||||
|
||||
unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
unprotected_id = unprotected_bkpt.GetID()
|
||||
|
||||
success = protected_bkpt.AddName(self.bp_name_string)
|
||||
self.assertTrue(success, "Couldn't add this name to the breakpoint")
|
||||
|
||||
self.target.DisableAllBreakpoints()
|
||||
self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
|
||||
self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
|
||||
|
||||
# Try from the command line too:
|
||||
unprotected_bkpt.SetEnabled(True)
|
||||
result = lldb.SBCommandReturnObject()
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break disable", result)
|
||||
self.assertTrue(result.Succeeded())
|
||||
self.assertEqual(protected_bkpt.IsEnabled(), True, "Didnt' keep breakpoint from being disabled")
|
||||
self.assertEqual(unprotected_bkpt.IsEnabled(), False, "Protected too many breakpoints from disabling.")
|
||||
|
||||
self.target.DeleteAllBreakpoints()
|
||||
bkpt = self.target.FindBreakpointByID(protected_id)
|
||||
self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
|
||||
bkpt = self.target.FindBreakpointByID(unprotected_id)
|
||||
self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
|
||||
|
||||
# Remake the unprotected breakpoint and try again from the command line:
|
||||
unprotected_bkpt = self.target.BreakpointCreateByLocation(self.main_file_spec, 10)
|
||||
unprotected_id = unprotected_bkpt.GetID()
|
||||
|
||||
self.dbg.GetCommandInterpreter().HandleCommand("break delete -f", result)
|
||||
self.assertTrue(result.Succeeded())
|
||||
bkpt = self.target.FindBreakpointByID(protected_id)
|
||||
self.assertTrue(bkpt.IsValid(), "Didn't keep the breakpoint from being deleted.")
|
||||
bkpt = self.target.FindBreakpointByID(unprotected_id)
|
||||
self.assertFalse(bkpt.IsValid(), "Protected too many breakpoints from deletion.")
|
||||
|
||||
def do_check_configuring_permissions_sb(self):
|
||||
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
|
||||
|
||||
# Make a breakpoint name with delete disallowed:
|
||||
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
|
||||
self.assertTrue(bp_name.IsValid(), "Failed to make breakpoint name for valid name.")
|
||||
|
||||
bp_name.SetAllowDelete(False)
|
||||
bp_name.SetAllowDisable(False)
|
||||
bp_name.SetAllowList(False)
|
||||
self.check_permission_results(bp_name)
|
||||
|
||||
def do_check_configuring_permissions_cli(self):
|
||||
# Make the name with the right options using the command line:
|
||||
self.runCmd("breakpoint name configure -L 0 -D 0 -A 0 %s"%(self.bp_name_string), check=True)
|
||||
# Now look up the breakpoint we made, and check that it works.
|
||||
bp_name = lldb.SBBreakpointName(self.target, self.bp_name_string)
|
||||
self.assertTrue(bp_name.IsValid(), "Didn't make a breakpoint name we could find.")
|
||||
self.check_permission_results(bp_name)
|
||||
|
|
|
@ -71,6 +71,17 @@ class APIDefaultConstructorTestCase(TestBase):
|
|||
import sb_breakpointlocation
|
||||
sb_breakpointlocation.fuzz_obj(obj)
|
||||
|
||||
@add_test_categories(['pyapi'])
|
||||
@no_debug_info_test
|
||||
def test_SBBreakpointName(self):
|
||||
obj = lldb.SBBreakpointName()
|
||||
if self.TraceOn():
|
||||
print(obj)
|
||||
self.assertFalse(obj)
|
||||
# Do fuzz testing on the invalid obj, it should not crash lldb.
|
||||
import sb_breakpointname
|
||||
sb_breakpointname.fuzz_obj(obj)
|
||||
|
||||
@add_test_categories(['pyapi'])
|
||||
@no_debug_info_test
|
||||
def test_SBBroadcaster(self):
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
"""
|
||||
Fuzz tests an object after the default construction to make sure it does not crash lldb.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import lldb
|
||||
|
||||
|
||||
def fuzz_obj(obj):
|
||||
obj.IsValid()
|
||||
obj.GetName()
|
||||
obj.SetEnabled(True)
|
||||
obj.IsEnabled()
|
||||
obj.SetOneShot(True)
|
||||
obj.IsOneShot()
|
||||
obj.SetIgnoreCount(1)
|
||||
obj.GetIgnoreCount()
|
||||
obj.SetCondition("1 == 2")
|
||||
obj.GetCondition()
|
||||
obj.SetAutoContinue(False)
|
||||
obj.GetAutoContinue()
|
||||
obj.SetThreadID(0x1234)
|
||||
obj.GetThreadID()
|
||||
obj.SetThreadIndex(10)
|
||||
obj.GetThreadIndex()
|
||||
obj.SetThreadName("AThread")
|
||||
obj.GetThreadName()
|
||||
obj.SetQueueName("AQueue")
|
||||
obj.GetQueueName()
|
||||
obj.SetScriptCallbackFunction("AFunction")
|
||||
commands = lldb.SBStringList()
|
||||
obj.SetCommandLineCommands(commands)
|
||||
obj.GetCommandLineCommands(commands)
|
||||
obj.SetScriptCallbackBody("Insert Python Code here")
|
||||
obj.GetAllowList()
|
||||
obj.SetAllowList(False)
|
||||
obj.GetAllowDelete()
|
||||
obj.SetAllowDelete(False)
|
||||
obj.GetAllowDisable()
|
||||
obj.SetAllowDisable(False)
|
||||
stream = lldb.SBStream()
|
||||
obj.GetDescription(stream)
|
|
@ -71,6 +71,21 @@
|
|||
}
|
||||
}
|
||||
|
||||
%extend lldb::SBBreakpointName {
|
||||
PyObject *lldb::SBBreakpointName::__str__ (){
|
||||
lldb::SBStream description;
|
||||
$self->GetDescription (description);
|
||||
const char *desc = description.GetData();
|
||||
size_t desc_len = description.GetSize();
|
||||
if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
|
||||
--desc_len;
|
||||
if (desc_len > 0)
|
||||
return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
|
||||
else
|
||||
return lldb_private::PythonString("").release();
|
||||
}
|
||||
}
|
||||
|
||||
%extend lldb::SBBroadcaster {
|
||||
%pythoncode %{
|
||||
def __eq__(self, rhs):
|
||||
|
|
|
@ -113,6 +113,13 @@ SBTypeToSWIGWrapper (lldb::SBBreakpointLocation* breakpoint_location_sb)
|
|||
return SWIG_NewPointerObj((void *) breakpoint_location_sb, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
|
||||
}
|
||||
|
||||
template <>
|
||||
PyObject*
|
||||
SBTypeToSWIGWrapper (lldb::SBBreakpointName* breakpoint_name_sb)
|
||||
{
|
||||
return SWIG_NewPointerObj((void *) breakpoint_name_sb, SWIGTYPE_p_lldb__SBBreakpointName, 0);
|
||||
}
|
||||
|
||||
template <>
|
||||
PyObject*
|
||||
SBTypeToSWIGWrapper (lldb::SBValue* value_sb)
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace lldb {
|
||||
|
||||
%feature("docstring",
|
||||
|
@ -81,11 +80,6 @@ class SBBreakpoint
|
|||
{
|
||||
public:
|
||||
|
||||
typedef bool (*BreakpointHitCallback) (void *baton,
|
||||
SBProcess &process,
|
||||
SBThread &thread,
|
||||
lldb::SBBreakpointLocation &location);
|
||||
|
||||
SBBreakpoint ();
|
||||
|
||||
SBBreakpoint (const lldb::SBBreakpoint& rhs);
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
//===-- SWIG interface for SBBreakpointName.h -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace lldb {
|
||||
%feature("docstring",
|
||||
"Represents a breakpoint name registered in a given SBTarget.
|
||||
|
||||
Breakpoint names provide a way to act on groups of breakpoints. When you add a
|
||||
name to a group of breakpoints, you can then use the name in all the command
|
||||
line lldb commands for that name. You can also configure the SBBreakpointName
|
||||
options and those options will be propagated to any SBBreakpoints currently
|
||||
using that name. Adding a name to a breakpoint will also apply any of the
|
||||
set options to that breakpoint.
|
||||
|
||||
You can also set permissions on a breakpoint name to disable listing, deleting
|
||||
and disabling breakpoints. That will disallow the given operation for breakpoints
|
||||
except when the breakpoint is mentioned by ID. So for instance deleting all the
|
||||
breakpoints won't delete breakpoints so marked."
|
||||
) SBBreakpointName;
|
||||
class LLDB_API SBBreakpointName {
|
||||
public:
|
||||
SBBreakpointName();
|
||||
|
||||
SBBreakpointName(SBTarget &target, const char *name);
|
||||
|
||||
SBBreakpointName(SBBreakpoint &bkpt, const char *name);
|
||||
|
||||
SBBreakpointName(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
~SBBreakpointName();
|
||||
|
||||
const lldb::SBBreakpointName &operator=(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
// Tests to see if the opaque breakpoint object in this object matches the
|
||||
// opaque breakpoint object in "rhs".
|
||||
bool operator==(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
bool operator!=(const lldb::SBBreakpointName &rhs);
|
||||
|
||||
bool IsValid() const;
|
||||
|
||||
const char *GetName() const;
|
||||
|
||||
void SetEnabled(bool enable);
|
||||
|
||||
bool IsEnabled();
|
||||
|
||||
void SetOneShot(bool one_shot);
|
||||
|
||||
bool IsOneShot() const;
|
||||
|
||||
void SetIgnoreCount(uint32_t count);
|
||||
|
||||
uint32_t GetIgnoreCount() const;
|
||||
|
||||
void SetCondition(const char *condition);
|
||||
|
||||
const char *GetCondition();
|
||||
|
||||
void SetAutoContinue(bool auto_continue);
|
||||
|
||||
bool GetAutoContinue();
|
||||
|
||||
void SetThreadID(lldb::tid_t sb_thread_id);
|
||||
|
||||
lldb::tid_t GetThreadID();
|
||||
|
||||
void SetThreadIndex(uint32_t index);
|
||||
|
||||
uint32_t GetThreadIndex() const;
|
||||
|
||||
void SetThreadName(const char *thread_name);
|
||||
|
||||
const char *GetThreadName() const;
|
||||
|
||||
void SetQueueName(const char *queue_name);
|
||||
|
||||
const char *GetQueueName() const;
|
||||
|
||||
void SetScriptCallbackFunction(const char *callback_function_name);
|
||||
|
||||
void SetCommandLineCommands(SBStringList &commands);
|
||||
|
||||
bool GetCommandLineCommands(SBStringList &commands);
|
||||
|
||||
SBError SetScriptCallbackBody(const char *script_body_text);
|
||||
|
||||
bool GetAllowList() const;
|
||||
void SetAllowList(bool value);
|
||||
|
||||
bool GetAllowDelete();
|
||||
void SetAllowDelete(bool value);
|
||||
|
||||
bool GetAllowDisable();
|
||||
void SetAllowDisable(bool value);
|
||||
|
||||
bool GetDescription(lldb::SBStream &description);
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
|
@ -213,6 +213,11 @@ public:
|
|||
lldb::SBTarget
|
||||
CreateTarget (const char *filename);
|
||||
|
||||
%feature("docstring",
|
||||
"The dummy target holds breakpoints and breakpoint names that will prime newly created targets."
|
||||
) GetDummyTarget;
|
||||
lldb::SBTarget GetDummyTarget();
|
||||
|
||||
%feature("docstring",
|
||||
"Return true if target is deleted from the target list of the debugger."
|
||||
) DeleteTarget;
|
||||
|
|
|
@ -711,6 +711,10 @@ public:
|
|||
|
||||
bool FindBreakpointsByName(const char *name, SBBreakpointList &bkpt_list);
|
||||
|
||||
void DeleteBreakpointName(const char *name);
|
||||
|
||||
void GetBreakpointNames(SBStringList &names);
|
||||
|
||||
bool
|
||||
EnableAllBreakpoints ();
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ import six
|
|||
#include "lldb/API/SBBlock.h"
|
||||
#include "lldb/API/SBBreakpoint.h"
|
||||
#include "lldb/API/SBBreakpointLocation.h"
|
||||
#include "lldb/API/SBBreakpointName.h"
|
||||
#include "lldb/API/SBBroadcaster.h"
|
||||
#include "lldb/API/SBCommandInterpreter.h"
|
||||
#include "lldb/API/SBCommandReturnObject.h"
|
||||
|
@ -168,6 +169,7 @@ import six
|
|||
%include "./interface/SBBlock.i"
|
||||
%include "./interface/SBBreakpoint.i"
|
||||
%include "./interface/SBBreakpointLocation.i"
|
||||
%include "./interface/SBBreakpointName.i"
|
||||
%include "./interface/SBBroadcaster.i"
|
||||
%include "./interface/SBCommandInterpreter.i"
|
||||
%include "./interface/SBCommandReturnObject.i"
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
#include "SBBreakpointOptionCommon.h"
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
@ -44,21 +46,6 @@
|
|||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
struct CallbackData {
|
||||
SBBreakpoint::BreakpointHitCallback callback;
|
||||
void *callback_baton;
|
||||
};
|
||||
|
||||
class SBBreakpointCallbackBaton : public TypedBaton<CallbackData> {
|
||||
public:
|
||||
SBBreakpointCallbackBaton(SBBreakpoint::BreakpointHitCallback callback,
|
||||
void *baton)
|
||||
: TypedBaton(llvm::make_unique<CallbackData>()) {
|
||||
getItem()->callback = callback;
|
||||
getItem()->callback_baton = baton;
|
||||
}
|
||||
};
|
||||
|
||||
SBBreakpoint::SBBreakpoint() {}
|
||||
|
||||
SBBreakpoint::SBBreakpoint(const SBBreakpoint &rhs)
|
||||
|
@ -500,37 +487,9 @@ bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool SBBreakpoint::PrivateBreakpointHitCallback(void *baton,
|
||||
StoppointCallbackContext *ctx,
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id) {
|
||||
ExecutionContext exe_ctx(ctx->exe_ctx_ref);
|
||||
BreakpointSP bp_sp(
|
||||
exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
|
||||
if (baton && bp_sp) {
|
||||
CallbackData *data = (CallbackData *)baton;
|
||||
lldb_private::Breakpoint *bp = bp_sp.get();
|
||||
if (bp && data->callback) {
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process) {
|
||||
SBProcess sb_process(process->shared_from_this());
|
||||
SBThread sb_thread;
|
||||
SBBreakpointLocation sb_location;
|
||||
assert(bp_sp);
|
||||
sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (thread)
|
||||
sb_thread.SetThread(thread->shared_from_this());
|
||||
|
||||
return data->callback(data->callback_baton, sb_process, sb_thread,
|
||||
sb_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // Return true if we should stop at this breakpoint
|
||||
}
|
||||
|
||||
void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
|
||||
void SBBreakpoint
|
||||
::SetCallback(SBBreakpointHitCallback callback,
|
||||
void *baton) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
BreakpointSP bkpt_sp = GetSP();
|
||||
LLDB_LOG(log, "breakpoint = {0}, callback = {1}, baton = {2}", bkpt_sp.get(),
|
||||
|
@ -540,7 +499,8 @@ void SBBreakpoint::SetCallback(BreakpointHitCallback callback, void *baton) {
|
|||
std::lock_guard<std::recursive_mutex> guard(
|
||||
bkpt_sp->GetTarget().GetAPIMutex());
|
||||
BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
|
||||
bkpt_sp->SetCallback(SBBreakpoint::PrivateBreakpointHitCallback, baton_sp,
|
||||
bkpt_sp->SetCallback(SBBreakpointCallbackBaton
|
||||
::PrivateBreakpointHitCallback, baton_sp,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
@ -599,10 +559,17 @@ bool SBBreakpoint::AddName(const char *new_name) {
|
|||
bkpt_sp->GetTarget().GetAPIMutex());
|
||||
Status error; // Think I'm just going to swallow the error here, it's
|
||||
// probably more annoying to have to provide it.
|
||||
return bkpt_sp->AddName(new_name, error);
|
||||
bkpt_sp->GetTarget().AddNameToBreakpoint(bkpt_sp, new_name, error);
|
||||
if (error.Fail())
|
||||
{
|
||||
if (log)
|
||||
log->Printf("Failed to add name: '%s' to breakpoint: %s",
|
||||
new_name, error.AsCString());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SBBreakpoint::RemoveName(const char *name_to_remove) {
|
||||
|
@ -613,7 +580,8 @@ void SBBreakpoint::RemoveName(const char *name_to_remove) {
|
|||
if (bkpt_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
bkpt_sp->GetTarget().GetAPIMutex());
|
||||
bkpt_sp->RemoveName(name_to_remove);
|
||||
bkpt_sp->GetTarget().RemoveNameFromBreakpoint(bkpt_sp,
|
||||
ConstString(name_to_remove));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,662 @@
|
|||
//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/API/SBBreakpointName.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBError.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/API/SBTarget.h"
|
||||
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
#include "SBBreakpointOptionCommon.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
namespace lldb
|
||||
{
|
||||
class SBBreakpointNameImpl {
|
||||
public:
|
||||
SBBreakpointNameImpl(SBTarget &sb_target, const char *name)
|
||||
{
|
||||
if (!name || name[0] == '\0')
|
||||
return;
|
||||
m_name.assign(name);
|
||||
|
||||
if (!sb_target.IsValid())
|
||||
return;
|
||||
|
||||
TargetSP target_sp = sb_target.GetSP();
|
||||
if (!target_sp)
|
||||
return;
|
||||
|
||||
m_target_wp = target_sp;
|
||||
}
|
||||
|
||||
SBBreakpointNameImpl(TargetSP target_sp, const char *name)
|
||||
{
|
||||
if (!name || name[0] == '\0')
|
||||
return;
|
||||
m_name.assign(name);
|
||||
|
||||
if (!target_sp)
|
||||
return;
|
||||
|
||||
m_target_wp = target_sp;
|
||||
}
|
||||
|
||||
bool operator==(const SBBreakpointNameImpl &rhs) {
|
||||
return m_name == rhs.m_name
|
||||
&& m_target_wp.lock() == rhs.m_target_wp.lock();
|
||||
}
|
||||
|
||||
bool operator!=(const SBBreakpointNameImpl &rhs) {
|
||||
return m_name != rhs.m_name
|
||||
|| m_target_wp.lock() != rhs.m_target_wp.lock();
|
||||
}
|
||||
// For now we take a simple approach and only keep the name, and relook
|
||||
// up the location when we need it.
|
||||
|
||||
TargetSP GetTarget() {
|
||||
return m_target_wp.lock();
|
||||
}
|
||||
|
||||
const char *GetName() {
|
||||
return m_name.c_str();
|
||||
}
|
||||
|
||||
bool IsValid() {
|
||||
return !m_name.empty() && m_target_wp.lock();
|
||||
}
|
||||
|
||||
lldb_private::BreakpointName *GetBreakpointName()
|
||||
{
|
||||
if (!IsValid())
|
||||
return nullptr;
|
||||
TargetSP target_sp = GetTarget();
|
||||
if (!target_sp)
|
||||
return nullptr;
|
||||
Status error;
|
||||
return target_sp->FindBreakpointName(ConstString(m_name), true, error);
|
||||
}
|
||||
|
||||
const lldb_private::BreakpointName *GetBreakpointName() const
|
||||
{
|
||||
return GetBreakpointName();
|
||||
}
|
||||
|
||||
private:
|
||||
TargetWP m_target_wp;
|
||||
std::string m_name;
|
||||
};
|
||||
} // namespace lldb
|
||||
|
||||
SBBreakpointName::SBBreakpointName() {}
|
||||
|
||||
SBBreakpointName::SBBreakpointName(SBTarget &sb_target, const char *name)
|
||||
{
|
||||
m_impl_up.reset(new SBBreakpointNameImpl(sb_target, name));
|
||||
// Call FindBreakpointName here to make sure the name is valid, reset if
|
||||
// not:
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
m_impl_up.reset();
|
||||
}
|
||||
|
||||
SBBreakpointName::SBBreakpointName(SBBreakpoint &sb_bkpt, const char *name)
|
||||
{
|
||||
if (!sb_bkpt.IsValid()) {
|
||||
m_impl_up.reset();
|
||||
return;
|
||||
}
|
||||
BreakpointSP bkpt_sp = sb_bkpt.GetSP();
|
||||
Target &target = bkpt_sp->GetTarget();
|
||||
|
||||
m_impl_up.reset(new SBBreakpointNameImpl(target.shared_from_this(), name));
|
||||
|
||||
// Call FindBreakpointName here to make sure the name is valid, reset if
|
||||
// not:
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name) {
|
||||
m_impl_up.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
// Now copy over the breakpoint's options:
|
||||
target.ConfigureBreakpointName(*bp_name, *bkpt_sp->GetOptions(),
|
||||
BreakpointName::Permissions());
|
||||
}
|
||||
|
||||
SBBreakpointName::SBBreakpointName(const SBBreakpointName &rhs)
|
||||
{
|
||||
if (!rhs.m_impl_up)
|
||||
return;
|
||||
else
|
||||
m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
|
||||
rhs.m_impl_up->GetName()));
|
||||
}
|
||||
|
||||
SBBreakpointName::~SBBreakpointName() = default;
|
||||
|
||||
const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs)
|
||||
{
|
||||
if (!rhs.m_impl_up) {
|
||||
m_impl_up.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
m_impl_up.reset(new SBBreakpointNameImpl(rhs.m_impl_up->GetTarget(),
|
||||
rhs.m_impl_up->GetName()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) {
|
||||
return *m_impl_up.get() == *rhs.m_impl_up.get();
|
||||
}
|
||||
|
||||
bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) {
|
||||
return *m_impl_up.get() != *rhs.m_impl_up.get();
|
||||
}
|
||||
|
||||
bool SBBreakpointName::IsValid() const {
|
||||
if (!m_impl_up)
|
||||
return false;
|
||||
return m_impl_up->IsValid();
|
||||
}
|
||||
|
||||
const char *SBBreakpointName::GetName() const {
|
||||
if (!m_impl_up)
|
||||
return "<Invalid Breakpoint Name Object>";
|
||||
return m_impl_up->GetName();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetEnabled(bool enable) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} enabled: {1}\n", bp_name->GetName(), enable);
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetEnabled(enable);
|
||||
}
|
||||
|
||||
void SBBreakpointName::UpdateName(BreakpointName &bp_name) {
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
TargetSP target_sp = m_impl_up->GetTarget();
|
||||
if (!target_sp)
|
||||
return;
|
||||
target_sp->ApplyNameToBreakpoints(bp_name);
|
||||
|
||||
}
|
||||
|
||||
bool SBBreakpointName::IsEnabled() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().IsEnabled();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetOneShot(bool one_shot) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), one_shot);
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetOneShot(one_shot);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
bool SBBreakpointName::IsOneShot() const {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
const BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().IsOneShot();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetIgnoreCount(uint32_t count) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(), count);
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetIgnoreCount(count);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
uint32_t SBBreakpointName::GetIgnoreCount() const {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetIgnoreCount();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetCondition(const char *condition) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} one_shot: {1}\n", bp_name->GetName(),
|
||||
condition ? condition : "<NULL>");
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetCondition(condition);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
const char *SBBreakpointName::GetCondition() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return nullptr;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetConditionText();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetAutoContinue(bool auto_continue) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} auto-continue: {1}\n", bp_name->GetName(), auto_continue);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetAutoContinue(auto_continue);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetAutoContinue() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return nullptr;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().IsAutoContinue();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetThreadID(tid_t tid) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} tid: {1:x}\n", bp_name->GetName(), tid);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().SetThreadID(tid);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
tid_t SBBreakpointName::GetThreadID() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return LLDB_INVALID_THREAD_ID;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetThreadSpec()->GetTID();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetThreadIndex(uint32_t index) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} thread index: {1}\n", bp_name->GetName(), index);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().GetThreadSpec()->SetIndex(index);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
uint32_t SBBreakpointName::GetThreadIndex() const {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return LLDB_INVALID_THREAD_ID;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetThreadSpec()->GetIndex();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetThreadName(const char *thread_name) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} thread name: {1}\n", bp_name->GetName(), thread_name);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().GetThreadSpec()->SetName(thread_name);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
const char *SBBreakpointName::GetThreadName() const {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return nullptr;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetThreadSpec()->GetName();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetQueueName(const char *queue_name) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} queue name: {1}\n", bp_name->GetName(), queue_name);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
bp_name->GetOptions().GetThreadSpec()->SetQueueName(queue_name);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
const char *SBBreakpointName::GetQueueName() const {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return nullptr;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
return bp_name->GetOptions().GetThreadSpec()->GetQueueName();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
if (commands.GetSize() == 0)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} commands\n", bp_name->GetName());
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
std::unique_ptr<BreakpointOptions::CommandData> cmd_data_up(
|
||||
new BreakpointOptions::CommandData(*commands, eScriptLanguageNone));
|
||||
|
||||
bp_name->GetOptions().SetCommandDataCallback(cmd_data_up);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetCommandLineCommands(SBStringList &commands) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
StringList command_list;
|
||||
bool has_commands =
|
||||
bp_name->GetOptions().GetCommandLineCallbacks(command_list);
|
||||
if (has_commands)
|
||||
commands.AppendList(command_list);
|
||||
return has_commands;
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetDescription(SBStream &s) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
{
|
||||
s.Printf("No value");
|
||||
return false;
|
||||
}
|
||||
|
||||
LLDB_LOG(log, "Name: {0}\n", bp_name->GetName());
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
bp_name->GetDescription(s.get(), eDescriptionLevelFull);
|
||||
return true;
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetCallback(SBBreakpointHitCallback callback,
|
||||
void *baton) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
LLDB_LOG(log, "callback = {1}, baton = {2}", callback, baton);
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
BatonSP baton_sp(new SBBreakpointCallbackBaton(callback, baton));
|
||||
bp_name->GetOptions().SetCallback(SBBreakpointCallbackBaton
|
||||
::PrivateBreakpointHitCallback,
|
||||
baton_sp,
|
||||
false);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetScriptCallbackFunction(
|
||||
const char *callback_function_name) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
|
||||
callback_function_name);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
BreakpointOptions &bp_options = bp_name->GetOptions();
|
||||
m_impl_up->GetTarget()
|
||||
->GetDebugger()
|
||||
.GetCommandInterpreter()
|
||||
.GetScriptInterpreter()
|
||||
->SetBreakpointCommandCallbackFunction(&bp_options,
|
||||
callback_function_name);
|
||||
UpdateName(*bp_name);
|
||||
}
|
||||
|
||||
SBError SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
SBError sb_error;
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return sb_error;
|
||||
|
||||
LLDB_LOG(log, "Name: {0} callback: {1}\n", bp_name->GetName(),
|
||||
callback_body_text);
|
||||
|
||||
std::lock_guard<std::recursive_mutex> guard(
|
||||
m_impl_up->GetTarget()->GetAPIMutex());
|
||||
|
||||
BreakpointOptions &bp_options = bp_name->GetOptions();
|
||||
Status error =
|
||||
m_impl_up->GetTarget()
|
||||
->GetDebugger()
|
||||
.GetCommandInterpreter()
|
||||
.GetScriptInterpreter()
|
||||
->SetBreakpointCommandCallback(&bp_options, callback_body_text);
|
||||
sb_error.SetError(error);
|
||||
if (!sb_error.Fail())
|
||||
UpdateName(*bp_name);
|
||||
|
||||
return sb_error;
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetAllowList() const
|
||||
{
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
return bp_name->GetPermissions().GetAllowList();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetAllowList(bool value)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
if (log)
|
||||
log->Printf("Setting allow list to %u for %s.", value,
|
||||
bp_name->GetName().AsCString());
|
||||
bp_name->GetPermissions().SetAllowList(value);
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetAllowDelete()
|
||||
{
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
return bp_name->GetPermissions().GetAllowDelete();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetAllowDelete(bool value)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
if (log)
|
||||
log->Printf("Setting allow delete to %u for %s.", value,
|
||||
bp_name->GetName().AsCString());
|
||||
bp_name->GetPermissions().SetAllowDelete(value);
|
||||
}
|
||||
|
||||
bool SBBreakpointName::GetAllowDisable()
|
||||
{
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return false;
|
||||
return bp_name->GetPermissions().GetAllowDisable();
|
||||
}
|
||||
|
||||
void SBBreakpointName::SetAllowDisable(bool value)
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
|
||||
BreakpointName *bp_name = GetBreakpointName();
|
||||
if (!bp_name)
|
||||
return;
|
||||
if (log)
|
||||
log->Printf("Setting allow disable to %u for %s.", value,
|
||||
bp_name->GetName().AsCString());
|
||||
bp_name->GetPermissions().SetAllowDisable(value);
|
||||
}
|
||||
|
||||
lldb_private::BreakpointName *SBBreakpointName::GetBreakpointName() const
|
||||
{
|
||||
if (!IsValid())
|
||||
return nullptr;
|
||||
return m_impl_up->GetBreakpointName();
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
//===-- SBBreakpointName.cpp ----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/API/SBBreakpointName.h"
|
||||
#include "lldb/API/SBBreakpointLocation.h"
|
||||
#include "lldb/API/SBDebugger.h"
|
||||
#include "lldb/API/SBEvent.h"
|
||||
#include "lldb/API/SBProcess.h"
|
||||
#include "lldb/API/SBStream.h"
|
||||
#include "lldb/API/SBStringList.h"
|
||||
#include "lldb/API/SBThread.h"
|
||||
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/Breakpoint/StoppointCallbackContext.h"
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/Debugger.h"
|
||||
#include "lldb/Core/StreamFile.h"
|
||||
#include "lldb/Interpreter/CommandInterpreter.h"
|
||||
#include "lldb/Interpreter/ScriptInterpreter.h"
|
||||
#include "lldb/Target/Process.h"
|
||||
#include "lldb/Target/Target.h"
|
||||
#include "lldb/Target/Thread.h"
|
||||
#include "lldb/Target/ThreadSpec.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
|
||||
#include "SBBreakpointOptionCommon.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
SBBreakpointCallbackBaton::SBBreakpointCallbackBaton(SBBreakpointHitCallback
|
||||
callback,
|
||||
void *baton)
|
||||
: TypedBaton(llvm::make_unique<CallbackData>()) {
|
||||
getItem()->callback = callback;
|
||||
getItem()->callback_baton = baton;
|
||||
}
|
||||
|
||||
bool SBBreakpointCallbackBaton::PrivateBreakpointHitCallback(void *baton,
|
||||
StoppointCallbackContext *ctx,
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id)
|
||||
{
|
||||
ExecutionContext exe_ctx(ctx->exe_ctx_ref);
|
||||
BreakpointSP bp_sp(
|
||||
exe_ctx.GetTargetRef().GetBreakpointList().FindBreakpointByID(break_id));
|
||||
if (baton && bp_sp) {
|
||||
CallbackData *data = (CallbackData *)baton;
|
||||
lldb_private::Breakpoint *bp = bp_sp.get();
|
||||
if (bp && data->callback) {
|
||||
Process *process = exe_ctx.GetProcessPtr();
|
||||
if (process) {
|
||||
SBProcess sb_process(process->shared_from_this());
|
||||
SBThread sb_thread;
|
||||
SBBreakpointLocation sb_location;
|
||||
assert(bp_sp);
|
||||
sb_location.SetLocation(bp_sp->FindLocationByID(break_loc_id));
|
||||
Thread *thread = exe_ctx.GetThreadPtr();
|
||||
if (thread)
|
||||
sb_thread.SetThread(thread->shared_from_this());
|
||||
|
||||
return data->callback(data->callback_baton, sb_process, sb_thread,
|
||||
sb_location);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // Return true if we should stop at this breakpoint
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
//===-- SBBreakpointOptionCommon.h ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBBreakpointOptionCommons_h_
|
||||
#define LLDB_SBBreakpointOptionCommons_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
#include "lldb/Utility/Baton.h"
|
||||
|
||||
namespace lldb
|
||||
{
|
||||
struct CallbackData {
|
||||
SBBreakpointHitCallback callback;
|
||||
void *callback_baton;
|
||||
};
|
||||
|
||||
class SBBreakpointCallbackBaton : public lldb_private::TypedBaton<CallbackData> {
|
||||
public:
|
||||
SBBreakpointCallbackBaton(SBBreakpointHitCallback callback,
|
||||
void *baton);
|
||||
|
||||
static bool PrivateBreakpointHitCallback(void *baton,
|
||||
lldb_private::StoppointCallbackContext *ctx,
|
||||
lldb::user_id_t break_id,
|
||||
lldb::user_id_t break_loc_id);
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
#endif // LLDB_SBBreakpointOptionCommons_h_
|
|
@ -622,6 +622,20 @@ SBTarget SBDebugger::CreateTarget(const char *filename) {
|
|||
return sb_target;
|
||||
}
|
||||
|
||||
SBTarget SBDebugger::GetDummyTarget() {
|
||||
SBTarget sb_target;
|
||||
if (m_opaque_sp) {
|
||||
sb_target.SetSP(m_opaque_sp->GetDummyTarget()->shared_from_this());
|
||||
}
|
||||
Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
|
||||
if (log)
|
||||
log->Printf(
|
||||
"SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
|
||||
static_cast<void *>(m_opaque_sp.get()),
|
||||
static_cast<void *>(sb_target.GetSP().get()));
|
||||
return sb_target;
|
||||
}
|
||||
|
||||
bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
|
||||
bool result = false;
|
||||
if (m_opaque_sp) {
|
||||
|
|
|
@ -1087,11 +1087,38 @@ bool SBTarget::FindBreakpointsByName(const char *name,
|
|||
return true;
|
||||
}
|
||||
|
||||
void SBTarget::GetBreakpointNames(SBStringList &names)
|
||||
{
|
||||
names.Clear();
|
||||
|
||||
TargetSP target_sp(GetSP());
|
||||
if (target_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
|
||||
std::vector<std::string> name_vec;
|
||||
target_sp->GetBreakpointNames(name_vec);
|
||||
for (auto name : name_vec)
|
||||
names.AppendString(name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void SBTarget::DeleteBreakpointName(const char *name)
|
||||
{
|
||||
TargetSP target_sp(GetSP());
|
||||
if (target_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
|
||||
std::vector<std::string> name_vec;
|
||||
target_sp->DeleteBreakpointName(ConstString(name));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool SBTarget::EnableAllBreakpoints() {
|
||||
TargetSP target_sp(GetSP());
|
||||
if (target_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
target_sp->EnableAllBreakpoints();
|
||||
target_sp->EnableAllowedBreakpoints();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1101,7 +1128,7 @@ bool SBTarget::DisableAllBreakpoints() {
|
|||
TargetSP target_sp(GetSP());
|
||||
if (target_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
target_sp->DisableAllBreakpoints();
|
||||
target_sp->DisableAllowedBreakpoints();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1111,7 +1138,7 @@ bool SBTarget::DeleteAllBreakpoints() {
|
|||
TargetSP target_sp(GetSP());
|
||||
if (target_sp) {
|
||||
std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
|
||||
target_sp->RemoveAllBreakpoints();
|
||||
target_sp->RemoveAllowedBreakpoints();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -210,7 +210,7 @@ lldb::BreakpointSP Breakpoint::CreateFromStructuredData(
|
|||
llvm::StringRef name;
|
||||
Status error;
|
||||
success = names_array->GetItemAtIndexAsString(i, name);
|
||||
result_sp->AddName(name, error);
|
||||
target.AddNameToBreakpoint(result_sp, name.str().c_str(), error);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,6 +455,10 @@ bool Breakpoint::InvokeCallback(StoppointCallbackContext *context,
|
|||
|
||||
BreakpointOptions *Breakpoint::GetOptions() { return m_options_up.get(); }
|
||||
|
||||
const BreakpointOptions *Breakpoint::GetOptions() const {
|
||||
return m_options_up.get();
|
||||
}
|
||||
|
||||
void Breakpoint::ResolveBreakpoint() {
|
||||
if (m_resolver_sp)
|
||||
m_resolver_sp->ResolveBreakpoint(*m_filter_sp);
|
||||
|
@ -841,18 +845,8 @@ size_t Breakpoint::GetNumResolvedLocations() const {
|
|||
|
||||
size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); }
|
||||
|
||||
bool Breakpoint::AddName(llvm::StringRef new_name, Status &error) {
|
||||
if (new_name.empty())
|
||||
return false;
|
||||
if (!BreakpointID::StringIsBreakpointName(new_name, error)) {
|
||||
error.SetErrorStringWithFormatv("input name \"{0}\" not a breakpoint name.",
|
||||
new_name);
|
||||
return false;
|
||||
}
|
||||
if (!error.Success())
|
||||
return false;
|
||||
|
||||
m_name_list.insert(new_name);
|
||||
bool Breakpoint::AddName(llvm::StringRef new_name) {
|
||||
m_name_list.insert(new_name.str().c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,15 +101,24 @@ BreakpointID::ParseCanonicalReference(llvm::StringRef input) {
|
|||
bool BreakpointID::StringIsBreakpointName(llvm::StringRef str, Status &error) {
|
||||
error.Clear();
|
||||
if (str.empty())
|
||||
{
|
||||
error.SetErrorStringWithFormat("Empty breakpoint names are not allowed");
|
||||
return false;
|
||||
}
|
||||
|
||||
// First character must be a letter or _
|
||||
if (!isalpha(str[0]) && str[0] != '_')
|
||||
{
|
||||
error.SetErrorStringWithFormat("Breakpoint names must start with a "
|
||||
"character or underscore: %s",
|
||||
str.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot contain ., -, or space.
|
||||
if (str.find_first_of(".- ") != llvm::StringRef::npos) {
|
||||
error.SetErrorStringWithFormat("invalid breakpoint name: \"%s\"",
|
||||
error.SetErrorStringWithFormat("Breakpoint names cannot contain "
|
||||
"'.' or '-': \"%s\"",
|
||||
str.str().c_str());
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Breakpoint/BreakpointIDList.h"
|
||||
|
||||
#include "lldb/Breakpoint/Breakpoint.h"
|
||||
|
@ -117,6 +118,8 @@ void BreakpointIDList::InsertStringArray(const char **string_array,
|
|||
|
||||
void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
|
||||
bool allow_locations,
|
||||
BreakpointName::Permissions
|
||||
::PermissionKinds purpose,
|
||||
CommandReturnObject &result,
|
||||
Args &new_args) {
|
||||
llvm::StringRef range_from;
|
||||
|
@ -302,14 +305,29 @@ void BreakpointIDList::FindAndReplaceIDRanges(Args &old_args, Target *target,
|
|||
}
|
||||
|
||||
// Okay, now see if we found any names, and if we did, add them:
|
||||
if (target && names_found.size()) {
|
||||
for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
|
||||
for (std::string name : names_found) {
|
||||
if (bkpt_sp->MatchesName(name.c_str())) {
|
||||
StreamString canonical_id_str;
|
||||
BreakpointID::GetCanonicalReference(
|
||||
&canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
|
||||
new_args.AppendArgument(canonical_id_str.GetString());
|
||||
if (target && !names_found.empty()) {
|
||||
Status error;
|
||||
// Remove any names that aren't visible for this purpose:
|
||||
auto iter = names_found.begin();
|
||||
while (iter != names_found.end()) {
|
||||
BreakpointName *bp_name = target->FindBreakpointName(ConstString(*iter),
|
||||
true,
|
||||
error);
|
||||
if (bp_name && !bp_name->GetPermission(purpose))
|
||||
iter = names_found.erase(iter);
|
||||
else
|
||||
iter++;
|
||||
}
|
||||
|
||||
if (!names_found.empty()) {
|
||||
for (BreakpointSP bkpt_sp : target->GetBreakpointList().Breakpoints()) {
|
||||
for (std::string name : names_found) {
|
||||
if (bkpt_sp->MatchesName(name.c_str())) {
|
||||
StreamString canonical_id_str;
|
||||
BreakpointID::GetCanonicalReference(
|
||||
&canonical_id_str, bkpt_sp->GetID(), LLDB_INVALID_BREAK_ID);
|
||||
new_args.AppendArgument(canonical_id_str.GetString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,6 +71,13 @@ void BreakpointList::SetEnabledAll(bool enabled) {
|
|||
bp_sp->SetEnabled(enabled);
|
||||
}
|
||||
|
||||
void BreakpointList::SetEnabledAllowed(bool enabled) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
for (const auto &bp_sp : m_breakpoints)
|
||||
if (bp_sp->AllowDisable())
|
||||
bp_sp->SetEnabled(enabled);
|
||||
}
|
||||
|
||||
void BreakpointList::RemoveAll(bool notify) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
ClearAllBreakpointSites();
|
||||
|
@ -90,6 +97,32 @@ void BreakpointList::RemoveAll(bool notify) {
|
|||
m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end());
|
||||
}
|
||||
|
||||
void BreakpointList::RemoveAllowed(bool notify) {
|
||||
std::lock_guard<std::recursive_mutex> guard(m_mutex);
|
||||
|
||||
bp_collection::iterator pos, end = m_breakpoints.end();
|
||||
if (notify) {
|
||||
for (pos = m_breakpoints.begin(); pos != end; ++pos) {
|
||||
if(!(*pos)->AllowDelete())
|
||||
continue;
|
||||
if ((*pos)->GetTarget().EventTypeHasListeners(
|
||||
Target::eBroadcastBitBreakpointChanged)) {
|
||||
(*pos)->GetTarget().BroadcastEvent(
|
||||
Target::eBroadcastBitBreakpointChanged,
|
||||
new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved,
|
||||
*pos));
|
||||
}
|
||||
}
|
||||
}
|
||||
pos = m_breakpoints.begin();
|
||||
while ( pos != end) {
|
||||
if((*pos)->AllowDelete())
|
||||
pos = m_breakpoints.erase(pos);
|
||||
else
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
|
||||
class BreakpointIDMatches {
|
||||
public:
|
||||
BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
//===-- Breakpoint.cpp ------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details->
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
// Other libraries and framework includes
|
||||
#include "llvm/Support/Casting.h"
|
||||
|
||||
// Project includes
|
||||
#include "lldb/Breakpoint/Breakpoint.h"
|
||||
#include "lldb/Breakpoint/BreakpointOptions.h"
|
||||
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolver.h"
|
||||
#include "lldb/Breakpoint/BreakpointResolverFileLine.h"
|
||||
#include "lldb/Utility/Log.h"
|
||||
#include "lldb/Utility/Stream.h"
|
||||
#include "lldb/Utility/StreamString.h"
|
||||
|
||||
using namespace lldb;
|
||||
using namespace lldb_private;
|
||||
|
||||
const Flags::ValueType BreakpointName::Permissions::permissions_mask
|
||||
[BreakpointName::Permissions::PermissionKinds::allPerms + 1] = {
|
||||
(1u << 0),
|
||||
(1u << 1),
|
||||
(1u << 2),
|
||||
(0x5u)
|
||||
};
|
||||
|
||||
BreakpointName::BreakpointName(const ConstString &name, const Breakpoint &bkpt,
|
||||
const char *help) :
|
||||
m_name(name), m_options(bkpt.GetOptions())
|
||||
{
|
||||
SetHelp(help);
|
||||
}
|
||||
|
||||
bool BreakpointName::Permissions::GetDescription(Stream *s,
|
||||
lldb::DescriptionLevel level) {
|
||||
if (!AnySet())
|
||||
return false;
|
||||
s->IndentMore();
|
||||
s->Indent();
|
||||
if (IsSet(listPerm))
|
||||
s->Printf("list: %s", GetAllowList() ? "allowed" : "disallowed");
|
||||
|
||||
if (IsSet(disablePerm))
|
||||
s->Printf("disable: %s", GetAllowDisable() ? "allowed" : "disallowed");
|
||||
|
||||
if (IsSet(deletePerm))
|
||||
s->Printf("delete: %s", GetAllowDelete() ? "allowed" : "disallowed");
|
||||
s->IndentLess();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BreakpointName::GetDescription(Stream *s, lldb::DescriptionLevel level) {
|
||||
bool printed_any = false;
|
||||
if (GetOptions().AnySet())
|
||||
{
|
||||
s->PutCString("Options: \n");
|
||||
s->IndentMore();
|
||||
s->Indent();
|
||||
GetOptions().GetDescription(s, level);
|
||||
printed_any = true;
|
||||
s->IndentLess();
|
||||
}
|
||||
if (GetPermissions().AnySet())
|
||||
{
|
||||
s->PutCString("Permissions: \n");
|
||||
s->IndentMore();
|
||||
s->Indent();
|
||||
GetPermissions().GetDescription(s, level);
|
||||
printed_any = true;
|
||||
s->IndentLess();
|
||||
}
|
||||
return printed_any;
|
||||
}
|
||||
|
||||
void BreakpointName::ConfigureBreakpoint(lldb::BreakpointSP bp_sp)
|
||||
{
|
||||
bp_sp->GetOptions()->CopyOverSetOptions(GetOptions());
|
||||
bp_sp->GetPermissions().MergeInto(GetPermissions());
|
||||
}
|
|
@ -132,7 +132,7 @@ BreakpointOptions::BreakpointOptions(bool all_flags_set)
|
|||
m_baton_is_command_baton(false), m_callback_is_synchronous(false),
|
||||
m_enabled(true), m_one_shot(false), m_ignore_count(0), m_thread_spec_ap(),
|
||||
m_condition_text(), m_condition_text_hash(0), m_auto_continue(false),
|
||||
m_set_flags() {
|
||||
m_set_flags(0) {
|
||||
if (all_flags_set)
|
||||
m_set_flags.Set(~((Flags::ValueType) 0));
|
||||
}
|
||||
|
@ -142,11 +142,14 @@ BreakpointOptions::BreakpointOptions(const char *condition, bool enabled,
|
|||
bool auto_continue)
|
||||
: m_callback(nullptr), m_baton_is_command_baton(false),
|
||||
m_callback_is_synchronous(false), m_enabled(enabled),
|
||||
m_one_shot(one_shot), m_ignore_count(ignore), m_condition_text(condition),
|
||||
m_one_shot(one_shot), m_ignore_count(ignore),
|
||||
m_condition_text_hash(0), m_auto_continue(auto_continue)
|
||||
{
|
||||
m_set_flags.Set(eEnabled | eIgnoreCount | eOneShot
|
||||
| eCondition | eAutoContinue);
|
||||
| eAutoContinue);
|
||||
if (condition && *condition != '\0') {
|
||||
SetCondition(condition);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -187,6 +190,59 @@ operator=(const BreakpointOptions &rhs) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
void BreakpointOptions::CopyOverSetOptions(const BreakpointOptions &incoming)
|
||||
{
|
||||
if (incoming.m_set_flags.Test(eEnabled))
|
||||
{
|
||||
m_enabled = incoming.m_enabled;
|
||||
m_set_flags.Set(eEnabled);
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eOneShot))
|
||||
{
|
||||
m_one_shot = incoming.m_one_shot;
|
||||
m_set_flags.Set(eOneShot);
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eCallback))
|
||||
{
|
||||
m_callback = incoming.m_callback;
|
||||
m_callback_baton_sp = incoming.m_callback_baton_sp;
|
||||
m_callback_is_synchronous = incoming.m_callback_is_synchronous;
|
||||
m_baton_is_command_baton = incoming.m_baton_is_command_baton;
|
||||
m_set_flags.Set(eCallback);
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eIgnoreCount))
|
||||
{
|
||||
m_ignore_count = incoming.m_ignore_count;
|
||||
m_set_flags.Set(eIgnoreCount);
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eCondition))
|
||||
{
|
||||
// If we're copying over an empty condition, mark it as unset.
|
||||
if (incoming.m_condition_text.empty()) {
|
||||
m_condition_text.clear();
|
||||
m_condition_text_hash = 0;
|
||||
m_set_flags.Clear(eCondition);
|
||||
} else {
|
||||
m_condition_text = incoming.m_condition_text;
|
||||
m_condition_text_hash = incoming.m_condition_text_hash;
|
||||
m_set_flags.Set(eCondition);
|
||||
}
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eAutoContinue))
|
||||
{
|
||||
m_auto_continue = incoming.m_auto_continue;
|
||||
m_set_flags.Set(eAutoContinue);
|
||||
}
|
||||
if (incoming.m_set_flags.Test(eThreadSpec) && incoming.m_thread_spec_ap)
|
||||
{
|
||||
if (!m_thread_spec_ap)
|
||||
m_thread_spec_ap.reset(new ThreadSpec(*incoming.m_thread_spec_ap.get()));
|
||||
else
|
||||
*m_thread_spec_ap.get() = *incoming.m_thread_spec_ap.get();
|
||||
m_set_flags.Set(eThreadSpec);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -327,23 +383,23 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData(
|
|||
StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
|
||||
StructuredData::DictionarySP options_dict_sp(
|
||||
new StructuredData::Dictionary());
|
||||
if (m_set_flags.Set(eEnabled))
|
||||
if (m_set_flags.Test(eEnabled))
|
||||
options_dict_sp->AddBooleanItem(GetKey(OptionNames::EnabledState),
|
||||
m_enabled);
|
||||
if (m_set_flags.Set(eOneShot))
|
||||
if (m_set_flags.Test(eOneShot))
|
||||
options_dict_sp->AddBooleanItem(GetKey(OptionNames::OneShotState),
|
||||
m_one_shot);
|
||||
if (m_set_flags.Set(eAutoContinue))
|
||||
if (m_set_flags.Test(eAutoContinue))
|
||||
options_dict_sp->AddBooleanItem(GetKey(OptionNames::AutoContinue),
|
||||
m_auto_continue);
|
||||
if (m_set_flags.Set(eIgnoreCount))
|
||||
if (m_set_flags.Test(eIgnoreCount))
|
||||
options_dict_sp->AddIntegerItem(GetKey(OptionNames::IgnoreCount),
|
||||
m_ignore_count);
|
||||
if (m_set_flags.Set(eCondition))
|
||||
if (m_set_flags.Test(eCondition))
|
||||
options_dict_sp->AddStringItem(GetKey(OptionNames::ConditionText),
|
||||
m_condition_text);
|
||||
|
||||
if (m_set_flags.Set(eCallback) && m_baton_is_command_baton) {
|
||||
if (m_set_flags.Test(eCallback) && m_baton_is_command_baton) {
|
||||
auto cmd_baton =
|
||||
std::static_pointer_cast<CommandBaton>(m_callback_baton_sp);
|
||||
StructuredData::ObjectSP commands_sp =
|
||||
|
@ -353,7 +409,7 @@ StructuredData::ObjectSP BreakpointOptions::SerializeToStructuredData() {
|
|||
BreakpointOptions::CommandData::GetSerializationKey(), commands_sp);
|
||||
}
|
||||
}
|
||||
if (m_set_flags.Set(eThreadSpec) && m_thread_spec_ap) {
|
||||
if (m_set_flags.Test(eThreadSpec) && m_thread_spec_ap) {
|
||||
StructuredData::ObjectSP thread_spec_sp =
|
||||
m_thread_spec_ap->SerializeToStructuredData();
|
||||
options_dict_sp->AddItem(ThreadSpec::GetSerializationKey(), thread_spec_sp);
|
||||
|
@ -618,3 +674,18 @@ bool BreakpointOptions::BreakpointOptionsCallbackFunction(
|
|||
}
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
void BreakpointOptions::Clear()
|
||||
{
|
||||
m_set_flags.Clear();
|
||||
m_thread_spec_ap.release();
|
||||
m_one_shot = false;
|
||||
m_ignore_count = 0;
|
||||
m_auto_continue = false;
|
||||
m_callback = nullptr;
|
||||
m_callback_baton_sp.reset();
|
||||
m_baton_is_command_baton = false;
|
||||
m_callback_is_synchronous = false;
|
||||
m_enabled = false;
|
||||
m_condition_text.clear();
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -18,11 +18,14 @@
|
|||
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Breakpoint/BreakpointName.h"
|
||||
#include "lldb/Core/Address.h"
|
||||
#include "lldb/Core/STLUtils.h"
|
||||
#include "lldb/Interpreter/CommandObjectMultiword.h"
|
||||
#include "lldb/Interpreter/Options.h"
|
||||
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
@ -37,20 +40,26 @@ public:
|
|||
|
||||
static void VerifyBreakpointOrLocationIDs(Args &args, Target *target,
|
||||
CommandReturnObject &result,
|
||||
BreakpointIDList *valid_ids) {
|
||||
VerifyIDs(args, target, true, result, valid_ids);
|
||||
BreakpointIDList *valid_ids,
|
||||
BreakpointName::Permissions
|
||||
::PermissionKinds purpose) {
|
||||
VerifyIDs(args, target, true, result, valid_ids, purpose);
|
||||
}
|
||||
|
||||
static void VerifyBreakpointIDs(Args &args, Target *target,
|
||||
CommandReturnObject &result,
|
||||
BreakpointIDList *valid_ids) {
|
||||
VerifyIDs(args, target, false, result, valid_ids);
|
||||
BreakpointIDList *valid_ids,
|
||||
BreakpointName::Permissions::PermissionKinds
|
||||
purpose) {
|
||||
VerifyIDs(args, target, false, result, valid_ids, purpose);
|
||||
}
|
||||
|
||||
private:
|
||||
static void VerifyIDs(Args &args, Target *target, bool allow_locations,
|
||||
CommandReturnObject &result,
|
||||
BreakpointIDList *valid_ids);
|
||||
BreakpointIDList *valid_ids,
|
||||
BreakpointName::Permissions::PermissionKinds
|
||||
purpose);
|
||||
};
|
||||
|
||||
} // namespace lldb_private
|
||||
|
|
|
@ -390,7 +390,8 @@ protected:
|
|||
|
||||
BreakpointIDList valid_bp_ids;
|
||||
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
|
||||
command, target, result, &valid_bp_ids);
|
||||
command, target, result, &valid_bp_ids,
|
||||
BreakpointName::Permissions::PermissionKinds::listPerm);
|
||||
|
||||
m_bp_options_vec.clear();
|
||||
|
||||
|
@ -571,7 +572,8 @@ protected:
|
|||
|
||||
BreakpointIDList valid_bp_ids;
|
||||
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
|
||||
command, target, result, &valid_bp_ids);
|
||||
command, target, result, &valid_bp_ids,
|
||||
BreakpointName::Permissions::PermissionKinds::listPerm);
|
||||
|
||||
if (result.Succeeded()) {
|
||||
const size_t count = valid_bp_ids.GetSize();
|
||||
|
@ -662,7 +664,8 @@ protected:
|
|||
|
||||
BreakpointIDList valid_bp_ids;
|
||||
CommandObjectMultiwordBreakpoint::VerifyBreakpointOrLocationIDs(
|
||||
command, target, result, &valid_bp_ids);
|
||||
command, target, result, &valid_bp_ids,
|
||||
BreakpointName::Permissions::PermissionKinds::listPerm);
|
||||
|
||||
if (result.Succeeded()) {
|
||||
const size_t count = valid_bp_ids.GetSize();
|
||||
|
|
|
@ -1113,7 +1113,8 @@ CommandObject::ArgumentTableEntry CommandObject::g_arguments_data[] = {
|
|||
{ eArgTypeWatchpointID, "watchpt-id", CommandCompletions::eNoCompletion, { nullptr, false }, "Watchpoint IDs are positive integers." },
|
||||
{ eArgTypeWatchpointIDRange, "watchpt-id-list", CommandCompletions::eNoCompletion, { nullptr, false }, "For example, '1-3' or '1 to 3'." },
|
||||
{ eArgTypeWatchType, "watch-type", CommandCompletions::eNoCompletion, { nullptr, false }, "Specify the type for a watchpoint." },
|
||||
{ eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." }
|
||||
{ eArgRawInput, "raw-input", CommandCompletions::eNoCompletion, { nullptr, false }, "Free-form text passed to a command without prior interpretation, allowing spaces without requiring quotes. To pass arguments and free form text put two dashes ' -- ' between the last argument and any raw input." },
|
||||
{ eArgTypeCommand, "command", CommandCompletions::eNoCompletion, { nullptr, false }, "An LLDB Command line command." }
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
|
|
|
@ -3615,13 +3615,15 @@ RenderScriptRuntime::CreateKernelBreakpoint(const ConstString &name) {
|
|||
}
|
||||
|
||||
BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name));
|
||||
BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
|
||||
Target &target = GetProcess()->GetTarget();
|
||||
BreakpointSP bp = target.CreateBreakpoint(
|
||||
m_filtersp, resolver_sp, false, false, false);
|
||||
|
||||
// Give RS breakpoints a specific name, so the user can manipulate them as a
|
||||
// group.
|
||||
Status err;
|
||||
if (!bp->AddName("RenderScriptKernel", err))
|
||||
target.AddNameToBreakpoint(bp, "RenderScriptKernel", err);
|
||||
if (err.Fail() && log)
|
||||
if (log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
|
@ -3643,14 +3645,15 @@ RenderScriptRuntime::CreateReductionBreakpoint(const ConstString &name,
|
|||
|
||||
BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver(
|
||||
nullptr, name, &m_rsmodules, kernel_types));
|
||||
BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
|
||||
Target &target = GetProcess()->GetTarget();
|
||||
BreakpointSP bp = target.CreateBreakpoint(
|
||||
m_filtersp, resolver_sp, false, false, false);
|
||||
|
||||
// Give RS breakpoints a specific name, so the user can manipulate them as a
|
||||
// group.
|
||||
Status err;
|
||||
if (!bp->AddName("RenderScriptReduction", err))
|
||||
if (log)
|
||||
target.AddNameToBreakpoint(bp, "RenderScriptReduction", err);
|
||||
if (err.Fail() && log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
|
||||
|
@ -3885,15 +3888,16 @@ RenderScriptRuntime::CreateScriptGroupBreakpoint(const ConstString &name,
|
|||
|
||||
BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver(
|
||||
nullptr, name, m_scriptGroups, stop_on_all));
|
||||
BreakpointSP bp = GetProcess()->GetTarget().CreateBreakpoint(
|
||||
Target &target = GetProcess()->GetTarget();
|
||||
BreakpointSP bp = target.CreateBreakpoint(
|
||||
m_filtersp, resolver_sp, false, false, false);
|
||||
// Give RS breakpoints a specific name, so the user can manipulate them as a
|
||||
// group.
|
||||
Status err;
|
||||
if (!bp->AddName(name.AsCString(), err))
|
||||
if (log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
target.AddNameToBreakpoint(bp, name.GetCString(), err);
|
||||
if (err.Fail() && log)
|
||||
log->Printf("%s - error setting break name, '%s'.", __FUNCTION__,
|
||||
err.AsCString());
|
||||
// ask the breakpoint to resolve itself
|
||||
bp->ResolveBreakpoint();
|
||||
return bp;
|
||||
|
|
|
@ -123,6 +123,13 @@ void Target::PrimeFromDummyTarget(Target *target) {
|
|||
BreakpointSP new_bp(new Breakpoint(*this, *breakpoint_sp.get()));
|
||||
AddBreakpoint(new_bp, false);
|
||||
}
|
||||
|
||||
for (auto bp_name_entry : target->m_breakpoint_names)
|
||||
{
|
||||
|
||||
BreakpointName *new_bp_name = new BreakpointName(*bp_name_entry.second);
|
||||
AddBreakpointName(new_bp_name);
|
||||
}
|
||||
}
|
||||
|
||||
void Target::Dump(Stream *s, lldb::DescriptionLevel description_level) {
|
||||
|
@ -601,6 +608,112 @@ void Target::AddBreakpoint(lldb::BreakpointSP bp_sp, bool internal) {
|
|||
}
|
||||
}
|
||||
|
||||
void Target::AddNameToBreakpoint(BreakpointID &id,
|
||||
const char *name,
|
||||
Status &error)
|
||||
{
|
||||
BreakpointSP bp_sp
|
||||
= m_breakpoint_list.FindBreakpointByID(id.GetBreakpointID());
|
||||
if (!bp_sp)
|
||||
{
|
||||
StreamString s;
|
||||
id.GetDescription(&s, eDescriptionLevelBrief);
|
||||
error.SetErrorStringWithFormat("Could not find breakpoint %s",
|
||||
s.GetData());
|
||||
return;
|
||||
}
|
||||
AddNameToBreakpoint(bp_sp, name, error);
|
||||
}
|
||||
|
||||
void Target::AddNameToBreakpoint(BreakpointSP &bp_sp,
|
||||
const char *name,
|
||||
Status &error)
|
||||
{
|
||||
if (!bp_sp)
|
||||
return;
|
||||
|
||||
BreakpointName *bp_name = FindBreakpointName(ConstString(name), true, error);
|
||||
if (!bp_name)
|
||||
return;
|
||||
|
||||
bp_name->ConfigureBreakpoint(bp_sp);
|
||||
bp_sp->AddName(name);
|
||||
}
|
||||
|
||||
void Target::AddBreakpointName(BreakpointName *bp_name) {
|
||||
m_breakpoint_names.insert(std::make_pair(bp_name->GetName(), bp_name));
|
||||
}
|
||||
|
||||
BreakpointName *Target::FindBreakpointName(const ConstString &name,
|
||||
bool can_create,
|
||||
Status &error)
|
||||
{
|
||||
BreakpointID::StringIsBreakpointName(name.GetStringRef(), error);
|
||||
if (!error.Success())
|
||||
return nullptr;
|
||||
|
||||
BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
|
||||
if (iter == m_breakpoint_names.end()) {
|
||||
if (!can_create)
|
||||
{
|
||||
error.SetErrorStringWithFormat("Breakpoint name \"%s\" doesn't exist and "
|
||||
"can_create is false.", name.AsCString());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
iter = m_breakpoint_names.insert(std::make_pair(name,
|
||||
new BreakpointName(name)))
|
||||
.first;
|
||||
}
|
||||
return (iter->second);
|
||||
}
|
||||
|
||||
void
|
||||
Target::DeleteBreakpointName(const ConstString &name)
|
||||
{
|
||||
BreakpointNameList::iterator iter = m_breakpoint_names.find(name);
|
||||
|
||||
if (iter != m_breakpoint_names.end()) {
|
||||
const char *name_cstr = name.AsCString();
|
||||
m_breakpoint_names.erase(iter);
|
||||
for (auto bp_sp : m_breakpoint_list.Breakpoints())
|
||||
bp_sp->RemoveName(name_cstr);
|
||||
}
|
||||
}
|
||||
|
||||
void Target::RemoveNameFromBreakpoint(lldb::BreakpointSP &bp_sp,
|
||||
const ConstString &name)
|
||||
{
|
||||
bp_sp->RemoveName(name.AsCString());
|
||||
}
|
||||
|
||||
void Target::ConfigureBreakpointName(BreakpointName &bp_name,
|
||||
const BreakpointOptions &new_options,
|
||||
const BreakpointName::Permissions &new_permissions)
|
||||
{
|
||||
bp_name.GetOptions().CopyOverSetOptions(new_options);
|
||||
bp_name.GetPermissions().MergeInto(new_permissions);
|
||||
ApplyNameToBreakpoints(bp_name);
|
||||
}
|
||||
|
||||
void Target::ApplyNameToBreakpoints(BreakpointName &bp_name) {
|
||||
BreakpointList bkpts_with_name(false);
|
||||
m_breakpoint_list.FindBreakpointsByName(bp_name.GetName().AsCString(),
|
||||
bkpts_with_name);
|
||||
|
||||
for (auto bp_sp : bkpts_with_name.Breakpoints())
|
||||
bp_name.ConfigureBreakpoint(bp_sp);
|
||||
}
|
||||
|
||||
void Target::GetBreakpointNames(std::vector<std::string> &names)
|
||||
{
|
||||
names.clear();
|
||||
for (auto bp_name : m_breakpoint_names) {
|
||||
names.push_back(bp_name.first.AsCString());
|
||||
}
|
||||
std::sort(names.begin(), names.end());
|
||||
}
|
||||
|
||||
bool Target::ProcessIsValid() {
|
||||
return (m_process_sp && m_process_sp->IsAlive());
|
||||
}
|
||||
|
@ -703,6 +816,17 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size,
|
|||
return wp_sp;
|
||||
}
|
||||
|
||||
void Target::RemoveAllowedBreakpoints ()
|
||||
{
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
log->Printf("Target::%s \n", __FUNCTION__);
|
||||
|
||||
m_breakpoint_list.RemoveAllowed(true);
|
||||
|
||||
m_last_created_breakpoint.reset();
|
||||
}
|
||||
|
||||
void Target::RemoveAllBreakpoints(bool internal_also) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
|
@ -727,6 +851,14 @@ void Target::DisableAllBreakpoints(bool internal_also) {
|
|||
m_internal_breakpoint_list.SetEnabledAll(false);
|
||||
}
|
||||
|
||||
void Target::DisableAllowedBreakpoints() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
log->Printf("Target::%s", __FUNCTION__);
|
||||
|
||||
m_breakpoint_list.SetEnabledAllowed(false);
|
||||
}
|
||||
|
||||
void Target::EnableAllBreakpoints(bool internal_also) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
|
@ -738,6 +870,14 @@ void Target::EnableAllBreakpoints(bool internal_also) {
|
|||
m_internal_breakpoint_list.SetEnabledAll(true);
|
||||
}
|
||||
|
||||
void Target::EnableAllowedBreakpoints() {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
log->Printf("Target::%s", __FUNCTION__);
|
||||
|
||||
m_breakpoint_list.SetEnabledAllowed(true);
|
||||
}
|
||||
|
||||
bool Target::RemoveBreakpointByID(break_id_t break_id) {
|
||||
Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));
|
||||
if (log)
|
||||
|
|
Loading…
Reference in New Issue