summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Górny <mgorny@gentoo.org>2019-11-09 11:56:08 +0100
committerMichał Górny <mgorny@gentoo.org>2019-11-25 20:11:59 +0100
commitd970d4d4aa7345ebf8b7169b09f2775a93f86c33 (patch)
treeb65fdfad38ad39bc75f52397dab60b2479f1278b
parent8d9400b65b972cb50fe2266360443192ea107ec9 (diff)
downloadbcm5719-llvm-d970d4d4aa7345ebf8b7169b09f2775a93f86c33.tar.gz
bcm5719-llvm-d970d4d4aa7345ebf8b7169b09f2775a93f86c33.zip
[lldb] [Process/NetBSD] Copy watchpoints to newly-created threads
NetBSD ptrace interface does not populate watchpoints to newly-created threads. Solve this via copying the watchpoints from the current thread when new thread is reported via TRAP_LWP. Add a test that verifies that when the user does not have permissions to set watchpoints on NetBSD, the 'watchpoint set' errors out gracefully and thread monitoring does not crash on being unable to copy watchpoints to new threads. Differential Revision: https://reviews.llvm.org/D70023
-rw-r--r--lldb/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py2
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py1
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py1
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp15
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp2
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h5
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp15
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h3
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp14
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h8
-rw-r--r--lldb/test/Shell/Watchpoint/Inputs/thread-dbreg.c23
-rw-r--r--lldb/test/Shell/Watchpoint/netbsd-nouserdbregs.test22
-rw-r--r--lldb/test/Shell/lit.cfg.py15
20 files changed, 114 insertions, 19 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py b/lldb/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
index e02cce66129..3e6329eb91f 100644
--- a/lldb/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
+++ b/lldb/packages/Python/lldbsuite/test/commands/watchpoints/multiple_threads/TestWatchpointMultipleThreads.py
@@ -18,12 +18,10 @@ class WatchpointForMultipleThreadsTestCase(TestBase):
NO_DEBUG_INFO_TESTCASE = True
main_spec = lldb.SBFileSpec("main.cpp", False)
- @expectedFailureNetBSD
def test_watchpoint_before_thread_start(self):
"""Test that we can hit a watchpoint we set before starting another thread"""
self.do_watchpoint_test("Before running the thread")
- @expectedFailureNetBSD
def test_watchpoint_after_thread_start(self):
"""Test that we can hit a watchpoint we set after starting another thread"""
self.do_watchpoint_test("After running the thread")
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py
index 1d85dd046c3..275d54d2149 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentBreakpointsDelayedBreakpointOneWatchpoint.py
@@ -16,7 +16,6 @@ class ConcurrentBreakpointsDelayedBreakpointOneWatchpoint(
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test a breakpoint, a delayed breakpoint, and one watchpoint thread. """
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py
index 84565bf98bc..28c5c68d450 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelaySignalWatch.py
@@ -15,7 +15,6 @@ class ConcurrentDelaySignalWatch(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test a watchpoint and a (1 second delay) signal in multiple threads."""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py
index cd67116f318..2d7c984e0e1 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentDelayWatchBreak.py
@@ -15,7 +15,6 @@ class ConcurrentDelayWatchBreak(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test (1-second delay) watchpoint and a breakpoint in multiple threads."""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py
index 508084cac0c..0fbaf364045 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentSignalWatch.py
@@ -15,7 +15,6 @@ class ConcurrentSignalWatch(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test a watchpoint and a signal in multiple threads."""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py
index 762b23c89a8..687be17ddc5 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentTwoBreakpointsOneWatchpoint.py
@@ -15,7 +15,6 @@ class ConcurrentTwoBreakpointsOneWatchpoint(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test two threads that trigger a breakpoint and one watchpoint thread. """
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py
index cf86df9b324..241ea5b64a0 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreak.py
@@ -15,7 +15,6 @@ class ConcurrentWatchBreak(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test watchpoint and a breakpoint in multiple threads."""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py
index 1cef5936ad1..79a54b620e5 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchBreakDelay.py
@@ -15,7 +15,6 @@ class ConcurrentWatchBreakDelay(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test watchpoint and a (1 second delay) breakpoint in multiple threads."""
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py
index adbd2b036d8..6a37abdbcbb 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointDelayWatchpointOneBreakpoint.py
@@ -15,7 +15,6 @@ class ConcurrentWatchpointDelayWatchpointOneBreakpoint(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test two threads that trigger a watchpoint (one with a 1 second delay) and one breakpoint thread. """
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py
index 35798227128..67ac92b853c 100644
--- a/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/thread/concurrent_events/TestConcurrentWatchpointWithDelayWatchpointThreads.py
@@ -15,7 +15,6 @@ class ConcurrentWatchpointWithDelayWatchpointThreads(ConcurrentEventsBase):
@skipIfFreeBSD # timing out on buildbot
# Atomic sequences are not supported yet for MIPS in LLDB.
@skipIf(triple='^mips')
- @expectedFailureNetBSD
@add_test_categories(["watchpoint"])
def test(self):
"""Test two threads that trigger a watchpoint where one thread has a 1 second delay. """
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 0b21c7862b0..372ac059cb5 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -272,12 +272,21 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
switch (pst.pe_report_event) {
- case PTRACE_LWP_CREATE:
+ case PTRACE_LWP_CREATE: {
LLDB_LOG(log,
"monitoring new thread, pid = {0}, LWP = {1}", pid,
pst.pe_lwp);
- AddThread(pst.pe_lwp);
- break;
+ NativeThreadNetBSD& t = AddThread(pst.pe_lwp);
+ error = t.CopyWatchpointsFrom(
+ static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
+ if (error.Fail()) {
+ LLDB_LOG(log,
+ "failed to copy watchpoints to new thread {0}: {1}",
+ pst.pe_lwp, error);
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+ } break;
case PTRACE_LWP_EXIT:
LLDB_LOG(log,
"removing exited thread, pid = {0}, LWP = {1}", pid,
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
index 3a9caaad74c..a8afa0b2030 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.cpp
@@ -8,6 +8,8 @@
#include "NativeRegisterContextNetBSD.h"
+#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
+
#include "lldb/Host/common/NativeProcessProtocol.h"
using namespace lldb_private;
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
index f5dd0c33b67..2947454af2d 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h
@@ -11,12 +11,13 @@
#include "lldb/Host/common/NativeThreadProtocol.h"
-#include "Plugins/Process/NetBSD/NativeProcessNetBSD.h"
#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h"
namespace lldb_private {
namespace process_netbsd {
+class NativeProcessNetBSD;
+
class NativeRegisterContextNetBSD : public NativeRegisterContextRegisterInfo {
public:
NativeRegisterContextNetBSD(NativeThreadProtocol &native_thread,
@@ -30,6 +31,8 @@ public:
static NativeRegisterContextNetBSD *
CreateHostNativeRegisterContextNetBSD(const ArchSpec &target_arch,
NativeThreadProtocol &native_thread);
+ virtual Status
+ CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD &source) = 0;
protected:
Status DoRegisterSet(int req, void *buf);
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
index 35ebbedf26a..afb62b8170e 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp
@@ -988,4 +988,19 @@ uint32_t NativeRegisterContextNetBSD_x86_64::NumSupportedHardwareWatchpoints() {
return 4;
}
+Status NativeRegisterContextNetBSD_x86_64::CopyHardwareWatchpointsFrom(
+ NativeRegisterContextNetBSD &source) {
+ auto &r_source = static_cast<NativeRegisterContextNetBSD_x86_64&>(source);
+ Status res = r_source.ReadRegisterSet(DBRegSet);
+ if (!res.Fail()) {
+ // copy dbregs only if any watchpoints were set
+ if ((r_source.m_dbr_x86_64.dr[7] & 0xFF) == 0)
+ return res;
+
+ m_dbr_x86_64 = r_source.m_dbr_x86_64;
+ res = WriteRegisterSet(DBRegSet);
+ }
+ return res;
+}
+
#endif // defined(__x86_64__)
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
index 4ef8989ae93..0da0351a7b0 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.h
@@ -71,6 +71,9 @@ public:
uint32_t NumSupportedHardwareWatchpoints() override;
+ Status
+ CopyHardwareWatchpointsFrom(NativeRegisterContextNetBSD &source) override;
+
private:
// Private member types.
enum { GPRegSet, FPRegSet, XStateRegSet, DBRegSet };
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
index c3251c88a42..3dd14f0e1f6 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp
@@ -221,9 +221,9 @@ bool NativeThreadNetBSD::GetStopReason(ThreadStopInfo &stop_info,
llvm_unreachable("unhandled StateType!");
}
-NativeRegisterContext& NativeThreadNetBSD::GetRegisterContext() {
+NativeRegisterContextNetBSD &NativeThreadNetBSD::GetRegisterContext() {
assert(m_reg_context_up);
-return *m_reg_context_up;
+ return *m_reg_context_up;
}
Status NativeThreadNetBSD::SetWatchpoint(lldb::addr_t addr, size_t size,
@@ -284,3 +284,13 @@ Status NativeThreadNetBSD::RemoveHardwareBreakpoint(lldb::addr_t addr) {
return Status("Clearing hardware breakpoint failed.");
}
+
+Status NativeThreadNetBSD::CopyWatchpointsFrom(NativeThreadNetBSD &source) {
+ Status s = GetRegisterContext().CopyHardwareWatchpointsFrom(
+ source.GetRegisterContext());
+ if (!s.Fail()) {
+ m_watchpoint_index_map = source.m_watchpoint_index_map;
+ m_hw_break_index_map = source.m_hw_break_index_map;
+ }
+ return s;
+}
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
index f944b50efe0..89b61ef8672 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
+++ b/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.h
@@ -11,6 +11,8 @@
#include "lldb/Host/common/NativeThreadProtocol.h"
+#include "Plugins/Process/NetBSD/NativeRegisterContextNetBSD.h"
+
#include <csignal>
#include <map>
#include <string>
@@ -34,7 +36,7 @@ public:
bool GetStopReason(ThreadStopInfo &stop_info,
std::string &description) override;
- NativeRegisterContext& GetRegisterContext() override;
+ NativeRegisterContextNetBSD &GetRegisterContext() override;
Status SetWatchpoint(lldb::addr_t addr, size_t size, uint32_t watch_flags,
bool hardware) override;
@@ -62,10 +64,12 @@ private:
void SetRunning();
void SetStepping();
+ Status CopyWatchpointsFrom(NativeThreadNetBSD& source);
+
// Member Variables
lldb::StateType m_state;
ThreadStopInfo m_stop_info;
- std::unique_ptr<NativeRegisterContext> m_reg_context_up;
+ std::unique_ptr<NativeRegisterContextNetBSD> m_reg_context_up;
std::string m_stop_description;
using WatchpointIndexMap = std::map<lldb::addr_t, uint32_t>;
WatchpointIndexMap m_watchpoint_index_map;
diff --git a/lldb/test/Shell/Watchpoint/Inputs/thread-dbreg.c b/lldb/test/Shell/Watchpoint/Inputs/thread-dbreg.c
new file mode 100644
index 00000000000..14f3474789a
--- /dev/null
+++ b/lldb/test/Shell/Watchpoint/Inputs/thread-dbreg.c
@@ -0,0 +1,23 @@
+#include <pthread.h>
+
+int g_watchme = 0;
+
+void *thread_func(void *arg) {
+ /* watchpoint trigger from subthread */
+ g_watchme = 2;
+ return 0;
+}
+
+int main() {
+ pthread_t thread;
+ if (pthread_create(&thread, 0, thread_func, 0))
+ return 1;
+
+ /* watchpoint trigger from main thread */
+ g_watchme = 1;
+
+ if (pthread_join(thread, 0))
+ return 2;
+
+ return 0;
+}
diff --git a/lldb/test/Shell/Watchpoint/netbsd-nouserdbregs.test b/lldb/test/Shell/Watchpoint/netbsd-nouserdbregs.test
new file mode 100644
index 00000000000..884636c7cdf
--- /dev/null
+++ b/lldb/test/Shell/Watchpoint/netbsd-nouserdbregs.test
@@ -0,0 +1,22 @@
+# Check that 'watchpoint set' errors out gracefully when we can't set dbregs
+# and that new threads are monitored correctly even though we can't copy dbregs.
+
+# REQUIRES: system-netbsd && (target-x86 || target-x86_64) && !dbregs-set
+# RUN: %clang_host %p/Inputs/thread-dbreg.c -pthread -g -o %t.out
+# RUN: %lldb -b -o 'settings set interpreter.stop-command-source-on-error false' -s %s %t.out 2>&1 | FileCheck %s
+
+settings show interpreter.stop-command-source-on-error
+# CHECK: interpreter.stop-command-source-on-error (boolean) = false
+
+b main
+# CHECK: Breakpoint {{[0-9]+}}: where = {{.*}}`main
+b thread_func
+# CHECK: Breakpoint {{[0-9]+}}: where = {{.*}}`thread_func
+run
+# CHECK: stop reason = breakpoint
+watchpoint set variable g_watchme
+# CHECK: error: Watchpoint creation failed
+cont
+# CHECK: stop reason = breakpoint
+cont
+# CHECK: Process {{[0-9]+}} exited with status = 0
diff --git a/lldb/test/Shell/lit.cfg.py b/lldb/test/Shell/lit.cfg.py
index cc54234faf7..84c5b730dd3 100644
--- a/lldb/test/Shell/lit.cfg.py
+++ b/lldb/test/Shell/lit.cfg.py
@@ -5,6 +5,7 @@ import platform
import re
import shutil
import site
+import subprocess
import sys
import lit.formats
@@ -103,3 +104,17 @@ if config.lldb_enable_lzma:
if find_executable('xz') != None:
config.available_features.add('xz')
+
+# NetBSD permits setting dbregs either if one is root
+# or if user_set_dbregs is enabled
+can_set_dbregs = True
+if platform.system() == 'NetBSD' and os.geteuid() != 0:
+ try:
+ output = subprocess.check_output(["/sbin/sysctl", "-n",
+ "security.models.extensions.user_set_dbregs"]).decode().strip()
+ if output != "1":
+ can_set_dbregs = False
+ except subprocess.CalledProcessError:
+ can_set_dbregs = False
+if can_set_dbregs:
+ config.available_features.add('dbregs-set')
OpenPOWER on IntegriCloud