Document number:

ISO/IEC/JTC1/SC22/WG21/P2810R2

Date:

2023-12-02

Audience:

LEWG

Project:

ISO/IEC JTC1/SC22/WG21 14882: Programming Language — C++

Reply-to:

René Ferdinand Rivera Morell - grafikrobot at gmail dot com
Ben Craig - ben dot craig at gmail dot com

1. Abstract

This proposes to add std::is_debugger_present, proposed in P2546 [1], to the set of replacement functions to allow users the flexibility to control the result of the function when otherwise it would not be possible to determine the platform specific result.

2. Revision History

2.1. Revision 2 (December 2023)

Add poll results from LEWG 2023-09-19 meeting. Adjust wording per LEWG consensus feedback for no-precondition on the user replacement function.

2.2. Revision 1 (July 2023)

Wording relative to final P2546 revision 5.

2.3. Revision 0 (February 2023)

Initial.

3. Motivation

The debugging support proposed in P2546 [1] defines its functions as available in both hosted and freestanding realms. In it the std::is_debugger_present function poses some challenges for embedded platforms where determining the circumstances of debuggers in a freestanding environment is most times impossible. Hence it is reasonable to allow the user to control what the function returns by some means. While some options are possible, like environment variables, platform configuration files, alternate runtime implementations, they are not ideal. As even those options may not be implementable for the platform. It is also ideal to not remove the function from freestanding as that will complicate the use of the functions with macro checks and alternative implementations. Placing the C++ ecosystem in yet more reliance on the preprocessor.

The option we propose is to allow users to replace the function in their programs, i.e. a replaceable function. This has the benefits of giving users the ability to overcome any deficiencies in the default platform implementation and to have fine control over the result even on hosted platforms. Possible user implementations could:

  • Wire it to return true in special verifying builds of their application.

  • Wire it to return true from external input like: a key press or other external mechanical signal, a software signal as might be caught by a process signal handler, and so on.

4. Impact on the Standard

This proposal marks the one function as an allowed replacement function.

5. Polls

5.1. SG15: P2810R0 (2023-06-16)

Poll: Forward P2810R0 is_debugger_present is_replaceable to LEWG.

Outcome: Unanimous Consent

5.2. LEWG: P2810R1 (2023-09-19)

Poll: We should mandate a replaced is_debugger_present implementation to have no preconditions.

Outcome: Unanimous Consent

Poll: Send "P2810R1: is_debugger_present is_replaceable" to LWG for C++26, to be confirmed by electronic poll.

SF F N A SA

5

6

1

0

1

Attendance: 18

Number of Authors: 2

Author Position: 2 SF

Outcome: Consensus in favor

Strongly Against: Lack of implementation experience (Walter Brown).

6. Wording

Wording is relative to P2546R5. [1]

6.1. Feature Test Macro

In [version.syn] change date on adoption:

#define __cpp_lib_debugging YYYYMML // freestanding, also in <debugging>

6.2. Library

Insert the following paragraph between [replacement.functions] par. 2 and par. 3.

A C++ program may provide the definition of the following function signature declared in header <debugging> ([debugging.syn]):

bool std::is_debugger_present() noexcept

Change wording of definition of is_debugger_present in [debugging.utility] as:

bool is_debugger_present() noexcept;

The semantics of this function are implementation-defined.

Replaceable: A C++ program may define a function with the function signature, and thereby displace the default version defined by the C++ standard library.

Required behavior: This function has no preconditions.

NOTE 1: A call to this function does not result in undefined behavior, even in the presence of a program-defined replacement.

Default behavior: Implementation defined.

NOTE 1 2: When tracing with a debugger the execution of a program an implementation returns true. An implementation performs an immediate query, as needed, to determine if the program is traced by a debugger. On Windows, or equivalent, systems this can be achieved by calling the ::IsDebuggerPresent() Win32 function. 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.

7. Acknowledgements

Thank you Ben Craig for the idea of using a replaceable function.


1. P2546R5 Debugging Support, René Ferdinand Rivera Morell 2023-07-05 (https://wg21.link/P2546R5)