Files
gcc-reflection/libstdc++-v3/include/std/debugging
Jonathan Wakely 3c95766e92 libstdc++: Implement C++26 <debugging> features [PR119670]
This implements P2546R5 (Debugging Support), including the P2810R4
(is_debugger_present is_replaceable) changes, allowing
std::is_debugger_present to be replaced by the program.

It would be good to provide a macOS definition of is_debugger_present as
per https://developer.apple.com/library/archive/qa/qa1361/_index.html
but that isn't included in this change.

The src/c++26/debugging.cc file defines a global volatile int which can
be set by debuggers to indicate when they are attached and detached from
a running process. This allows std::is_debugger_present() to give a
reliable answer, and additionally allows a debugger to choose how
std::breakpoint() should behave. Setting the global to a positive value
will cause std::breakpoint() to use that value as an argument to
std::raise, so debuggers that prefer SIGABRT for breakpoints can select
that. By default std::breakpoint() will use a platform-specific action
such as the INT3 instruction on x86, or GCC's __builtin_trap().

On Linux the std::is_debugger_present() function checks whether the
process is being traced by a process named "gdb", "gdbserver" or
"lldb-server", to try to avoid interpreting other tracing processes
(such as strace) as a debugger. There have been comments suggesting this
isn't desirable and that std::is_debugger_present() should just return
true for any tracing process (which is the case for non-Linux targets
that support the ptrace system call).

libstdc++-v3/ChangeLog:

	PR libstdc++/119670
	* acinclude.m4 (GLIBCXX_CHECK_DEBUGGING): Check for facilities
	needed by <debugging>.
	* config.h.in: Regenerate.
	* configure: Regenerate.
	* configure.ac: Use GLIBCXX_CHECK_DEBUGGING.
	* include/Makefile.am: Add new header.
	* include/Makefile.in: Regenerate.
	* include/bits/version.def (debugging): Add.
	* include/bits/version.h: Regenerate.
	* include/precompiled/stdc++.h: Add new header.
	* 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.
	* testsuite/19_diagnostics/debugging/is_debugger_present.cc: New
	test.
	* testsuite/19_diagnostics/debugging/is_debugger_present-2.cc:
	New test.

Reviewed-by: Tomasz Kamiński <tkaminsk@redhat.com>
2025-08-28 17:47:00 +01:00

78 lines
2.5 KiB
C++

// 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
// <http://www.gnu.org/licenses/>.
/** @file include/debugging
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_DEBUGGING
#define _GLIBCXX_DEBUGGING 1
#define __glibcxx_want_debugging
#include <bits/version.h>
#if __cpp_lib_debugging // C++ >= 26
namespace std _GLIBCXX_VISIBILITY(default)
{
// N.B. _GLIBCXX_BEGIN_NAMESPACE_VERSION is not used here.
/** 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 that use the ptrace system call.
*
* @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
*/
void
breakpoint_if_debugging() noexcept;
} // namespace std
#endif
#endif // _GLIBCXX_DEBUGGING