From patchwork Sat Jun 1 10:22:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 1942410 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=FD/osEgC; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Vrx2V2yt4z20Pb for ; Sat, 1 Jun 2024 20:25:21 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B642B388267B for ; Sat, 1 Jun 2024 10:25:19 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 45BD1388210F for ; Sat, 1 Jun 2024 10:24:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 45BD1388210F Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 45BD1388210F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1717237492; cv=none; b=v/lyl022MSKJJgsesNhOfeg58fQVTftEuc2KQlCq0BNTzSF/eVxwKAfj2LNYIhvMFDtYxUFuAttxbqVaxRJttLobTHLwhFntAJUJWmK716XgHS0zPg5i7F6cL0lGFgsTFSrulJnjdpXqHTXdTrNLBedX4WqBcFyRqb5lisHR4ME= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1717237492; c=relaxed/simple; bh=sI+Xt7G99NhnROTyIMKMnAVt6a2V77k2X3JkMm3gC7k=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=pbaG5A8EdRH7VZn5VbXXoRp+3YcFfhfd+jerNn6nIAL1BT31KND6syqYwte2DyiHj7PNFllwxaEbs8HHNnNIlmW6LpKxOboJLUCj26gZRpUktJUYdj85Cc/EDjnEadqHSph17ngFtrLH10W2QOoEnpO3ErlHn6HWeEv9mHXZ8Nc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1717237490; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=1GNMcJ+uLPNNQb/NRCdpvQyulLsEm8/GrCsSm9YkQhM=; b=FD/osEgCAH6RJHdenLm/7q2ia5I12pFq7e5Vycq3mpgcKGy5StAGlUaoT3RqgY9/zdFsgz tVMqLZUmPY5sEGySkb12ifiWM69xa/ViVU8/NP8t6G+7Y5UOVzs/PpDXH/K5uMNGx9rykc GSQVYllbKQV2K/AnpKWlYv5qxlvOi2o= Received: from mimecast-mx02.redhat.com (mx-ext.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-252-ouVLtP0HNNGykKQqsJIpaA-1; Sat, 01 Jun 2024 06:24:47 -0400 X-MC-Unique: ouVLtP0HNNGykKQqsJIpaA-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 9E2F63C025AC; Sat, 1 Jun 2024 10:24:47 +0000 (UTC) Received: from localhost (unknown [10.42.28.51]) by smtp.corp.redhat.com (Postfix) with ESMTP id 51AD5492BC6; Sat, 1 Jun 2024 10:24:47 +0000 (UTC) From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: drepper@redhat.com Subject: [PATCH] libstdc++: Implement C++26 features (P2546R5) Date: Sat, 1 Jun 2024 11:22:18 +0100 Message-ID: <20240601102446.878286-1-jwakely@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.11.54.9 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Here's an implementation of the C++26 header. We should really have some tests that invoke GDB and check that the breakpoint works when a debugger is attached. That seems tricky to do via the main conformance.exp testsuite. It could be done via the prettyprinters.exp testsuite, which already uses GDB, but would require some changes to the gdb-test procedure, which assumes it needs to insert its own breakpoint at marked spots in the code. I think we could add this without those tests, and improve it later. -- >8 -- It would be good to provide a macOS definition of is_debugger_present, but that isn't included in this change. libstdc++-v3/ChangeLog: * config.h.in: Regenerate. * configure: Regenerate. * configure.ac: Check for facilities needed by . * include/Makefile.am: Add new header. * include/Makefile.in: Regenerate. * include/bits/version.def (debugging): Add. * include/bits/version.h: Regenerate. * src/c++26/Makefile.am: Add new file. * src/c++26/Makefile.in: Regenerate. * include/std/debugging: New file. * src/c++26/debugging.cc: New file. * testsuite/19_diagnostics/debugging/breakpoint.cc: New test. * testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc: New test. --- libstdc++-v3/config.h.in | 9 ++ libstdc++-v3/configure | 22 +++ libstdc++-v3/configure.ac | 9 ++ libstdc++-v3/include/Makefile.am | 1 + libstdc++-v3/include/Makefile.in | 1 + libstdc++-v3/include/bits/version.def | 9 ++ libstdc++-v3/include/bits/version.h | 10 ++ libstdc++-v3/include/std/debugging | 82 ++++++++++++ libstdc++-v3/src/c++26/Makefile.am | 4 +- libstdc++-v3/src/c++26/Makefile.in | 7 +- libstdc++-v3/src/c++26/debugging.cc | 126 ++++++++++++++++++ .../19_diagnostics/debugging/breakpoint.cc | 9 ++ .../debugging/breakpoint_if_debugging.cc | 9 ++ 13 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 libstdc++-v3/include/std/debugging create mode 100644 libstdc++-v3/src/c++26/debugging.cc create mode 100644 libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc create mode 100644 libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc diff --git a/libstdc++-v3/config.h.in b/libstdc++-v3/config.h.in index 486ba450749..07203815459 100644 --- a/libstdc++-v3/config.h.in +++ b/libstdc++-v3/config.h.in @@ -70,6 +70,9 @@ /* Define to 1 if you have the `cosl' function. */ #undef HAVE_COSL +/* Define to 1 if you have the header file. */ +#undef HAVE_DEBUGAPI_H + /* Define to 1 if you have the declaration of `strnlen', and to 0 if you don't. */ #undef HAVE_DECL_STRNLEN @@ -436,6 +439,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_PARAM_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PTRACE_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_RESOURCE_H @@ -847,6 +853,9 @@ /* Define if nl_langinfo_l should be used for std::text_encoding. */ #undef _GLIBCXX_USE_NL_LANGINFO_L +/* Define if /proc/self/status should be used for . */ +#undef _GLIBCXX_USE_PROC_SELF_STATUS + /* Define if pthreads_num_processors_np is available in . */ #undef _GLIBCXX_USE_PTHREADS_NUM_PROCESSORS_NP diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure index 5645e991af7..55ddf36a7f1 100755 --- a/libstdc++-v3/configure +++ b/libstdc++-v3/configure @@ -54612,6 +54612,28 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +# For std::is_debugger_present +case "$target_os" in + linux*) + +$as_echo "#define _GLIBCXX_USE_PROC_SELF_STATUS 1" >>confdefs.h + + ;; +esac +for ac_header in sys/ptrace.h debugapi.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + # Define documentation rules conditionally. # See if makeinfo has been installed and is modern enough diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac index ccb24a82be7..96b412fb7ae 100644 --- a/libstdc++-v3/configure.ac +++ b/libstdc++-v3/configure.ac @@ -573,6 +573,15 @@ GLIBCXX_CHECK_FILEBUF_NATIVE_HANDLES # For std::text_encoding GLIBCXX_CHECK_TEXT_ENCODING +# For std::is_debugger_present +case "$target_os" in + linux*) + AC_DEFINE([_GLIBCXX_USE_PROC_SELF_STATUS],1, + [Define if /proc/self/status should be used for .]) + ;; +esac +AC_CHECK_HEADERS([sys/ptrace.h debugapi.h]) + # Define documentation rules conditionally. # See if makeinfo has been installed and is modern enough diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 422a0f4bd0a..94eca0b42f9 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -67,6 +67,7 @@ std_headers = \ ${std_srcdir}/codecvt \ ${std_srcdir}/complex \ ${std_srcdir}/condition_variable \ + ${std_srcdir}/debugging \ ${std_srcdir}/deque \ ${std_srcdir}/execution \ ${std_srcdir}/filesystem \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index 9fd4ab4848c..299597ef657 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -423,6 +423,7 @@ std_freestanding = \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/codecvt \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/complex \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/condition_variable \ +@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/debugging \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/deque \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/execution \ @GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/filesystem \ diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 683b967d54b..ea271901e5d 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1752,6 +1752,15 @@ ftms = { }; }; +ftms = { + name = debugging; + values = { + v = 202403; + cxxmin = 26; + extra_cond = "_GLIBCXX_USE_PROC_SELF_STATUS || _GLIBCXX_HAVE_SYS_PTRACE_H || _GLIBCXX_HAVE_DEBUGAPI_H"; + }; +}; + ftms = { name = fstream_native_handle; values = { diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 4850041c0a3..50d2d604ce9 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -1953,6 +1953,16 @@ #endif /* !defined(__cpp_lib_unreachable) && defined(__glibcxx_want_unreachable) */ #undef __glibcxx_want_unreachable +#if !defined(__cpp_lib_debugging) +# if (__cplusplus > 202302L) && (_GLIBCXX_USE_PROC_SELF_STATUS || _GLIBCXX_HAVE_SYS_PTRACE_H || _GLIBCXX_HAVE_DEBUGAPI_H) +# define __glibcxx_debugging 202403L +# if defined(__glibcxx_want_all) || defined(__glibcxx_want_debugging) +# define __cpp_lib_debugging 202403L +# endif +# endif +#endif /* !defined(__cpp_lib_debugging) && defined(__glibcxx_want_debugging) */ +#undef __glibcxx_want_debugging + #if !defined(__cpp_lib_fstream_native_handle) # if (__cplusplus > 202302L) && _GLIBCXX_HOSTED # define __glibcxx_fstream_native_handle 202306L diff --git a/libstdc++-v3/include/std/debugging b/libstdc++-v3/include/std/debugging new file mode 100644 index 00000000000..76f81e23e72 --- /dev/null +++ b/libstdc++-v3/include/std/debugging @@ -0,0 +1,82 @@ +// Debugging support -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file include/debugging + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_DEBUGGING +#define _GLIBCXX_DEBUGGING 1 + +#define __glibcxx_want_debugging +#include + +#if __cpp_lib_debugging // C++ >= 26 +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +/** Try to determine if the program is running under control of a debugger. + * + * On GNU/Linux systems this function will only return true if the program + * is being traced by another program which is known to be a debugger. + * This is determined by checking the command name of the tracing program + * against a list of known debuggers, such as "gdb". + * + * On other POSIX-based systems, this function will return true if the + * program is being traced by any other process, which means it can return + * true for non-debugger utilities such as strace. + * + * @since C++26 + */ +bool +is_debugger_present() noexcept; + +/** Stop the program with a breakpoint or debug trap. + * + * The details of how a breakpoint is implemented are platform-specific. + * Some systems provide a special instruction, such as `int3` in x86. + * When no more appropriate mechanism is available, this will stop the + * program using `__builtin_trap()`. It might not be possible for the + * program to continue after such a breakpoint. + * + * @since C++26 + */ +void +breakpoint() noexcept; + +/** Stop the program if it is running under control of a debugger. + * + * @since C++26 + */ +inline void +breakpoint_if_debugging() noexcept +{ + if (std::is_debugger_present()) [[unlikely]] + breakpoint(); +} + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif +#endif // _GLIBCXX_DEBUGGING diff --git a/libstdc++-v3/src/c++26/Makefile.am b/libstdc++-v3/src/c++26/Makefile.am index 000ced1f501..551d08d583e 100644 --- a/libstdc++-v3/src/c++26/Makefile.am +++ b/libstdc++-v3/src/c++26/Makefile.am @@ -35,7 +35,9 @@ else inst_sources = endif -sources = text_encoding.cc +sources = \ + debugging.cc \ + text_encoding.cc vpath % $(top_srcdir)/src/c++26 diff --git a/libstdc++-v3/src/c++26/Makefile.in b/libstdc++-v3/src/c++26/Makefile.in index 77e73b2b265..1c317d6ac7c 100644 --- a/libstdc++-v3/src/c++26/Makefile.in +++ b/libstdc++-v3/src/c++26/Makefile.in @@ -121,7 +121,7 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libc__26convenience_la_LIBADD = -am__objects_1 = text_encoding.lo +am__objects_1 = debugging.lo text_encoding.lo am__objects_2 = @GLIBCXX_HOSTED_TRUE@am_libc__26convenience_la_OBJECTS = \ @GLIBCXX_HOSTED_TRUE@ $(am__objects_1) $(am__objects_2) @@ -430,7 +430,10 @@ headers = # XTEMPLATE_FLAGS = -fno-implicit-templates @ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = -sources = text_encoding.cc +sources = \ + debugging.cc \ + text_encoding.cc + @GLIBCXX_HOSTED_FALSE@libc__26convenience_la_SOURCES = @GLIBCXX_HOSTED_TRUE@libc__26convenience_la_SOURCES = $(sources) $(inst_sources) diff --git a/libstdc++-v3/src/c++26/debugging.cc b/libstdc++-v3/src/c++26/debugging.cc new file mode 100644 index 00000000000..150ac1ed2e7 --- /dev/null +++ b/libstdc++-v3/src/c++26/debugging.cc @@ -0,0 +1,126 @@ +// Implementation of -*- C++ -*- + +// Copyright The GNU Toolchain Authors. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +#include + +#if __cpp_lib_debugging + +#if _GLIBCXX_USE_PROC_SELF_STATUS +# include +# include +#endif + +#if _GLIBCXX_HAVE_SYS_PTRACE_H +# include +# include +#endif + +#if _GLIBCXX_HAVE_DEBUGAPI_H +# include +#endif + +_GLIBCXX_WEAK_DEFINITION +bool +std::is_debugger_present() noexcept +{ +#if _GLIBCXX_HOSTED +# if _GLIBCXX_USE_PROC_SELF_STATUS + const string_view prefix = "TracerPid:\t"; + ifstream in("/proc/self/status"); + string line; + while (std::getline(in, line)) + { + if (!line.starts_with(prefix)) + continue; + + string_view tracer = line; + tracer.remove_prefix(prefix.size()); + if (tracer.size() == 1 && tracer[0] == '0') [[likely]] + return false; // Not being traced. + + in.close(); + string_view cmd; + string proc_dir = "/proc/" + string(tracer) + '/'; + in.open(proc_dir + "comm"); // since Linux 2.6.33 + if (std::getline(in, line)) [[likely]] + cmd = line; + else + { + in.close(); + in.open(proc_dir + "cmdline"); + if (std::getline(in, line)) + cmd = line.c_str(); // Only up to first '\0' + else + return false; + } + + for (auto i : {"gdb", "lldb"}) // known debuggers + if (cmd.ends_with(i)) + return true; + + // We found the TracerPid line, no need to do any more work. + return false; + } +# endif +# if _GLIBCXX_HAVE_SYS_PTRACE_H + if (::ptrace(PTRACE_TRACEME, 0, 1, 0) == -1) + return errno == EPERM; +# endif +# if _GLIBCXX_HAVE_DEBUGAPI_H && defined(_WIN32) && !defined(__CYGWIN__) + return IsDebuggerPresent(); +# endif +#endif // HOSTED + return false; +} + +void +std::breakpoint() noexcept +{ +#if _GLIBCXX_HAVE_DEBUGAPI_H && defined(_WIN32) && !defined(__CYGWIN__) + DebugBreak(); +#elif __has_builtin(__builtin_debugtrap) + __builtin_debugtrap(); // Clang +#elif defined(__i386__) || defined(__x86_64__) + __asm__ volatile ("int3"); +#elifdef __thumb__ + __asm__ volatile (".inst 0xde01"); +#elifdef __aarch64__ + __asm__ volatile (".inst 0xd4200000"); +#elifdef __arm__ + __asm__ volatile (".inst 0xe7f001f0"); +#elifdef __riscv + /* section 2.8 in the RISC-V unprivileged ISA manual says for semi-hosted + * environments we want the sequence: + * slli x0, x0, 0x1f # Entry NOP + * ebreak # Break to debugger + * srai x0, x0, 7 # NOP encoding the semihosting call number 7 + */ + __asm__ volatile (".4byte 0x00100073"); +#elifdef __powerpc__ + __asm__ volatile(".4byte 0x7d821008"); +#else + __builtin_trap(); +#endif +} // If the debugger stops here, std::breakpoint() was called. + +#endif // __cpp_lib_debugging diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc new file mode 100644 index 00000000000..ee572dc9424 --- /dev/null +++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint.cc @@ -0,0 +1,9 @@ +// { dg-do run { target c++26 xfail c++26 } } +// { dg-options "-lstdc++exp" } +// { dg-require-cpp-feature-test __cpp_lib_debugging } +#include + +int main() +{ + std::breakpoint(); +} diff --git a/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc new file mode 100644 index 00000000000..02ac245daaf --- /dev/null +++ b/libstdc++-v3/testsuite/19_diagnostics/debugging/breakpoint_if_debugging.cc @@ -0,0 +1,9 @@ +// { dg-do run { target c++26 } } +// { dg-options "-lstdc++exp" } +// { dg-require-cpp-feature-test __cpp_lib_debugging } +#include + +int main() +{ + std::breakpoint_if_debugging(); +}