-
Notifications
You must be signed in to change notification settings - Fork 14.9k
WIP - [libc++][debugging] P2546R5: Debugging support & P2810R4: is_debugger_present
is_replaceable
#81447
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
WIP - [libc++][debugging] P2546R5: Debugging support & P2810R4: is_debugger_present
is_replaceable
#81447
Conversation
✅ With the latest revision this PR passed the Python code formatter. |
96b5e74
to
5223217
Compare
WIP notes to collect feedback on the possible implementation:
|
@llvm/pr-subscribers-libcxx Author: Hristo Hristov (H-G-Hristov) ChangesImplements (partially): https://wg21.link/P0543R3 What was implemented so far:
Patch is 54.03 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/81447.diff 38 Files Affected:
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 468226c0c2dddf..6b86aed145218c 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -400,7 +400,7 @@ Status
--------------------------------------------------- -----------------
``__cpp_lib_copyable_function`` *unimplemented*
--------------------------------------------------- -----------------
- ``__cpp_lib_debugging`` *unimplemented*
+ ``__cpp_lib_debugging`` ``202311L``
--------------------------------------------------- -----------------
``__cpp_lib_freestanding_algorithm`` *unimplemented*
--------------------------------------------------- -----------------
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index a62faee4f44e22..bc391e198be4e7 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -29,7 +29,7 @@
"","","","","","",""
"`P0543R3 <https://wg21.link/P0543R3>`__","LWG","Saturation arithmetic","Kona November 2023","|Complete|","18.0",""
"`P2407R5 <https://wg21.link/P2407R5>`__","LWG","Freestanding Library: Partial Classes","Kona November 2023","","",""
-"`P2546R5 <https://wg21.link/P2546R5>`__","LWG","Debugging Support","Kona November 2023","","",""
+"`P2546R5 <https://wg21.link/P2546R5>`__","LWG","Debugging Support","Kona November 2023","|Partial|","19.0",""
"`P2905R2 <https://wg21.link/P2905R2>`__","LWG","Runtime format strings","Kona November 2023","|Complete|","18.0","|format| |DR|"
"`P2918R2 <https://wg21.link/P2918R2>`__","LWG","Runtime format strings II","Kona November 2023","|Complete|","18.0","|format|"
"`P2909R4 <https://wg21.link/P2909R4>`__","LWG","Fix formatting of code units as integers (Dude, where’s my ``char``?)","Kona November 2023","|Complete|","18.0","|format| |DR|"
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index b44068357e7089..52f28da2a20af7 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -914,6 +914,7 @@ set(files
cuchar
cwchar
cwctype
+ debugging
deque
errno.h
exception
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 0797880cb2f5da..1766aea8b92190 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -516,6 +516,7 @@ _LIBCPP_HARDENING_MODE_DEBUG
# define _LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN
# define _LIBCPP_HAS_NO_INCOMPLETE_TZDB
# define _LIBCPP_HAS_NO_EXPERIMENTAL_SYNCSTREAM
+# define _LIBCPP_HAS_NO_INCOMPLETE_DEBUGGING
# endif
// Need to detect which libc we're using if we're on Linux.
@@ -1567,6 +1568,11 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
# define _LIBCPP_HAS_EXPLICIT_THIS_PARAMETER
# endif
+# if (defined(__APPLE__) || defined(__FreeBSD__) || defined(__linux__) || defined(_LIBCPP_WIN32API)) && \
+ !defined(__PICOLIBC__) && !defined(_LIBCPP_HAS_NO_INCOMPLETE_DEBUGGING)
+# define _LIBCPP_HAS_DEBUGGING
+# endif
+
#endif // __cplusplus
#endif // _LIBCPP___CONFIG
diff --git a/libcxx/include/__std_clang_module b/libcxx/include/__std_clang_module
index 18d6ce6b46c1f6..7dcee53c68b399 100644
--- a/libcxx/include/__std_clang_module
+++ b/libcxx/include/__std_clang_module
@@ -81,6 +81,7 @@
#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
# include <cwctype>
#endif
+#include <debugging>
#include <deque>
#include <errno.h>
#include <exception>
diff --git a/libcxx/include/debugging b/libcxx/include/debugging
new file mode 100644
index 00000000000000..686ce7c861fa7e
--- /dev/null
+++ b/libcxx/include/debugging
@@ -0,0 +1,44 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_DEBUGGING
+#define _LIBCPP_DEBUGGING
+
+/*
+// all freestanding
+namespace std {
+ // [debugging.utility], utility
+ void breakpoint() noexcept;
+ void breakpoint_if_debugging() noexcept;
+ bool is_debugger_present() noexcept;
+}
+*/
+
+#include <__config>
+#include <version>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_DEBUGGING)
+
+_LIBCPP_EXPORTED_FROM_ABI void breakpoint() noexcept;
+
+_LIBCPP_EXPORTED_FROM_ABI void breakpoint_if_debugging() noexcept;
+
+_LIBCPP_EXPORTED_FROM_ABI bool is_debugger_present() noexcept;
+
+#endif
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_DEBUGGING
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index 63af3a90d88b9b..11dca60a92b5db 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -59,6 +59,10 @@ module std_coroutine [system] {
header "coroutine"
export *
}
+module std_debugging [system] {
+ header "debugging"
+ export *
+}
module std_deque [system] {
header "deque"
export *
diff --git a/libcxx/include/version b/libcxx/include/version
index b18927a2bc38c2..5f9203ae36091f 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -491,7 +491,9 @@ __cpp_lib_within_lifetime 202306L <type_traits>
# define __cpp_lib_bind_front 202306L
# define __cpp_lib_bitset 202306L
// # define __cpp_lib_copyable_function 202306L
-// # define __cpp_lib_debugging 202311L
+# if _LIBCPP_STD_VER >= 26 && defined(_LIBCPP_HAS_DEBUGGING)
+# define __cpp_lib_debugging 202311L
+# endif
// # define __cpp_lib_freestanding_algorithm 202311L
// # define __cpp_lib_freestanding_array 202311L
// # define __cpp_lib_freestanding_cstring 202306L
diff --git a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index 2064f45bf8c084..7612a3ec25ff53 100644
--- a/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/arm64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -862,6 +862,7 @@
{'is_defined': True, 'name': '__ZNSt3__110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5alnumE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5alphaE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5blankE', 'size': 0, 'type': 'OBJECT'}
@@ -1516,6 +1517,7 @@
{'is_defined': True, 'name': '__ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119declare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__119is_debugger_presentEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKvx', 'type': 'FUNC'}
@@ -1537,6 +1539,7 @@
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__123breakpoint_if_debuggingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index fec3a4505a0c6d..b57785484f8ae8 100644
--- a/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/i686-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -543,6 +543,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5alnumE', 'size': 4, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5alphaE', 'size': 4, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5blankE', 'size': 4, 'type': 'OBJECT'}
@@ -1197,6 +1198,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119declare_no_pointersEPcj', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk119is_debugger_presentEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1218,6 +1220,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk123breakpoint_if_debuggingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
index bced6b2ea81ba5..c6c24b148ea80a 100644
--- a/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-apple-darwin.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -862,6 +862,7 @@
{'is_defined': True, 'name': '__ZNSt3__110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5alnumE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5alphaE', 'size': 0, 'type': 'OBJECT'}
{'is_defined': True, 'name': '__ZNSt3__110ctype_base5blankE', 'size': 0, 'type': 'OBJECT'}
@@ -1516,6 +1517,7 @@
{'is_defined': True, 'name': '__ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__119declare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__119is_debugger_presentEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEEx', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__120__libcpp_atomic_waitEPVKvx', 'type': 'FUNC'}
@@ -1537,6 +1539,7 @@
{'is_defined': True, 'name': '__ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIxNS_22__cxx_atomic_base_implIxEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '__ZNSt3__123breakpoint_if_debuggingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '__ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
index efa2189e9c9287..0187b958bed61c 100644
--- a/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-linux-android21.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -543,6 +543,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5alnumE', 'size': 8, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5alphaE', 'size': 8, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt6__ndk110ctype_base5blankE', 'size': 8, 'type': 'OBJECT'}
@@ -1197,6 +1198,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk119declare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk119is_debugger_presentEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEEi', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk120__libcpp_atomic_waitEPVKvi', 'type': 'FUNC'}
@@ -1218,6 +1220,7 @@
{'is_defined': True, 'name': '_ZNSt6__ndk123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIiNS_22__cxx_atomic_base_implIiEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt6__ndk123breakpoint_if_debuggingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt6__ndk132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
index ebda5b0dfba57d..467284019aab7c 100644
--- a/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-freebsd.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -557,6 +557,7 @@
{'is_defined': True, 'name': '_ZNSt3__110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110ctype_base5alnumE', 'size': 8, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__110ctype_base5alphaE', 'size': 8, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__110ctype_base5blankE', 'size': 8, 'type': 'OBJECT'}
@@ -1211,6 +1212,7 @@
{'is_defined': True, 'name': '_ZNSt3__119basic_istringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119basic_ostringstreamIcNS_11char_traitsIcEENS_9allocatorIcEEEaSEOS5_', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__119declare_no_pointersEPcm', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__119is_debugger_presentEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__get_collation_nameEPKc', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEEl', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__120__libcpp_atomic_waitEPVKvl', 'type': 'FUNC'}
@@ -1232,6 +1234,7 @@
{'is_defined': True, 'name': '_ZNSt3__123__cxx_atomic_notify_oneEPVKv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKNS_17__cxx_atomic_implIlNS_22__cxx_atomic_base_implIlEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__123__libcpp_atomic_monitorEPVKv', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__123breakpoint_if_debuggingEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__125notify_all_at_thread_exitERNS_18condition_variableENS_11unique_lockINS_5mutexEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__131__arrive_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseEh', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__132__destroy_barrier_algorithm_baseEPNS_24__barrier_algorithm_baseE', 'type': 'FUNC'}
diff --git a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
index 6432ad3be35859..2c4045dc798ebf 100644
--- a/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
+++ b/libcxx/lib/abi/x86_64-unknown-linux-gnu.libcxxabi.v1.stable.exceptions.nonew.abilist
@@ -555,6 +555,7 @@
{'is_defined': True, 'name': '_ZNSt3__110__time_putC2ERKNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110__time_putD1Ev', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110__time_putD2Ev', 'type': 'FUNC'}
+{'is_defined': True, 'name': '_ZNSt3__110breakpointEv', 'type': 'FUNC'}
{'is_defined': True, 'name': '_ZNSt3__110ctype_base5alnumE', 'size': 2, 'type': 'OBJECT'}
{'is_defined': True, 'name': '_ZNSt3__110ctype_base5alphaE', 'size': 2, 'type': 'O...
[truncated]
|
5223217
to
722d2bb
Compare
b8203d0
to
757f05e
Compare
FYI This morning https://isocpp.org/files/papers/P2810R4.html was approved. This seems small and maybe can be done directly in this commit. |
Thank you for reminding! |
Thanks for working on this. I can provide access to this if you'd like (I'll reach out on discord as well) |
@daltenty Thank you! Please reach me on Discord (Zingam). |
c05baf2
to
91ca034
Compare
Implements (partially): https://wg21.link/P0543R3 - https://eel.is/c++draft/debugging
... the new implementation is 3-4x faster than the previous one.
run | ||
cont | ||
quit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@daltenty Could you please check if the "breakpoint" tests makes sense and if it can be fixed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not do a deep review, mainly looked at the general approach.
I like the approach, but I think we could add some comments regarding the restrictions and the proposal by @vogelsgesang. I think it might be faster if we can directly check for LLDB/GDB without going through the proc filesystem.
libcxx/include/debugging
Outdated
|
||
_LIBCPP_AVAILABILITY_DEBUGGING _LIBCPP_EXPORTED_FROM_ABI void __breakpoint() noexcept; | ||
|
||
_LIBCPP_AVAILABILITY_DEBUGGING _LIBCPP_HIDE_FROM_ABI inline void breakpoint() noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on
4.1. Unconditional Breakpoint
The goal of the std::breakpoint function is to "break" or pause the running program when called. Having an unconditional, i.e. attempts to break even if the debugger is or is not actually monitoring the program allows for use in conditions where it is not possible to detect if a debugger is present.
Implementations are expected to optimize the code generated to be as minimal as possible for the platform. For example, on X86 it’s expected that this produces a single INT3 instruction. The goal in this expectation is to place the debugger as close as possible in the caller of breakpoint() to improve the debugging experience for users.
I think it would be good to mark this function _LIBCPP_ALWAYS_INLINE
with a short comment.
Did you verify the generated assembly? Also for -O0
?
libcxx/include/debugging
Outdated
# elif defined(_MSC_VER) | ||
__debugbreak(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We support clang-cl which should behave like MSVC. We also support MinGW.
}, | ||
"headers": ["debugging"], | ||
"unimplemented": True, | ||
"test_suite_guard": "TEST_STD_VER >= 26 && defined(_LIBCPP_AVAILABILITY_HAS_DEBUGGING)", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why guard against the Standard version?
libcxx/utils/libcxx/test/features.py
Outdated
] | ||
|
||
|
||
# Detect whether dbx is on the system. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please explain what DBX is, I guess the platform debugger of AIX. LLDB and GDB are well known debuggers so there only the name suffices.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not just AIX: https://en.wikipedia.org/wiki/Dbx_(debugger)
|
||
|
||
# Detect whether LLDB is on the system. | ||
def check_lldb(cfg): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not detect Python support in LLDB the name of the associated feature implies support host-has-lldb-with-python
. I assume the tests require Python support so this looks like it needs more work. Maybe look at the LLDB test suite how they determine Python support.
libcxx/src/debugging.cpp
Outdated
|
||
#elif defined(_AIX) | ||
|
||
static bool __is_debugger_present() noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Determining the filename of the proc
feels quite hacky. Is this safe when using threading and spawing subprocesses?
Why not using std::string __filename = std::format("/proc/{}/status", getpid());
?
_LIBCPP_ASSERT_INTERNAL(false, | ||
"Function is not available. Could not open '/proc/self/status' for reading, libc++ was " | ||
"compiled with _LIBCPP_HAS_NO_FILESYSTEM."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does AIX not have the same issue?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bare metal linux systems without a filesystem are a thing, but is "freestanding AIX" a thing? I doubt it.
#include <debugging> | ||
|
||
void test() { | ||
static_assert(noexcept(std::breakpoint())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to test the noexcept
one time in a separate test.
Since these tests do not use constexpr
there is no reason for the test()
indirection.
|
||
// <debugging> | ||
|
||
// bool is_debugger_present() noexcept; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add comment that this test tests the "true" result and that libcxx/test/std/utilities/debugging/is_debugger_present.pass.cpp
tests the properties and the false
result. The same for the other tests.
free(__line); | ||
fclose(__proc_status_fp); | ||
|
||
return __is_debugger_present; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The paper has the non-normative note "On POSIX this can be achieved by checking for a tracer parent process, with best effort determination that such a tracer parent process is a debugger." Did you investigate how easy it is to determined the process name of the tracing program and add a filter for some names?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
atoi(__tokenPos + strlen(__tokenStr))
gives you the tracer's PID so you can use /proc/{pid}
again to find its details (although not 100% reliably if the executable has been removed from the filesystem, or the tracer process modified its argv[0]
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer an implementation which uses plain POSIX to access the /proc
filesystem.
It should be the absolute Minimum to end up in the breakpoint ASAP when stuff goes wrong.
C libraries might do any kind of buffering or additional accesses too, for example Musl warns about using stdio for /proc (likely only relevant or writes, but still).
It doesn't make sense to depend on any of at.
Following is a tested implementation, based on the beginning of the status format that should never change
// 171 bytes would enough to include TracerPid on Linux 6.11 with hypothetical 64bit pids
#ifdef __GNUC__
__attribute__((__aligned__(8)))
#endif
char buffer[256 + 1];
int buf_read = ::open("/proc/self/status", O_RDONLY | O_CLOEXEC);
if (buf_read >= 0)
{
const ssize_t result = ::read(buf_read, buffer, sizeof(buffer) - 1);
::close(buf_read);
buf_read = static_cast<int>(result);
}
if (buf_read < 80)
{
return false;
}
// to use strstr if memmem is not available
buffer[buf_read] = '\0';
#define TRACER_KEY "\nTracerPid:\t"
// Skip some bytes including the Name field which might contain unexpected characters
char *pos = (char *)memmem(buffer + 64 , buf_read - 64, TRACER_KEY, sizeof(TRACER_KEY) - 1);
return pos != nullptr && pos[sizeof(TRACER_KEY) - 1] != '0';
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nolange Thanks for the suggestion!
See https://discourse.llvm.org/t/runtime-support-for-std-is-debugger-present/79338?u=jwakely for the approach we're considering for libstdc++ and GDB, which is similar to @vogelsgesang's suggestion. I completely agree that a better user experience would be for the debugger to recognize I also agree that an internal bool flag in the library is valuable. A public API like A suggestion for libstdc++ was that the "attach_debugger" API should return the address of |
If debuggers are going to do that, could they also recognize |
Implements (partially):
is_debugger_present
is_replaceable
What was implemented so far:
breakpoint()
breakpoint_if_debugging()
is_debugger_present()
breakpoint()
breakpoint_if_debugging()
is_debugger_present()
breakpoint()
breakpoint_if_debugging()
is_debugger_present()
breakpoint()
breakpoint_if_debugging()
is_debugger_present()
Closes #105392
Closes #105422