-
Notifications
You must be signed in to change notification settings - Fork 157
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
C++26対応として<debugging>ライブラリを追加 (close #1232)
- Loading branch information
1 parent
806a8c8
commit 07e9e02
Showing
7 changed files
with
302 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# debugging | ||
* debugging[meta header] | ||
* cpp26[meta cpp] | ||
|
||
`<debugging>`ヘッダでは、プログラムのデバッグ実行をサポートする機能を提供する。 | ||
|
||
| 名前 | 説明 | 対応バージョン | | ||
|------|------|----------------| | ||
| [`breakpoint`](debugging/breakpoint.md) | ブレークポイントを設置する (functional) | C++26 | | ||
| [`breakpoint_if_debugging`](debugging/breakpoint_if_debugging.md) | デバッガ実行のみブレークポイントを設置する (functional) | C++26 | | ||
| [`is_debugger_present`](debugging/is_debugger_present.md) | デバッガ実行中か判定する (functional) | C++26 | | ||
|
||
|
||
## この機能が必要になった背景・経緯 | ||
開発プラットフォームによってデバッガやブレークポイントの機能は提供されているが、本ライブラリのようにプログラム中に明示的にブレークポイントを設置し、プログラムとデバッガを対話させることでデバッグ体験が向上することがある。 | ||
|
||
実装経験としては以下のようなものがあり、これらをこのライブラリで標準化した: | ||
|
||
| 開発環境 | 機能 | | ||
|----------|------| | ||
| Microsoft C/C++ Optimizing Compiler | `__debugbreak()`関数 (無条件ブレークポイント) | | ||
| Win32 API | `IsDebuggerPresent()`関数 (デバッガ実行中か判定) | | ||
| LLVM Clang | `__builtin_debugtrap()`組み込み関数 (無条件ブレークポイント) | | ||
| arm Keil, ARM Compiler | `__breakpoint()`関数 (無条件ブレークポイント) | | ||
| Portable Snippetsライブラリ | `psnip_trap()`関数 (無条件ブレークポイント) | | ||
| Debug Breakライブラリ | `debug_break()`関数 (無条件ブレークポイント) | | ||
| Boost.Testライブラリ | `debugger_break()`関数 (無条件ブレークポイント)<br/> `under_debugger()`関数 (出張っg実行中か判定) | | ||
| EASTLライブラリ | `EASTL_DEBUG_BREAK()`マクロ (無条件ブレークポイント)、 | | ||
| Catch2ライブラリ | `CATCH_TRAP`マクロ (無条件ブレークポイント)<br/> `CATCH_BREAK_INTO_DEBUGGER`マクロ (条件付きブレークポイント)<br/> `isDebuggerActive()`関数 (デバッガ実行中か判定) | | ||
| JUCEライブラリ | `JUCE_BREAK_IN_DEBUGGER`マクロ (無条件ブレークポイント)<br/> `juce_isRunningUnderDebugger()`関数、`Process::isRunningUnderDebugger()`関数 (デバッガ実行中か判定) | | ||
| ImGuiライブラリ | `IM_DEBUG_BREAK()`マクロ (無条件ブレークポイント) | | ||
| AWS C SDK | `aws_debug_break()`関数 (条件付きブレークポイント)<br/> `aws_is_debugger_present()`関数 (デバッガ実行中か判定) | | ||
| UnrealEngine | `UE_DEBUG_BREAK`マクロ (条件付きブレークポイント)<br/> `IsDebuggerPresent()`関数 (デバッガ実行中か判定) | | ||
|
||
|
||
## バージョン | ||
### 言語 | ||
- C++26 | ||
|
||
|
||
## 参照 | ||
- [P2546R5 Debugging Support](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2546r5.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
# breakpoint | ||
* debugging[meta header] | ||
* std[meta namespace] | ||
* function[meta id-type] | ||
* cpp26[meta cpp] | ||
|
||
```cpp | ||
namespace std { | ||
void breakpoint() noexcept; // (1) C++26 | ||
} | ||
``` | ||
## 概要 | ||
ブレークポイントを設置する。 | ||
この関数は無条件のブレークポイントであり、デバッガがプログラムを監視しているかに関わらずプログラムの一時停止 (ブレーク) を試みる。 | ||
## 効果 | ||
標準規格としては、この関数の意味論は実装定義である。 | ||
実際の動作としては、この関数が呼び出されるとプログラムの実行が一時停止され、以下のいずれかの時点までデバッガに制御が渡される: | ||
- デバッガによってプログラムが終了される、または | ||
- デバッガが、この関数が呼び出されなかったかのようにプログラムの実行を再開する | ||
## 例外 | ||
投げない | ||
## 備考 | ||
- 実装としては、生成されるコードがプラットフォームに対して可能な限り最小になるように最適化することが期待される。例として、x86ターゲット環境ではINT3命令をひとつだけ生成することが期待される | ||
## 例 | ||
```cpp example | ||
#include <print> | ||
#include <debugging> | ||
#include <cmath> | ||
// なんらかの処理 | ||
double g(double a, double b) { | ||
return a / b; | ||
} | ||
double f(double a, double b) { | ||
double ret = g(a, b); | ||
if (std::isnan(ret)) { | ||
// 演算結果でNaNが発生したらブレークし、 | ||
// デバッガでパラメータ (ローカル変数) などを確認する | ||
std::breakpoint(); | ||
} | ||
} | ||
int main() { | ||
double ret = f(2.0, 0.0); | ||
std::println("{}", ret); | ||
} | ||
``` | ||
* std::breakpoint[color ff0000] | ||
* std::isnan[link /reference/cmath/isnan.md] | ||
|
||
### 出力 | ||
``` | ||
``` | ||
|
||
|
||
## バージョン | ||
### 言語 | ||
- C++26 | ||
|
||
### 処理系 | ||
- [Clang](/implementation.md#clang): 19 [mark noimpl] | ||
- [GCC](/implementation.md#gcc): 14 [mark noimpl] | ||
- [Visual C++](/implementation.md#visual_cpp): 2022 Update 10 | ||
|
||
|
||
## 参照 | ||
- [P2546R5 Debugging Support](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2546r5.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# breakpoint_if_debugging | ||
* debugging[meta header] | ||
* std[meta namespace] | ||
* function[meta id-type] | ||
* cpp26[meta cpp] | ||
|
||
```cpp | ||
namespace std { | ||
void breakpoint_if_debugging() noexcept; // (1) C++26 | ||
} | ||
``` | ||
## 概要 | ||
デバッガ実行のみブレークポイントを設置する。 | ||
この関数は条件付きブレークポイントであり、デバッガがプログラムを監視中であればプログラムを一時停止 (ブレーク) するが、そうでなければ何もしないよう動作する。 | ||
## 効果 | ||
以下と等価: | ||
```cpp | ||
if (is_debugger_present()) { | ||
breakpoint(); | ||
} | ||
``` | ||
* is_debugger_present()[link is_debugger_present.md] | ||
* breakpoint()[link breakpoint.md] | ||
|
||
|
||
## 例外 | ||
投げない | ||
|
||
|
||
## 備考 | ||
- 実装としては、生成されるコードがプラットフォームに対して可能な限り最小になるように最適化することが期待される。例として、x86ターゲット環境ではINT3命令をひとつだけ生成することが期待される | ||
|
||
|
||
## 例 | ||
```cpp example | ||
#include <print> | ||
#include <debugging> | ||
#include <cmath> | ||
|
||
// なんらかの処理 | ||
double g(double a, double b) { | ||
return a / b; | ||
} | ||
|
||
double f(double a, double b) { | ||
double ret = g(a, b); | ||
if (std::isnan(ret)) { | ||
// 演算結果でNaNが発生したらブレークし、 | ||
// デバッガでパラメータ (ローカル変数) などを確認する | ||
std::breakpoint_if_debugging(); | ||
} | ||
} | ||
|
||
int main() { | ||
double ret = f(2.0, 0.0); | ||
std::println("{}", ret); | ||
} | ||
``` | ||
* std::breakpoint_if_debugging[color ff0000] | ||
* std::isnan[link /reference/cmath/isnan.md] | ||
### 出力 | ||
``` | ||
``` | ||
## バージョン | ||
### 言語 | ||
- C++26 | ||
### 処理系 | ||
- [Clang](/implementation.md#clang): 19 [mark noimpl] | ||
- [GCC](/implementation.md#gcc): 14 [mark noimpl] | ||
- [Visual C++](/implementation.md#visual_cpp): 2022 Update 10 | ||
## 参照 | ||
- [P2546R5 Debugging Support](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2546r5.html) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
# is_debugger_present | ||
* debugging[meta header] | ||
* std[meta namespace] | ||
* function[meta id-type] | ||
* cpp26[meta cpp] | ||
|
||
```cpp | ||
namespace std { | ||
bool is_debugger_present() noexcept; // (1) C++26 | ||
} | ||
``` | ||
## 概要 | ||
デバッガ実行中か判定する。 | ||
この関数は、デバッガがプログラムを監視中かどうかを判定する。プラットフォーム固有の結果を決定できない場合、ユーザーがこの関数を定義することで柔軟に動作を制御できる。 | ||
## 置き換え可能 | ||
ユーザーのプログラムでこの関数を定義することで、標準ライブラリで定義されるデフォルトの動作を置き換えることができる。 | ||
## 要求される振る舞い | ||
- この関数は事前条件をもたないこと | ||
## デフォルトの振る舞い | ||
- 実装定義 | ||
## 効果 | ||
デバッガがプログラムを監視中である場合、実装は`true`を返す。 | ||
## 例外 | ||
投げない | ||
## 備考 | ||
- 実装は、プログラムがデバッガによって監視されているかどうかを判定するために、必要に応じて即時クエリを実行する | ||
- Windowsまたは同等のシステムでは、この関数の動作はWin32関数の`::IsDebuggerPresent()`を呼び出すことで実現できる | ||
- POSIX環境では、監視親プロセスをチェックすることで実現できる。その際、監視親プロセスがデバッガであるかどうかは最善の努力で判定する | ||
- この関数は、結果のキャッシュを規定しない。既存の実装もデバッガの存在クエリについての結果をキャッシュするようなことはしておらず、そのコストが問題にはなっていなかった。また、結果をキャッシュする場合、[`std::breakpoint_if_debugging()`](breakpoint_if_debugging.md)のインタフェースにも影響してしまう | ||
## 例 | ||
```cpp example | ||
#include <print> | ||
#include <debugging> | ||
#include <cmath> | ||
// なんらかの処理 | ||
double g(double a, double b) { | ||
return a / b; | ||
} | ||
double f(double a, double b) { | ||
double ret = g(a, b); | ||
if (std::isnan(ret)) { | ||
// 演算結果でNaNが発生したらブレークし、 | ||
// デバッガでパラメータ (ローカル変数) などを確認する | ||
if (std::is_debugger_present()) { | ||
std::breakpoint(); | ||
} | ||
} | ||
} | ||
int main() { | ||
double ret = f(2.0, 0.0); | ||
std::println("{}", ret); | ||
} | ||
``` | ||
* std::is_debugger_present[color ff0000] | ||
* std::breakpoint[link breakpoint.md] | ||
* std::isnan[link /reference/cmath/isnan.md] | ||
|
||
### 出力 | ||
``` | ||
``` | ||
|
||
|
||
## バージョン | ||
### 言語 | ||
- C++26 | ||
|
||
### 処理系 | ||
- [Clang](/implementation.md#clang): 19 [mark noimpl] | ||
- [GCC](/implementation.md#gcc): 14 [mark noimpl] | ||
- [Visual C++](/implementation.md#visual_cpp): 2022 Update 10 | ||
|
||
|
||
## 参照 | ||
- [P2546R5 Debugging Support](https://open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2546r5.html) | ||
- [P2810R4 `is_debugger_present` `is_replaceable`](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p2810r4.html) |