summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointList.h9
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointLocation.h17
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h14
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointOptions.h25
-rw-r--r--lldb/include/lldb/Breakpoint/BreakpointSite.h16
-rw-r--r--lldb/include/lldb/Breakpoint/StoppointLocation.h6
-rw-r--r--lldb/include/lldb/Target/Thread.h3
-rw-r--r--lldb/include/lldb/Target/ThreadSpec.h134
-rw-r--r--lldb/include/lldb/lldb-forward.h1
-rw-r--r--lldb/lldb.xcodeproj/project.pbxproj8
-rw-r--r--lldb/source/API/SBBreakpointLocation.cpp3
-rw-r--r--lldb/source/Breakpoint/Breakpoint.cpp8
-rw-r--r--lldb/source/Breakpoint/BreakpointList.cpp6
-rw-r--r--lldb/source/Breakpoint/BreakpointLocation.cpp40
-rw-r--r--lldb/source/Breakpoint/BreakpointLocationCollection.cpp18
-rw-r--r--lldb/source/Breakpoint/BreakpointOptions.cpp37
-rw-r--r--lldb/source/Breakpoint/BreakpointSite.cpp9
-rw-r--r--lldb/source/Breakpoint/StoppointLocation.cpp12
-rw-r--r--lldb/source/Breakpoint/WatchpointLocation.cpp1
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.cpp305
-rw-r--r--lldb/source/Commands/CommandObjectBreakpoint.h64
-rw-r--r--lldb/source/Commands/CommandObjectBreakpointCommand.cpp5
-rw-r--r--lldb/source/Commands/CommandObjectFile.cpp1
-rw-r--r--lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp63
-rw-r--r--lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp16
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp17
-rw-r--r--lldb/source/Target/Thread.cpp42
-rw-r--r--lldb/source/Target/ThreadPlan.cpp4
-rw-r--r--lldb/source/Target/ThreadSpec.cpp58
29 files changed, 802 insertions, 140 deletions
diff --git a/lldb/include/lldb/Breakpoint/BreakpointList.h b/lldb/include/lldb/Breakpoint/BreakpointList.h
index 225bb3ba498..84ccf935230 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointList.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointList.h
@@ -153,6 +153,15 @@ public:
void
ClearAllBreakpointSites ();
+
+ //------------------------------------------------------------------
+ /// Sets the passed in Locker to hold the Breakpoint List mutex.
+ ///
+ /// @param[in] locker
+ /// The locker object that is set.
+ //------------------------------------------------------------------
+ void
+ GetListMutex (lldb_private::Mutex::Locker &locker);
protected:
typedef std::list<lldb::BreakpointSP> bp_collection;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
index 1324ced5431..7aed5589ec1 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocation.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocation.h
@@ -179,16 +179,6 @@ public:
SetThreadID (lldb::tid_t thread_id);
//------------------------------------------------------------------
- /// Return the current stop thread value.
- ///
- /// @return
- /// The thread id for which the breakpoint hit will stop,
- /// LLDB_INVALID_THREAD_ID for all threads.
- //------------------------------------------------------------------
- lldb::tid_t
- GetThreadID ();
-
- //------------------------------------------------------------------
// The next section deals with this location's breakpoint sites.
//------------------------------------------------------------------
@@ -267,8 +257,11 @@ public:
/// A pointer to the containing breakpoint's options if this
/// location doesn't have its own copy.
//------------------------------------------------------------------
- BreakpointOptions *
- GetOptionsNoCopy ();
+ const BreakpointOptions *
+ GetOptionsNoCopy () const;
+
+ bool
+ ValidForThisThread (Thread *thread);
protected:
friend class Breakpoint;
diff --git a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
index 9e04a2c4277..9f0dd0fb2e0 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h
@@ -156,6 +156,20 @@ public:
/// @see lldb::DescriptionLevel
//------------------------------------------------------------------
void GetDescription (Stream *s, lldb::DescriptionLevel level);
+
+ //------------------------------------------------------------------
+ /// Check whether this collection of breakpoint locations have any
+ /// thread specifiers, and if yes, is \a thread_id contained in any
+ /// of these specifiers.
+ ///
+ /// @param[in] thread
+ /// The thread against which to test.
+ ///
+ /// return
+ /// \b true if the collection contains at least one location that
+ /// would be valid for this thread, false otherwise.
+ //------------------------------------------------------------------
+ bool ValidForThisThread (Thread *thread);
diff --git a/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/lldb/include/lldb/Breakpoint/BreakpointOptions.h
index e7a3e3bf1d2..c0c3eeb5778 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointOptions.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointOptions.h
@@ -12,6 +12,7 @@
// C Includes
// C++ Includes
+#include <memory>
// Other libraries and framework includes
// Project includes
#include "lldb/lldb-private.h"
@@ -84,6 +85,7 @@ public:
return m_callback_is_synchronous;
};
Baton *GetBaton ();
+ const Baton *GetBaton () const;
void ClearCallback ();
//------------------------------------------------------------------
@@ -122,21 +124,24 @@ public:
//------------------------------------------------------------------
//------------------------------------------------------------------
- /// Return the current stop thread value.
+ /// Return the current thread spec. This is used to pass to Thread::MatchesSpec.
/// @return
- /// The thread id for which the breakpoint hit will stop,
- /// LLDB_INVALID_THREAD_ID for all threads.
+ /// The thread specification pointer for this option, or NULL if none has
+ /// been set yet.
//------------------------------------------------------------------
- lldb::tid_t
- GetThreadID () const;
+ const ThreadSpec *
+ GetThreadSpec () const;
//------------------------------------------------------------------
- /// Set the valid thread to be checked when the breakpoint is hit.
- /// @param[in] thread_id
- /// If this thread hits the breakpoint, we stop, otherwise not.
+ /// Returns a pointer to the ThreadSpec for this option, creating it.
+ /// if it hasn't been created already. This API is used for setting the
+ /// ThreadSpec items for this option.
//------------------------------------------------------------------
+ ThreadSpec *
+ GetThreadSpec ();
+
void
- SetThreadID (lldb::tid_t thread_id);
+ SetThreadID(lldb::tid_t thread_id);
//------------------------------------------------------------------
/// This is the default empty callback.
@@ -201,7 +206,7 @@ private:
bool m_callback_is_synchronous;
bool m_enabled;
int32_t m_ignore_count; // Number of times to ignore this breakpoint
- lldb::tid_t m_thread_id; // Thread for which this breakpoint will take
+ std::auto_ptr<ThreadSpec> m_thread_spec_ap; // Thread for which this breakpoint will take
};
diff --git a/lldb/include/lldb/Breakpoint/BreakpointSite.h b/lldb/include/lldb/Breakpoint/BreakpointSite.h
index aeb385ba18e..50d8fe50137 100644
--- a/lldb/include/lldb/Breakpoint/BreakpointSite.h
+++ b/lldb/include/lldb/Breakpoint/BreakpointSite.h
@@ -182,6 +182,22 @@ public:
//------------------------------------------------------------------
lldb::BreakpointLocationSP
GetOwnerAtIndex (uint32_t index);
+
+ //------------------------------------------------------------------
+ /// Check whether the owners of this breakpoint site have any
+ /// thread specifiers, and if yes, is \a thread contained in any
+ /// of these specifiers.
+ ///
+ /// @param[in] thread
+ /// The thread against which to test.
+ ///
+ /// return
+ /// \b true if the collection contains at least one location that
+ /// would be valid for this thread, false otherwise.
+ //------------------------------------------------------------------
+ bool
+ ValidForThisThread (Thread *thread);
+
//------------------------------------------------------------------
/// Print a description of this breakpoint site to the stream \a s.
diff --git a/lldb/include/lldb/Breakpoint/StoppointLocation.h b/lldb/include/lldb/Breakpoint/StoppointLocation.h
index b52551005a6..2978fd5ecc6 100644
--- a/lldb/include/lldb/Breakpoint/StoppointLocation.h
+++ b/lldb/include/lldb/Breakpoint/StoppointLocation.h
@@ -28,12 +28,10 @@ public:
//------------------------------------------------------------------
StoppointLocation (lldb::break_id_t bid,
lldb::addr_t m_addr,
- lldb::tid_t tid,
bool hardware);
StoppointLocation (lldb::break_id_t bid,
lldb::addr_t m_addr,
- lldb::tid_t tid,
size_t size,
bool hardware);
@@ -62,9 +60,6 @@ public:
uint32_t
GetHardwareIndex () const;
- lldb::tid_t
- GetThreadID() const;
-
bool
HardwarePreferred () const;
@@ -88,7 +83,6 @@ protected:
// Classes that inherit from StoppointLocation can see and modify these
//------------------------------------------------------------------
lldb::break_id_t m_loc_id; // Break ID
- lldb::tid_t m_tid; // The thread ID if this stoppoint location is thread specific, or LLDB_INVALID_THREAD_ID if not thread specific.
lldb::addr_t m_addr; // The load address of this stop point. The base Stoppoint doesn't
// store a full Address since that's not needed for the breakpoint sites.
bool m_hw_preferred; // 1 if this point has been requested to be set using hardware (which may fail due to lack of resources)
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index e7b0ce4f73d..bd8bdf069ba 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -262,6 +262,9 @@ public:
lldb::Vote
ShouldReportRun (Event *event_ptr);
+
+ virtual bool
+ MatchesSpec (const ThreadSpec *spec);
bool
GetStopInfo (StopInfo *stop_info);
diff --git a/lldb/include/lldb/Target/ThreadSpec.h b/lldb/include/lldb/Target/ThreadSpec.h
new file mode 100644
index 00000000000..2ee28a28b46
--- /dev/null
+++ b/lldb/include/lldb/Target/ThreadSpec.h
@@ -0,0 +1,134 @@
+//===-- ThreadSpec.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_ThreadSpec_h_
+#define liblldb_ThreadSpec_h_
+
+#include <map>
+#include <string>
+
+#include "lldb/lldb-private.h"
+
+namespace lldb_private {
+
+// Note: For now the thread spec has only fixed elements -
+// Thread ID
+// Thread Index
+// Thread Name
+// Thread Queue Name
+//
+// But if we need more generality, we can hang a key/value map off of this structure.
+// That's why the thread matches spec test is done as a virtual method in Thread::MatchesSpec,
+// since it is the native thread that would know how to interpret the keys.
+// I was going to do the Queue Name this way out of sheer orneriness, but that seems a
+// sufficiently general concept, so I put it in here on its own.
+
+class ThreadSpec
+{
+public:
+ ThreadSpec ();
+
+ ThreadSpec (const ThreadSpec &rhs);
+
+ const ThreadSpec &
+ operator=(const ThreadSpec &rhs);
+
+ void
+ SetIndex (uint32_t index)
+ {
+ m_index = index;
+ }
+
+ void
+ SetTID (lldb::tid_t tid)
+ {
+ m_tid = tid;
+ }
+
+ void
+ SetName (const char *name)
+ {
+ m_name = name;
+ }
+
+ void
+ SetQueueName (const char *queue_name)
+ {
+ m_queue_name = queue_name;
+ }
+
+ uint32_t
+ GetIndex () const
+ {
+ return m_index;
+ }
+
+ lldb::tid_t
+ GetTID () const
+ {
+ return m_tid;
+ }
+
+ const char *
+ GetName () const;
+
+ const char *
+ GetQueueName () const;
+
+ bool
+ TIDMatches (lldb::tid_t thread_id) const
+ {
+ if (m_tid == LLDB_INVALID_THREAD_ID || thread_id == LLDB_INVALID_THREAD_ID)
+ return true;
+ else
+ return thread_id == m_tid;
+ }
+
+ bool
+ IndexMatches (uint32_t index) const
+ {
+ if (m_index == -1 || index == -1)
+ return true;
+ else
+ return index == m_index;
+ }
+
+ bool
+ NameMatches (const char *name) const
+ {
+ if (m_name.empty())
+ return true;
+ else if (name == NULL)
+ return false;
+ else
+ return m_name == name;
+ }
+
+ bool
+ QueueNameMatches (const char *queue_name) const
+ {
+ if (m_queue_name.empty())
+ return true;
+ else if (queue_name == NULL)
+ return false;
+ else
+ return m_queue_name == queue_name;
+ }
+
+protected:
+private:
+ uint32_t m_index;
+ lldb::tid_t m_tid;
+ std::string m_name;
+ std::string m_queue_name;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_ThreadSpec_h_
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 9e69ca09f52..59500d8f2df 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -129,6 +129,7 @@ class ThreadPlanStepOverBreakpoint;
class ThreadPlanStepThrough;
class ThreadPlanStepRange;
class ThreadPlanRunToAddress;
+class ThreadSpec;
class TimeValue;
class Type;
class TypeList;
diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj
index 790b25130b4..1586c0b4fa1 100644
--- a/lldb/lldb.xcodeproj/project.pbxproj
+++ b/lldb/lldb.xcodeproj/project.pbxproj
@@ -335,6 +335,8 @@
49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; };
49F1A74611B3388F003ED505 /* ClangExpressionDeclMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */; };
49F1A74A11B338AE003ED505 /* ClangExpressionDeclMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */; };
+ 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */; };
+ 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */; };
4CA9637B11B6E99A00780E28 /* CommandObjectApropos.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CA9637911B6E99A00780E28 /* CommandObjectApropos.cpp */; };
4CA9637C11B6E99A00780E28 /* CommandObjectApropos.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CA9637A11B6E99A00780E28 /* CommandObjectApropos.h */; };
9A19A6AF1163BBB200E0D453 /* SBValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 9A19A6A51163BB7E00E0D453 /* SBValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -920,6 +922,8 @@
49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpressionDeclMap.h; path = include/lldb/Expression/ClangExpressionDeclMap.h; 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>"; };
+ 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>"; };
4C09CB74116BD98B00C7A725 /* CommandCompletions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CommandCompletions.cpp; path = source/Commands/CommandCompletions.cpp; sourceTree = "<group>"; };
4C43DEF9110641F300E55CBF /* ThreadPlanShouldStopHere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThreadPlanShouldStopHere.h; path = include/lldb/Target/ThreadPlanShouldStopHere.h; sourceTree = "<group>"; };
@@ -1963,6 +1967,8 @@
260C847510F50EFC00BB2B04 /* ThreadPlanStepThrough.cpp */,
4CEDAED311754F5E00E875A6 /* ThreadPlanStepUntil.h */,
2660D9FE11922A7F00958FBD /* ThreadPlanStepUntil.cpp */,
+ 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */,
+ 4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */,
4C00986F11500B4300F316B0 /* UnixSignals.h */,
4C00987011500B4300F316B0 /* UnixSignals.cpp */,
26E3EEBD11A9870400FBADB6 /* Unwind.h */,
@@ -2199,6 +2205,7 @@
49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */,
4CA9637C11B6E99A00780E28 /* CommandObjectApropos.h in Headers */,
261B5A5511C3F2AD00AABD0A /* SharingPtr.h in Headers */,
+ 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2651,6 +2658,7 @@
4CA9637B11B6E99A00780E28 /* CommandObjectApropos.cpp in Sources */,
AF94005911C03F6500085DB9 /* SymbolVendor.cpp in Sources */,
261B5A5411C3F2AD00AABD0A /* SharingPtr.cpp in Sources */,
+ 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/lldb/source/API/SBBreakpointLocation.cpp b/lldb/source/API/SBBreakpointLocation.cpp
index 8bb36bd7324..d917deab4f1 100644
--- a/lldb/source/API/SBBreakpointLocation.cpp
+++ b/lldb/source/API/SBBreakpointLocation.cpp
@@ -14,6 +14,7 @@
#include "lldb/lldb-types.h"
#include "lldb/lldb-defines.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
+#include "lldb/Target/ThreadSpec.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
@@ -102,7 +103,7 @@ SBBreakpointLocation::GetThreadID ()
{
tid_t sb_thread_id = (lldb::tid_t) LLDB_INVALID_THREAD_ID;
if (m_break_loc_sp)
- sb_thread_id = m_break_loc_sp->GetThreadID();
+ sb_thread_id = m_break_loc_sp->GetLocationOptions()->GetThreadSpec()->GetTID();
return sb_thread_id;
}
diff --git a/lldb/source/Breakpoint/Breakpoint.cpp b/lldb/source/Breakpoint/Breakpoint.cpp
index c475cf0f0d7..b3576b6a5da 100644
--- a/lldb/source/Breakpoint/Breakpoint.cpp
+++ b/lldb/source/Breakpoint/Breakpoint.cpp
@@ -24,6 +24,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/Target.h"
+#include "lldb/Target/ThreadSpec.h"
#include "lldb/lldb-private-log.h"
using namespace lldb;
@@ -166,13 +167,16 @@ Breakpoint::GetIgnoreCount () const
void
Breakpoint::SetThreadID (lldb::tid_t thread_id)
{
- m_options.SetThreadID(thread_id);
+ m_options.GetThreadSpec()->SetTID(thread_id);
}
lldb::tid_t
Breakpoint::GetThreadID ()
{
- return m_options.GetThreadID();
+ if (m_options.GetThreadSpec() == NULL)
+ return LLDB_INVALID_THREAD_ID;
+ else
+ return m_options.GetThreadSpec()->GetTID();
}
// This function is used when "baton" doesn't need to be freed
diff --git a/lldb/source/Breakpoint/BreakpointList.cpp b/lldb/source/Breakpoint/BreakpointList.cpp
index c10aa770b82..0d9444f7371 100644
--- a/lldb/source/Breakpoint/BreakpointList.cpp
+++ b/lldb/source/Breakpoint/BreakpointList.cpp
@@ -196,3 +196,9 @@ BreakpointList::ClearAllBreakpointSites ()
(*pos)->ClearAllBreakpointSites ();
}
+
+void
+BreakpointList::GetListMutex (Mutex::Locker &locker)
+{
+ return locker.Reset (m_mutex.GetMutex());
+}
diff --git a/lldb/source/Breakpoint/BreakpointLocation.cpp b/lldb/source/Breakpoint/BreakpointLocation.cpp
index 0f82829bdd7..e00afcad750 100644
--- a/lldb/source/Breakpoint/BreakpointLocation.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocation.cpp
@@ -22,6 +22,7 @@
#include "lldb/Core/StreamString.h"
#include "lldb/lldb-private-log.h"
#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
@@ -34,12 +35,13 @@ BreakpointLocation::BreakpointLocation
lldb::tid_t tid,
bool hardware
) :
- StoppointLocation (loc_id, addr.GetLoadAddress(owner.GetTarget().GetProcessSP().get()), tid, hardware),
+ StoppointLocation (loc_id, addr.GetLoadAddress(owner.GetTarget().GetProcessSP().get()), hardware),
m_address (addr),
m_owner (owner),
m_options_ap (),
m_bp_site_sp ()
{
+ SetThreadID (tid);
}
BreakpointLocation::~BreakpointLocation()
@@ -93,13 +95,15 @@ BreakpointLocation::SetEnabled (bool enabled)
void
BreakpointLocation::SetThreadID (lldb::tid_t thread_id)
{
- GetLocationOptions()->SetThreadID(thread_id);
-}
-
-lldb::tid_t
-BreakpointLocation::GetThreadID ()
-{
- return GetOptionsNoCopy()->GetThreadID();
+ if (thread_id != LLDB_INVALID_THREAD_ID)
+ GetLocationOptions()->SetThreadID(thread_id);
+ else
+ {
+ // If we're resetting this to an invalid thread id, then
+ // don't make an options pointer just to do that.
+ if (m_options_ap.get() != NULL)
+ m_options_ap->SetThreadID (thread_id);
+ }
}
bool
@@ -150,8 +154,8 @@ BreakpointLocation::SetIgnoreCount (int32_t n)
GetLocationOptions()->SetIgnoreCount(n);
}
-BreakpointOptions *
-BreakpointLocation::GetOptionsNoCopy ()
+const BreakpointOptions *
+BreakpointLocation::GetOptionsNoCopy () const
{
if (m_options_ap.get() != NULL)
return m_options_ap.get();
@@ -168,8 +172,16 @@ BreakpointLocation::GetLocationOptions ()
return m_options_ap.get();
}
+bool
+BreakpointLocation::ValidForThisThread (Thread *thread)
+{
+ return thread->MatchesSpec(GetOptionsNoCopy()->GetThreadSpec());
+}
+
// RETURNS - true if we should stop at this breakpoint, false if we
-// should continue.
+// should continue. Note, we don't check the thread spec for the breakpoint
+// here, since if the breakpoint is not for this thread, then the event won't
+// even get reported, so the check is redundant.
bool
BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
@@ -181,10 +193,6 @@ BreakpointLocation::ShouldStop (StoppointCallbackContext *context)
if (!IsEnabled())
return false;
- if (GetThreadID() != LLDB_INVALID_THREAD_ID
- && context->context.thread->GetID() != GetThreadID())
- return false;
-
if (m_hit_count <= GetIgnoreCount())
return false;
@@ -379,7 +387,7 @@ BreakpointLocation::Dump(Stream *s) const
s->Printf("BreakpointLocation %u: tid = %4.4x load addr = 0x%8.8llx state = %s type = %s breakpoint hw_index = %i hit_count = %-4u ignore_count = %-4u",
GetID(),
- m_tid,
+ GetOptionsNoCopy()->GetThreadSpec()->GetTID(),
(uint64_t) m_address.GetLoadAddress(m_owner.GetTarget().GetProcessSP().get()),
(m_options_ap.get() ? m_options_ap->IsEnabled() : m_owner.IsEnabled()) ? "enabled " : "disabled",
IsHardware() ? "hardware" : "software",
diff --git a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
index 7b574263003..464d38f1d78 100644
--- a/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
+++ b/lldb/source/Breakpoint/BreakpointLocationCollection.cpp
@@ -16,6 +16,8 @@
#include "lldb/Core/ModuleList.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointLocationList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
@@ -145,6 +147,22 @@ BreakpointLocationCollection::ShouldStop (StoppointCallbackContext *context)
return shouldStop;
}
+bool
+BreakpointLocationCollection::ValidForThisThread (Thread *thread)
+{
+ collection::iterator pos,
+ begin = m_break_loc_collection.begin(),
+ end = m_break_loc_collection.end();
+
+ for (pos = begin; pos != end; ++pos)
+ {
+ if ((*pos)->ValidForThisThread (thread))
+ return true;
+ }
+ return false;
+}
+
+
void
BreakpointLocationCollection::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
diff --git a/lldb/source/Breakpoint/BreakpointOptions.cpp b/lldb/source/Breakpoint/BreakpointOptions.cpp
index 4f664c4692f..695f4ee5ccd 100644
--- a/lldb/source/Breakpoint/BreakpointOptions.cpp
+++ b/lldb/source/Breakpoint/BreakpointOptions.cpp
@@ -16,6 +16,7 @@
#include "lldb/Core/Stream.h"
#include "lldb/Core/StringList.h"
#include "lldb/Breakpoint/StoppointCallbackContext.h"
+#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
@@ -35,7 +36,7 @@ BreakpointOptions::BreakpointOptions() :
m_callback_baton_sp (),
m_enabled (true),
m_ignore_count (0),
- m_thread_id (LLDB_INVALID_THREAD_ID)
+ m_thread_spec_ap (NULL)
{
}
@@ -48,8 +49,10 @@ BreakpointOptions::BreakpointOptions(const BreakpointOptions& rhs) :
m_callback_is_synchronous (rhs.m_callback_is_synchronous),
m_enabled (rhs.m_enabled),
m_ignore_count (rhs.m_ignore_count),
- m_thread_id (rhs.m_thread_id)
+ m_thread_spec_ap (NULL)
{
+ if (rhs.m_thread_spec_ap.get() != NULL)
+ m_thread_spec_ap.reset (new ThreadSpec(*rhs.m_thread_spec_ap.get()));
}
//----------------------------------------------------------------------
@@ -63,7 +66,8 @@ BreakpointOptions::operator=(const BreakpointOptions& rhs)
m_callback_is_synchronous = rhs.m_callback_is_synchronous;
m_enabled = rhs.m_enabled;
m_ignore_count = rhs.m_ignore_count;
- m_thread_id = rhs.m_thread_id;
+ if (rhs.m_thread_spec_ap.get() != NULL)
+ m_thread_spec_ap.reset(new ThreadSpec(*rhs.m_thread_spec_ap.get()));
return *this;
}
@@ -98,6 +102,12 @@ BreakpointOptions::GetBaton ()
return m_callback_baton_sp.get();
}
+const Baton *
+BreakpointOptions::GetBaton () const
+{
+ return m_callback_baton_sp.get();
+}
+
bool
BreakpointOptions::InvokeCallback (StoppointCallbackContext *context,
lldb::user_id_t break_id,
@@ -141,19 +151,26 @@ BreakpointOptions::SetIgnoreCount (int32_t n)
m_ignore_count = n;
}
-void
-BreakpointOptions::SetThreadID (lldb::tid_t thread_id)
+const ThreadSpec *
+BreakpointOptions::GetThreadSpec () const
{
- m_thread_id = thread_id;
+ return m_thread_spec_ap.get();
}
-lldb::tid_t
-BreakpointOptions::GetThreadID () const
+ThreadSpec *
+BreakpointOptions::GetThreadSpec ()
{
- return m_thread_id;
+ if (m_thread_spec_ap.get() == NULL)
+ m_thread_spec_ap.reset (new ThreadSpec());
+
+ return m_thread_spec_ap.get();
}
-
+void
+BreakpointOptions::SetThreadID (lldb::tid_t thread_id)
+{
+ GetThreadSpec()->SetTID(thread_id);
+}
void
BreakpointOptions::CommandBaton::GetDescription (Stream *s, lldb::DescriptionLevel level) const
diff --git a/lldb/source/Breakpoint/BreakpointSite.cpp b/lldb/source/Breakpoint/BreakpointSite.cpp
index cd0920d07c7..d9397fcb412 100644
--- a/lldb/source/Breakpoint/BreakpointSite.cpp
+++ b/lldb/source/Breakpoint/BreakpointSite.cpp
@@ -80,9 +80,8 @@ BreakpointSite::Dump(Stream *s) const
if (s == NULL)
return;
- s->Printf("BreakpointSite %u: tid = %4.4x addr = 0x%8.8llx type = %s breakpoint hw_index = %i hit_count = %-4u",
+ s->Printf("BreakpointSite %u: addr = 0x%8.8llx type = %s breakpoint hw_index = %i hit_count = %-4u",
GetID(),
- m_tid,
(uint64_t)m_addr,
IsHardware() ? "hardware" : "software",
GetHardwareIndex(),
@@ -178,6 +177,12 @@ BreakpointSite::GetOwnerAtIndex (uint32_t index)
}
bool
+BreakpointSite::ValidForThisThread (Thread *thread)
+{
+ return m_owners.ValidForThisThread(thread);
+}
+
+bool
BreakpointSite::IntersectsRange(lldb::addr_t addr, size_t size, lldb::addr_t *intersect_addr, size_t *intersect_size, size_t *opcode_offset) const
{
// We only use software traps for software breakpoints
diff --git a/lldb/source/Breakpoint/StoppointLocation.cpp b/lldb/source/Breakpoint/StoppointLocation.cpp
index 999ad536ab8..60280ef2748 100644
--- a/lldb/source/Breakpoint/StoppointLocation.cpp
+++ b/lldb/source/Breakpoint/StoppointLocation.cpp
@@ -20,9 +20,8 @@ using namespace lldb_private;
//----------------------------------------------------------------------
// StoppointLocation constructor
//----------------------------------------------------------------------
-StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, tid_t tid, bool hardware) :
+StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, bool hardware) :
m_loc_id(bid),
- m_tid(tid),
m_byte_size(0),
m_addr(addr),
m_hit_count(0),
@@ -31,9 +30,8 @@ StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, tid_t tid, bo
{
}
-StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, tid_t tid, size_t size, bool hardware) :
+StoppointLocation::StoppointLocation (break_id_t bid, addr_t addr, size_t size, bool hardware) :
m_loc_id(bid),
- m_tid(tid),
m_byte_size(size),
m_addr(addr),
m_hit_count(0),
@@ -62,12 +60,6 @@ StoppointLocation::GetLoadAddress() const
return m_addr;
}
-tid_t
-StoppointLocation::GetThreadID() const
-{
- return m_tid;
-}
-
uint32_t
StoppointLocation::GetHitCount () const
{
diff --git a/lldb/source/Breakpoint/WatchpointLocation.cpp b/lldb/source/Breakpoint/WatchpointLocation.cpp
index f765ef43202..bf24421a091 100644
--- a/lldb/source/Breakpoint/WatchpointLocation.cpp
+++ b/lldb/source/Breakpoint/WatchpointLocation.cpp
@@ -79,7 +79,6 @@ WatchpointLocation::Dump(Stream *s) const
s->Printf("WatchpointLocation %u: tid = %4.4x addr = 0x%8.8llx size = %zu state = %s type = %s watchpoint (%s%s) hw_index = %i hit_count = %-4u ignore_count = %-4u callback = %8p baton = %8p",
GetID(),
- m_tid,
(uint64_t)m_addr,
m_byte_size,
m_enabled ? "enabled " : "disabled",
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.cpp b/lldb/source/Commands/CommandObjectBreakpoint.cpp
index e001cbb4028..698a2999f4c 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpoint.cpp
@@ -25,6 +25,8 @@
#include "lldb/Target/Target.h"
#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
@@ -51,9 +53,13 @@ CommandObjectBreakpointSet::CommandOptions::CommandOptions() :
m_func_name (),
m_func_regexp (),
m_modules (),
- m_load_addr()
+ m_load_addr(),
+ m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_index (-1),
+ m_thread_name(),
+ m_queue_name(),
+ m_ignore_count (-1)
{
- BuildValidOptionSets();
}
CommandObjectBreakpointSet::CommandOptions::~CommandOptions ()
@@ -69,6 +75,21 @@ CommandObjectBreakpointSet::CommandOptions::g_option_table[] =
{ LLDB_OPT_SET_ALL, false, "ignore_inlines", 'i', no_argument, NULL, 0, NULL,
"Ignore inlined subroutines when setting the breakppoint." },
+ { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
+ "Set the number of times this breakpoint is sKipped before stopping." },
+
+ { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
+ "The breakpoint stops only for the thread whose indeX matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
+ "The breakpoint stops only for the thread whose TID matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
+ "The breakpoint stops only for the thread whose thread name matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
+ "The breakpoint stops only for threads in the queue whose name is given by this argument."},
+
{ LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<filename>",
"Set the breakpoint by source location in this particular file."},
@@ -138,6 +159,33 @@ CommandObjectBreakpointSet::CommandOptions::SetOptionValue (int option_idx, cons
m_modules.push_back (std::string (option_arg));
break;
}
+ case 'k':
+ {
+ m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
+ if (m_ignore_count == -1)
+ error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
+ }
+ case 't' :
+ {
+ m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
+ if (m_thread_id == LLDB_INVALID_THREAD_ID)
+ error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
+ }
+ break;
+ case 'T':
+ m_thread_name = option_arg;
+ break;
+ case 'q':
+ m_queue_name = option_arg;
+ break;
+ case 'x':
+ {
+ m_thread_index = Args::StringToUInt64(optarg, -1, 0);
+ if (m_thread_id == -1)
+ error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
+
+ }
+ break;
default:
error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
break;
@@ -159,6 +207,11 @@ CommandObjectBreakpointSet::CommandOptions::ResetOptionValues ()
m_func_regexp.clear();
m_load_addr = LLDB_INVALID_ADDRESS;
m_modules.clear();
+ m_ignore_count = -1;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_index = -1;
+ m_thread_name.clear();
+ m_queue_name.clear();
}
//-------------------------------------------------------------------------
@@ -223,7 +276,7 @@ CommandObjectBreakpointSet::Execute
if ((num_modules > 0) && (break_type != eSetTypeAddress))
use_module = true;
-
+
switch (break_type)
{
case eSetTypeFileAndLine: // Breakpoint by source position
@@ -361,6 +414,25 @@ CommandObjectBreakpointSet::Execute
break;
}
+ // Now set the various options that were passed in:
+ if (bp)
+ {
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
+ bp->SetThreadID (m_options.m_thread_id);
+
+ if (m_options.m_thread_index != -1)
+ bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
+
+ if (m_options.m_ignore_count != -1)
+ bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
+ }
+
if (bp && !use_module)
{
StreamString &output_stream = result.GetOutputStream();
@@ -378,8 +450,6 @@ CommandObjectBreakpointSet::Execute
return result.Succeeded();
}
-
-
//-------------------------------------------------------------------------
// CommandObjectMultiwordBreakpoint
//-------------------------------------------------------------------------
@@ -397,12 +467,14 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
CommandObjectSP disable_command_object (new CommandObjectBreakpointDisable ());
CommandObjectSP set_command_object (new CommandObjectBreakpointSet ());
CommandObjectSP command_command_object (new CommandObjectBreakpointCommand (interpreter));
+ CommandObjectSP configure_command_object (new CommandObjectBreakpointConfigure());
enable_command_object->SetCommandName("breakpoint enable");
disable_command_object->SetCommandName("breakpoint disable");
set_command_object->SetCommandName("breakpoint set");
command_command_object->SetCommandName ("breakpoint command");
list_command_object->SetCommandName ("breakpoint list");
+ configure_command_object->SetCommandName ("breakpoint configure");
status = LoadSubCommand (list_command_object, "list", interpreter);
status = LoadSubCommand (enable_command_object, "enable", interpreter);
@@ -410,6 +482,7 @@ CommandObjectMultiwordBreakpoint::CommandObjectMultiwordBreakpoint (CommandInter
status = LoadSubCommand (delete_command_object, "delete", interpreter);
status = LoadSubCommand (set_command_object, "set", interpreter);
status = LoadSubCommand (command_command_object, "command", interpreter);
+ status = LoadSubCommand (configure_command_object, "configure", interpreter);
}
CommandObjectMultiwordBreakpoint::~CommandObjectMultiwordBreakpoint ()
@@ -481,7 +554,6 @@ CommandObjectBreakpointList::CommandOptions::CommandOptions() :
Options (),
m_level (lldb::eDescriptionLevelFull) // Breakpoint List defaults to brief descriptions
{
- BuildValidOptionSets();
}
CommandObjectBreakpointList::CommandOptions::~CommandOptions ()
@@ -590,6 +662,9 @@ CommandObjectBreakpointList::Execute
}
const BreakpointList &breakpoints = target->GetBreakpointList(m_options.m_internal);
+ Mutex::Locker locker;
+ target->GetBreakpointList(m_options.m_internal).GetListMutex(locker);
+
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0)
@@ -672,7 +747,11 @@ CommandObjectBreakpointEnable::Execute (Args& args, CommandContext *context,
return false;
}
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
+
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0)
@@ -771,6 +850,9 @@ CommandObjectBreakpointDisable::Execute (Args& args, CommandContext *context,
return false;
}
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
size_t num_breakpoints = breakpoints.GetSize();
@@ -866,7 +948,11 @@ CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
return false;
}
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
const BreakpointList &breakpoints = target->GetBreakpointList();
+
size_t num_breakpoints = breakpoints.GetSize();
if (num_breakpoints == 0)
@@ -931,3 +1017,210 @@ CommandObjectBreakpointDelete::Execute (Args& args, CommandContext *context,
}
return result.Succeeded();
}
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointConfigure::CommandOptions
+//-------------------------------------------------------------------------
+
+CommandObjectBreakpointConfigure::CommandOptions::CommandOptions() :
+ Options (),
+ m_thread_id(LLDB_INVALID_THREAD_ID),
+ m_thread_index (-1),
+ m_thread_name(),
+ m_queue_name(),
+ m_ignore_count (-1)
+{
+}
+
+CommandObjectBreakpointConfigure::CommandOptions::~CommandOptions ()
+{
+}
+
+lldb::OptionDefinition
+CommandObjectBreakpointConfigure::CommandOptions::g_option_table[] =
+{
+ { LLDB_OPT_SET_ALL, false, "ignore_count", 'k', required_argument, NULL, 0, NULL,
+ "Set the number of times this breakpoint is sKipped before stopping." },
+
+ { LLDB_OPT_SET_ALL, false, "thread_index", 'x', required_argument, NULL, NULL, "<thread_index>",
+ "The breakpoint stops only for the thread whose indeX matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "thread_id", 't', required_argument, NULL, NULL, "<thread_id>",
+ "The breakpoint stops only for the thread whose TID matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "thread_name", 'T', required_argument, NULL, NULL, "<thread_name>",
+ "The breakpoint stops only for the thread whose thread name matches this argument."},
+
+ { LLDB_OPT_SET_ALL, false, "queue_name", 'q', required_argument, NULL, NULL, "<queue_name>",
+ "The breakpoint stops only for threads in the queue whose name is given by this argument."},
+
+ { 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+const lldb::OptionDefinition*
+CommandObjectBreakpointConfigure::CommandOptions::GetDefinitions ()
+{
+ return g_option_table;
+}
+
+Error
+CommandObjectBreakpointConfigure::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
+{
+ Error error;
+ char short_option = (char) m_getopt_table[option_idx].val;
+
+ switch (short_option)
+ {
+ case 'k':
+ {
+ m_ignore_count = Args::StringToSInt32(optarg, -1, 0);
+ if (m_ignore_count == -1)
+ error.SetErrorStringWithFormat ("Invalid ignore count '%s'.\n", optarg);
+ }
+ case 't' :
+ {
+ m_thread_id = Args::StringToUInt64(optarg, LLDB_INVALID_THREAD_ID, 0);
+ if (m_thread_id == LLDB_INVALID_THREAD_ID)
+ error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", optarg);
+ }
+ break;
+ case 'T':
+ m_thread_name = option_arg;
+ break;
+ case 'q':
+ m_queue_name = option_arg;
+ break;
+ case 'x':
+ {
+ m_thread_index = Args::StringToUInt64(optarg, -1, 0);
+ if (m_thread_id == -1)
+ error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", optarg);
+
+ }
+ break;
+ default:
+ error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option);
+ break;
+ }
+
+ return error;
+}
+
+void
+CommandObjectBreakpointConfigure::CommandOptions::ResetOptionValues ()
+{
+ Options::ResetOptionValues();
+
+ m_ignore_count = -1;
+ m_thread_id = LLDB_INVALID_THREAD_ID;
+ m_thread_index = -1;
+ m_thread_name.clear();
+ m_queue_name.clear();
+}
+
+//-------------------------------------------------------------------------
+// CommandObjectBreakpointSet
+//-------------------------------------------------------------------------
+
+CommandObjectBreakpointConfigure::CommandObjectBreakpointConfigure () :
+ CommandObject ("breakpoint configure", "Configures the options on a breakpoint or set of breakpoints in the executable.",
+ "breakpoint configure <cmd-options> break-id [break-id ...]")
+{
+}
+
+CommandObjectBreakpointConfigure::~CommandObjectBreakpointConfigure ()
+{
+}
+
+Options *
+CommandObjectBreakpointConfigure::GetOptions ()
+{
+ return &m_options;
+}
+
+bool
+CommandObjectBreakpointConfigure::Execute
+(
+ Args& command,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result
+)
+{
+ if (command.GetArgumentCount() == 0)
+ {
+ result.AppendError ("No breakpoints specified.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Target *target = context->GetTarget();
+ if (target == NULL)
+ {
+ result.AppendError ("Invalid target, set executable file using 'file' command.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ Mutex::Locker locker;
+ target->GetBreakpointList().GetListMutex(locker);
+
+ BreakpointIDList valid_bp_ids;
+
+ CommandObjectMultiwordBreakpoint::VerifyBreakpointIDs (command, target, result, &valid_bp_ids);
+
+ if (result.Succeeded())
+ {
+ for (int i = 0; i < valid_bp_ids.Size(); ++i)
+ {
+ BreakpointID cur_bp_id = valid_bp_ids.GetBreakpointIDAtIndex (i);
+
+ if (cur_bp_id.GetBreakpointID() != LLDB_INVALID_BREAK_ID)
+ {
+ Breakpoint *bp = target->GetBreakpointByID (cur_bp_id.GetBreakpointID()).get();
+ if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
+ {
+ BreakpointLocation *location = bp->FindLocationByID (cur_bp_id.GetLocationID()).get();
+ if (location)
+ {
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
+ location->SetThreadID (m_options.m_thread_id);
+
+ if (m_options.m_thread_index != -1)
+ location->GetLocationOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ location->GetLocationOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ location->GetLocationOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
+
+ if (m_options.m_ignore_count != -1)
+ location->GetLocationOptions()->SetIgnoreCount(m_options.m_ignore_count);
+ }
+ }
+ else
+ {
+ if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
+ bp->SetThreadID (m_options.m_thread_id);
+
+ if (m_options.m_thread_index != -1)
+ bp->GetOptions()->GetThreadSpec()->SetIndex(m_options.m_thread_index);
+
+ if (!m_options.m_thread_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetName(m_options.m_thread_name.c_str());
+
+ if (!m_options.m_queue_name.empty())
+ bp->GetOptions()->GetThreadSpec()->SetQueueName(m_options.m_queue_name.c_str());
+
+ if (m_options.m_ignore_count != -1)
+ bp->GetOptions()->SetIgnoreCount(m_options.m_ignore_count);
+ }
+ }
+ }
+ }
+
+ return result.Succeeded();
+}
+
+
diff --git a/lldb/source/Commands/CommandObjectBreakpoint.h b/lldb/source/Commands/CommandObjectBreakpoint.h
index 8e705918c8f..7e7bd61181f 100644
--- a/lldb/source/Commands/CommandObjectBreakpoint.h
+++ b/lldb/source/Commands/CommandObjectBreakpoint.h
@@ -106,6 +106,70 @@ public:
std::string m_func_regexp;
lldb::addr_t m_load_addr;
STLStringArray m_modules;
+ int32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ uint32_t m_thread_index;
+ std::string m_thread_name;
+ std::string m_queue_name;
+
+ };
+
+private:
+ CommandOptions m_options;
+};
+
+//-------------------------------------------------------------------------
+// CommandObjectMultiwordBreakpointConfigure
+//-------------------------------------------------------------------------
+
+
+class CommandObjectBreakpointConfigure : public CommandObject
+{
+public:
+
+ CommandObjectBreakpointConfigure ();
+
+ virtual
+ ~CommandObjectBreakpointConfigure ();
+
+ virtual bool
+ Execute (Args& command,
+ CommandContext *context,
+ CommandInterpreter *interpreter,
+ CommandReturnObject &result);
+
+ virtual Options *
+ GetOptions ();
+
+ class CommandOptions : public Options
+ {
+ public:
+
+ CommandOptions ();
+
+ virtual
+ ~CommandOptions ();
+
+ virtual Error
+ SetOptionValue (int option_idx, const char *option_arg);
+
+ void
+ ResetOptionValues ();
+
+ const lldb::OptionDefinition*
+ GetDefinitions ();
+
+ // Options table: Required for subclasses of Options.
+
+ static lldb::OptionDefinition g_option_table[];
+
+ // Instance variables to hold the values for command options.
+
+ int32_t m_ignore_count;
+ lldb::tid_t m_thread_id;
+ uint32_t m_thread_index;
+ std::string m_thread_name;
+ std::string m_queue_name;
};
diff --git a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
index dc1c84b0e64..cc0687c7b64 100644
--- a/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
+++ b/lldb/source/Commands/CommandObjectBreakpointCommand.cpp
@@ -34,7 +34,6 @@ using namespace lldb_private;
CommandObjectBreakpointCommandAdd::CommandOptions::CommandOptions () :
Options ()
{
- BuildValidOptionSets();
}
CommandObjectBreakpointCommandAdd::CommandOptions::~CommandOptions ()
@@ -532,7 +531,7 @@ CommandObjectBreakpointCommandList::Execute (Args& command,
if (bp)
{
- BreakpointOptions *bp_options = NULL;
+ const BreakpointOptions *bp_options = NULL;
if (cur_bp_id.GetLocationID() != LLDB_INVALID_BREAK_ID)
{
BreakpointLocationSP bp_loc_sp(bp->FindLocationByID (cur_bp_id.GetLocationID()));
@@ -556,7 +555,7 @@ CommandObjectBreakpointCommandList::Execute (Args& command,
{
StreamString id_str;
BreakpointID::GetCanonicalReference (&id_str, cur_bp_id.GetBreakpointID(), cur_bp_id.GetLocationID());
- Baton *baton = bp_options->GetBaton();
+ const Baton *baton = bp_options->GetBaton();
if (baton)
{
result.GetOutputStream().Printf ("Breakpoint %s:\n", id_str.GetData());
diff --git a/lldb/source/Commands/CommandObjectFile.cpp b/lldb/source/Commands/CommandObjectFile.cpp
index 09d9bd0c558..af7e2fed943 100644
--- a/lldb/source/Commands/CommandObjectFile.cpp
+++ b/lldb/source/Commands/CommandObjectFile.cpp
@@ -28,7 +28,6 @@ CommandObjectFile::CommandOptions::CommandOptions() :
Options (),
m_arch () // Breakpoint info defaults to brief descriptions
{
- BuildValidOptionSets();
}
CommandObjectFile::CommandOptions::~CommandOptions ()
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
index d887b09dd3a..2dfbaa16978 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp
@@ -1000,16 +1000,20 @@ ProcessMacOSX::EnableBreakpoint (BreakpointSite *bp_site)
if (bp_site->HardwarePreferred())
{
- ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp_site->GetThreadID()).get();
- if (thread)
- {
- bp_site->SetHardwareIndex (thread->SetHardwareBreakpoint(bp_site));
- if (bp_site->IsHardware())
- {
- bp_site->SetEnabled(true);
- return error;
- }
- }
+ // FIXME: This code doesn't make sense. Breakpoint sites don't really have single ThreadID's, since one site could be
+ // owned by a number of Locations, each with a different Thread ID. So either this should run over all the Locations and
+ // set it for all threads owned by those locations, or set it for all threads, and let the thread specific code sort it out.
+
+// ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp_site->GetThreadID()).get();
+// if (thread)
+// {
+// bp_site->SetHardwareIndex (thread->SetHardwareBreakpoint(bp_site));
+// if (bp_site->IsHardware())
+// {
+// bp_site->SetEnabled(true);
+// return error;
+// }
+// }
}
// Just let lldb::Process::EnableSoftwareBreakpoint() handle everything...
@@ -1030,17 +1034,6 @@ ProcessMacOSX::DisableBreakpoint (BreakpointSite *bp_site)
if (bp_site->IsHardware())
{
- ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(bp_site->GetThreadID()).get();
- if (thread)
- {
- if (thread->ClearHardwareBreakpoint(bp_site))
- {
- bp_site->SetEnabled(false);
- if (log)
- log->Printf ("ProcessMacOSX::DisableBreakpoint (site_id = %d) addr = 0x%8.8llx -- SUCCESS (hardware)", site_id, (uint64_t)addr);
- return error;
- }
- }
error.SetErrorString("hardware breakpoints are no supported");
return error;
}
@@ -1068,20 +1061,8 @@ ProcessMacOSX::EnableWatchpoint (WatchpointLocation *wp)
}
else
{
- ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(wp->GetThreadID()).get();
- if (thread)
- {
- wp->SetHardwareIndex (thread->SetHardwareWatchpoint (wp));
- if (wp->IsHardware ())
- {
- wp->SetEnabled(true);
- return error;
- }
- }
- else
- {
- error.SetErrorString("Watchpoints currently only support thread specific watchpoints.");
- }
+ // Watchpoints aren't supported at present.
+ error.SetErrorString("Watchpoints aren't currently supported.");
}
}
return error;
@@ -1103,17 +1084,7 @@ ProcessMacOSX::DisableWatchpoint (WatchpointLocation *wp)
if (wp->IsHardware())
{
- ThreadMacOSX *thread = (ThreadMacOSX *)m_thread_list.FindThreadByID(wp->GetThreadID()).get();
- if (thread)
- {
- if (thread->ClearHardwareWatchpoint (wp))
- {
- wp->SetEnabled(false);
- if (log)
- log->Printf ("ProcessMacOSX::Disablewatchpoint (watchID = %d) addr = 0x%8.8llx (hardware) => success", watchID, (uint64_t)addr);
- return error;
- }
- }
+ error.SetErrorString("Watchpoints aren't currently supported.");
}
// TODO: clear software watchpoints if we implement them
error.SetErrorToGenericError();
diff --git a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
index 46d84a853d0..826407662ad 100644
--- a/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
+++ b/lldb/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp
@@ -81,11 +81,19 @@ ThreadMacOSX::GetRawStopReason (Thread::StopInfo *stop_info )
if (data_0 == MACH_SOFTWARE_BREAKPOINT_DATA_0)
{
lldb::addr_t pc = GetRegisterContext()->GetPC();
- lldb::user_id_t break_id = m_process.GetBreakpointSiteList().FindIDByAddress(pc);
- if (break_id != LLDB_INVALID_BREAK_ID)
+ lldb::BreakpointSiteSP bp_site_sp = m_process.GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp)
{
- stop_info->Clear ();
- stop_info->SetStopReasonWithBreakpointSiteID (break_id);
+ if (bp_site_sp->ValidForThisThread (this))
+ {
+ stop_info->Clear ();
+ stop_info->SetStopReasonWithBreakpointSiteID (GetID());
+ }
+ else
+ {
+ stop_info->Clear ();
+ stop_info->SetStopReasonToNone();
+ }
return success;
}
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 81369c2368f..a528120915d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1034,8 +1034,8 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
else if (exc_type == EXC_BREAKPOINT && exc_data[0] == MACH_EXC_DATA0_SOFTWARE_BREAKPOINT)
{
addr_t pc = gdb_thread->GetRegisterContext()->GetPC();
- user_id_t break_id = GetBreakpointSiteList().FindIDByAddress(pc);
- if (break_id == LLDB_INVALID_BREAK_ID)
+ lldb::BreakpointSiteSP bp_site_sp = GetBreakpointSiteList().FindByAddress(pc);
+ if (!bp_site_sp)
{
//log->Printf("got EXC_BREAKPOINT at 0x%llx but didn't find a breakpoint site.\n", pc);
stop_info.SetStopReasonWithException(exc_type, exc_data.size());
@@ -1044,8 +1044,17 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
}
else
{
- stop_info.Clear ();
- stop_info.SetStopReasonWithBreakpointSiteID (break_id);
+ if (bp_site_sp->ValidForThisThread (thread_sp.get()))
+ {
+ stop_info.Clear ();
+ stop_info.SetStopReasonWithBreakpointSiteID (bp_site_sp->GetID());
+ }
+ else
+ {
+ stop_info.Clear ();
+ stop_info.SetStopReasonToNone();
+ }
+
}
}
#endif
diff --git a/lldb/source/Target/Thread.cpp b/lldb/source/Target/Thread.cpp
index 068cc392f7d..510988a1591 100644
--- a/lldb/source/Target/Thread.cpp
+++ b/lldb/source/Target/Thread.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/lldb-private-log.h"
+#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamString.h"
@@ -29,6 +30,7 @@
#include "lldb/Target/ThreadPlanStepOverRange.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepUntil.h"
+#include "lldb/Target/ThreadSpec.h"
using namespace lldb;
using namespace lldb_private;
@@ -292,14 +294,25 @@ Thread::StopInfo::Dump (Stream *s) const
case eStopReasonBreakpoint:
{
bool no_details = true;
- s->PutCString ("breakpoint ");
+ s->PutCString ("breakpoint");
if (m_thread)
{
BreakpointSiteSP bp_site_sp = m_thread->GetProcess().GetBreakpointSiteList().FindByID(m_details.breakpoint.bp_site_id);
if (bp_site_sp)
{
- bp_site_sp->GetDescription(s, lldb::eDescriptionLevelBrief);
- no_details = false;
+ // Only report the breakpoint locations that actually caused this hit - some of them may
+ // have options that would have caused us not to stop here...
+ uint32_t num_locations = bp_site_sp->GetNumberOfOwners();
+ for (uint32_t i = 0; i < num_locations; i++)
+ {
+ BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(i);
+ if (bp_loc_sp->ValidForThisThread(m_thread))
+ {
+ s->PutCString(" ");
+ bp_loc_sp->GetDescription(s, lldb::eDescriptionLevelBrief);
+ no_details = false;
+ }
+ }
}
}
@@ -599,6 +612,27 @@ Thread::ShouldReportRun (Event* event_ptr)
return GetCurrentPlan()->ShouldReportRun (event_ptr);
}
+bool
+Thread::MatchesSpec (const ThreadSpec *spec)
+{
+ if (spec == NULL)
+ return true;
+
+ if (!spec->TIDMatches(GetID()))
+ return false;
+
+ if (!spec->IndexMatches(GetIndexID()))
+ return false;
+
+ if (!spec->NameMatches (GetName()))
+ return false;
+
+ if (!spec->QueueNameMatches (GetQueueName()))
+ return false;
+
+ return true;
+}
+
void
Thread::PushPlan (ThreadPlanSP &thread_plan_sp)
{
@@ -990,7 +1024,7 @@ void
Thread::DumpThreadPlans (lldb_private::Stream *s) const
{
uint32_t stack_size = m_plan_stack.size();
- s->Printf ("Plan Stack: %d elements.\n", stack_size);
+ s->Printf ("Plan Stack for thread #%u: tid = 0x%4.4x - %d elements.\n", GetIndexID(), GetID(), stack_size);
for (int i = stack_size - 1; i > 0; i--)
{
s->Printf ("Element %d: ", i);
diff --git a/lldb/source/Target/ThreadPlan.cpp b/lldb/source/Target/ThreadPlan.cpp
index c9005c1f345..3be8e9a36bd 100644
--- a/lldb/source/Target/ThreadPlan.cpp
+++ b/lldb/source/Target/ThreadPlan.cpp
@@ -127,8 +127,8 @@ ThreadPlan::WillResume (StateType resume_state, bool current_plan)
Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP);
if (log)
- log->Printf("About to resume the \"%s\" plan - state: %s - stop others: %d.",
- m_name.c_str(), StateAsCString(resume_state), StopOthers());
+ log->Printf("Thread #%u: tid = 0x%4.4x about to resume the \"%s\" plan - state: %s - stop others: %d.",
+ m_thread.GetIndexID(), m_thread.GetID(), m_name.c_str(), StateAsCString(resume_state), StopOthers());
}
return true;
}
diff --git a/lldb/source/Target/ThreadSpec.cpp b/lldb/source/Target/ThreadSpec.cpp
new file mode 100644
index 00000000000..5d1089188fe
--- /dev/null
+++ b/lldb/source/Target/ThreadSpec.cpp
@@ -0,0 +1,58 @@
+//===-- ThreadSpec.cpp ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadSpec.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ThreadSpec::ThreadSpec() :
+ m_index (-1),
+ m_tid (LLDB_INVALID_THREAD_ID),
+ m_name(),
+ m_queue_name ()
+{
+}
+
+ThreadSpec::ThreadSpec (const ThreadSpec &rhs) :
+ m_index(rhs.m_index),
+ m_tid(rhs.m_tid),
+ m_name(rhs.m_name),
+ m_queue_name(rhs.m_queue_name)
+{
+}
+
+const ThreadSpec &
+ThreadSpec::operator=(const ThreadSpec &rhs)
+{
+ m_index = rhs.m_index;
+ m_tid = rhs.m_tid;
+ m_name = rhs.m_name;
+ m_queue_name = rhs.m_queue_name;
+ return *this;
+}
+
+const char *
+ThreadSpec::GetName () const
+{
+ if (m_name.empty())
+ return NULL;
+ else
+ return m_name.c_str();
+}
+
+const char *
+ThreadSpec::GetQueueName () const
+{
+ if (m_queue_name.empty())
+ return NULL;
+ else
+ return m_queue_name.c_str();
+}
OpenPOWER on IntegriCloud